Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Blog Design Solutions (2006)

.pdf
Скачиваний:
39
Добавлен:
17.08.2013
Размер:
38.67 Mб
Скачать

B L O G D E S I G N S O L U T I O N S

The subject, body, and headers are constructed using the following code:

$emailsubject = "Comment added to: ".$posttitle;

$emailbody = "Comment on '".$posttitle."'"."\r\n"

."http://www.your-domain-name.com/post.php?post_id=".$post_id Â

."#c".$comment_id."\r\n\r\n"

.$comment."\r\n\r\n"

.$name." (".$website.")\r\n\r\n"; $emailbody = stripslashes($emailbody);

$emailheader = "From: ".$name." <".$email.">\r\n"."Reply-To: ".$email;

@mail("you@your-domain-name.com", $emailsubject, $emailbody, Â $emailheader);

Remember to replace www.your-domain-name.com with your website domain, and you@your-domain-name.com with your e-mail address. Note also the @ in front of the mail function. This prevents any errors being written to the screen if for some reason the mail function fails.

And the final line of the comment insert script is as follows:

header("Location: post.php?post_id=$post_id&message=$message");

The header function creates an HTTP header, which is essentially an instruction to the web server. In this case, the instruction is to go to the post page with a success message appended to the query string. This step prevents readers from submitting their comment twice if they click reload in their browser.

So now readers can add comments to your posts, and you are notified each time that happens. The final step is to show those comments in your blog. Let’s look at the script that will pull the comments from the database. Add this script to the end of PHP code at the top of post.php:

if ($myposts) {

$sql = "SELECT comment_id, name, website, comment FROM comments WHERE post_id = $post_id";

$result3 = mysql_query($sql);

$mycomments = mysql_fetch_array($result3);

}

If the post exists, the comments for this post are pulled from the database. Next you can display them on the page by inserting this code into the posts div, just after the closing ?> delimiter in your post loop:

<div id="comments"> <h2>Comments</h2> <?php

316

W R I T E Y O U R O W N B L O G E N G I N E

if($mycomments) { echo "<dl>"; do {

$comment_id = $mycomments["comment_id"]; $name = $mycomments["name"];

$website = $mycomments["website"]; $comment = format($mycomments["comment"]); if ($website != "") {

echo "<dt><a href='$website'>$name</a> wrote:</dt>\n"; } else {

echo "<dt>$name wrote:</dt>\n";

}

echo "<dd>$comment</dd>\n";

} while ($mycomments = mysql_fetch_array($result3)); echo "</dl>";

} else {

echo "<p>There are no comments yet.</p>";

}

?>

</div>

This code should be quite familiar to you by now. First, it checks that some comments

have been found in the database and then uses a do-while loop to display them on the 7 screen, adding a link to the commenter’s name if one was supplied. Notice also that I am

using the format function to format the comment.

Figure 7-17 shows what your post page should like after a comment has been added.

Figure 7-17. Post page with a comment added

317

B L O G D E S I G N S O L U T I O N S

Creating an archive

For your readers to be able to peruse what you wrote in the past, you will need an archive of blog posts. The archive page I will show you works in two ways. In the first instance, if you pass a valid year and month in the query string (such as archive. php?year=2005&month=2), the archive page will show titles and summaries for the posts you made in that month, as shown in Figure 7-18.

Figure 7-18. An archive page for a single month

Otherwise, the archive page will link to the months in which you have posted, as shown in Figure 7-19.

Figure 7-19. The overall archive page

318

W R I T E Y O U R O W N B L O G E N G I N E

Here is the entire code for the archive page. Save it as archive.php in your root directory:

<?php

// Open connection to database include("db_connect.php");

$month = (isset($_REQUEST["month"]))?$_REQUEST["month"]:""; $year = (isset($_REQUEST["year"]))?$_REQUEST["year"]:"";

if (preg_match("/^[0-9][0-9][0-9][0-9]$/", $year) AND preg_match("/^[0-9]?[0-9]$/", $month)) {

// Select posts for this month

$sql = "SELECT post_id, title, summary, DATE_FORMAT(postdate, '%e %b %Y at %H:%i')

AS dateattime FROM posts

WHERE MONTH(postdate) = $month AND YEAR(postdate) = $year"; $result = mysql_query($sql);

$myposts = mysql_fetch_array($result); if ($myposts) {

 

$showbymonth = true;

 

 

$text = strtotime("$month/1/$year");

 

 

$thismonth = date("F Y", $text);

7

}

 

 

 

}

 

 

if (!isset($showbymonth)) { $showbymonth = false;

// Select posts grouped by month and year

$sql = "SELECT DATE_FORMAT(postdate, '%M %Y') AS monthyear, MONTH(postdate) AS month, YEAR(postdate) AS year, count(*) AS count FROM posts GROUP BY monthyear

ORDER BY year, month"; $result = mysql_query($sql);

$myposts = mysql_fetch_array($result);

}

include("functions.php");

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head>

<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />

<title><?php if(isset($thismonth)) echo $thismonth; ?> Archive | Samuel's Blog</title>

<style type="text/css"> @import url(blog.css);

319

B L O G D E S I G N S O L U T I O N S

</style>

</head>

<body>

<?php include("header.php"); ?>

<!-- this is the main part of the page --> <div id="maincontent">

<div id="posts">

<h2><?php if(isset($thismonth)) echo $thismonth; ?> Archive</h2>

<?php

switch ($showbymonth) {

case true: if($myposts) {

echo "<dl>\n"; do {

$post_id = $myposts["post_id"]; $title = $myposts["title"]; $summary = $myposts["summary"];

echo "<dt><a href='post.php?post_id=$post_id' rel='bookmark'> $title</a></dt>\n";

echo "<dd>$summary</dd>\n";

} while ($myposts = mysql_fetch_array($result)); echo "</dl>";

}

break;

case false: $previousyear = ""; if($myposts) {

do {

$year = $myposts["year"]; $month = $myposts["month"];

$monthyear = $myposts["monthyear"]; $count = $myposts["count"];

if ($year != $previousyear) { if ($previousyear != "") {

echo "</ul>\n";

}

echo "<h3>$year</h3>"; echo "<ul>\n"; $previousyear = $year;

}

$plural = ($count==1) ? "" : "s";

320

W R I T E Y O U R O W N B L O G E N G I N E

echo "<li><a href='archive.php?year=$year&month=$month'> $monthyear</a> ($count post$plural)</li>\n";

} while ($myposts = mysql_fetch_array($result)); echo "</ul>";

}

break;

}

 

?>

 

</div>

 

<div id="sidebar">

 

<?php include("searchform.php"); ?>

 

</div>

 

<!-- sidebar ends -->

 

</div>

 

<!-- maincontent ends -->

 

<?php include("footer.php"); ?>

 

</body>

 

</html>

7

 

Stepping through the code:

 

<?php

 

// Open connection to database

 

include("db_connect.php");

 

$month = (isset($_REQUEST["month"]))?$_REQUEST["month"]:"";

 

$year = (isset($_REQUEST["year"]))?$_REQUEST["year"]:"";

 

A database connection is opened as usual, and the query string contents are extracted:

 

if (preg_match("/^[0-9][0-9][0-9][0-9]$/", $year) AND

 

preg_match("/^[0-9]?[0-9]$/", $month)) {

 

Here I use two regular expressions to check that the year (exactly four numbers long) and

 

the month (either one or two numbers long) look roughly correct:

 

// Select posts for this month

 

$sql = "SELECT post_id, title, summary, DATE_FORMAT(postdate,

 

'%e %b %Y at %H:%i') AS dateattime FROM posts WHERE MONTH

 

(postdate) = $month

 

AND YEAR(postdate) = $year";

 

$result = mysql_query($sql);

 

$myposts = mysql_fetch_array($result);

 

321

B L O G D E S I G N S O L U T I O N S

If the year and month look correct, the posts are retrieved. These posts are identified by using the MONTH and YEAR MySQL functions to match the postdate to the year and month specified in the query string:

if ($myposts) { $showbymonth = true;

$text = strtotime("$month/1/$year"); $thismonth = date("F Y", $text);

}

}

If the database query returns a result (that is, it finds one or more posts for that month), the $showbymonth flag is set to true so the page knows it is showing a month archive. Then the strtotime and date functions are combined to convert the numeric month and year into more readable text such as April 2005. The strtotime function takes a string that looks like a date and tries to turn it into a timestamp that can be processed by PHP. The date function takes a timestamp and formats it into text (much like the MySQL date_ format function mentioned earlier in the chapter).

if (!isset($showbymonth)) { $showbymonth = false;

// Select posts grouped by month and year

$sql = "SELECT DATE_FORMAT(postdate, '%M %Y') AS monthyear, MONTH(postdate) AS month, YEAR(postdate) AS year, count(*) AS count FROM posts GROUP BY monthyear

ORDER BY year, month"; $result = mysql_query($sql);

$myposts = mysql_fetch_array($result);

}

If the $showbymonth flag has not been set (because no posts were found for the specified month, or if no valid month or year were specified), the flag is set to false and the database is queried for all posts. There are a number of new concepts introduced in this SQL query, so I will step through it bit by bit:

SELECT DATE_FORMAT(postdate, '%M %Y') AS monthyear,

The postdate for each post is formatted as month and year; for example, April 2005.

MONTH(postdate) AS month, YEAR(postdate) AS year,

The postdate is also formatted as a month and a year separately. These values will be used to construct a link to the archive.

count(*) AS count FROM posts GROUP BY monthyear

GROUP BY monthyear is used to combine all the posts that have the same value of monthyear; for example, all the posts made in April 2005. The count(*) function can then be used to output the number of posts that have been grouped together for that value of monthyear; in other words, the number of posts made in April 2005.

ORDER BY year, month

322

W R I T E Y O U R O W N B L O G E N G I N E

The results are finally ordered by year and then month.

Skipping through the code to the posts div:

<div id="posts">

<h2><?php if(isset($thismonth)) echo $thismonth; ?> Archive</h2>

The textual value of the month and year is inserted in the heading.

<?php

 

 

switch

($showbymonth) {

 

A switch is introduced so different code can be run depending on the value of the

 

showbymonth flag.

 

case true:

 

if($myposts) {

 

echo

"<dl>\n";

 

do {

 

 

$post_id = $myposts["post_id"];

 

$title = $myposts["title"];

 

$summary = $myposts["summary"];

 

echo

"<dt><a href='post.php?post_id=$post_id' rel='bookmark'>

7

$title</a></dt>\n";

 

echo

"<dd>$summary</dd>\n";

 

} while ($myposts = mysql_fetch_array($result));

 

echo

"</dl>";

 

}

 

 

break;

 

 

If showbymonth is true, the familiar do-while loop is executed to display a list of posts for the selected month.

case false: $previousyear = ""; if($myposts) {

do {

$year = $myposts["year"]; $month = $myposts["month"];

$monthyear = $myposts["monthyear"]; $count = $myposts["count"];

if ($year != $previousyear) { if ($previousyear != "") {

echo "</ul>\n";

}

echo "<h3>$year</h3>"; echo "<ul>\n"; $previousyear = $year;

}

323

B L O G D E S I G N S O L U T I O N S

If showbymonth is false, another do-while loop is started. The desired output for the loop is a heading for the year, followed by a list of months in that year:

<h3>2004</h3>

<ul>

<li><a href='archive.php?year=2004&month=11'> November 2004</a> (1 post)</li>

<li><a href='archive.php?year=2004&month=12'> December 2004</a> (4 posts)</li>

</ul>

<h3>2005</h3><ul>

<li><a href='archive.php?year=2005&month=1'> January 2005</a> (9 posts)</li>

<li><a href='archive.php?year=2005&month=2'> February 2005</a> (12 posts)</li>

</ul>

So the headings are not repeated with every row, the normal loop is preceded by some logic that determines whether there has been a change of year; if so, the list is closed, and a new heading is written.

$plural = ($count==1) ? "" : "s";

echo "<li><a href='archive.php?year=$year&month=$month'> $monthyear</a> ($count post$plural)</li>\n";

} while ($myposts = mysql_fetch_array($result)); echo "</ul>";

}

break;

}

?>

</div>

After the year headings have been checked for, the month is written with a link back to the archive page so that the posts for that month can be viewed on a page. Note the shorthand logic used to determine whether the word post should be singular or plural, depending on the number of posts for that month. The following line:

$plural = ($count==1) ? "" : "s";

could also have been written as follows:

if ($count==1) { $plural = "";

}else { $plural = "s";

}

324

W R I T E Y O U R O W N B L O G E N G I N E

Making your blog searchable

You no doubt have noticed the search form repeated throughout your blog. Thanks to MySQL, adding search capabilities to your blog is easy. All you need to do is add a search index to your posts table. To do this, open up phpMyAdmin in your browser, select the blog database, and click the posts link in the left frame. In the Indexes box (halfway down the screen), type 3 in the Create an index on n columns box and click Go (see Figure 7-20).

7

Figure 7-20. Creating an index in PHPMyAdmin

Now fill out the form as shown in Figure 7-21 and click Save.

Figure 7-21. Adding a fulltext index to the posts table in phpMyAdmin

325