$result = mysql_query$sql, $conn or die‘Could not get list of pending articles; ‘.. $result = mysql_query$sql, $conn or die‘Could not get list of pending articles; ‘... Whatever the reas
Trang 1Display all the current comments for this article on this page:
Try It Out User Control Panel
In this exercise, you’re going to create a page so users can maintain their own information
1. Enter the following code, and save it as cpanel.php:
“WHERE user_id=” $_SESSION[‘user_id’];
$result = mysql_query($sql, $conn)
or die(‘Could not look up user data; ‘ mysql_error());
$user = mysql_fetch_array($result);
?>
<form method=”post” action=”transact-user.php”>
<p>Name:<br>
<input type=”text” id=”name” name=”name”
value=”<?php echo htmlspecialchars($user[‘name’]); ?>”></p>
<p>Email:<br>
<input type=”text” id=”email” name=”email”
value=”<?php echo htmlspecialchars($user[‘email’]); ?>”></p>
<p><input type=”submit” class=”submit” name=”action”
value=”Change my info”></p>
Trang 2$result = mysql_query($sql, $conn)
or die(‘Could not get list of pending articles; ‘ mysql_error());
if (mysql_num_rows($result) == 0) {echo “ <em>No pending articles available</em>”;
} else {while ($row = mysql_fetch_array($result)) {echo “<tr>\n”;
echo ‘<td><a href=”reviewarticle.php?article=’
$row[‘article_id’] ‘“>’ htmlspecialchars($row[‘title’])
“</a> (submitted “ date(“F j, Y”, strtotime($row[‘date_submitted’]))
“)</td>\n”;
echo “</tr>\n”;
}}
$result = mysql_query($sql, $conn)
or die(‘Could not get list of pending articles; ‘ mysql_error());
if (mysql_num_rows($result) == 0) {echo “ <em>No published articles available</em>”;
} else {while ($row = mysql_fetch_array($result)) {echo “<tr>\n”;
echo ‘<td><a href=”viewarticle.php?article=’
Trang 3$row[‘article_id’] ‘“>’ htmlspecialchars($row[‘title’])
“</a> (published “ date(“F j, Y”, strtotime($row[‘date_published’]))
Figure 13-11
Trang 4How It WorksNow let’s take a look at cpanel.php The Control Panel page cpanel.phpis used to allow users to changetheir usernames and e-mail addresses They can also see all of the articles they have written, categorized byPending and Published articles
As always, you need to connect to the database And, as always, conn.phptakes care of that This time,you are displaying a Web page You load up header.php, which is your standard header for all Webdisplay pages
require_once ‘conn.php’;
require_once ‘header.php’;
You first go out to the database and get the user’s name and e-mail address
$sql = “SELECT name, email “
“FROM cms_users “
“WHERE user_id=” $_SESSION[‘user_id’];
$result = mysql_query($sql, $conn)
or die(‘Could not look up user data; ‘ mysql_error());
<form method=”post” action=”transact-user.php”>
Note the use of htmlspecialchars() This prevents strange characters such as < or > from messing upthe page These characters will be displayed using their entity equivalents (such as <and >)
<p>Name:<br>
<input type=”text” id=”name” name=”name”
value=”<?php echo htmlspecialchars($user[‘name’]); ?>”></p>
The rest of the form is standard HTML Now you need to display Pending and Published articles Time
to drop back into PHP:
<p>Email:<br>
<input type=”text” id=”email” name=”email”
value=”<?php echo htmlspecialchars($user[‘email’]); ?>”></p>
<p><input type=”submit” class=”submit” name=”action”
value=”Change my info”></p>
Trang 5<h2>Pending Articles</h2>
<div class=”scroller”>
<table>
This code gets all pending articles written by this user They are ordered by date_submitted, with the
oldest being first Please note that if there are no pending articles, this will not return a MySQL error.
You will still get a result set, but there won’t be any rows You handle that contingency next
$result = mysql_query($sql, $conn)
or die(‘Could not get list of pending articles; ‘ mysql_error());
If there are no pending articles, you simply state so and move on Otherwise
$result = mysql_query($sql, $conn)
or die(‘Could not get list of pending articles; ‘ mysql_error());
Trang 6if (mysql_num_rows($result) == 0) {echo “ <em>No published articles available</em>”;
} else {while ($row = mysql_fetch_array($result)) {echo “<tr>\n”;
echo ‘<td><a href=”viewarticle.php?article=’
$row[‘article_id’] ‘“>’ htmlspecialchars($row[‘title’])
“</a> (published “ date(“F j, Y”,strtotime($row[‘date_published’]))
“)</td>\n”;
echo “</tr>\n”;
}}Then load the footer It is only a few lines of HTML for now, but some day you will want to put a menu,
or perhaps a copyright line The great thing is, even if your site uses 300 pages, you will have to add thatinformation in only one place: footer.php
require_once ‘outputfunctions.php’;
require_once ‘header.php’;
$result = NULL;
if (isset($_GET[‘keywords’])) {
$sql = “SELECT article_id FROM cms_articles “
“WHERE MATCH (title,body) “
“AGAINST (‘“ $_GET[‘keywords’] “‘ IN BOOLEAN MODE) “
“ORDER BY MATCH (title,body) “
“AGAINST (‘“ $_GET[‘keywords’] “‘ IN BOOLEAN MODE) DESC”;
$result = mysql_query($sql, $conn)
or die(‘Could not perform search; ‘ mysql_error());
}echo “<h1>Search Results</h1>\n”;
if ($result and !mysql_num_rows($result)) {echo “<p>No articles found that match the search terms.</p>\n”;
} else {while ($row = mysql_fetch_array($result)) {
Trang 7First, you include the necessary files:
$sql = “SELECT article_id FROM cms_articles “
“WHERE MATCH (title,body) “
“AGAINST (‘“ $_GET[‘keywords’] “‘ IN BOOLEAN MODE) “
“ORDER BY MATCH (title,body) “
“AGAINST (‘“ $_GET[‘keywords’] “‘ IN BOOLEAN MODE) DESC”;
$result = mysql_query($sql, $conn)
or die(‘Could not perform search; ‘ mysql_error());
}
If you didn’t find a match, say so:
echo “<h1>Search Results</h1>\n”;
if ($result and !mysql_num_rows($result)) {
echo “<p>No articles found that match the search terms.</p>\n”;
Otherwise, loop through the results and display them as snippets on the screen:
Trang 8Summar y
Well, if you didn’t have writer’s cramp before, you probably do now We hope this application has givenyou some insight into the separation of content and design Because of the way the application wasdesigned, you can easily modify the look and feel of the application by either directly altering yourheader and footer files, or using a CSS file to set up different styles This won’t matter to your users;they will still be able to enter articles without ever having to worry about what the article will look like
on the Web when it’s published
We also hope that you understand the importance of updating your site often enough to draw usersback again and again By adding an application like this to your site, and allowing users to add contentfor you, you create a dynamically changing site with fresh information Just think about all the ways youcould implement such a design:
❑ Create a message board (This is examined in more detail in Chapter 16.)
❑ Add a daily comic Perhaps you have an artist who can draw you a comic every day You couldcreate an application that allows him or her to upload comic strips and allows users to comment
on them
❑ Compile photo journals A while back, there was a project in which photographers went all overthe world, and in a 24-hour period, they took their pictures and uploaded the digital images,and people in the central office typed up descriptions and allowed people to view them online
It was a very ambitious project and a perfect example of a CMS application
The bottom line is that if you have content that you want to be able to update on a regular basis, youdefinitely want to implement a CMS application And now, you have the basic tools to build one onyour own!
Perhaps you should send your users an e-mail to tell them of your improved functionality You’ll do that
in Chapter 14
Exercises
After all that typing, are we so cruel that we’d include more work at the end? Yes Yes we are
See how you might accomplish the following tasks:
1. Delete when appropriate When reviewing an article, the delete button always shows up,regardless of what happens in the transaction page Alter the code so the Delete button onlyshows up when the article is pending
2. Find out about the author.Authors of articles might want the readers to know a little moreabout them Add the ability to enter extra fields in a user’s profile, and provide a link on thearticle full-view page to the author’s information
3. Notify the author.Authors might want to be automatically notified when their stories havebeen approved Add an e-mail notification upon approval, and give the user the ability to toggletheir notification on and off
Trang 10Whatever the reason, you will occasionally need to send e-mails to many people, and you willneed a relatively easy way to do so.
Specifically, this chapter discusses the following:
❑ Administering a mailing list
❑ Creating a mailing list
❑ Opt-in and opt-out
So, are you ready to learn how to spam your Web site users? We hope not, because that is not whatyou are going to do Yes, you are going to use mailing lists And yes, you are going to send out
“mass” e-mails However, you are going to be responsible, and send e-mails only to those peoplewho have agreed to be recipients Right? Let’s get started
What Do You Want to Send Today?
Before you actually create the mailing list, you must have something that you intend to send toyour recipients The train of thought usually goes like this: You decide that you have some infor-mation you want to share with your users Here are a few possibilities:
Trang 11❑ Web site notifications: These are important tidbits of information about your Web site You willwant to let your users know you’ve improved the level of security for online transactions onyour site, for example.
❑ Newsletters:If you had a family Web site, for example, and wanted to let your whole familyknow about the new addition to your family, you could send them a newsletter
❑ Important announcements:“Our site will be down for 5 days Sorry for the inconvenience
We’ll let you know when it is back up.” (Oooh an opportunity for two mailings!)
❑ Advertising: Perhaps you’ve partnered with an online comic book store to offer deals on rarecomics to your members
Once you know what you want to say, you format the information you wish to share, using plain text or
HTML You try to figure out how you are going to e-mail this information to every member of your Web
site If you can figure out how to send it, you hope that your users will be able to read and appreciatewhat you sent with their many types of e-mail clients
In this chapter’s project, you are going to send out two different e-mails: Web site change notificationsand a newsletter The former will be sent to all members of the Web site The latter will be sent to thosewho subscribe to the newsletter only
You are going to use HTML in your mass e-mail, of course Because Chapter 11 taught you how to sendHTML in an e-mail, this should pose no problem at all You can also e-mail links to an online version ofthe HTML you are sending, so that those with text e-mail clients can see your hard work, as well
Coding the Administration Application
The first thing you’re going to do is to create the administration page, where you can add and removemailing lists There are a few scripts to tackle, but because they all rely on each other to work, you need
to enter them all now Hey you’re the one who wanted to write some code Let’s get cracking!Try It Out Preparing the Database
First, you’re going to create the file that will hold the server, username, password, and database values
1. Open your favorite text editor, and enter the following code, making sure you use the propervalues for your server:
Trang 123. Now you’re going to create the tables You can create them with your MySQL tool (such asPHPMyAdmin), or you can simply enter the following code, save it as sql.phpon your server,and load it in your browser:
<?phprequire(‘config.php’);
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
$sql = “CREATE DATABASE IF NOT EXISTS “ SQL_DB;
$res = mysql_query($sql) or die(mysql_error());
mysql_select_db(SQL_DB, $conn);
$sql1 = <<<EOSCREATE TABLE IF NOT EXISTS ml_lists (ml_id int(11) NOT NULL auto_increment,listname varchar(255) NOT NULL default ‘’,PRIMARY KEY (ml_id)
)EOS;
$sql2 = <<<EOSCREATE TABLE IF NOT EXISTS ml_subscriptions (ml_id int(11) NOT NULL default ‘0’,
user_id int(11) NOT NULL default ‘0’,pending tinyint(1) NOT NULL default ‘1’,PRIMARY KEY (ml_id,user_id)
)EOS;
$sql3 = <<<EOSCREATE TABLE IF NOT EXISTS ml_users (user_id int(11) NOT NULL auto_increment,firstname varchar(255) default ‘’,lastname varchar(255) default ‘’,email varchar(255) NOT NULL default ‘’,PRIMARY KEY (user_id)
)EOS;
$res = mysql_query($sql1) or die(mysql_error());
$res = mysql_query($sql2) or die(mysql_error());
$res = mysql_query($sql3) or die(mysql_error());
echo “Done.”;
?>
4. If you ran sql.phpin your browser, it should display a “Done.” message, indicating thedatabase tables were created
Trang 13Include config.phpin each file that requires access to MySQL like so:
As you can see here, the constants from config.phpare used to make your connection:
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
$sql = “CREATE DATABASE IF NOT EXISTS” SQL_DB;
$res = mysql_query($sql) or die(mysql_error());
mysql_select_db(SQL_DB, $conn);
Take notice of the CREATE DATABASEstatement There are a couple of things you should be aware ofabout creating databases If you already have a database (one that you created in another chapter, or ifyour site is already using a database), it’s better to keep your mailing list tables in that database Youdon’t need extra databases because if your Web site spans multiple databases, you will need to createmultiple connections to those databases, and that is extra overhead that is just not necessary
In addition, if there are any relationships between your tables from this application and tables fromother apps, they need to be in the same database For example, if you have a user table that stores yourregistered users for all applications, all of the applications that rely on that user table should reside in thesame database
If you do need to create a new database, the CREATE DATABASEcommand may still not work if your site ishosted by an Internet service provider (ISP) Some ISPs don’t allow programmed creation of databases Ifthis is the case, you may need to go through your ISP to create the database (through PHPMyAdmin, forexample) and run sql.php Just be sure to put the proper database name in the code See Chapter 10 formore information about creating databases
Trang 14This SQL is used to create the tables in your database:
$sql1 = <<<EOSCREATE TABLE IF NOT EXISTS ml_lists (ml_id int(11) NOT NULL auto_increment,listname varchar(255) NOT NULL default ‘’,PRIMARY KEY (ml_id)
)EOS;
$sql2 = <<<EOSCREATE TABLE IF NOT EXISTS ml_subscriptions (ml_id int(11) NOT NULL default ‘0’,
user_id int(11) NOT NULL default ‘0’,pending tinyint(1) NOT NULL default ‘1’,PRIMARY KEY (ml_id,user_id)
)EOS;
$sql3 = <<<EOSCREATE TABLE IF NOT EXISTS ml_users (user_id int(11) NOT NULL auto_increment,firstname varchar(255) default ‘’,lastname varchar(255) default ‘’,email varchar(255) NOT NULL default ‘’,PRIMARY KEY (user_id)
)EOS;
Note there are three tables: ml_lists, ml_users, and ml_subscriptions The ml_liststable tains two columns: the unique ID (ml_id) and the name of the mailing list (listname) The ml_userstable contains four columns: the unique ID (user_id), first and last name (firstname, lastname), ande-mail address (email)
con-The ml_subscriptionstable is where most of the “work” is done when it comes to mailing lists It tains three columns: ml_id, user_id, and pending The combination of ml_idand user_idmust beunique (You don’t want to have the same user subscribed to the same mailing list more than once,right?) The pendingcolumn is used to determine whether or not a user has confirmed his or her sub-scription Use of the pendingcolumn is discussed later in this chapter
con-The following lines simply run the SQL queries to create the tables As long as all three tables are created(or already exist), you will see “Done” echoed to the screen Otherwise, you will see an error message
$res = mysql_query($sql1) or die(mysql_error());
$res = mysql_query($sql2) or die(mysql_error());
$res = mysql_query($sql3) or die(mysql_error());
echo “Done.”;
Trang 15Try It Out Mailing List Administration
Next, you will create the admin page, where the administrator (that’s you!) can create, delete, andrename mailing lists
1. Create the following code, and save it as admin.php:
Add Mailing List:<br />
<input type=”text” name=”listname” maxlength=”255” />
<input type=”submit” name=”action” value=”Add New Mailing List” />
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
mysql_select_db(SQL_DB, $conn);
$sql = “SELECT * FROM ml_lists ORDER BY listname”;
$result = mysql_query($sql)
or die(‘Invalid query: ‘ mysql_error());
while ($row = mysql_fetch_array($result)) {
echo “ <option value=\”” $row[‘ml_id’] “\”>” $row[‘listname’]
Trang 162. The administrator needs the ability to send e-mails to the members of various mailing lists.Otherwise, what was the point of creating the mailing lists in the first place? Okay, you knowthe routine Enter the following code, and save it as quickmsg.php:
<?phprequire(‘config.php’);
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
mysql_select_db(SQL_DB, $conn);
$sql = “SELECT * FROM ml_lists ORDER BY listname”;
$result = mysql_query($sql)
or die(‘Invalid query: ‘ mysql_error());
while ($row = mysql_fetch_array($result)) {echo “ <option value=\”” $row[‘ml_id’] “\”>” $row[‘listname’]
Trang 17public $send_text = TRUE;
public $send_html = FALSE;
Trang 18} elseif ($this->send_html and !$this->send_text) {
if (!mail($this->to,$this->subject,$this->message,$this->headers)) {throw new Exception(‘Sending mail failed.’);
return FALSE;
} else {return TRUE;
}}}
?>
4. Okay, one more script When the administrator clicks a button, you need to have a page thathandles the transactions Enter the following, and save it as admin_transact.php:
<?phprequire(‘config.php’);
require(‘class.SimpleMail.php’);
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
mysql_select_db(SQL_DB, $conn);
if (isset($_POST[‘action’])) {
Trang 19switch ($_POST[‘action’]) {
case ‘Add New Mailing List’:
$sql = “INSERT INTO ml_lists (listname) “
“VALUES (‘“ $_POST[‘listname’] “‘)”;
mysql_query($sql)
or die(‘Could not add mailing list ‘ mysql_error());
break;
case ‘Delete Mailing List’:
$sql = “DELETE FROM ml_lists WHERE ml_id=” $_POST[‘ml_id’];
mysql_query($sql)
or die(‘Could not delete mailing list ‘ mysql_error());
$sql = “DELETE FROM ml_subscriptions “
“WHERE ml_id=” $_POST[‘ml_id’];
$sql = “SELECT listname FROM ml_lists “
“WHERE ml_id=’” $_POST[‘ml_id’] “‘“;
$result = mysql_query($sql, $conn)
$sql = “SELECT DISTINCT usr.email, usr.firstname, usr.user_id “
“FROM ml_users usr “
“INNER JOIN ml_subscriptions mls “
“ON usr.user_id = mls.user_id “
or die(‘Could not get list of email addresses ‘ mysql_error());
$headers = “From: “ ADMIN_EMAIL “\r\n”;
while ($row = mysql_fetch_array($result)) {
if (is_numeric($_POST[‘ml_id’])) {
$ft = “You are receiving this message as a member of the “;
$ft = $listname “\n mailing list If you have received “;
$ft = “this email in error, or would like to\n remove your “;
$ft = “name from this mailing list, please visit the “;
Trang 20$ft = “following URL:\n”;
$ft = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’]) “/remove.php?u=”
$row[‘user_id’] “&ml=” $_POST[‘ml_id’];
} else {
$ft = “You are receiving this email because you subscribed “;
$ft = “to one or more\n mailing lists Visit the following “;
$ft = “URL to change your subscriptions:\n”;
$ft = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’]) “/user.php?u=”
}}header(‘Location: admin.php’);
?>
That’s it for now You still have the user functions to worry about, but you’ll tackle those in a bit.For now, load a few of these pages in your browser to see them in action; then we’ll figure outhow they work
5. The first page of the mailing list application you want to take a look at is the Mailing ListAdministrator page Load admin.phpin your browser As you can see in Figure 14-1, you cancreate a new mailing list, delete an existing mailing list, or send a quick message to users Feelfree to create a couple of new mailing lists Go crazy, have fun, get wacky Good Let’s move on
6. Click the link at the bottom of the Mailing List Administrator page, “Send a quick message tousers.” A new page appears where you can compose a new message and send it to either a sin-gle mailing list, or all users (see Figure 14-2) If you just created these pages, you don’t have anyusers yet You can compose a message, but it won’t go to anyone You’ll need to create the userpages first, which you’ll do shortly
Trang 21Figure 14-1
Figure 14-2
Trang 22How It WorksLet’s take a look at admin.php:require(‘config.php’);
Now you should see why you put the connection values in a separate file By doing this, all you need is
a single line to include the constants, and you can use them in this page
Let’s pause here for a moment and talk about form submittal A common practice is to post a form back
to itself, and you certainly could have done that here When your page contains data that needs to beinserted into a database, however, you need to think twice about a self-posting form If the user were torefresh or reload the page, all of your database functions would run again, and that could be disastrous.You would end up with duplicate data, or delete records you didn’t mean to delete
Obviously, you don’t want anything like that to happen, so to minimize the probability, you post to aseparate form called admin_transact.php This page handles all of the necessary database transac-tions, and then redirects back to the page from which you came If the user reloads the page at thatpoint, no harm will come to your database
<form method=”post” action=”admin_transact.php”>
You might notice that all of your buttons have the same name, “action,” each with a different value.When posting the form, you will be accessing the $_POST[‘action’]variable to see which button waspressed, and perform the appropriate actions This allows you to use one script for multiple transactions,rather than having to create a page with multiple forms, each posting to a different transaction page
<input type=”submit” name=”action” value=”Add New Mailing List” />
Now you get all of the mailing lists available and wrap them in option tags so that they will appear onyour page in a drop-down select box
<select name=”ml_id”>
<?php
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
mysql_select_db(SQL_DB, $conn);
$sql = “SELECT * FROM ml_lists ORDER BY listname”;
$result = mysql_query($sql)
or die(‘Invalid query: ‘ mysql_error());
while ($row = mysql_fetch_array($result)) {echo “ <option value=\”” $row[‘ml_id’] “\”>” $row[‘listname’]
“</option>\n”;
}
?>
</select>
Trang 23This is the link to the e-mail portion of the admin’s functions, which is pretty self-explanatory:
<a href=”quickmsg.php”>Send a quick message to users</a>
You should be able to figure out quickmsg.phpfairly easily Most of it is HTML, and the PHP code ispractically identical to the code used to build the select in admin.php Feel free to cannibalize your owncode as often as you need
If you are scratching your head and trying to remember exactly how class.SimpleMail.phpworks,now would be a good time to take a break and go check out Chapter 11 There’s an analysis of the scripttoward the end of the chapter
Finally, you come to the real workhorse of the Mailing List Administrator application, admin_
transact.php This page is the one to which you post your forms, and it will process that information,update the database tables, and send out e-mails as required Let’s take a look under the hood:
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
Not only must you delete the mailing list, like this:
case ‘Add New Mailing List’:
$sql = “INSERT INTO ml_lists (listname) “
“VALUES (‘“ $_POST[‘listname’] “‘)”;
mysql_query($sql)
or die(‘Could not add mailing list ‘ mysql_error());
break;
case ‘Delete Mailing List’:
$sql = “DELETE FROM ml_lists WHERE ml_id=” $_POST[‘ml_id’];
mysql_query($sql)
or die(‘Could not delete mailing list ‘ mysql_error());
Trang 24If anyone was subscribed to that mailing list, you must delete those subscriptions, too:
$sql = “DELETE FROM ml_subscriptions “
“WHERE ml_id=” $_POST[‘ml_id’];
$sql = “SELECT listname FROM ml_lists “
“WHERE ml_id=’” $_POST[‘ml_id’] “‘“;
$result = mysql_query($sql, $conn)
by using the INNER JOINcommand in SQL You also must not send any e-mails or newsletters to those
that are awaiting subscription confirmation, so select only those where pending = 0, or false If pending
= 1(true), then that row is ignored
$sql = “SELECT DISTINCT usr.email, usr.firstname, usr.user_id”
“FROM ml_users usr “
“INNER JOIN ml_subscriptions mls “
“ON usr.user_id = mls.user_id “
“WHERE mls.pending=0”;
If the administrator did not choose “all” in the select list, you must limit your selection to the specificusers that are subscribed to the mailing list the administrator selected You do this by tacking on the ANDcondition:
if ($_POST[‘ml_id’] != ‘all’) {
$sql = “ AND mls.ml_id=” $_POST[‘ml_id’];
}Now execute the previous SQL statement, and return the results:
$result = mysql_query($sql)
or die(‘Could not get list of email addresses ‘ mysql_error());
Trang 25You may remember the next step from Chapter 11 This is how you add the From: header to an e-mail It
is fairly self-explanatory:
$headers = “From: “ ADMIN_EMAIL “\r\n”;
The following pretty piece of work is nothing more than a way to build up a custom message, depending
on whether the administrator is sending the e-mail to all mailing lists, or to a specific one:
while ($row = mysql_fetch_array($result)) {
if (is_numeric($_POST[‘ml_id’])) {
$ft = “You are receiving this message as a member of the “;
$ft = $listname “\n mailing list If you have received “;
$ft = “this email in error, or would like to\n remove your “;
$ft = “name from this mailing list, please visit the “;
$ft = “following URL:\n”;
$ft = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’]) “/remove.php?u=”
$row[‘user_id’] “&ml=” $_POST[‘ml_id’];
} else {
$ft = “You are receiving this email because you subscribed “;
$ft = “to one or more\n mailing lists Visit the following “;
$ft = “URL to change your subscriptions:\n”;
$ft = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’]) “/user.php?u=”
$row[‘user_id’];
}
Wrap the message entered on the quickmsg.phpform inside some extra disclaimer text before you send
it off to SimpleMail’s send()method:
And away it goes, before you loop back to the top of your whileloop and do it again with the next user
Notice that you are looping through each e-mail address you have and sending an e-mail to each one
using the $email->send()method It is important to note that the page will not finish loading until ithas sent every e-mail This works fine if you have a few e-mail addresses (a hundred or less) It has theadded benefit of allowing you (with slight modifications to the code) to personalize each e-mail with theperson’s first name (“Dear Billy-Bob,”)
If you need to send to more people and don’t want to deal with the long wait time, we recommend puttingall of your e-mail addresses in the BCC: field of the mail, using headers (as discussed in Chapter 11) Youcan’t personalize the e-mail, but the page will load much faster
Trang 26Of course, some day your site will be extremely popular, and you might have thousands of e-mails to send At that point, it might be time to start looking at a professional mailing list management applica- tion That, however, is beyond the scope of this book
After the page is done with its transactions, redirect the user to the admin.phppage Most of the time,this happens so quickly that you don’t notice the redirection at all
header(‘Location: admin.php’);
Sign Me Up!
Now it’s time to look at the other half of the application, the Mailing List Signup form This is the pageyou send your users to that enables them to sign up for any of the mailing lists that you have created.This application consists of user.php, user_transact.php, thanks.php, and remove.php Asalways, you’ll also be using the config.phpfile that you already created
On the surface, when you view the page from the Web, it looks like a simple application However,there’s a lot going on inside So let’s open it up and see what’s under the hood!
Try It Out Mailing List SignupThe first page you are going to create is the actual signup form
1. Enter the following code in your favorite PHP editor and save it as user.php:
<?phprequire(‘config.php’);
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
Trang 27$result = mysql_query(“SELECT * FROM ml_lists ORDER BY listname”)
or die(‘Invalid query: ‘ mysql_error());
while ($row = mysql_fetch_array($result)) {
echo “ <option value=\”” $row[‘ml_id’] “\”>”
Trang 282. Enter the transaction page by entering the following code in your PHP editor and saving it asuser_transact.php:
<?phprequire(‘config.php’);
require(‘class.SimpleMail.php’);
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
mysql_select_db(SQL_DB, $conn);
$headers = “From: “ ADMIN_EMAIL “\r\n”;
if (isset($_REQUEST[‘action’])) {switch ($_REQUEST[‘action’]) {case ‘Remove’:
$sql = “SELECT user_id FROM ml_users “
“WHERE email=’” $_POST[‘email’] “‘“;
$result = mysql_query($sql, $conn);
if (mysql_num_rows($result)) {
$row = mysql_fetch_array($result);
$user_id = $row[‘user_id’];
$url = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’])
$sql = “SELECT user_id FROM ml_users “
“WHERE email=’” $_POST[‘email’] “‘“;
$result = mysql_query($sql, $conn);
$sql = “INSERT INTO ml_subscriptions (user_id,ml_id) “
“VALUES (‘“ $user_id “‘,’” $_POST[‘ml_id’] “‘)”;
Trang 29mysql_query($sql, $conn);
$sql = “SELECT listname FROM ml_lists “
“WHERE ml_id=” $_POST[‘ml_id’];
$result = mysql_query($sql, $conn);
$row = mysql_fetch_array($result);
$listname = $row[‘listname’];
$url = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’])
“/user_transact.php?u=” $user_id
“&ml=” $_POST[‘ml_id’] “&action=confirm”;
$subject = ‘Mailing list confirmation’;
$body = “Hello “ $_POST[‘firstname’] “\n”
“Our records indicate that you have subscribed to “
“the “ $listname “ mailing list.\n\n”
“If you did not subscribe, please accept our “
“apologies You will not be subscribed if you do “
“not visit the confirmation URL.\n\n”
“If you subscribed, please confirm this by visiting “
“the following URL:\n” $url;
$mailmsg = new SimpleMail();
$sql = “UPDATE ml_subscriptions SET pending=0 “
“WHERE user_id=” $_GET[‘u’]
“ AND ml_id=” $_GET[‘ml’];
mysql_query($sql, $conn);
$sql = “SELECT listname FROM ml_lists “
“WHERE ml_id=” $_GET[‘ml’];
$result = mysql_query($sql, $conn);
$row = mysql_fetch_array($result);
$listname = $row[‘listname’];
$sql = “SELECT * FROM ml_users “
“WHERE user_id=’” $_GET[‘u’] “‘“;
$result = mysql_query($sql, $conn);
$row = mysql_fetch_array($result);
$firstname = $row[‘firstname’];
$email = $row[‘email’];
$url = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’])
Trang 30“/remove.php?u=” $_GET[‘u’]
“&ml=” $_GET[‘ml’];
$subject = ‘Mailing List Subscription Confirmed’;
$body = “Hello “ $firstname “,\n”
“Thank you for subscribing to the “
$listname “ mailing list Welcome!\n\n”
“If you did not subscribe, please accept our “
“apologies.\n”
“You can remove this subscription immediately by “
“visiting the following URL:\n” $url;
$mailmsg = new SimpleMail();
default:
$redirect = ‘user.php’;
}}header(‘Location: ‘ $redirect);
?>
3. You may have noticed when entering the last bit of code that you are redirecting your users to apage called thanks.php It would probably be a good idea to create that page now by enteringthe following code and saving it as thanks.php:
<?phprequire(‘config.php’);
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
Trang 31$msg = “Thank you for subscribing to the <i>”
$row[‘listname’] “</i> mailing list.<br />”;
$msg = “A subscription notification has been “
“sent to you at <b>$email</b>.<br /><br />”;
Excellent job! Now it’s time to test your code and figure out how it works
4. Open your browser and open user.php You should see a form that looks very much like theone in Figure 14-3
Trang 336. Open the confirmation e-mail There will be a link at the bottom (or a nonlinked URL if you areusing a text e-mail client).
7. Click the link, and it takes you back to the Thank You page, this time thanking you for ing your subscription You will get another e-mail informing you about your subscription, with
confirm-a link thconfirm-at confirm-allows you to remove yourself from the mconfirm-ailing list Don’t click thconfirm-at link just yet Firstyou’re going to send an e-mail to the mailing list you just subscribed to
8. Open admin.php, and then click the link at the bottom, “Send a quick message to users.”
9. In the Quick Message page, choose the mailing list that you just subscribed to in the previoussteps, and enter a subject Then type a quick message
10. Click Send Message.
11. Open your e-mail client again, and read the message you should have received.
How It Works
By now, you know how config.phpworks You know why you use it We won’t insult your gence by explaining again how it’s important to use this file to hold your MySQL connection info andpassword We are also going to skip over parts of the code that we’ve touched on before We certainlydon’t want to bore you!
intelli-Let’s take a look at user.phpinstead, shall we?
and finally looks up the user’s e-mail address:
$sql = “SELECT * FROM ml_users WHERE user_id = ‘$uid’;”;
$result = mysql_query($sql)
or die(‘Invalid query: ‘ mysql_error());
If you find a row, grab the e-mail address and stick it into a variable:
Trang 34Then use that e-mail address as the default value for the e-mail field on the form (How clever is that?)Email Address:<br />
<input type=”text” name=”email” size=”40” value=”<?php echo
$result = mysql_query(“SELECT * FROM ml_lists ORDER BY listname”)
or die(‘Invalid query: ‘ mysql_error());
while ($row = mysql_fetch_array($result)) {echo “ <option value=\”” $row[‘ml_id’] “\”>”
First, make the connection to the server, and select the database:
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
mysql_select_db(SQL_DB, $conn);
You will be building the e-mail message later The parameter $headerswill be the fourth parameter ofthe mail()function, and will insert a From address in the e-mail
$headers = “From: “ ADMIN_EMAIL “\r\n”;
For more information about headers, see Chapter 11 When loading user_transact.php, you eitherclicked a button named ‘action’(POST), or actionis in the URL as ?action=xyz(GET) Because itcan come across as a POSTor a GET, you use $_REQUESTto grab the value The variable $_REQUESTisyour “catch-all” predefined variable, which contains an associative array of all $_GET, $_POST, and
$_COOKIEvariables
if (isset($_REQUEST[‘action’])) {switch ($_REQUEST[‘action’]) {
Trang 35If ‘action’ = ‘Remove’, you look up the user ID in the ml_usersdatabase If you find a user id, youpass that ID on to remove.php, along with the mailing list id Your job is done, so you redirect the user
to remove.php
case ‘Remove’:
$sql = “SELECT user_id FROM ml_users “
“WHERE email=’” $_POST[‘email’] “‘“;
$result = mysql_query($sql, $conn);
if (mysql_num_rows($result)) {
$row = mysql_fetch_array($result);
$user_id = $row[‘user_id’];
$url = “http://” $_SERVER[‘HTTP_HOST’] dirname($_SERVER[‘PHP_SELF’])
If the user clicks the Subscribe button, a number of things have to happen First, you must look up thee-mail address that was provided to see if the user already exists:
case ‘Subscribe’:
$sql = “SELECT user_id FROM ml_users “
“WHERE email=’” $_POST[‘email’] “‘“;
$result = mysql_query($sql, $conn);
If the user does not exist (no rows were returned from your query), you will insert a new record in theml_userstable MySQL automatically assigns a user id
$result = mysql_query($sql, $conn);
To retrieve that user id, use the PHP function mysql_insert_id The variable $connis optional, but it’susually a good idea to include it If you omit it, it will automatically use the last open connection Themysql_insert_idfunction will return a valid value only if the last SQL statement run resulted in a col-umn being automatically incremented In this case that did happen — the column is user_id, which isthe value you need for the next part of your code
$user_id = mysql_insert_id($conn);
Trang 36If the e-mail address was found in the database, you simply grab the user ID from the record thatwas returned Either way, you now have a $user_id You also have a mailing list id, retrieved from
$_POST[‘ml_id’] That’s all you need to create a subscription record
} else {
$row = mysql_fetch_array($result);
$user_id = $row[‘user_id’];
}You may recall that the ml_subscriptionstable contains three columns: user_id, ml_id, and pending.The first two values you have The last one, pending, should be set to 1 until the user confirms the sub-scription You initially set up the table to set pendingto 1 as a default, so that column is automaticallytaken care of So you now have all the data you need to create a subscription, and just like that, you insertthe appropriate data into the subscriptions table
$sql = “INSERT INTO ml_subscriptions (user_id,ml_id) “
“VALUES (‘“ $user_id “‘,’” $_POST[‘ml_id’] “‘)”;
mysql_query($sql, $conn);
Now all that is left to do is to notify the user You do this in two ways: with a Thank You Web page thatconfirms that the subscription was processed, and with an e-mail to request confirmation because youdon’t want people to be able to sign other people up for mail It’s not a foolproof security measure, but itwill stop most abuse
You’ll send the e-mail, and then redirect the user to the Thank You page The first thing you do is get thename of the mailing list, using the mailing list id That’s because you want to tell the user in the e-mailwhich mailing list he or she subscribed to, and it wouldn’t be too helpful to say it was mailing list #42
$sql = “SELECT listname FROM ml_lists “
“WHERE ml_id=” $_POST[‘ml_id’];
$result = mysql_query($sql, $conn);
“/user_transact.php?u=” $user_id
“&ml=” $_POST[‘ml_id’] “&action=confirm”;
Then you build the subject and body of the message, concatenating the URL to the bottom, and send itoff with the mail()command:
$subject = ‘Mailing list confirmation’;
$body = “Hello “ $_POST[‘firstname’] “\n”
“Our records indicate that you have subscribed to “
“the “ $listname “ mailing list.\n\n”
Trang 37“If you did not subscribe, please accept our “
“apologies You will not be subscribed if you do “
“not visit the confirmation URL.\n\n”
“If you subscribed, please confirm this by visiting “
“the following URL:\n” $url;
$mailmsg = new SimpleMail();
The first thing to do is make sure the user ID and mailing list ID were passed to the function If not, yousimply redirect the user to user.php
Next, find the subscription that matches the user ID and mailing list ID and update the pending column
to 0 Remember that the user_idand ml_idcolumns combined make up a primary key, so there can bejust one record for each set of possible values
$sql = “UPDATE ml_subscriptions SET pending=0 “
“WHERE user_id=” $_GET[‘u’]
“ AND ml_id=” $_GET[‘ml’];
mysql_query($sql, $conn);
Look familiar? It should — you are grabbing the mailing list name based on the mailing list id, just asyou did for the Subscribe case Looks like this is a prime candidate for a function:
$sql = “SELECT listname FROM ml_lists “
“WHERE ml_id=” $_GET[‘ml’];
$result = mysql_query($sql, $conn);
$row = mysql_fetch_array($result);
$listname = $row[‘listname’];
Trang 38Now you need to retrieve the user’s e-mail address based on his or her user id, so you can send him orher an e-mail This should also look familiar:
$sql = “SELECT * FROM ml_users “
“WHERE user_id=’” $_GET[‘u’] “‘;”;
$result = mysql_query($sql, $conn);
“/remove.php?u=” $_GET[‘u’]
“&ml=” $_GET[‘ml’];
$subject = ‘Mailing List Subscription Confirmed’;
$body = “Hello “ $firstname “,\n”
“Thank you for subscribing to the “
$listname “ mailing list Welcome!\n\n”
“If you did not subscribe, please accept our “
“apologies.\n”
“You can remove this subscription immediately by “
“visiting the following URL:\n” $url;
$mailmsg = new SimpleMail();
$mailmsg->send($email,$subject,$body,$headers);
Off your user goes, to the Thank You page:
$redirect = “thanks.php?u=” $_GET[‘u’] “&ml=”
The user_transact.phppage is not terribly complicated However, when you have a single page forming multiple tasks, you need to be careful that all situations are handled correctly
per-thanks.phpNext let’s look at the code in thanks.php Most of it is familiar code that you have used elsewhere Youshould have no problem breezing through this one
Trang 39Connect to the database:
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
Next, you get the listname, based on the mailing list id If you find it, you build the message to include
“Thanks for subscribing.” Once you get past this point, you know you have the user ID and mailinglist ID
$msg = “Thank you for subscribing to the <i>”
$row[‘listname’] “</i> mailing list.<br />”;
Trang 40Then comes the custom part of the message Currently, there are two types of Thank You messages:
“A confirmation request has been sent to ”, and “A subscription notification has been sent ”switch ($_GET[‘t’]) {
$msg = “A subscription notification has been “
“sent to you at <b>$email</b>.<br /><br />”;
}Finally, you finish the page by putting a link back to user.php, and displaying the page
1. The e-mail that you sent yourself has a link on it allowing your users to remove themselvesfrom the mailing list, if they desire Enter that file now, and save it as remove.php:
<?phprequire(‘config.php’);
$conn = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS)
or die(‘Could not connect to MySQL database ‘ mysql_error());
mysql_select_db(SQL_DB, $conn);
if (isset($_GET[‘u’], $_GET[‘ml’])) {
$sql = “DELETE FROM ml_subscriptions “
“WHERE user_id=” $_GET[‘u’]
“ AND ml_id=” $_GET[‘ml’];
$result = mysql_query($sql, $conn);
} else {die(“Incorrect parameters passed for deletion”);