Completing a Blogger with PHP

If you’re looking for a comprehensive series on how to create an expansible blog application with PHP 5, then this group of tutorials might be what you’ve been expecting to find. Welcome to the concluding installment of the series "Building a blogger with PHP." Made up of three friendly articles, this series provides you with all the information you need to start building a blog system with PHP in a few easy steps.

Introduction

Now, and returning for a moment to the second article of this series, I’m pretty certain that you’ll recall all the topics that I covered in that tutorial. Since my primary goal was to construct an expansible blogger, in the previous article I coded some additional methods that corresponded to the already familiar “BlogProcessor” class. These methods provided it with the capacity for displaying all the blog entries stored on the corresponding database table, as well as showing the respective input forms for inserting and updating different blogs.

Of course, all the features that I mentioned above mean that the blog application in question is close to completion. After all, what else can we ask for? Well, not so fast, since the blogger is still immature when it comes to its visual presentation. It could also use some extra features, such as a basic client-side validation mechanism that must be applied to the input forms that I referenced before.

As you can see, there are still some aspects of the blog system that need to be addressed properly. Therefore, in this concluding part of the series, I’ll cover them and complete the system.

Sounds really interesting doesn’t it? Let’s waste no more time in preliminaries and start reading. We’re almost done, believe me!

{mospagebreak title=A quick look at the BlogProcessor class}

As I usually do in each of my articles on web development, before I leap forward and start giving the final touches to the blog application, I’d like to show you briefly how the “BlogProcessor” class looked originally. This will refresh your memory before we proceed.

Here is the full source code that corresponds to the mentioned class, in accordance with the signature defined in the previous article. Please, have a look at it:

class BlogProcessor{

            private $mysql;

            private $blogData;

            public function __construct(MySQL $mysql){

                        $this->mysql=$mysql;

                        $this->blogData=$_POST;

            }

            // display blog system

            public function displayBlogger(){

                        // edit blog

                        if($this->blogData['editblog']){

                                   // display edit page

                                   return $this->displayEditPage
();

                        }

                        else{

                                   // insert new blog

                                   if($this->blogData
['insertblog']){

                                               $this->insertBlog();

                                   }

                                   // update blog

                                   elseif($this->blogData
['updateblog']){

                                               $this->updateBlog
();

                                   }

                                   // delete blog

                                   elseif($this->blogData
['deleteblog']){

                                               $this->deleteBlog
();      

                                   }

                        }

                        // display main page

                        return $this->displayMainPage();

            }

            // insert new blog

            private function insertBlog(){

                        $title=$this->blogData['title'];

                        $author=$this->blogData['author'];

                        $content=$this->blogData['content'];

                        $this->mysql->query("INSERT INTO blogs
(id,author,title,content,date) VALUES
(NULL,’$author’,'$title’,'$content’,TIMESTAMP(10))");

                        header(‘Location:’.$_SERVER
['PHP_SELF']);                            

            }

            // update blog

            private function updateBlog(){

                        $id=$this->blogData['id'];

                        $title=$this->blogData['title'];

                        $author=$this->blogData['author'];

                        $content=$this->blogData['content'];

                        $this->mysql->query("UPDATE blogs SET
title=’$title’,author=’$author’,content=’$content’,date=TIMESTAMP
(10) WHERE id=’$id’");

                        header(‘Location:’.$_SERVER['PHP_SELF']);

            }

            // delete blog

            private function deleteBlog(){

                        $id=$this->blogData['id'];

                        $title=$this->blogData['title'];

                        $author=$this->blogData['author'];

                        $content=$this->blogData['content'];

                        $this->mysql->query("DELETE FROM blogs
WHERE id=’$id’");

                        header(‘Location:’.$_SERVER['PHP_SELF']);

            }

            // display all the blogs

            private function displayBlogs(){

                        $result=$this->mysql->query("SELECT *
FROM blogs");

                        $output=”;

                        while($row=$result->fetchRow()){

                                   $content=nl2br($row
['content']); 

$output.=<<<EOD

<div class="blog">

<h2>$row[title]</h2>

<h3> Author: $row[author]<h3>

<h3> Posted: $row[date]</h3>

<p>$content</p>

<form action="$_SERVER[PHP_SELF]" method="post">

<input type="submit" value="Edit Blog" name="editblog" />

<input type="submit" value="Delete Blog" name="deleteblog" />

<input type="hidden" value="$row[id]" name="id" />

</form>

</div>

EOD;

                        }

                        return $output;

            }

            // display insertion form

            private function displayInsertForm(){

$output=<<<EOD

<div class="dataform">

<h2>Insert New Blog</h2>

<form action="$_SERVER[PHP_SELF]" method="post" id="insertform">

<p>Title:</p><p><input type="text" name="title"
class="datafield" /></p>

<p>Author:</p><p><input type="text" name="author"
class="datafield" /></p>

<p>Type your content below</p><p><textarea
name="content"></textarea></p>

<p><input type="submit" name="insertblog" value="Insert
Blog" /></p>

</form>

</div>

EOD;

                        return $output;  

            }

            // display update form

            private function displayUpdateForm(){

                        $id=$this->blogData['id'];

                        $result=$this->mysql->query("SELECT *
FROM blogs WHERE id=’$id’");

                        if($result->countRows()>0){

                                   $row=$result->fetchRow();

$output=<<<EOD

<div class="dataform">

<h2>Update Blog</h2>

<form action="$_SERVER[PHP_SELF]" method="post" id="updateform">

<p>Title:</p><p><input type="text" name="title" value="$row
[title]" class="datafield" /></p>

<p>Author:</p><p><input type="text" name="author" value="$row
[author]" class="datafield" /></p>

<p>Update your content below</p><p><textarea name="content">$row
[content]</textarea></p>

<p><input type="submit" name="updateblog" value="Update
Blog" /></p>

<input type="hidden" value="$id" name="id" />

</form>

</div>

EOD;

                                   return $output;

                        }

            }

            // display page header

            private function displayHeader(){

$output=<<<EOD

<!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">

<head>

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

<title>Blogger System</title>

<link href="styles.css" rel="stylesheet" type="text/css"
media="screen" />

<script language="javascript" src="valfunctions.js"></script>

</head>

<body>

<h1>PHP-BASED BLOG SYSTEM</h1>

EOD;

                        return $output;

            }

            // display page footer

            private function displayFooter(){

                        return ‘</body></html>’;

            }

            // display main page

            private function displayMainPage(){

                        return $this->displayHeader().$this-
>displayBlogs().$this->displayInsertForm().$this->displayFooter
();

            }

            // display edit page

            private function displayEditPage(){

                        return $this->displayHeader().$this-
>displayUpdateForm().$this->displayFooter();

            }

}

As you’ll probably remember at this point, the above blog processor class has been provided with all the required methods for inserting, updating and deleting blog entries, in addition to displaying these entries in the browser. However, you’ll notice this class also accepts an object of type “MySQL,” which is very convenient for performing all the database-related operations inside the context of the class.

Now that you hopefully recalled how the “BlogProcessor” class was defined originally, you’re surely wondering…what’s the next step? Well, obviously I need to show you the respective signature of the “MySQL” class, which is aggregated by the blog processor. In the following section, I’ll be doing exactly that.

Want to learn how this MySQL wrapping class really looks? Be a bit more patient and keep reading.

{mospagebreak title=Providing the blog processor with database connectivity}

As I discussed in the previous section, the blog processor aggregates a simple MySQL wrapping class to have at its disposal the required capacity for handling all the database-related operations. As you’ll imagine, this functionality is easily achieved by coding a new pair of classes, which are shown below.

Take a look at their respective definitions, please:

// define ‘MySQL’ class

class MySQL{

private $conId;

            private $host;

            private $user;

            private $password;

            private $database;

            private $result;

            const OPTIONS=4;

            public function __construct($options=array()){

                        if(count($options)!=self::OPTIONS){

                                               throw new
Exception(‘Invalid number of connection parameters’);

                        }

                        foreach($options as $parameter=>$value){

                                               if(!$value){

                                               throw new
Exception(‘Invalid parameter ‘.$parameter);

                                               }

                                               $this->
{$parameter}=$value;

                        }

                        $this->connectDB();

            }

            // connect to MySQL

            private function connectDB(){

                        if(!$this->conId=mysql_connect($this-
>host,$this->user,$this->password)){

                                               throw new
Exception(‘Error connecting to the server’);

                        }

                        if(!mysql_select_db($this-
>database,$this->conId)){

                                               throw new
Exception(‘Error selecting database’);

                        }

            }

            // run query

            public function query($query){

                        if(!$this->result=mysql_query
($query,$this->conId)){

                                               throw new
Exception(‘Error performing query ‘.$query);

                        }

                        return new Result($this,$this->result);

            }

}

// define ‘Result’ class

class Result {

            private $mysql;

            private $result;

            public function __construct(&$mysql,$result){

                        $this->mysql=&$mysql;

                        $this->result=$result;

            }

            // fetch row

            public function fetchRow(){

                        return mysql_fetch_assoc($this->result);

            }

            // count rows

            public function countRows(){

                        if(!$rows=mysql_num_rows($this->result)){

                                               throw new
Exception(‘Error counting rows’);

                        }

                        return $rows;

            }

            // count affected rows

            public function countAffectedRows(){

                        if(!$rows=mysql_affected_rows($this-
>mysql->conId)){

                                               throw new
Exception(‘Error counting affected rows’);

                        }

                        return $rows;

            }

            // get ID form last-inserted row

            public function getInsertID(){

                        if(!$id=mysql_insert_id($this->mysql-
>conId)){

                                               throw new
Exception(‘Error getting ID’);

                        }

                        return $id;

            }

            // seek row

            public function seekRow($row=0){

                        if(!is_int($row)||$row<0){

                                               throw new
Exception(‘Invalid result set offset’);

                        }

                        if(!mysql_data_seek($this->result,$row)){

                                               throw new
Exception(‘Error seeking data’);

                        }

            }

}

All right, I think that the two classes listed above should be quite familiar to you, since I’ve been using them as part of different code samples in several PHP tutorials. With reference to these classes, you can see they offer a group of comprehensive methods for connecting to MySQL, running queries and handling result sets, which can be used inside the “BlogProcessor” class. Quite simple, right?

Obviously this isn’t rocket science, so let’s move on to the next section. We’ll learn how to provide all the input forms included with the blog processor with a basic JavaScript validation mechanism, which adds a useful feature to the whole application.

To see how these client-side verification routines will be integrated with the blog application, please click on the link below and keep reading.

{mospagebreak title=Implementing client-side data validation on input forms}

As I mentioned in the section that you just read, one of the last improvements that I plan to introduce to expand the existing functionality of the blogger consists essentially of implementing a basic (but effective) validation mechanism on each of the input forms included with the application.

As you probably already noticed from the beginning, the blogger program originally included a JavaScript file called “valfunctions.js.” Not surprisingly, this file is the container for all the JavaScript functions that will perform a basic validation on each value entered in the two input forms integrated with the application. These input forms were covered in detail in the previous article.

Regarding the JavaScript-based validation functions contained in the “valfunctions.js” file, they look like this:

// validate form

function validateForm(formObj){

            valid=true;

            var title=formObj.elements[0];

            if(!title){return};

            if(!title.value){showError(title,’*Enter a title for
your blog’)};

            var author=formObj.elements[1];

            if(!author){return};

            if(!author.value){showError(author,’*Enter your full
name’)};

            var content=formObj.elements[2];

            if(!content){return};

            if(!content.value){showError(content,’*Enter some
text for your blog’)};

            return valid;

}

// show error messages

function showError(obj,message){

            if(!obj.errorNode){

            obj.onchange=hideError;

            var span=document.createElement(‘span’);

                        span.className=’error’;

            span.appendChild(document.createTextNode(message));

            obj.parentNode.appendChild(span);

                        obj.errorNode=span;

            }

            valid=false;

            return

}

// hide error messages

function hideError(){

            this.parentNode.removeChild(this.errorNode);

            this.errorNode=null;

            this.onchange=null;

}

// execute ‘ValidateForm()’ function when page is loaded

window.onload=function(){

            // check if browser is W3CDOM compatible

            if(document.getElementById&&document.
getElementsByTagName&&document.createElement){

                        var insform=document.getElementById
(‘insertform’);

                        if(insform){insform.onsubmit=function()
{return validateForm(this)}};

                        var updform=document.getElementById
(‘updateform’);

                        if(updform){updform.onsubmit=function()
{return validateForm(this)}};

    }

}

As you’ll realize, the group of validation functions listed above performs a basic verification on the data entered in the corresponding blog insertion form of the application, as well on the one used for updating existing entries. It’s not my intention to develop a full-featured validation system here, since that will be certainly out of the scope of this series. However, the JavaScript data checking system that I coded previously really works decently when it comes to verifying whether or not a particular input box has been filled.

Okay, at this stage, the blogger is now capable of validating, at least basically, any data entered into the corresponding input forms. The last step required for completing the application rests simply on adding some CSS styles to the (X)HTML markup that structures the program, improving its look and feel.

As you might have guessed, all these useful tasks will be performed in the next few lines, thus jump forward into next section. I’ll be there, waiting for you.

{mospagebreak title=Improving the blogger’s visual appearance}

By following a similar approach to the one I took when I included a basic client-side validation mechanism, I’ll also provide the blog application with a few CSS rules aimed at improving the corresponding visual presentation. As you’ll imagine, this task can be easily achieved by including the CSS file listed below. Here is the file in question:

body{

            background: #eee;

            margin: 0;

            padding: 0;

}

h1{

            width: 600px;

            padding: 10px;

            margin-left: auto;

            margin-right: auto;

            background: #339;

            font: bold 20px Arial, Helvetica, sans-serif;

            color: #fff;

            border: 1px solid #000;

}

h2{

            font: bold 18px  Arial, Helvetica, sans-serif;

            color: #339;

}

h3{

            font: bold 16px Arial, Helvetica, sans-serif;

            color: #339;

}

textarea{

            width: 300px;

            height: 200px;

            font: normal 12px Arial, Helvetica, sans-serif;

            color: #000;

}

.blog{

            width: 600px;

            padding: 10px;

            margin-left: auto;

            margin-right: auto;

            margin-bottom: 5px;

            background: #ccf;

            border: 1px solid #000;

}

.blog p{

            font: normal 12px Arial, Helvetica, sans-serif;

            color: #000;

}

.dataform{

            width: 600px;

            height: 410px;

            padding: 10px;

            margin-left: auto;

            margin-right: auto;

            margin-bottom: 5px;

            background: #dccae8;

            border: 1px solid #000; 

}

.dataform p{

            margin: 5px;

            font: normal 12px Arial, Helvetica, sans-serif;

            color: #339;

}

.datafield{

            width: 300px;

            font: normal 12px Arial, Helvetica, sans-serif;

            color: #000;

}

.error{

            margin: 0 0 0 5px;

            font: normal 12px Arial, Helvetica, sans-serif;

            color: #f30;

Finally, the blog application has been completed! In this case, I decided to include the above CSS declarations, but this feature can be easily modified to suit your personal taste.

Final thoughts

Sad but true, we’ve come to the end of this series. In this hopefully instructive journey, you learned how to build a highly expansible blogger with PHP 5, which allows you to insert, update and delete entries very easily.

In this case I purposely used the term “expansible.” You can introduce your own modifications to the application to extend its existing functionality. See you in the next PHP tutorial!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan