Guest Book (Part 2 / 2)

3Back to Part 1

This is part two of my guestbook tutorial, in part one we created the actual guestbook. In this part we will now look at creating an administration area for our guestbook. In this admin area we will be able to edit and delete guestbook entries. We will also be able to add and delete administrators. The most important part of adding and deleting administrators of course is always making sure that we don?t delete ourselves. If we were to delete ourselves and we were the last one in the database we would not be able to get back in to do our administrative functions. Starting off we need to create a directory in our guestbook folder and call it ?admin?. The reason we need a new directory is this area will be password protected and in order to do this it will need its own Application.cfm file. First off we need a new table in our database and we will call this new table ?admin?! 

Notice that when creating our table we are populating it with a default entry, this is so we can get into the admin area once it is created and add ourselves properly. So our default login name will be:admin and our password will be:admin After your first login you will have to add a new administrator than logout. Than login again with your new administrator name and password and delete the default one.



CREATE TABLE admin (
    id smallint(6) NOT NULL auto_increment,
    username varchar(255) NOT NULL,
    password varchar(32) NOT NULL,
    fname varchar(255) NOT NULL,
    lname varchar(255) NOT NULL,
    PRIMARY KEY (id)
);

#
# Dumping data for table 'admin'
#

INSERT INTO admin VALUES ( '1', 'admin', '21232F297A57A5A743894A0E4A801FC3', 'Your', 'Name');


Now that we have our table setup we need to create an Application.cfm template in our new directory. At this point all templates I am referring to also belong in the new directory named ?admin?

<!--- The first part is just setting up our templates to use sessions --->
<cfapplication name="PasswordProtection"
                    sessionmanagement=
"Yes"
                    setclientcookies=
"no">

<!--- Always a wise idea to set default values for any sessions we are going to be using --->
<cfparam name="session.username" default="">

<!--- Here we are setting all users password entries to false in order to have the next cfif statement force the user to the login template if they have not already set their password value to ?true? --->
<cfparam name="session.passwordentry" default="false">

<!--- This cfif statement is saying if session passwordentry is not equal to ?true? than send them to the login screen, otherwise if the value is ?true? abort and let them in to the admin templates --->
<cfif session.passwordentry neq "true">
    <cfinclude template=
"adminlogin.cfm">
    <cfabort>
</cfif>



admin_login.cfm

<!--- The user is automatically sent here if the Application.cfm file determines that they have not set session.passwordentry to ?true? so they are presented with a simple form to change ?false? to ?true? so that they can proceed to do their administrative tasks. This template posts to itself so the start of the template is checking to see if the values needed to proceed have been defined! --->

<cfif IsDefined("form.username") and IsDefined("form.password")>
    <!--- Always assuming that no matter what there is the possibility that the user will enter the right data but in the wrong format we will take the users information and convert it all to lower case. This allows them to enter their data in either all upper case or in a mixed case and no errors will happen. We of course have to figure that perhaps they might have a space before or after their information and they might not even be aware of it so we will trim their input to allow for that! --->
<cfset username = lcase(trim(form.username))>
<cfset password = lcase(trim(form.password))>


<!--- We need to connect to our database Note: from previous tutorial our connection file is in the main root of our guestbook program --->
<cfinclude template="../connection.cfm">

<!--- Now we need to query our database using a where clause that only returns a value if the username passed from the form is correct --->
<cfquery name="hashpassword"
             datasource=#YOUR_DSN#
             username=#YOUR_USERNAME# 
             password=#YOUR_PASSWORD#>


    SELECT password
    FROM admin
    WHERE username = '#username#'

</cfquery>

<!--- Getting this far we now know that the username is in the database so all that is left to do is check to make sure that the username and the password are a complete set. So we start this process off with a cfif tag asking coldfusion first off to make sure that the values are not equal to ?? and because our password is hashed (encrypted) in the database we must check our form entry and compare it to a hashed value so we use ?hash(password)? to compare a unhashed value against a hashed value --->
<cfif username neq '' and password neq '' and hashpassword.password eq hash(password)>

<!--- Now that we have determined that our password and our username are a match we can use the cfset tag to change session.passwordentry from its default value of ?false? to ?true? and also we set adminusername to the username of the administrator that has logged in --->
<cfset session.passwordentry = "true"
<cfset session.adminusername = username>


<!--- The last thing we do because everything is a go is use the cfinclude tag to direct the successful administrator to our administrator index template --->
<cfinclude template="index.cfm">

<!--- We need to use cfabort to kill this template because we did a redirect in the previous piece of code --->
<cfabort>

<!--- Now we continue this section with a cfelse statement, where if all the conditions we were checking for were not met than we set loginerror to be ?true? and move onto the next section of this template which will show the user the login form and not let them progress into the site until all conditions needed for a successful login are set to ?true? --->
<cfelse>
    <cfset loginerror =
"true">
</cfif>


<!--- Remember the first tag we used in this template was checking to see if anything had been entered into the form we now have to close that cfif tag here --->
</cfif>

<!--- Now we move onto the login form: the first thing to notice is there is a slight change in our form action in that we are including our session.URLToken in the action. While we are in the admin directory all movement with url?s or form actions should have this feature. If you miss one you will find a annoying loop every time you click a link you will be redirected back to the login form as we need to carry our session id as this is how coldfusion server keeps track of the fact that we have legitimately logged in and passed all the conditions for being in this area. --->
<form action="adminlogin.cfm?<cfoutput>#session.urltoken#</cfoutput>" method="post">

<!--- First thing is if the person has already attempted a login and didn?t meet the conditions needed we let them know why they are back at this template. If they have just arrived this part of the code will not show. How this is done is simple if you look at the previous code you will see we set loginerror to ?true? this was one of the last things we did so they would have had to have progressed through the code by entering in bad information to have even reached that part and triggered the cfelse tag that sets this value --->
<cfif IsDefined("loginerror") and loginerror eq "true">
    Sorry, no go! There was a problem with your username & password.
    Please try again.
</cfif>

<!--- Now we have our simple login form with only two fields needed --->
UserName: <input type="text" name="username">
PassWord: <input type="password" name="password">
<input type="submit" name="Submit" value="LOG INTO ADMIN">

header.cfm

<!--- Just a little header include file that has the needed links to travel around our admin area once we are logged in properly After this point I will assume that you have included this template into the one you are currently working on --->
<a href="add_admin.cfm?<cfoutput>#session.urltoken#</cfoutput>">Add Admin</a> ||
<a href=
"admin.cfm?<cfoutput>#session.urltoken#</cfoutput>">Delete Admin</a> ||
<a href=
"index.cfm?<cfoutput>#session.urltoken#</cfoutput>">Edit / Delete Entry</a>

================================
index.cfm

<!--- I?m not going to go into the details on constructing this template too much as it is basically a duplicate of our index template from the users area. If I lost you there refer to Part One of this tutorial! The only change that you should note is the edit delete links inside the cfoutput tag --->

<!--- The query to show our data is the same as the end-user index, except for including edit and delete link in the data being displayed. These links need to be part of the cfoutput tag in order for each entries id number to be shown. Each link carries the entries unique ID to the next template where edit or delete functions takes place --->

<!--- We need to connect to our database --->

<cfinclude template="../connection.cfm">

<cfquery name="gbook_output"
             datasource=#YOUR_DSN#
             username=#YOUR_USERNAME# 
             password=#YOUR_PASSWORD#>


    SELECT id, 
               fname, 
               lname, 
               email, 
               webUrl, 
               comment

    FROM guests

</cfquery>

<cfoutput query="gbook_output">
   
Name: #gbook_output.fname# #gbook_output.lname#<br>
    Email: #gbook.email#<br>
    Website: #gbook_output.webUrl#<br>
    Comment: #gbook_output.comment#<br>
    <br>
    <a href="edit_entry.cfm?ID=#gbook_output.id#&#session.URLToken#">Edit Entry</a> || 
    <a href=
"delete_entry_action.cfm?ID=#gbook_output.ID#&#session.URLToken#">Delete Entry</a>
</cfoutput>
<hr>


edit_entry.cfm

<!--- Okay we clicked on the ?Edit Entry? link in the previous template, when we did that we carried over the ?ID? for the entry we want to edit to this template --->

<!--- First off we must connect to our database to extract the information related to the ?ID? we carried --->

<cfinclude template="../connection.cfm">

<cfquery name="view_entry"
             datasource=#YOUR_DSN#
             username=#YOUR_USERNAME# 
             password=#YOUR_PASSWORD#>


    SELECT id, 
               fname, 
               lname, 
               email, 
               webUrl, 
               comment

    FROM guests 
    WHERE ID=#ID#
</cfquery>

<!--- Now we place the data into a form for editing purposes. Note: that we are going to pass the ?ID? to the action template using a hidden field. --->
<cfoutput query="view_entry" maxrows="1">
    <form action="edit_entry_action.cfm" method="post">
    <input type=
"hidden" name="id" value="#view_entry.id#">

    <!--- Our form fields are pretty much the same as the form fields where the user actually submitted their data, the only major difference is we pull the value out of our database to reflect the entries original submission --->
First Name: <input type="text" name="fname" value="#view_entry.fname#" >
Last Name: <input type="text" name="lname" value="#view_entry.lname#" >
Email Address: <input type="text" name="email" value="#view_entry.email#" >
Web Address: <input type="text" name="webUrl" value="#view_entry.webUrl#" >
Comments : <textarea name="comment" cols="100" rows="4">#view_entry.comments#</textarea>

<input type="submit" name="Submit" value="Submit">

</cfoutput>


edit_entry_action.cfm

<!--- Okay we edited our information in the last template now we need to update our database with the new data, we do that on this action template --->

<!--- We need to connect to our database --->
<cfinclude template="../connection.cfm">


<!--- Pretty typical update using sql to do the actual update, important to note that form.id is coming from the hidden field in our edit form. --->
<cfquery name="edit_entry"
             datasource=#YOUR_DSN#
             username=#YOUR_USERNAME# 
             password=#YOUR_PASSWORD#>


    UPDATE guests
    SET      fname = '#fname#',
               lname = '#lname#',
               email = '#email#',
               webUrl = '#webUrl#',
               comment = '#comment#'

    WHERE id=#form.id#

</cfquery>

<!--- After our update we should display the updated information onto the template just to confirm the update was successful. I usually include a link back to the update template as well, just in case the end-user messed up again --->


delete_entry_action.cfm

<!--- Going back to the index template if you had clicked delete entry this template would kick in and the entry would be deleted permanently from the database. Again important to note that form.id is being passed from the index.cfm display template to insure that the correct entry is deleted --->

<!--- We need to connect to our database --->
<cfinclude template="../connection.cfm">


<cfquery name="delete_entries"
             datasource=#YOUR_DSN#
             username=#YOUR_USERNAME# 
             password=#YOUR_PASSWORD#>


    DELETE
    FROM guests
    WHERE ID=#form.id#

</cfquery>


admin.cfm

<!--- This template shows all the current administrators within your database and allows you to delete administrators as you see fit. One funky feature of this template is it will not allow the person logged in to delete themselves. This is simply accomplished with a couple of cfif tags. The delete action of this template posts back to itself --->

<!--- First off we must set a default user value in this case we set the default value to nothing --->
<cfparam name="user" default="">

<!--- Just making sure that a user is actually being passed to the delete query with a cfif tag --->
<cfif user neq "">

    <!--- We need to connect to our database --->
    <cfinclude template="../connection.cfm">

    <cfquery name="delete_entries"
                 datasource=#YOUR_DSN#
                 username=#YOUR_USERNAME# 
                 password=#YOUR_PASSWORD#>


        DELETE
        FROM admin
        WHERE ID=#ID#

    </cfquery>

</cfif>

<!--- Query to Get the username and password from the admin table in our database --->

<cfquery name="get_admin_user_pass"
             datasource=#YOUR_DSN#
             username=#YOUR_USERNAME# 
             password=#YOUR_PASSWORD#>


    SELECT id, 
               username, 
               password
    FROM admin
    ORDER BY username

</cfquery>

<!--- One of the following links is a delete administrator link if that link is clicked the administrator is deleted from the database and this cfif tag kicks in to tell you which administrator has been deleted successfully --->
<cfif user neq "">
    The Administrator <cfoutput>#url.user#</cfoutput> has been deleted
</cfif>


<!--- Now we need to display all the administrators currently in the database --->
<cfoutput query="get_admin_user_pass">

    <!--- Just showing the administrators name, using a bold html tag to make it stand out a little better --->
   
<strong>#get_admin_user_pass.username#</strong>

    <!--- Now we need to jump into the session that was created when we logged in this how we identify ourselves as the current administrator so we don?t accidentally delete ourselves --->
   
<cfif session.adminusername eq get_admin_user_pass.username>
        Administrator logged in
    <cfelse>

    <!--- Now that we?ve display our self as the logged in administrator we can display the remaining administrator with active delete links! If one of these delete links is clicked it will move the page back to the start and use the delete query we originally coded into this template ---> 
    <a href="admin.cfm?#session.URLToken#&id=#id#&user=#get_admin_user_pass.username#">Delete This Administrator</a>

    </cfif>

</cfoutput>



add_admin.cfm

<!--- If we had selected the add admin link from our header.cfm include file we come to this simply template. All it is really is a simple form, this form posts to a separate action template. The action template is rather involved with major error checking and duplicate entry checking so in order to keep things tidy I have placed this in a separate template. You can of course put it all in one template but I found it easier to separate the two --->


<cfoutput>
    <form action="add_admin_action.cfm?#session.urltoken#" method="post">
</cfoutput>
First Name: <input type="text"

All ColdFusion Tutorials By Author: Redmanz
  • Advanced Form Checking
    This tutorial places the submitted form values into a session, than error checks them. If there is an error it will show the form again with the previous values the user entered pre-entered in the form. It will also tell the user which form fields had errors in them.
    Author: Redmanz
    Views: 38,485
    Posted Date: Tuesday, November 26, 2002
  • Duplicate Data Checking
    This tutorial uses a opt-in mailing list as an example. After the end-user enters their information the information goes to an action page which checks to see if the users email address already exists in the database. If it exists it lets them know and will not enter the duplicate data, if it does not exist it enters them into the mailing list.
    Author: Redmanz
    Views: 23,666
    Posted Date: Monday, December 9, 2002
  • Dynamic Sorting
    This tutorial shows the basics of allowing your end-users to dynamically sort the order in which they view your records. You can have as many sort orders as you have fields viewed!
    Author: Redmanz
    Views: 22,141
    Posted Date: Thursday, December 5, 2002
  • Guest Book (Part 1 / 2)
    This Guestbook is part one of a two part tutorial. This part deals with the guest book itself the second part will build a administration area for this guestbook. The guest book submits to two tables in a mySql database the first table being for the actual guest book display template and the second table to be used for an opt-in mailing list.
    Author: Redmanz
    Views: 34,064
    Posted Date: Friday, December 13, 2002
  • Guest Book (Part 2 / 2)
    This is part two of my guestbook tutorial, in part one we created the actual guestbook. In this part we will now look at creating an administration area for our guestbook. In this admin area we will be able to edit and delete guestbook entries as well as add or delete administrators.
    Author: Redmanz
    Views: 23,079
    Posted Date: Saturday, December 21, 2002
  • Send Page Url to A Friend
    A simple script where a user can click a link that will take the current templates url and pass it to a email form which they can than fill in with their friends emails addresses to send their friends your site address.
    Author: Redmanz
    Views: 27,691
    Posted Date: Saturday, November 23, 2002
  • Show Source to Friends
    Not really a tutorial but some code to help you solve programming problems by showing your code online to your friends or associates.
    Author: Redmanz
    Views: 14,431
    Posted Date: Tuesday, February 18, 2003