Today, we are going to be building a newsletter system using PHP with
a MySQL background. The tutorial will cover building a system that
allows for multiple newsletter lists and the sending of messages to
specific lists.
Hey guys, so we are going to be building a pretty complex newsletter system, so lets get started! You are going to need two resources for the project.
Now let's first create our database, and our tables we be created progressively later. We are now going to start coding. Also, as a word of note, I will assume that we will be working with files in our admin folder, unless I otherwise specify, as most of code be in this folder.
So the first section sets up our database variables, so make sure you
edit it so it firsts your local configuration. Our next blurb sets up
some email attributes we will use later. The last section starts up our
session so we can access it, requires our classes.php
file (we'll create that in just a second), sets the defaults for some
layout options, and then sets error reporting to 0 to stop annoying
warnings. However, if you seem to be having trouble, try commenting out
this line.
Now go ahead and create our classes.php file and add in:
That is a huge chunk of code, and I'll go through it. Our first
function handles when the user posts our login, and then sends the data
to our check_username_and_pw function. Our logged_in function simply
returns whether a user is logged in. Our login_required function checks
to see if we are logged in, and if not, sends us to the login page.
The next function simply named query() preforms a query on our DB, and was created by Jeffrey Way. I added the link creation and close functions to make it even easier. Our next function I created especially so we can easily run COUNT SQL queries, and our check_username_and_pw function checks to see if we can find a user with the same email and MD5 hashed password, and if so, sets our session variables.
Now, we are going to create our index.php page just so we can style. Open up index.php and add:
So in this, we require our config file, set up our title, and then
sets up our content variable, and then last requires our layout file.
When you first open it up it should look like:
Now open up our style sheet. I like to use the 960.gs reset and typography styles, compressed in TextMate. So the top of my CSS file looks like:
Let's first style our main elements, so add the following styles:
Now your page should look like:
Now if we style the tabs with a nav background and then a hover background on each of the links and you should see:
Now, while we are working on the file, go ahead and add the following styles for our mini layout, form inputs, tables, large links, and our error & success messages.
Those are some styles that I like to use across all my projects. Now
that we have finished the layout, we are going to continue onto
authentication.
I'll explain each part of the code. First we require our config file.
Next we check to see if we are logged in, and if we are, we redirect
home. Next we set the title, and our layout options. Then we check to
see if we have a POST and if the POST had a username and password, and
if so, we call the validate_user function from our classes file. We next
set the variable error to our session errors, and then we set up our
form and output any errors. Now we are going to create our logout page,
so create logout.php and put the following in it:
We again require our config file, set our session to an empty array,
then destroy our session and redirect to our login page. Now that you
have done all this, your login page should look like:
We are also going to create a user record (and our table) so that we can add in the authentication logic and you can view the pages with the code up ahead. To create a user with the username of admin and a password of secret. To add this, run this SQL:
So now that we have our newsletters table, we are going to create the pages for each action. Create four files named: newsletters.php, newsletters_delete.php, newsletters_edit.php, and newsletters_new.php. First open up newsletters.php:
So this file has the same basic feel of our login page. We require
our config, make sure we are logged in, set our title. Next we use our
query() function to perform a SELECT query to find all of our
newsletters. We then set the current tab for our layout. After we loop
through the array returned by our query, and create the the table
layout. Then we call a yet-unknown function, and create our page. Before
you will be able to view the page, you will need to add the following
to your classes.php file to easily handle our error messages:
While you probably will not have any data, when you have a few records it will look like: (though a bit less squished)
Now we are going to work on our new action, so open up newsletters_new.php and add the following:
So I hope you have noticed the pattern at the top of each of our files. We first require our config.php
file, then make sure we are logged in, and then set our current tab,
and we then add some extra logic for handling POSTs and then we set our
title, our content, and then render the page. The POST section is fairly
simple to understand so I'll explain it quickly.
We first check to see if an item with the name of submitted was sent. This is the hidden field we have after the submit button. Next, we create a link to our database using the variables from our config file. Next we create our SQL insert query, using our POSTed variables. Next we query (not our function) the database, and if an error is raised, we show the error returned. Next, we close the query, then we set our success message, and then redirect to the listing page. Your page should look like:
Next we are going to work on our edit page and add the following:
Just like all of our files, we start off with the same block. After
our POST block (which I will talk about in a second), we set id to our
requested id, making sure it is an integer. We then use our query
function to find the newsletter we are working with, and sets a few
variables to the returned results. You may ask why we put a [0] before
we requested each value, and the reason is the query function returns an
array of all the records, and each record is an array, so we need to
access the first array in our results variable. The line where we set
the variable visible ifs actually a compressed if/else statement. the if
part is the == 1, then if that is true, the variable is set to checked,
else to nothing. Then we have our form.
Our POST block is very similar to our new page, and will always start the same way across the rest of our pages. We then check to see if the check box was check, and set a variable here again. Then we have our UPDATE query, again run the query, set our success message, and then redirect home. THis is how the form looks and the message seen after editing:
The last page for this section is the easiest, as it is the delete page. Open up the file and paste to following:
In this block we require our config, make sure we are logged in, then
save the requested id to a variable, create a MySQL connection, setup
our SQL query, then execute the query. We next check to see if a row was
affected, and sets a message appropriately. We then redirect to the
newsletters page. Congrats, you have finished the first of four CRUD
sections. Next, we will work on the CRUD for our templates.
We have an auto-incrementing id column, a name column, a columns
column to save the number of columns (the application only scales to 2
columns, which should be enough, but can easily be expanded. This could
also be used for different sections.), and our body. Just like last
time, we need to make each of our pages, and we will have a templates.php page, as well as templates_new.php, templates_edit.php, templates_delete.php, and templates_preview.php. We are first going to work on our templates.php file, so open it up and paste:
Again we start with the basics. We then preform a query to find all
of our templates. We then loop through each array in templates and we
create a table. We then get our error (and success) messages, and then
our content. Your page should look something like:
Now, moving on to our our new page, paste the following:
So, again, we have our same header. Our POST again creates a MySQL
connection, then we create our query, and using mysql_real_escape_string
to allow any characters into the record, and then we execute our query,
set our success message, and redirect to our templates listing. If you
look at our form, I also ask for variables to be inserted for our
content, and I will show you how this comes into play later when we
match a message with a template. Your page should look like:
Next we are going to work on our edit page. If you have noticed, much of this code is copy and paste across all of the same actions, so make it easy on yourself.
We start with the same intro, then our POST block, our title, then
our requested id. After, we try and find the template we are working
with, then sets three variables so that we can inset them into our
content block. We also convert all of the tags we stored to HTML
characters so everything will display. When looking at our POST block,
you will notice we create our link, then our query and again use
mysql_real_escape_string to save everything, execute our query, and then
set our message, and redirect to our templates list. Your edit page
(with a sample record) should look like:
Now we will create another delete page, so open up our delete page and paste in:
I hope you have picked up the pattern here, this is a very simple
page. Now we are going to work on an extra page that is not part of the
CRUD spectrum; we are going to create a preview page. The binoculars in
the action part on the table is the link for each one (in a new window).
So open up our preview page. The page is very simple, we find our
template and echo the data, and then append a javascript close button.
The code looks like:
And an example preview looks like:
Now we have finished with our Templates, we are ready to move onto the next step!
Refers to each subscriber, and the second:
Creates a table for our many-to-many relationship with our
newsletters. A subscriber can have multiple subscription to newsletters,
so they can subscribe to multiple ones, and each newsletter can have
many subscribers. To create the most dynamic solution, we have a linking
table.
Let's first create our files. The files we are going are going to have are subscribers.php, subscribers_delete.php, and subscribers_edit.php. Our create action will be created later for the front-end. First open up subscribers.php and paste in:
We have basically the same listing pages as before, except this time
we will be finding our subscribers. Your page (with some sample data)
should look like:
Now we will move on to our edit page:
This page is fairly different so I will explain each part. The header
is the same we have been using. I'll skip the POST block and come back
to it. We then continue the same code. We next find our current
subscriber. Next we find all newsletters (this includes ones that are
not visible - visible mean visible to the public) and then all of the
subscriber's subscriptions. We next loop through every newsletter record
returned, we next reset some values. Next, we loop through every
subscription the user has, and if the subscription's newsletter_id is
equal to the current newsletter we are looping we set $s true, and
$subid equal to the subscription id. We then set the variable $checked
equal to either checked or nothing depending on whether a subscription
was found for this subscriber and the current newsletter in the loop.
Next we create the checkbox form area, with a lot of hidden fields.
First, we have the actual checkbox with a name that will create an array
for each checkbox. We then have our label, and next we output wether or
not the subscription exists, the newsletter_id and then the
subscription_id for when the subscription exists. After which we have
our normal content.
Now, if we move on to our POST block. We first get the id posted from our hidden field at the bottom. We next create our MySQL link. Next we have our first SQL query where we update the subscriber record. Next we loop through every newsletter checkbox. The first conditional statement checks to see if the POSTed data says we do not have an existing subscription, and the user wants to subscribe to the newsletter. To handle this, we are going to perform a SQL INSERT into our subscriptions table where our subscriber_id is the same as the user_id we are editing, and newsletter_id equal to the 'nlid' value POSTed by one of our hidden fields. We then execute that SQL INSERT query. The elseif conditional statement says that if our subscription exists, but the checkbox was unchecked so we unsubscribe, we need to delete the subscription. We handle this with a SQL DELETE query. To form our query we set $subid equal to the posted value for our 'subid'. We then create our query by deleting the record where the subscription id equals our variable of $subid. Next we execute the query, set our session success message, and then redirect back to our subscribers page. Your final edit page should look like: (filled with sample data)
We have one last page to work on for the subscribers part of the backend: the delete page. Just like before, this page is very simple:
Next, we'll create the files for this step. Creates seven files, each named messages.php, messages_delete.php, messages_edit.php, messages_new.php, messages_new_step2.php, messages_new_step3.php, and messages_preview.php. Let's first open up messages.php and make it look like:
This is our routine table, except we now have 4 'extra' links now,
one to send the message, one to preview, one to edit, and one to delete.
Your page should look like:
Now we are going to start work on our new pages. The first page is where all messages start out, and then you can progress on and enter the actual message on the next page. The reason for this is because we first need to create the initial message in the DB and so we can find information about the template. The step2 page is basically the edit page (there are six line differences according to FileMerge). Open up our new file and paste the following:
This page is very similar to what our other new pages look like, but
this one was one change in the POST block. Right after we perform the
SQL INSERT, we find the most recent insert id. Now this is not the
perfect solution, but I prefer it to performing another SQL query to
find a row using unindexed columns. This step should look like:
We then redirect to step2, so let's open up the file:
Hopefully you have gotten the gist of all the pages and understand
the page above. We have our normal heading. we then set our id from our
GET request. Next we find the message we are working with, then we find
all the templates and construct a drop down. We also use this look to
define whether we will have one or two textareas. Next we have our POST
block, which creates the link, then checks to see if we are working with
one or two columns and creates the appropriate SQL query. After that we
have our form. Your form should look like:
Now we will continue onto step 3, so open up the file and paste:
The page is very simple and is the end of creating a message. It
offers us a few links. The first is a link to preview the message. The
next offers to take us back home. The third offers to take us to send
the message (Step 10). The page looks like:
Now we are going to continue on to our edit page. I will not explain it as it is the same file as messages_new_step2.php, so you can refer there.
The page will look almost identical to our step 2, but the textarea will have content. Now we will create the delete page with:
That page should also look familiar. The final page we are going to
work on in this step is our preview page, so open it up and place:
This file is somewhat different than you have seen, so I'll walk you
through it. First have have our normal heading. Next we find the current
message we are working with, and set a few variables to the results.
Next we find the template we are working with and set a variable equal
to the body. Next, we have a conditional statement that checks to see
the number of columns the template has. If it has we use the PHP
function str_replace to replace the %content% tag we have with our
actual content. Otherwise, we first perform a str_replace for the left
column, and then on the result of that we perform str_replace again for
the right column. Now we are ready to continue onto the front-end.
I'll explain the page first and then we will get to the picture
so-far and the page styling. In the PHP section at the top we require
our config.php file (now in the
admin directory), then find all of our publicly visible newsletters and
create a check box array. You will notice that we are not handling the
POSTed data here, and I chose to do that in our subscribe.php, and we will get to that, but first let's style the page. The page should currently look like:
First I added the 960.gs reset file like I did in our other stylesheet. Then I added the three following styles to make the design look like:
So now that we have a clean and simple page, we are going to continue on and work on our subscribe.php file. Go ahead and open the file and paste:
This page is very much like our edit subscribers page, but no DELETE
SQL queries happen here. We simply check to make sure we have all POSTed
data. We then set a few variables to our POSTed data, and then create
and perform a SQL INSERT query to add the person to our subscribers
table. After which we perform a SQL query to find that just created
subscriber (insert_id was not working this time for me). We then loop
through all of the POSTed newsletters and check to see if we want to
subscribe to them, and perform SQL INSERTs when needed. If all goes to
plan, you see a nice screen like the one below:
We have on last page here to work on, and that is the preferences.php file. This is where a user can edit their email subscription. I am going to split the page in two. First we have our PHP block:
In this block, a lot is going on. First, we include our config file.
Next, we check for a POST, and if we have one, we update our database.
This portion is copied exactly from our subscribers_edit.php
file so you can look there for a bit more explanation. Next depending
on if we have a get request, we set our variable (this variable is used
in the HTML section of the page). We then look for a subscriber with
that email, and if one exists or we are showing the find portion, we
continue, otherwise we are redirected home. Next we find all of our
newsletters, and all of the subscriber's subscriptions, and then create
our checkbox form. The HTML portion looks like:
In our HTML block we have two forms and some PHP to choose which one
to display. The top form is the form the user sees if a record in the
database has been found. The second form is for entering your email and
having the system find it. The second form looks like:
And the first looks like:
And the second form after we saved our preferences:
Now that we have finished the front-end, we have one last step: sending the emails!
The first part we again require our config, then make sure the user
is logged in, then our title, make sure our id is an integer, and then
set our tab. Next we have our complicated post block. First we set up
our base query, and running just that would return 0 records, which is
good because that means no users will be send the newsletter. Next we
loop through every newsletter that we want to send to, and find all of
the subscriptions for that newsletter. We then create a string that will
be appended to our original SQL query so that we can find every
subscriber. Now, we run that query and create an array where the keys
are the emails and the name is the value, and this helps us use names
when the user looks at the email in their mail application, showing the
TO: as their name. We next find the message we are working with, and set
the subject, message, and template id to variables. We then find our
template and set the body to a variable. Then we use the same code from
the message preview to replace the strings inside the template the the
parts of the message. Then we call our yet-to-be-created-function
send_email_to_mass and then redirect home.
Leaving our POST block, we create the same checkbox list of newsletters so the admin can pick which one(s) he wants to send the message to. Then we have a simple form that looks like:
Now, open up our classes.php file and add the following function:
So first, we have our function declaration, and it expects four
variables to be passed to it, from, recipients, body, and subject. Next
we require the sqift_required.php
file of our Swift Mailer Library. Next we create a new Mail Transport
(this uses the PHP mail function, so it would be sending from your local
machine, for the documentation on the three transport types, see the documentation).
Next we create a mailer using that transport. Then we create a new
message from our subject, then set our from, to, and body. Then we use
the batch_send function so that each recipient only sees themselves on
the email, and no one else.
There is one possibly downside of doing it the way I have, and that is if you are sending many messages, the page may take forever to load. A solution to tthis would be running a Javascript AJAX request to send each and every message, but I won't cover that here. Now that we have finished working on sending messages, we are going to spice up the home page and then we will be done!
The page is very simple. We require our config, make sure we are
logged in, then we perform six count queries, one for each of our tables
and then output that. This is what the final page look like:
Hey guys, so we are going to be building a pretty complex newsletter system, so lets get started! You are going to need two resources for the project.
- The Silk Icon set will be used to add some visual 'flair' to the application.
- The Swift PHP Mailer will be used to send our emails.
Step 1: Create the Application Skeleton
When starting any project, I like to layout the folders before I start coding, so lets do that now. First, create the overall project directory. Next, create a folder named admin within your project folder. Then inside the admin folder, add two folders names media and swift. Finally, create a folder named images inside the media directory. Also, you can place the Swift lib folder inside the swift folder we created. You can also copy over the six silks icons we will be using:- bullet_green.png
- bullet_red.png
- delete.png
- email_go.png
- find.png
- page_edit.png
Now let's first create our database, and our tables we be created progressively later. We are now going to start coding. Also, as a word of note, I will assume that we will be working with files in our admin folder, unless I otherwise specify, as most of code be in this folder.
Step 2: Application Configuration
Every application will have some type of configuration file, and we are going to create ours now. Go ahead and create a file named config.php and add the following:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
| # admin/config.php <?php // DB Settings define( 'DB_SERVER' , 'localhost' ); define( 'DB_USER' , 'root' ); define( 'DB_PASSWORD' , '' ); define( 'DB_NAME' , 'nettuts_ns_demo' ); define( 'FROM_EMAIL' , 'no_reply@ohyeahemail.com' ); define( 'FROM_NAME' , 'oh yeah email!' ); session_start(); require_once 'classes.php' ; $mini = false; $nonav = false; error_reporting (0); |
Now go ahead and create our classes.php file and add in:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
| # admin/classes.php <?php // Authentication function validate_user( $username , $pw ) { if (check_username_and_pw( $username , $pw )) { header( 'Location: index.php' ); } else { $_SESSION [ 'error' ] = "Login error." ; header( 'Location: login.php' ); } } function logged_in() { if ( $_SESSION [ 'authorized' ] == true) { return true; } else { return false; } } function login_required() { if (logged_in()) { return true; } else { header( 'Location: login.php' ); } } // mysql function query( $sql ) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $stmt = $link ->prepare( $sql ) or die ( 'error' ); $stmt ->execute(); $meta = $stmt ->result_metadata(); while ( $field = $meta ->fetch_field()) { $parameters [] = & $row [ $field ->name]; } $results = array (); call_user_func_array( array ( $stmt , 'bind_result' ), $parameters ); while ( $stmt ->fetch()) { foreach ( $row as $key => $val ) { $x [ $key ] = $val ; } $results [] = $x ; } return $results ; $results ->close(); $link ->close(); } function count_query( $query ) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); if ( $stmt = $link ->prepare( $query )) { $stmt ->execute(); $stmt ->bind_result( $result ); $stmt ->fetch(); return $result ; $stmt ->close(); } $link ->close(); } function check_username_and_pw( $u , $pw ) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $query = "SELECT * FROM users WHERE username = ? AND password = ? LIMIT 1" ; if ( $stmt = $link ->prepare( $query )) { $p = md5( $pw ); $stmt ->bind_param( 'ss' , $u , $p ); $stmt ->execute(); $stmt ->bind_result( $id , $username , $pw ); if ( $stmt ->fetch()) { $_SESSION [ 'authorized' ] = true; $_SESSION [ 'username' ] = $username ; return true; } else { return false; } $stmt ->close(); } $link ->close(); } |
The next function simply named query() preforms a query on our DB, and was created by Jeffrey Way. I added the link creation and close functions to make it even easier. Our next function I created especially so we can easily run COUNT SQL queries, and our check_username_and_pw function checks to see if we can find a user with the same email and MD5 hashed password, and if so, sets our session variables.
Step 3: Application Layout
Our next file we will work on is our layout.php file, so go ahead and create it. In our head section we simply declare our regular XHTML declarations. If you notice, we automatically add the title of the page to another string for our title. Then we have a stylesheet (go ahead and create that too in our media folder). After which we open our body tag, and check to see if we want a mini layout, and if so adds a class. Then we have our header, and then check to see if we want our navigation, and if we do, we show our tabs. I also added a way to add a current class for each tab. We also then have a logout link, and then have our container div. In this, we add an h3 tag with our title, and then echo our content.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| # admin/layout.php <head> <meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" /> <title><?php echo $title ; ?> » my newsletter app</title> <!-- Stylesheets --> <!-- <link rel= "stylesheet" href= "media/style.css" type= "text/css" media= "all" /> --> </head> <body<?php if ( $mini == true) { ?> class = "mini" <?php } ?>> <div id= "header" > <h1><a href= "index.php" >my newsletter app</a></h1> </div> <?php if ( $nonav == false) { ?> <div id= "nav" > <a href= "messages.php" <?php if ( $tab == 'mess' ) {?> class = "current" <?php } ?>>messages</a> <a href= "subscribers.php" <?php if ( $tab == 'sub' ) {?> class = "current" <?php } ?>>subscribers</a> <a href= "newsletters.php" <?php if ( $tab == 'nl' ) {?> class = "current" <?php } ?>>newsletters</a> <a href= "templates.php" <?php if ( $tab == 'temp' ) {?> class = "current" <?php } ?>>templates</a> <span class = "right" > <a href= "logout.php" >log out</a> </span> </div> <?php } ?> <div id= "container" > <h3><?php echo $title ;?></h3> <?php echo $content ; ?> </div> </body> </html> |
1
2
3
4
5
6
7
8
9
| # admin/index.php <?php require_once 'config.php' ; $title = "Home!" ; $content = <<<EOF <h3>current stats</h3> Our home page! EOF; include 'layout.php' ; ?> |
Now open up our style sheet. I like to use the 960.gs reset and typography styles, compressed in TextMate. So the top of my CSS file looks like:
1
2
3
4
5
| # admin/media/style.css /* reset */ html,body,div,span,applet,object,iframe,h 1 ,h 2 ,h 3 ,h 4 ,h 5 ,h 6 ,p,blockquote, pre ,a,abbr,acronym,address,big,cite, code ,del,dfn,em,font,img,ins,kbd,q,s,samp,strike,strong, sub ,sup,tt,var,b,u,i, center ,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table, caption ,tbody,tfoot,thead,tr,th,td{ margin : 0 ; padding : 0 ; border : 0 ; outline : 0 ; font-size : 100% ; vertical-align : baseline ; background : transparent }body{ line-height : 1 }ol,ul{ list-style : none }blockquote,q{ quotes : none }blockquote:before,blockquote:after,q:before,q:after{ content : '' ; content : none }:focus{ outline : 0 }ins{ text-decoration : none }del{ text-decoration : line-through }table{ border-collapse : collapse ; border-spacing : 0 } /* typography */ body{ font : 13px / 1.5 Helvetica , Arial , 'Liberation Sans' ,FreeSans, sans-serif }a:focus{ outline : 1px dotted invert }hr{ border : 0 #ccc solid ; border-top-width : 1px ; clear : both ; height : 0 }h 1 { font-size : 25px }h 2 { font-size : 23px }h 3 { font-size : 21px }h 4 { font-size : 19px }h 5 { font-size : 17px }h 6 { font-size : 15px }ol{ list-style : decimal }ul{ list-style : square }li{ margin-left : 30px }p,dl,hr,h 1 ,h 2 ,h 3 ,h 4 ,h 5 ,h 6 ,ol,ul, pre ,table,address,fieldset{ margin : 10px 0 ;} |
1
2
3
4
| # admin/media/style.css #header { width : 85% ; margin : 0 auto ;} #header h 1 a { text-decoration : none ; color : #000 ;} #container { width : 85% ; background : #111 ; margin : 5px auto ; color : #fff ; padding : 10px ;} |
Now if we style the tabs with a nav background and then a hover background on each of the links and you should see:
1
2
3
4
5
6
| # admin/media/style.css /* tabs */ #nav { margin : 0 auto 2px ; padding : 10px ; width : 85% ; background : #444 ;} #nav a { padding : 12px 10px ; margin : 0 ; color : #fff ; text-decoration : none ; text-align : center ;} #nav a.current, #nav a:hover { background : #111 ;} #nav span. right { float : right ;} |
Now, while we are working on the file, go ahead and add the following styles for our mini layout, form inputs, tables, large links, and our error & success messages.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
| # admin/media/style.css body.mini #header { width : 30% ; text-align : center ;} body.mini #container { width : 30% ;} /* form */ form input.text { width : 95% ; font-size : 16px ;} form textarea { width : 95% ; height : 100% ;} /* table */ table { width : 98% ; text-align : right ; border : rgb ( 128 , 128 , 128 ); font-size : 12px ; margin : 5px 10px ; color : #000 ; background : #fff ;} table th { background-color : rgb ( 229 , 229 , 229 ); border : 1px solid rgb ( 187 , 187 , 187 ); padding : 3px 6px ; font-weight : normal ; color : #000 ;} table tr td { border : 1px solid rgb ( 221 , 221 , 221 ); padding : 3px 6px ;} table tr:hover { background-color : rgb ( 240 , 240 , 240 ); color : #000 ;} /* a */ a. large { padding : 5px ; color : #000 ; background : #eee ; text-decoration : none ; margin : 5px ;} a. large . right { float : right ;} a.large:hover, a. large .current { background : #444 ; color : #fff ;} /* messages */ #message { margin : 5px 10px ; padding : 4px ; display : block ; text-align : center ;} #message.error { background : #FFEBE8 ; border : 1px solid #CC0000 ; color : #CC0000 ;} #message.success { border : solid 1px #349534 ; background : #C9FFCA ; color : #008000 ;} |
Step 4: Authentication
We are going to be working with a very simple authentication system. Create a login.php and place the following inside:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| # admin/login.php <?php require_once 'config.php' ; if (logged_in()) {header( 'Location: index.php' );} $title = "login" ; $nonav = true; $mini = true; if ( $_POST && (! empty ( $_POST [ 'username' ]) ) && (! empty ( $_POST [ 'password' ]))) { validate_user( $_POST [ 'username' ], $_POST [ 'password' ]); } $error = $_SESSION [ 'error' ]; $content = <<<EOF $error <form action= "login.php" method= "post" > <p> <label for = "username" >username:</label><br /> <input type= "text" name= "username" class = "text" /> </p> <p> <label for = "password" >password:</label><br /> <input type= "password" name= "password" class = "text" /> </p> <p> <input type= "submit" value= "login" /> </p> </form> EOF; include 'layout.php' ; ?> |
1
2
3
4
5
6
7
| # admin/logout.php <?php require_once 'config.php' ; $_SESSION = array (); session_destroy(); header( 'Location: login.php' ); ?> |
We are also going to create a user record (and our table) so that we can add in the authentication logic and you can view the pages with the code up ahead. To create a user with the username of admin and a password of secret. To add this, run this SQL:
1
2
3
4
5
6
7
8
9
| CREATE TABLE `users` ( `id` int(10) AUTO_INCREMENT, `username` varchar(50), `password` varchar(32), PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET utf8; INSERT INTO `users` (`id`, `username`, `password`) VALUES ('1', 'admin', '5ebe2294ecd0e0f08eab7690d2a6ee69'); |
Step 5: Newsletters
I engineered this application to be very flexible. I wanted you (the user) to be able to create and manage as many newsletters as you want. So, first, we need to create our database table. Here is the SQL code from the export on my demo application:
1
2
3
4
5
6
7
| CREATE TABLE `newsletters` ( `id` int(10) AUTO_INCREMENT, `name` varchar(50), `description` varchar(255), `visible` varchar(10), PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET utf8; |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # admin/newsletters.php <?php require_once 'config.php' ; login_required(); $title = "newsletters" ; $newsletters = query( "SELECT * FROM newsletters ORDER BY id ASC" ); $tab = 'nl' ; $table = "" ; foreach ( $newsletters as $row ) { $dlink = '<a href="newsletters_delete.php?id=' . $row [ 'id' ]. '"
onclick="return confirm(\'Are you sure you want to delete this
newsletter?\');" title="delete"><img src="media/images/delete.png"
alt="delete"/></a>' ; $elink = '<a href="newsletters_edit.php?id=' . $row [ 'id' ]. '" title="edit" ><img src="media/images/page_edit.png" alt="edit"/></a>' ; if ( $row [ 'visible' ] == "1" ) { $visible = '<img src="media/images/bullet_green.png" />' ;} else { $visible = '<img src="media/images/bullet_red.png" />' ;} $table .= "<tr><td>" . $row [ 'id' ]. "</td><td>" . $row [ 'name' ]. "</td><td>" . $row [ 'description' ]. "</td><td>$visible</td><td>" . $dlink . " " . $elink . "</td></tr>\n" ; } $message = error_messages(); $content = <<<EOF <a href= "newsletters_new.php" class = "large" > new newsletter »</a> $message <table> <tr> <th></th> <th>name</th> <th>description</th> <th>visible</th> <th></th> </tr> $table </table> EOF; include 'layout.php' ; ?> |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
| # admin/classes.php // Render error messages function error_messages() { $message = '' ; if ( $_SESSION [ 'success' ] != '' ) { $message = '<span class="success" id="message">' . $_SESSION [ 'success' ]. '</span>' ; $_SESSION [ 'success' ] = '' ; } if ( $_SESSION [ 'error' ] != '' ) { $message = '<span class="error" id="message">' . $_SESSION [ 'error' ]. '</span>' ; $_SESSION [ 'error' ] = '' ; } return $message ; } |
Now we are going to work on our new action, so open up newsletters_new.php and add the following:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| # admin/newsletters_new.php <?php require_once 'config.php' ; login_required(); $tab = 'nl' ; if (isset( $_POST [ 'submitted' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "INSERT INTO NEWSLETTERS (name, description) VALUES ( '" . $_POST ['name ']."' , '".$_POST[' description ']."' )"; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; $_SESSION [ 'success' ] = "Added newsletter." ; header( 'Location: newsletters.php' ); } $title = "new newsletter" ; $content = <<<EOF <form action= "newsletters_new.php" method= 'POST' > <p> <label for = "name" >Name:</label><br /> <input type= 'text' name= 'name' class = "text" /> </p> <p> <label for = "description" >Description:</label> <input type= "text" name= "description" class = "text" /> </p> <p> <input type= 'submit' value= 'Add Newsletter' /> <input type= 'hidden' value= '1' name= 'submitted' /> </p> </form> EOF; include 'layout.php' ; ?> |
We first check to see if an item with the name of submitted was sent. This is the hidden field we have after the submit button. Next, we create a link to our database using the variables from our config file. Next we create our SQL insert query, using our POSTed variables. Next we query (not our function) the database, and if an error is raised, we show the error returned. Next, we close the query, then we set our success message, and then redirect to the listing page. Your page should look like:
Next we are going to work on our edit page and add the following:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| # admin/newsletters_edit.php <?php require_once 'config.php' ; login_required(); $tab = 'nl' ; if (isset( $_POST [ 'submitted' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); if (isset( $_POST [ 'visible' ])) { $visible = 1;} else { $visible = 0;} $sql = "UPDATE NEWSLETTERS SET name='" . $_POST ['name ']."' , description= '".$_POST[' description ']."' , visible=". $visible . " WHERE id=" . $_POST [ 'id' ]. "" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; $_SESSION [ 'success' ] = "Edited newsletter." ; header( 'Location: newsletters.php' ); } $title = "edit newsletter" ; $id = (int) $_GET [ 'id' ]; $results = query( "SELECT * FROM newsletters WHERE id='" . $id . "' LIMIT 1" ); $name = $results [0][ 'name' ]; $description = $results [0][ 'description' ]; $visible = ( $results [0][ 'visible' ] == "1" ) ? 'checked="checked"' : '' ; $content = <<<EOF <form action= "newsletters_edit.php" method= 'POST' > <p> <label for = "name" >Name:</label><br /> <input type= 'text' name= 'name' class = "text" value= "$name" /> </p> <p> <label for = "description" >Description:</label> <input type= "text" name= "description" class = "text" value= "$description" /> </p> <p> <label for = "visible" >Visible:</label> <input type= "checkbox" name= "visible" value= "true" $visible /> </p> <p> <input type= 'submit' value= 'Edit Newsletter' /> <input type= 'hidden' value= '1' name= 'submitted' /> <input type= 'hidden' value= '$id' name= 'id' /> </p> </form> EOF; include 'layout.php' ; ?> |
Our POST block is very similar to our new page, and will always start the same way across the rest of our pages. We then check to see if the check box was check, and set a variable here again. Then we have our UPDATE query, again run the query, set our success message, and then redirect home. THis is how the form looks and the message seen after editing:
The last page for this section is the easiest, as it is the delete page. Open up the file and paste to following:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
| # admin/newsletters_delete.php <?php require_once 'config.php' ; login_required(); $id = (int) $_GET [ 'id' ]; $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "DELETE FROM newsletters WHERE id=$id LIMIT 1" ; $stmt = $link ->query( $sql ) or die ( $link ->error); if ( $link ->affected_rows) { $_SESSION [ 'success' ] = "Newsletter deleted." ; } else { $_SESSION [ 'error' ] = 'Nothing deleted.' ; } header( 'Location: newsletters.php' ); |
Step 6: Templates
Our application will also allow multiple templates, all stored in the database. First, lets create our database table:
1
2
3
4
5
6
7
| CREATE TABLE `templates` ( `id` int(10) AUTO_INCREMENT, `name` varchar(50), `columns` tinyint(5), `body` text, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET utf8; |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| # admin/templates.php <?php require_once 'config.php' ; login_required(); $title = "templates" ; $tab = 'temp' ; $templates = query( "SELECT id,name,columns FROM templates ORDER BY id ASC" ); $table = "" ; foreach ( $templates as $row ) { $plink = '<a href="" onClick="window.open(\'templates_preview.php?id=' . $row [ 'id' ]. '\',width=800,height=600)" title="preview"><img src="media/images/find.png" alt="preview"/></a>' ; $dlink = '<a href="templates_delete.php?id=' . $row [ 'id' ]. '"
onclick="return confirm(\'Are you sure you want to delete this
template?\');" title="delete"><img src="media/images/delete.png"
alt="delete"/></a>' ; $elink = '<a href="templates_edit.php?id=' . $row [ 'id' ]. '" title="edit"><img src="media/images/page_edit.png" alt="edit"/></a>' ; $table .= "<tr><td>" . $row [ 'id' ]. "</td><td>" . $row [ 'name' ]. "</td><td>" . $row [ 'columns' ]. "</td><td>" . $plink . " " . $dlink . " " . $elink . "</td></tr>\n" ; } $message = error_messages(); $content = <<<EOF <a href= "templates_new.php" class = "large" > new template »</a> $message <table> <tr> <th></th> <th>name</th> <th>columns</th> <th></th> </tr> $table </table> EOF; include 'layout.php' ; ?> |
Now, moving on to our our new page, paste the following:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| # admin/templates_new.php <?php require_once 'config.php' ; login_required(); $tab = 'temp' ; if (isset( $_POST [ 'submitted' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "INSERT INTO templates (name, columns, body) VALUES ( '" . $_POST ['name ']."' , ". $_POST [ 'columns' ]. ", '" .mysql_real_escape_string( $_POST ['body '])."' )"; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; $_SESSION [ 'success' ] = "Added template." ; header( 'Location: templates.php' ); } $title = "new template" ; $content = <<<EOF <form action= "templates_new.php" method= 'POST' > <p> <label for = "name" >Name:</label><br /> <input type= 'text' name= 'name' class = "text" /> </p> <p> <label for = "columns" >Columns</label> <select name= "columns" > <option value= "1" >Single Column Layout</option> <option value= "2" >Two Column Layout</option> </select> </p> <p> <label for = "description" >Body: (raw html)</label><br /> Use %content% for a single column layout, %leftcol% and %rightcol% for a two column layout.<br /> <textarea name= "body" rows= "35" ></textarea> </p> <p> <input type= 'submit' value= 'Add Template' /> <input type= 'hidden' value= '1' name= 'submitted' /> </p> </form> EOF; include 'layout.php' ; ?> |
Next we are going to work on our edit page. If you have noticed, much of this code is copy and paste across all of the same actions, so make it easy on yourself.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| # admin/templates/edit.php <?php require_once 'config.php' ; login_required(); $tab = 'temp' ; if (isset( $_POST [ 'submitted' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "UPDATE templates SET name='" . $_POST ['name ']."' , body= '".mysql_real_escape_string($_POST[' body '])."' , columns=". $_POST [ 'columns' ]. " WHERE id=" . $_POST [ 'id' ]. "" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; $_SESSION [ 'success' ] = "Edited template." ; header( 'Location: templates.php' ); } $title = "edit template" ; $id = (int) $_GET [ 'id' ]; $results = query( "SELECT * FROM templates WHERE id='" . $id . "' LIMIT 1" ); $name = $results [0][ 'name' ]; $templatedata = stripslashes (htmlspecialchars( $results [0][ 'body' ])); $content = <<<EOF <form action= "templates_edit.php" method= 'POST' > <p> <label for = "name" >Name:</label><br /> <input type= 'text' name= 'name' class = "text" value= "$name" /> </p> <p> <label for = "columns" >Columns</label> <select name= "columns" > <option value= "1" >Single Column Layout</option> <option value= "2" >Two Column Layout</option> </select> </p> <p> <label for = "body" >Body: (raw html)</label><br /> Use %content% for a single column layout, %leftcol% and %rightcol% for a two column layout.<br /> <textarea name= "body" rows= "35" > $templatedata </textarea> </p> <p> <input type= 'submit' value= 'Edit Template' /> <input type= 'hidden' value= '1' name= 'submitted' /> <input type= 'hidden' value= '$id' name= 'id' /> </p> </form> EOF; include 'layout.php' ; ?> |
Now we will create another delete page, so open up our delete page and paste in:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
| # admin/templates_delete.php <?php require_once 'config.php' ; login_required(); $id = (int) $_GET [ 'id' ]; $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "DELETE FROM templates WHERE id=$id LIMIT 1" ; $stmt = $link ->query( $sql ) or die ( $link ->error); if ( $link ->affected_rows) { $_SESSION [ 'success' ] = "Template deleted." ; } else { $_SESSION [ 'error' ] = 'Nothing deleted.' ; } header( 'Location: templates.php' ); |
01
02
03
04
05
06
07
08
09
10
| # admin/templates_preview.php <?php require_once 'config.php' ; login_required(); $id = (int) $_GET [ 'id' ]; $data = query( "SELECT body FROM templates WHERE id=$id LIMIT 1" ); $template = $data [0][ 'body' ]; ?> <?php echo $template ; ?> <center><button type= "button" onclick= "self.close();" >close window</button></center> |
Now we have finished with our Templates, we are ready to move onto the next step!
Step 7: Subscribers
So now we are going to work with our subscribers! We are going to create two tables. The first:
1
2
3
4
5
6
| CREATE TABLE `subscribers` ( `id` tinyint(10) AUTO_INCREMENT, `name` varchar(50), `email` varchar(50), PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET utf8; |
1
2
3
4
5
6
| CREATE TABLE `subscriptions` ( `id` tinyint(10) AUTO_INCREMENT, `subscriber_id` tinyint(10), `newsletter_id` tinyint(10), PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET utf8; |
Let's first create our files. The files we are going are going to have are subscribers.php, subscribers_delete.php, and subscribers_edit.php. Our create action will be created later for the front-end. First open up subscribers.php and paste in:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # admin/subscribers.php <?php require_once 'config.php' ; login_required(); $title = "subscribers" ; $tab = 'sub' ; $table = "" ; $messages = query( "SELECT * FROM subscribers ORDER BY id ASC" ); foreach ( $messages as $row ) { $dlink = '<a href="subscribers_delete.php?id=' . $row [ 'id' ]. '"
onclick="return confirm(\'Are you sure you want to delete this
subscriber?\');" title="delete"><img src="media/images/delete.png"
alt="delete"/></a>' ; $elink = '<a href="subscribers_edit.php?id=' . $row [ 'id' ]. '" title="edit"><img src="media/images/page_edit.png" alt="edit"/></a>' ; $table .= '<tr><td>' . $row [ 'id' ]. '</td><td>' . $row [ 'name' ]. '</td><td>' . $row [ 'email' ]. '</td><td>' . $dlink . ' ' . $elink . '</td></tr>' ; } $message = error_messages(); $content = <<<EOF $message <table> <tr> <th></th> <th>name</th> <th>email</th> <th></th> </tr> $table </table> EOF; include 'layout.php' ; ?> |
Now we will move on to our edit page:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
| # admin/subscribers_edit.php <?php require_once 'config.php' ; login_required(); $tab = 'sub' ; if (isset( $_POST [ 'submitted' ])) { $id = (int) $_POST [ 'id' ]; $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "UPDATE subscribers SET name='" . $_POST ['name ']."' , email= '".$_POST[' email ']."' WHERE id= $id "; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; foreach ( $_POST [ 'newsletter' ] as $n ) { if ( $n [ 'exists' ] != '1' && $n [ 'subscribe' ] == "true" ) { // If we want to subscribe but the record doesnt exist $nlid = $n [ 'nlid' ]; $sql = "INSERT INTO subscriptions (subscriber_id, newsletter_id) VALUES ('$id', '$nlid')" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; } elseif ( $n [ 'exists' ] == '1' && $n [ 'subscribe' ] != "true" ) { // Else if we had an exits but we want to unsubscribe $subid = $n [ 'subid' ]; $sql = "DELETE FROM subscriptions WHERE id=$subid LIMIT 1" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; } } $_SESSION [ 'success' ] = "Edited subscriber." ; header( 'Location: subscribers.php' ); } $title = "edit newsletter" ; $id = (int) $_GET [ 'id' ]; $subscriber = query( "SELECT * FROM subscribers WHERE id='$id'" ); $name = $subscriber [0][ 'name' ]; $email = $subscriber [0][ 'email' ]; $newsletters = query( "SELECT * FROM newsletters" ); $subs = query( "SELECT * FROM subscriptions WHERE subscriber_id='" . $id . "'" ); $subscriptions = '' ; foreach ( $newsletters as $nl ) { $s = false; $subid = '' ; foreach ( $subs as $sub ) { if ( $sub [ 'newsletter_id' ] == $nl [ 'id' ]) { $s = true; $subid = $sub [ 'id' ];} } $checked = ( $s == true) ? 'checked="checked"' : '' ; $subscriptions .= ' <input type= "checkbox" name= "newsletter['.$nl[" id "].'][subscribe]" value= "true" '.$checked.' /> <label for = "newsletter['.$nl[" id "].']" > '.$nl[' name '].' </label> <input type= "hidden" name= "newsletter['.$nl[" id "].'][exists]" value= "'.$s.'" /> <input type= "hidden" name= "newsletter['.$nl[" id "].'][nlid]" value= "'.$nl['id'].'" /> <input type= "hidden" name= "newsletter['.$nl[" id "].'][subid]" value= "'.$subid.'" /><br /> '; } $content = <<<EOF <form action= "subscribers_edit.php" method= 'POST' > <p> <label for = "name" >Name:</label><br /> <input type= 'text' name= 'name' class = "text" value= "$name" /> </p> <p> <label for = "email" >Email</label><br /> <input type= "text" name= "email" class = "text" value= "$email" /> </p> <p> <strong>Newsletters:</strong><br /> $subscriptions </p> <p> <input type= 'submit' value= 'Edit Subscriber' /> <input type= 'hidden' value= '1' name= 'submitted' /> <input type= 'hidden' value= '$id' name= 'id' /> </p> </form> EOF; include 'layout.php' ; ?> |
Now, if we move on to our POST block. We first get the id posted from our hidden field at the bottom. We next create our MySQL link. Next we have our first SQL query where we update the subscriber record. Next we loop through every newsletter checkbox. The first conditional statement checks to see if the POSTed data says we do not have an existing subscription, and the user wants to subscribe to the newsletter. To handle this, we are going to perform a SQL INSERT into our subscriptions table where our subscriber_id is the same as the user_id we are editing, and newsletter_id equal to the 'nlid' value POSTed by one of our hidden fields. We then execute that SQL INSERT query. The elseif conditional statement says that if our subscription exists, but the checkbox was unchecked so we unsubscribe, we need to delete the subscription. We handle this with a SQL DELETE query. To form our query we set $subid equal to the posted value for our 'subid'. We then create our query by deleting the record where the subscription id equals our variable of $subid. Next we execute the query, set our session success message, and then redirect back to our subscribers page. Your final edit page should look like: (filled with sample data)
We have one last page to work on for the subscribers part of the backend: the delete page. Just like before, this page is very simple:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
| # admin/subscribers_delete.php <?php require_once 'config.php' ; login_required(); $id = (int) $_GET [ 'id' ]; $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "DELETE FROM subscribers WHERE id=$id LIMIT 1" ; $stmt = $link ->query( $sql ) or die ( $link ->error); if ( $link ->affected_rows) { $_SESSION [ 'success' ] = "Subscriber deleted." ; } else { $_SESSION [ 'error' ] = 'Nothing deleted.' ; } header( 'Location: subscribers.php' ); |
Step 8: Messages
I will tell you upfront, this section has the most pages. We will be working with seven now, and creating one more in Step 10. First, we are going to create our messages table with this SQL:
1
2
3
4
5
6
7
8
| CREATE TABLE `messages` ( `id` tinyint(10) AUTO_INCREMENT, `subject` varchar(255), `leftcol` text, `rightcol` text, `template_id` tinyint(10), PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET utf8; |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # admin/messages.php <?php require_once 'config.php' ; login_required(); $title = "messages" ; $tab = 'mess' ; $table = "" ; $messages = query( "SELECT * FROM messages ORDER BY id ASC" ); foreach ( $messages as $row ) { $slink = '<a href="messages_send.php?id=' . $row [ 'id' ]. '" title="send message"><img src="media/images/email_go.png" alt="send message"/></a>' ; $plink = '<a href="messages_preview.php?id=' . $row [ 'id' ]. '" target="_new" title="preview"><img src="media/images/find.png" alt="preview"/></a>' ; $dlink = '<a href="messages_delete.php?id=' . $row [ 'id' ]. '"
onclick="return confirm(\'Are you sure you want to delete this
message?\');" title="delete"><img src="media/images/delete.png"
alt="delete"/></a>' ; $elink = '<a href="messages_edit.php?id=' . $row [ 'id' ]. '" title="edit"><img src="media/images/page_edit.png" alt="edit"/></a>' ; $table .= '<tr><td>' . $row [ 'id' ]. '</td><td>' . $row [ 'subject' ]. '</td><td><a href="" onClick="window.open(\'templates_preview.php?id=' . $row [ 'template_id' ]. '\',width=800,height=600)"
title="preview"><img src="media/images/find.png"
alt="preview"/></a></td><td>' . $slink . ' ' . $plink . ' ' . $dlink . ' ' . $elink . '</td></tr>' ; } $message = error_messages(); $content = <<<EOF <a href= "messages_new.php" class = "large" > new message »</a> $message <table> <tr> <th></th> <th>subject</th> <th>template</th> <th></th> </tr> $table </table> EOF; include 'layout.php' ; ?> |
Now we are going to start work on our new pages. The first page is where all messages start out, and then you can progress on and enter the actual message on the next page. The reason for this is because we first need to create the initial message in the DB and so we can find information about the template. The step2 page is basically the edit page (there are six line differences according to FileMerge). Open up our new file and paste the following:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| # admin/messages_new.php <?php require_once 'config.php' ; login_required(); $tab = 'mess' ; if (isset( $_POST [ 'subject' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "INSERT INTO messages (subject, template_id) VALUES ( '" . $_POST ['subject ']."' , ". $_POST [ 'template' ]. ")" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $i = query( "SELECT id FROM messages WHERE subject='" . $_POST ['subject ']."' AND template_id=". $_POST [ 'template' ]. " " ); $id = $i [0][ 'id' ]; $stmt ->close; $_SESSION [ 'success' ] = "Added template." ; header( 'Location: messages_new_step2.php?id=' + $id ); } $title = "new message" ; $templates = query( "SELECT id,name,columns FROM templates" ); $tselect = '<select name="template">' ; foreach ( $templates as $row ) { $tselect .= '<option value="' . $row [ 'id' ]. '">' . $row [ 'name' ]. '</option>' ; } $tselect .= "</select>" ; $content = <<<EOF <form action= "messages_new.php" method= 'POST' > <p> <label for = "subject" >Subject:</label><br /> <input type= 'text' name= 'subject' class = "text" /> </p> <p> <label for = "template" >Template:</label> $tselect </p> <p> <button onclick= "" >Continue »</button> </p> </form> EOF; include 'layout.php' ; ?> |
We then redirect to step2, so let's open up the file:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
| # admin/messages_new_step2.php <?php require_once 'config.php' ; login_required(); $title = "new message - step 2" ; $tab = 'mess' ; $id = (int) $_GET [ 'id' ]; $mess = query( "SELECT * FROM messages WHERE id=$id" ); $message = $mess [0]; $subject = $message [ 'subject' ]; $templates = query( "SELECT id,name,columns FROM templates" ); $tselect = '<select name="template">' ; foreach ( $templates as $row ) { if ( $message [ 'template_id' ] == $row [ 'id' ]) { $selected = ' selected="selected"' ; if ( $row [ 'columns' ] == "1" ) { $textareas = '<p><label
for="body">Body: (raw html)</label><br /><textarea
name="body" rows="35"></textarea></p>' ; } else { $textareas = '<p><label for = "leftcol" >Left column: (raw html)</label><br /><textarea name= "leftcol" rows= "35" ></textarea></p> <p><label for = "rightcol" >Right column: (raw html)</label><br /><textarea name= "rightcol" rows= "35" ></textarea></p>'; } } else { $selected = '' ;} $tselect .= '<option value="' . $row [ 'id' ]. '"' . $selected . '>' . $row [ 'name' ]. '</option>' ; } $tselect .= '</select>' ; // Check for a POST if (isset( $_POST [ 'submitted' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $template = query( "SELECT columns FROM templates WHERE id=" . $message [ 'template_id' ]); if ( $template [0][ 'columns' ] == "1" ) { $body = mysql_real_escape_string( $_POST [ 'body' ]); $sql = "UPDATE messages SET subject='" . $_POST ['subject ']."' , leftcol= '$body' WHERE id= $id "; } else { $leftcol = mysql_real_escape_string( $_POST [ 'leftcol' ]); $rightcol = htmlentities( $_POST [ 'rightcol' ]); $sql = "UPDATE messages SET subject='" . $_POST ['subject ']."' , leftcol= '$leftcol' , rightcol= '$rightcol' WHERE id= $id "; } $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; header( 'Location: messages_new_step3.php?id=' . $id ); } $content = <<<EOF <form action= "messages_new_step2.php?id=$id" method= 'POST' > <p> <label for = "subject" >Subject:</label><br /> <input type= 'text' name= 'subject' class = "text" value= "$subject" /> </p> <p> <label for = "template" >Template:</label> $tselect </p> $textareas <p> <input type= 'submit' value= 'Continue »' /> <input type= 'hidden' value= '1' name= 'submitted' /> </p> </form> EOF; include 'layout.php' ; ?> |
Now we will continue onto step 3, so open up the file and paste:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
| # admin/messages_new_step3.php <?php require_once 'config.php' ; login_required(); $title = "new message - step 3" ; $id = (int) $_GET [ 'id' ]; $tab = 'mess' ; $mess = query( "SELECT * FROM messages WHERE id=$id" ); $message = $mess [0]; $subject = $message [ 'subject' ]; $content = <<<EOF <a href= "messages_preview.php?id=$id" class = "large" target= "_new" >preview »</a><br /> <p>Do you want to <a href= "messages.php" class = "large" > return to messages</a> or <a href= "messages_send.php?id=$id" class = "large" >send the message</a>?</p> EOF; include 'layout.php' ; ?> |
Now we are going to continue on to our edit page. I will not explain it as it is the same file as messages_new_step2.php, so you can refer there.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| # admin/messages_edit.php <?php require_once 'config.php' ; login_required(); $title = "edit message" ; $id = (int) $_GET [ 'id' ]; $tab = 'mess' ; $mess = query( "SELECT * FROM messages WHERE id=$id" ); $message = $mess [0]; $subject = $message [ 'subject' ]; $templates = query( "SELECT id,name,columns FROM templates" ); $tselect = '<select name="template">' ; foreach ( $templates as $row ) { if ( $message [ 'template_id' ] == $row [ 'id' ]) { $selected = ' selected="selected"' ; } else { $selected = '' ;} $tselect .= '<option value="' . $row [ 'id' ]. '"' . $selected . '>' . $row [ 'name' ]. '</option>' ; } $tselect .= '</select>' ; $mid = $message [ 'template_id' ]; $template = query( "SELECT id,name,columns FROM templates WHERE id=$mid" ); if ( $template [0][ 'columns' ] == "1" ) { $textareas = '<p><label for="body">Body: (raw html)</label><br /><textarea name="body" rows="35">' . $message [ 'leftcol' ]. '</textarea></p>' ; } else { $textareas = '<p><label for="leftcol">Left column: (raw html)</label><br /><textarea name="leftcol" rows="35">' . $message [ 'leftcol' ].'</textarea></p> <p><label for = "rightcol" >Right column: (raw html)</label><br /><textarea name= "rightcol" rows= "35" > '.$message[' rightcol '].' </textarea></p>'; } // Check for a POST if (isset( $_POST [ 'submitted' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); if ( $template [0][ 'columns' ] == "1" ) { $body = mysql_real_escape_string( $_POST [ 'body' ]); $sql = "UPDATE messages SET subject='" . $_POST ['subject ']."' , leftcol= '$body' WHERE id= $id "; } else { $leftcol = mysql_real_escape_string( $_POST [ 'leftcol' ]); $rightcol = htmlentities( $_POST [ 'rightcol' ]); $sql = "UPDATE messages SET subject='" . $_POST ['subject ']."' , leftcol= '$leftcol' , rightcol= '$rightcol' WHERE id= $id "; } $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; $_SESSION [ 'success' ] = "Edited message." ; header( 'Location: messages.php' ); } $content = <<<EOF <form action= "messages_edit.php?id=$id" method= 'POST' > <p> <label for = "subject" >Subject:</label><br /> <input type= 'text' name= 'subject' class = "text" value= "$subject" /> </p> <p> <label for = "template" >Template:</label> $tselect </p> $textareas <p> <input type= 'submit' value= 'Save »' /> <input type= 'hidden' value= '1' name= 'submitted' /> </p> </form> EOF; include 'layout.php' ; ?> |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
| # admin/messages_delete.php <?php require_once 'config.php' ; login_required(); $id = (int) $_GET [ 'id' ]; $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "DELETE FROM messages WHERE id=$id LIMIT 1" ; $stmt = $link ->query( $sql ) or die ( $link ->error); if ( $link ->affected_rows) { $_SESSION [ 'success' ] = "Message deleted." ; } else { $_SESSION [ 'error' ] = 'Nothing deleted.' ; } header( 'Location: messages.php' ); ?> |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| # admin/messages_preview.php <?php require_once 'config.php' ; login_required(); $id = (int) $_GET [ 'id' ]; $mess = query( "SELECT * FROM messages WHERE id=$id" ); $message = $mess [0]; $subject = $message [ 'subject' ]; $tid = $message [ 'template_id' ]; $data = query( "SELECT body,columns FROM templates WHERE id=$tid LIMIT 1" ); $template = $data [0][ 'body' ]; if ( $data [0][ 'columns' ] == "1" ) { $leftcol = $message [ 'leftcol' ]; $body = str_replace ( '%content%' , $leftcol , $template ); } else { $leftcol = $message [ 'leftcol' ]; $rightcol = $message [ 'rightcol' ]; $b = str_replace ( '%leftcol%' , $leftcol , $template ); $body = str_replace ( '%rightcol%' , $rightcol , $b ); } ?> <?php echo $body ; ?> <button type= "button" onclick= "self.close();" >close window</button> |
Step 9: The Front-End
We have finally reached the front-end! For this step and this step only, I will assume the files we are working with are in the root of the project (so not the admin folder, the one containing it). We are going to be working with four files here, so go ahead and create index.php, preferences.php, subscribe.php and a style.css file. First open up our index.php file and paste:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| # index.php <?php require_once 'admin/config.php' ; $newsletters = query( "SELECT * FROM newsletters WHERE visible=1" ); $subscriptions = '' ; foreach ( $newsletters as $nl ) { $subscriptions .= ' <input type= "checkbox" name= "newsletter['.$nl[" id "].'][subscribe]" value= "true" '.$checked.' /> <label for = "newsletter['.$nl[" id "].']" > '.$nl[' name '].' </label> <input type= "hidden" name= "newsletter['.$nl[" id "].'][nlid]" value= "'.$nl['id'].'" /><br /> '.$nl["description"].' <br /> '; } ?> <head> <meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" /> <title>my newsletters</title> <!-- Stylesheets --> <link rel= "stylesheet" href= "style.css" type= "text/css" media= "all" /> </head> <body> <div id= "header" > <h1>my newsletters</h1> </div> <div id= "container" > <h3>Subscribe to our newsletters!</h3> <form action= "subscribe.php" method= "POST" > <p> <label for = "name" >Name:</label><br /> <input type= 'text' name= 'name' class = "text" /> </p> <p> <label for = "email" >Email</label><br /> <input type= "text" name= "email" class = "text" /> </p> <p> <strong>Newsletters:</strong><br /> <?php echo $subscriptions ; ?> </p> <p> <input type= 'submit' value= 'Subscribe »' /> <input type= 'hidden' value= '1' name= 'submitted' /> </p> </form> </div> </body> </html> |
First I added the 960.gs reset file like I did in our other stylesheet. Then I added the three following styles to make the design look like:
1
2
3
4
5
| # style.css #header, #container { width : 65% ; margin : 0 auto ; padding : 0.7% ;} #container { background : #ccc ;} form input.text { width : 95% ; font-size : 16px ;} #message.success { border : solid 1px #349534 ; background : #C9FFCA ; color : #008000 ;} |
So now that we have a clean and simple page, we are going to continue on and work on our subscribe.php file. Go ahead and open the file and paste:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| # subscribe.php <?php require_once 'admin/config.php' ; if (isset( $_POST [ 'submitted' ])) { $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $name = $_POST [ 'name' ]; $email = $_POST [ 'email' ]; $sql = "INSERT INTO subscribers (name, email) VALUES ('$name', '$email')" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; $sql = "SELECT id FROM subscribers WHERE name='$name' AND email='$email' LIMIT 1" ; $subscriber = query( $sql ); $id = $subscriber [0][ 'id' ]; foreach ( $_POST [ 'newsletter' ] as $n ) { if ( $n [ 'subscribe' ] == "true" ) { // If we want to subscribe but the record doesnt exist $nlid = $n [ 'nlid' ]; $sql = "INSERT INTO subscriptions (subscriber_id, newsletter_id) VALUES ('$id', '$nlid')" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; } } } else {header( 'Location: index.php' );} ?> <head> <meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" /> <title>my newsletters</title> <!-- Stylesheets --> <link rel= "stylesheet" href= "style.css" type= "text/css" media= "all" /> </head> <body> <div id= "header" > <h1>my newsletters</h1> </div> <div id= "container" > <h3>Thank you for subscribing!</h3> </div> </body> </html> |
We have on last page here to work on, and that is the preferences.php file. This is where a user can edit their email subscription. I am going to split the page in two. First we have our PHP block:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| # preferences.php <?php require_once 'admin/config.php' ; if (isset( $_POST [ 'submitted' ])) { $id = (int) $_POST [ 'id' ]; $link = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die ( 'There was a problem connecting to the database.' ); $sql = "UPDATE subscribers SET name='" . $_POST ['name ']."' , email= '".$_POST[' email ']."' WHERE id= $id "; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; foreach ( $_POST [ 'newsletter' ] as $n ) { if ( $n [ 'exists' ] != '1' && $n [ 'subscribe' ] == "true" ) { // If we want to subscribe but the record doesnt exist $nlid = $n [ 'nlid' ]; $sql = "INSERT INTO subscriptions (subscriber_id, newsletter_id) VALUES ('$id', '$nlid')" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; } elseif ( $n [ 'exists' ] == '1' && $n [ 'subscribe' ] != "true" ) { // Else if we had an exits but we want to unsubscribe $subid = $n [ 'subid' ]; $sql = "DELETE FROM subscriptions WHERE id=$subid LIMIT 1" ; $stmt = $link ->query( $sql ) or die ( $link ->error); $stmt ->close; } } $_SESSION [ 'success' ] = "Preferences saved." ; } if (isset( $_GET [ 'email' ])) { $email = $_GET [ 'email' ]; $display = 'form' ;} else { $display = 'find' ;} $subscriber = query( "SELECT * FROM subscribers WHERE email='$email'" ); if ( $subscriber || $display == 'find' ) { $id = $subscriber [0][ 'id' ]; $name = $subscriber [0][ 'name' ]; $email = $subscriber [0][ 'email' ]; } else {header( 'Location: index.php' );} $newsletters = query( "SELECT * FROM newsletters WHERE visible=1" ); $subs = query( "SELECT * FROM subscriptions WHERE subscriber_id='" . $id . "'" ); $subscriptions = '' ; foreach ( $newsletters as $nl ) { $s = false; $subid = '' ; foreach ( $subs as $sub ) { if ( $sub [ 'newsletter_id' ] == $nl [ 'id' ]) { $s = true; $subid = $sub [ 'id' ];} } $checked = ( $s == true) ? 'checked="checked"' : '' ; $subscriptions .= ' <input type= "checkbox" name= "newsletter['.$nl[" id "].'][subscribe]" value= "true" '.$checked.' /> <label for = "newsletter['.$nl[" id "].']" > '.$nl[' name '].' </label> <input type= "hidden" name= "newsletter['.$nl[" id "].'][exists]" value= "'.$s.'" /> <input type= "hidden" name= "newsletter['.$nl[" id "].'][nlid]" value= "'.$nl['id'].'" /> <input type= "hidden" name= "newsletter['.$nl[" id "].'][subid]" value= "'.$subid.'" /><br /> '; } $message = error_messages(); ?> |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| # preferences.php <head> <meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" /> <title>my newsletters - my preferences</title> <!-- Stylesheets --> <link rel= "stylesheet" href= "style.css" type= "text/css" media= "all" /> </head> <body> <div id= "header" > <h1>my newsletters</h1> </div> <div id= "container" > <h3>my preferences</h3> <?php if ( $display == 'form' ) {?> <form action= "preferences.php" method= "POST" > <p> <label for = "name" >Name:</label><br /> <input type= 'text' name= 'name' class = "text" value= "<?php echo $name; ?>" /> </p> <p> <label for = "email" >Email</label><br /> <input type= "text" name= "email" class = "text" value= "<?php echo $email; ?>" /> </p> <p> <strong>Newsletters:</strong><br /> <?php echo $subscriptions ; ?> </p> <p> <input type= 'submit' value= 'Save my preferences »' /> <input type= 'hidden' value= '1' name= 'submitted' /> <input type= 'hidden' value= '<?php echo $id; ?>' name= 'id' /> </p> </form> <?php } else { ?> <?php echo $message ; ?> <form action= 'preferences.php' method= "get" > <p> <label for = "email" >Email</label><br /> <input type= "text" name= "email" class = "text" /> </p> <p> <input type= 'submit' value= 'Find »' /> </p> </form> <?php } ?> </div> </body> </html> |
And the first looks like:
And the second form after we saved our preferences:
Now that we have finished the front-end, we have one last step: sending the emails!
Step 10: Sending Messages
Our last step is to work on the page to send our message. We will be working in the admin directory, and only one file will be created. Go ahead and create our messages_send.php file and place the following in it:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
| # admin/messages_send.php <?php require_once 'config.php' ; login_required(); $title = "send message" ; $id = (int) $_GET [ 'id' ]; $tab = 'mess' ; if (isset( $_POST [ 'submitted' ])) { $query = "SELECT * FROM subscribers WHERE id=0 " ; $emails = array (); foreach ( $_POST [ 'newsletter' ] as $n ) { if ( $n [ 'send' ] == "true" ) { $nlid = $n [ 'nlid' ]; $e = query( "SELECT subscriber_id FROM subscriptions WHERE newsletter_id=$nlid" ); foreach ( $e as $s ) { $sqlids .= " OR id=" . $s [ 'subscriber_id' ]; } $query .= $sqlids ; } } $subscribers = query( $query ); foreach ( $subscribers as $sub ) { $emails [ $sub [ 'email' ]] = $sub [ 'name' ]; } $from = array (FROM_EMAIL => FROM_NAME); // BODY RENDERING $mess = query( "SELECT * FROM messages WHERE id=$id" ); $message = $mess [0]; $subject = $message [ 'subject' ]; $tid = $message [ 'template_id' ]; $data = query( "SELECT body FROM templates WHERE id=$tid LIMIT 1" ); $template = $data [0][ 'body' ]; if ( $message [ 'rightcol' ] == '' ) { $leftcol = $message [ 'leftcol' ]; $body = str_replace ( '%content%' , $leftcol , $template ); } else { $leftcol = $message [ 'leftcol' ]; $rightcol = $message [ 'rightcol' ]; $b = str_replace ( '%leftcol%' , $leftcol , $template ); $body = str_replace ( '%rightcol%' , $rightcol , $b ); } send_email_to_mass( $from , $emails , $body , $subject ) or die ( 'lol' ); header( 'Location: index.php' ); } $newsletters = query( "SELECT * FROM newsletters" ); foreach ( $newsletters as $nl ) { $nls .= ' <input type= "hidden" name= "newsletter['.$nl[" id "].'][nlid]" value= "'.$nl['id'].'" /> <input type= "checkbox" name= "newsletter['.$nl[" id "].'][send]" value= "true" '.$checked.' /> <label for = "newsletter['.$nl[" id "].']" > '.$nl[' name '].' </label> - '.$nl[' description '].' <br /> '; } $mess = query( "SELECT * FROM messages WHERE id=$id" ); $message = $mess [0]; $subject = $message [ 'subject' ]; $content = <<<EOF <a href= "messages_preview.php?id=$id" class = "large" target= "_new" >preview »</a><br /> <form action= 'messages_send.php?id=$id' method= "POST" > <p> Subject: $subject <br /> </p> <p>Send to:<br /> $nls </p> <p> <input type= 'submit' value= 'Send »' /> <input type= 'hidden' value= '1' name= 'submitted' /> </p> </form> EOF; include 'layout.php' ; ?> |
Leaving our POST block, we create the same checkbox list of newsletters so the admin can pick which one(s) he wants to send the message to. Then we have a simple form that looks like:
Now, open up our classes.php file and add the following function:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
| # admin/classes.php // EMAIL function send_email_to_mass( $from , $recipients , $body , $subject ) { require_once 'swift/lib/swift_required.php' ; //require lib $transport = Swift_MailTransport::newInstance(); $mailer = Swift_Mailer::newInstance( $transport ) or die ( 'Error creating mailer.' ); $message = Swift_Message::newInstance( $subject ) ->setFrom( $from ) ->setTo( $recipients ) ->setBody( $body , 'text/html' ) or die ( 'error here.' ); $result = $mailer ->batchSend( $message ); return true; } |
There is one possibly downside of doing it the way I have, and that is if you are sending many messages, the page may take forever to load. A solution to tthis would be running a Javascript AJAX request to send each and every message, but I won't cover that here. Now that we have finished working on sending messages, we are going to spice up the home page and then we will be done!
Step 11: The Homepage
When you load the admin index, the page does not really do much. I want to have some 'stats' on our homepage, and we will finally use the count_query function. Open up the admin index file and change it to look like:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
| # admin/index.php <?php require_once 'config.php' ; login_required(); $users = count_query( "SELECT COUNT(*) AS num FROM users" ); $emails = count_query( "SELECT COUNT(*) AS num FROM subscribers" ); $subs = count_query( "SELECT COUNT(*) AS num FROM subscriptions" ); $nls = count_query( "SELECT COUNT(*) AS num FROM newsletters" ); $mess = count_query( "SELECT COUNT(*) AS num FROM messages" ); $temps = count_query( "SELECT COUNT(*) AS num FROM templates" ); $title = "Home!" ; $content = <<<EOF <h3>current stats</h3> <p> $users user registered</p> <p> $emails subscribers</p> <p> $subs newsletter subscriptions</p> <p> $nls newsletters</p> <p> $mess messages</p> <p> $temps templates</p> EOF; include 'layout.php' ; ?> |
No comments:
Post a Comment