562 Chapter 26 Building a Content Management System $tn_width = $max_width; } else { $tn_width = ceil($y_ratio * $width); $tn_height = $max_height; } Solution Design/Overview A summary of the files in this application is shown in Table 26.1. Table 26.1 Files in the Content Management Application Name Type Description create_database.sql SQL SQL to set up the content database and some sample data include_fns.php Functions Collection of include files for this application db_fns.php Functions Collection of functions for connecting to content database select_fns.php Functions Collection of functions to aid creation of SELECT lists user_auth_fns.php Functions Collection of functions for authenticating users header.php Template Shown at the top of every content page footer.php Template Shown at the bottom of every content page logo.gif Image The logo file displayed in header.php headlines.php Application Shows the most recent headline from each page of the site page.php Application Lists the headlines and story text for a particular page resize_image.php Application Resizes an image on-the-fly for headlines.php search_form.php Application Form to enter keywords for searching the site content search.php Application Displays headlines of content matching keyword criteria login.php Application Authenticates a user’s password and logs her in to the system logout.php Application Logs a user out of the system stories.php Application Lists stories that the logged-in user has written with an option to add, modify, or delete stories story.php Application The story detail screen for editing or adding a new story 32 525x ch26 1/24/03 3:38 PM Page 562 563 Designing the Database story_submit.php Application Adds new story or commits changes from data entered in story.php delete_story.php Application Processes story delete request from stories.php keywords.php Application Lists keywords for a story with option to add or delete keywords keyword_add.php Application Processes keyword add request from key- words.php keyword_delete.php Application Processes keyword delete request from key- words.php publish.php Application Editor’s list of stories showing which ones are published with an option to toggle each one’s status publish_story.php Application Processes a publish request from publish.php unpublish_story.php Application Processes an unpublish request from publish.php Designing the Database Listing 26.2 shows the SQL queries used to create the database for the content system. This listing is part of the file create_database.sql. The file on the CD also contains queries to populate the database with some sample users and stories. Listing 26.2 Excerpt from create_database.sql—SQL File to Set Up the Content Database drop database if exists content; create database content; use content; drop table if exists writers; create table writers ( username varchar(16) primary key, password varchar(16) not null, full_name text ); drop table if exists stories; Table 26.1 Continued Name Type Description 32 525x ch26 1/24/03 3:38 PM Page 563 564 Chapter 26 Building a Content Management System create table stories ( id int primary key auto_increment, writer varchar(16) not null, # foreign key writers.username page varchar(16) not null, # foreign key pages.code headline text, story_text text, picture text, created int, modified int, published int ); drop table if exists pages; create table pages ( code varchar(16) primary key, description text ); drop table if exists writer_permissions; create table writer_permissions ( writer varchar(16) not null, # foreign key writers.username page varchar(16) not null # foreign key pages.code ); drop table if exists keywords; create table keywords ( story int not null, # foreign key stories.id keyword varchar(32) not null, weight int not null ); grant select, insert, update, delete on content.* to content@localhost identified by 'password'; We need to store a little information about each writer, including a login name and password, in the writers table.We’ll store their full names for displaying after each arti- cle and for greeting them when they log in. The pages table contains the page heading for each page on which stories can be displayed.The writer_permissions table implements a many-to-many relationship indicating for which pages a writer can submit stories. The stories table contains separate fields for headline, story_text,and picture as discussed previously.The created, modified, and published fields are integer fields and will Listing 26.2 Continued 32 525x ch26 1/24/03 3:38 PM Page 564 565 Implementation store the Unix timestamp value of the relevant times. To create the database, run the following command: mysql –u root < create_database.sql Implementation Now that we have a database and image resize function to draw on, let’s go about build- ing the main part of the system. Front End Let’s start by looking at headlines.php, shown in Listing 26.3, which would be the first page that a visitor to the site would see.We want to show her the headlines of the latest story from each page. Listing 26.3 headlines.php—Shows the Most Recent Headline from Each Page <?php include('include_fns.php'); include('header.php'); $conn = db_connect(); $pages_sql = 'select * from pages order by code'; $pages_result = mysql_query($pages_sql, $conn); while ($pages = mysql_fetch_array($pages_result)) { $story_sql = "select * from stories where page = '".$pages['code']."' and published is not null order by published desc"; $story_result = mysql_query($story_sql, $conn); if (mysql_num_rows($story_result)) { $story = mysql_fetch_array($story_result); print '<table border="0" width="400">'; print '<tr>'; print '<td rowspan="2" width="100">'; if ($story[picture]) print "<img src=\"resize_image.php?image=$story[picture]\" />"; print '</td>'; print '<td>'; print '<h3>'.$pages['description'].'</h3>'; print $story['headline']; print '</td>'; print '</tr>'; 32 525x ch26 1/24/03 3:38 PM Page 565 566 Chapter 26 Building a Content Management System print '<tr><td align="right">'; print '<a href="page.php?page='.$pages['code'].'">'; print '<font size="1">Read more '.$pages['code'].' </font>'; print '</a>'; print '</table>'; } } include('footer.php'); ?> This script, as with all the public scripts, includes header.php at the start and footer.php at the end. Any output generated by the script is therefore displayed within the main content cell in the page. The hard work is done by two database queries. First, select * from pages order by code will retrieve the list of pages that are in the database. Next the contents of the loop "select * from stories where page = '".$pages['code']."' and published is not null order by published desc" is executed to find the stories on that page in reverse order of the date published. Figure 26.3 shows the output from headline.php using the sample application data. Listing 26.3 Continued Figure 26.3 Showing the headlines from each page within the site. 32 525x ch26 1/24/03 3:38 PM Page 566 . Application Processes keyword add request from key- words .php keyword_delete .php Application Processes keyword delete request from key- words .php publish .php Application Editor’s list of stories showing. particular page resize_image .php Application Resizes an image on-the-fly for headlines .php search_form .php Application Form to enter keywords for searching the site content search .php Application Displays headlines of. keyword criteria login .php Application Authenticates a user’s password and logs her in to the system logout .php Application Logs a user out of the system stories .php Application Lists stories that the logged-in