567 Implementation Next to each headline, a link is generated in the following form: <a href="page.php?page=1"><font size="1">Read more news </font></a> This is done within the previous loop so that the query string value of page and the page name are printed next to the relevant headline. Clicking this link takes the visitor to page.php—the full list of stories for the particular page.The source for page.php can be found in Listing 26.4. Listing 26.4 page.php—Displays All the Published Stories on a Page <?php if (!isset($HTTP_GET_VARS['page'])) { header('Location: headlines.php'); exit; } $page = $HTTP_GET_VARS['page']; include('include_fns.php'); include('header.php'); $conn = db_connect(); $sql = "select * from stories where page = '$page' and published is not null order by published desc"; $result = mysql_query($sql, $conn); while ($story = mysql_fetch_array($result)) { print '<h2>'.$story['headline'].'</h2>'; if ($story['picture']) { $size = getImageSize($story['picture']); $width = $size[0]; $height = $size[1]; print "<img src=\"".$story['picture']."\" height=\"$height\" width=\"$width\" align=\"left\" />"; } print $story['story_text']; $w = get_writer_record($story['writer']); print '<br /><font size="1">'; print $w[full_name].', '; print date('M d, H:i', $story['modified']); 32 525x ch26 1/24/03 3:38 PM Page 567 568 Chapter 26 Building a Content Management System print '</font>'; } include('footer.php'); ?> Note that page.php requires a value for page to formulate the first query correctly. In case page.php is ever called directly without the query string, the first condition if (!isset($HTTP_GET_VARS['page'])) { header('Location: headlines.php'); exit; } will send the visitor back to the headline page so that the omission of page will not cause an error. The first query select * from stories where page = '$page' and published is not null order by published desc finds all stories published on the specified page, with the most recently published first. Within each loop, the uploaded image and story text are printed to the screen, followed by the writer’s name and date of last change. Figure 26.4 shows page.php in action, displaying all the news page items for our sample application. Back End Let’s look next at how stories can be added to the system.Writers begin at stories.php.This script, after a writer is authenticated, displays a list of the stories the author has written and either displays the published date, or offers options of adding a new story, editing or deleting an existing one, or setting the search keywords.An exam- ple is shown in Figure 26.5. These screens are not formatted inside the header and footer files, although they could be if desired. Because only the writers and editor will use these scripts, in our example we have chosen only to format as much as needed to create a usable system. The code for stories.php is shown in Listing 26.5. Listing 26.4 Continued 32 525x ch26 1/24/03 3:38 PM Page 568 569 Implementation Figure 26.4 Showing all published stories on the news page. Figure 26.5 The story management page for writers. 32 525x ch26 1/24/03 3:38 PM Page 569 570 Chapter 26 Building a Content Management System Listing 26.5 stories.php—Is the Interface for Writers to Manage Their Stories <?php include('include_fns.php'); session_start(); if (!check_auth_user()) { ?> <form action="login.php" method="post"> <table border="0"> <tr> <td>Username</td> <td><input size="16" name="username"></td> </tr> <tr> <td>Password</td> <td><input size="16" type="password" name="password"></td> </tr> </table> <input type="submit" value="Log in'> </form> <?php } else { $conn = db_connect(); $w = get_writer_record($HTTP_SESSION_VARS['auth_user']); print 'Welcome, '.$w['full_name']; print ' (<a href="logout.php">Logout</a>)'; print '<p>'; $sql = 'select * from stories where writer = \''. '$HTTP_SESSION_VARS['auth_user'].'\''.order by created desc'; $result = mysql_query($sql, $conn); print 'Your stories: '; print mysql_num_rows($result); print ' (<a href="story.php">Add new</a>)'; print '</p><br /><br />'; if (mysql_num_rows($result)) { print '<table>'; print '<tr><th>Headline</th><th>Page</th>'; print '<th>Created</th><th>Last modified</th></tr>'; while ($qry = mysql_fetch_array($result)) { 32 525x ch26 1/24/03 3:38 PM Page 570 571 Implementation print '<tr>'; print '<td>'; print $qry['headline']; print '</td>'; print '<td>'; print $qry['page']; print '</td>'; print '<td>'; print date('M d, H:i', $qry['created']); print '</td>'; print '<td>'; print date('M d, H:i', $qry['modified']); print '</td>'; print '<td>'; if ($qry['published']) print '[Published '.date('M d, H:i', $qry['published']).']'; else { print '[<a href="story.php?story='.$qry['id'].'">edit</a>] '; print '[<a href="delete_story.php?story='.$qry['id'].'">delete</a>] '; print '[<a href="keywords.php?story='.$qry['id'].'">keywords</a>]'; } print '</td>'; print '</tr>'; } print '</table>'; } } ?> The first step is to check whether a user has been authenticated, and if not, to display only a login form. The session variable auth_user will be set after a writer has logged in.The authenti- cation here isn’t particularly secure, and in reality you would take more care to ensure that the writers are properly authenticated.This is dealt with in detail in Chapter 14, “Implementing Authentication with PHP and MySQL.” The login form submits to login.php, which checks the username and password against database values. If the login is successful, the user is returned to the page she came from, using the HTTP_REFERER value.This means that the login script can be invoked from any calling page within the system. Next, we welcome the writer by name and give her the opportunity to log out.This link will always appear at the top of stories.php so she can easily log out when she is done. Listing 26.5 Continued 32 525x ch26 1/24/03 3:38 PM Page 571 . detail in Chapter 14, “Implementing Authentication with PHP and MySQL. ” The login form submits to login .php, which checks the username and password against database values. If the login is successful,. stories .php Is the Interface for Writers to Manage Their Stories < ?php include('include_fns .php& apos;); session_start(); if (!check_auth_user()) { ?> <form action="login .php& quot;. visitor to page .php the full list of stories for the particular page.The source for page .php can be found in Listing 26.4. Listing 26.4 page .php Displays All the Published Stories on a Page < ?php if