Building a Site Engine with PHP, Part 2

If you read the first article in this series, you’d know that we’re about to start talking about the plug-in and module system for our site engine. Along with the plug-ins and modules, we’re also going to be discussing some of the general functions that are needed to make site engine work correctly.

Don’t Plug it in Yet

In the last article I discussed briefly how the plug-in and module systems worked. This article will get more in-depth on the subject, but, before we talk about the plug-ins (in fact, before they’ll even work) we’ll have to make a few other functions. I’d also like to take this time to let you know that for this project we’re going to be using PHP5rc2 with MySQL.

Since all the information about the plug-ins and modules is in the database, we’re going to want to make a class that will let us perform the most common SQL functions with ease. Also, since the site engine will run multiple sites, each of which can have their own plug-ins and modules, we’ll want to make the functions that let the engine know what site is requesting the plug-ins and modules. Let’s get started with our general functions. I hope you learn something new and cool that you’ll like.

This is the SQL class; save the following as:

“your_site_dir/inc/sql.inc.php”

<?PHP
class sql{
   
    public $qcount;    //this keeps count of how many queries we make
   
    function sql(){    //we name the main function the same as the class so that it initializes when the class is called
        $this->qcount=0;    //set the default of $qcount to 0 because we don’t yet have any queries
       
$db=@mysql_connect($host,$user,$pass,$dbname);    //create connection string ready to accept the parameters to connect with
        if($db){    // check to see if a connection is made
            return $db;    //return the connection ID if it’s a valid connection
        }else{
            die(“<b>Error:</b> Database offline.<br/>”.mysql_error() );    //if connection is invalid quit script and return error
        }
    }
   
    function _select_db($dbname){
        return mysql_select_db($dbname);    //this is the function to select a MySQL database (of course…)
    }
   
    function _query($query){
        $this->qcount++;    //add 1 to the $qcount for each query, this will update $qcount everything the _query function is called
        return mysql_query($query);        //This is the function to execute a Query on a MySQL database
    }

    function _fetch_row($id){
        return mysql_fetch_row($id);    //this fetches one row of data from the result of calling the _query function, it returns data as an array with numeric offsets
    }
   
    function _fetch_array($id){
        return mysql_fetch_array($id);    //this function is just like the _fetch_row function, only this on returns both numeric offsets, and offsets named like the database field
    }
   
    function _insert_id(){
        return mysql_insert_id();    //this function returns the ID generated for an AUTO_INCREMENT column by the previous INSERT query
    }
   
    function _affected_rows($id){
        return mysql_affected_rows($id);    //this function returns the number of rows affected by the last INSERT, UPDATE or DELETE query
    }
   
    function _num_rows($id){
        return mysql_num_rows($id);        //this function counts the number of rows returned form a previous SELECT query
    }
   
    function _fetch_object($id){
        return mysql_fetch_object($id);        //This function is my favorite MySQL function, it’s just like the _fetch_array function except an object is returned instead of an array
    }
   
    function _mysql_error(){
        return mysql_error();    //This function will return and errors generated by MySQL
    }
       
}
?>

Now to complement our previous class file, we’ll make another little class called config. This should be self explanatory; save the following as “your_site_dir/inc/config.inc.php”

<?PHP
class config {
   
    public $dbhost;
    public $dbuser;
    public $dbpass;
    public $dbname;
   
    function config(){
        $this->dbhost=”localhost”;
        $this->dbuser=”root”;
        $this->dbpass=””;
        $this->dbname=”engine”;
    }
}
   
?>

These may not directly tie in to each other at the moment, but they will in just a bit.

{mospagebreak title=Best Site() Ever Made}

Now we need to make a class that will get all the information we need about the site. Since each site’s common information is stored in the database, all we’ll have to do is select it. However we’d need some bit of information about the site to give to the select statement to tell it what site we want information for. I really don’t think anyone wants to hand code an entire list of all the sites they have, just to have to update it when you add a site, therefore we look toward the parse_url() function. This function is really useful for something like this; it will take the URL for a site and bust it up into an array that contains all the information about a URL you could ever need. Here’s a list of all the elements it can handle:

  • scheme – e.g. http
  • host
  • port
  • user
  • pass
  • path
  • query – after the question mark ?
  • fragment – after the hashmark #

Pretty useful isn’t it? We’ll also need to know what page has been requested (www.url.com?page=thispage), therefore we’ll also include a small function to get that information. Here is the class we’ll use for doing everything, save it as “your_site_dir/inc/site.inc.php”:

<?PHP
class site{
   
    public $site; //This will hold the array of site information that will be used in other classes
   
    function site(){ //we name the main function the same as the class so that it initializes when the class is called
        global $sql; //this requests the $sql class as a global variable
        $purl=parse_url(‘http://’.$_SERVER['HTTP_HOST']);    //The parse_url function breaks the page’s URL into and array of the URL elements
        $purl=$purl['host'];    //This sets the $purl variable to the value of “host” in the array previously made by parse_url
        $host=explode(“.”,$purl);    //now we break the hostname from $purl into an array delimited by a period
        if($host[0]==’www’){    //check the value of the hostname
            $this->site['host']=$host[1];    //if the first element of the hostname is www, the variable $site['host'] to the second element of the hostname
        }else{
            $this->site['host']=$host[0]; //if the first element isn’t www, set the variable $site['host'] to the first element of the hostname
        }
        $site_info=$sql->_fetch_row($sql->_query(“SELECT `sites`.`site_ID`,`sites`.`site_name`FROM`sites`WHERE(`sites`.`site_host` = ‘{$this->site['host']}’) LIMIT 1″)); //select the information about the site from the database
        $this->site['ID'] = $site_info[0];    //set the site’s ID in the $site variable
        $this->site['name'] = $site_info[1];    //set the site’s name in the $site variable
        $this->page();    // call the function page()
    }
   
    function page(){   
        if(isset($_REQUEST['page'])){    //check to see if “page” has been set as a _GET or _POST variable
            $this->site['page']=$_REQUEST['page'];    //if it has been set as a _GET or _POST variable, set it as the page name in $site
        }else{
            $this->site['page']=”main”;    //if it hasn’t been set as a _GET or _POST variable, set the page name in $site too “main”
        }
    }
}
?>

This class will produce an object with an array that looks like this:

$site->site['host'] — the URL to a site without the www or the .com/.org/.net (i.e. www.devshed.com will be deshed)

$site->site['ID'] — the site’s ID in the database

$site->site['name'] — the name you gave to the site when you set it up (it’s nice to use as the title of the site)

$site->site['page'] — the currently requested page (www.url.com?page=thispage)

See, using the parse_url() function is pretty useful when you need to retrieve site information. Sometimes it’s even easier than calling the query_string.

{mospagebreak title=OK, Plug it in Now}

Now that the past couple of classes are all set up, we’re ready to start loading up all our plug-ins. Well, we’re ready to make the class that will load them. First we’ll select the plug-in ID, name, directory, and file from the database. Then we’ll set them all to an array in the plug-ins class, that way the information about the plug-ins can be used later without having to select it from the database again. After we’ve built our list of initialized plug-ins, we’ll use a function that will actually load the plug-ins and include them into our engine. With that all said, let’s take a look at the class file.

<?PHP

class plugins{

    public $pcount;    //this will hold the number of plug-ins that we actually load into the engine
    public $plugin_list;    //this will hold our array of plug-in information
    public $plugin_error;    //this will hold any errors that are produced by loading a plug-in
    public $lcount;    //this will hold the number of plugins in our plug-ins list
   
    function plugins($site_id=””){    //we name the main function the same as the class so that it initializes when the class is called
        global $sql,$site;    //this requests the $sql and $site classes as a global variables
        $this->pcount=0;    //set the default of $pcount to 0 because we don’t yet have any plug-ins loaded
        $this->lcount=0;    //set the default of $lcount to 0 because we don’t yet have any plug-ins in the plug-ins list
        if($site_id==””){    //check to see if the administrator overrides the $site_id to list plug-ins for other sites
            $site_id = $site->site['ID'];    //if the site_id isn’t overridden set it to the current site’s id
        }
        $plugins_list=$sql->_query(“SELECT
                                         plugins.plugin_ID,
                                         plugins.plugin_name,
                                         plugins.plugin_dir,
                                         plugins.plugin_file
                                     FROM
                                         plugin_status,
                                         plugins
                                     WHERE
                                         plugins.plugin_ID = plugin_status.plugin_ID AND
                                         plugin_status.site_ID = ‘$site_id’ AND
                                         plugin_status.plugin_status = ‘initialized’
                                     ORDER BY
                                         plugins.plugin_priority DESC”);    //select all the initialized plug-in information from the database
        while($plugin=$sql->_fetch_object($plugins_list)){    //start a loop to get the information from the select query using the _fetch_object function
            $this->lcount++;    // update lcount for each plug-in we add to the plug-ins list
            $this->plugin_list['plug_ID'][]=$plugin->plugin_ID;    //add the current plug-in’s ID to the plugin list
            $this->plugin_list['plug_name'][]=$plugin->plugin_name;    //add the current plug-in’s name to the plugin list
            $this->plugin_list['plug_dir'][]=$plugin->plugin_dir;    //add the current plug-in’s directory to the plugin list
            $this->plugin_list['plug_file'][]=$plugin->plugin_file;    //add the current plug-in’s file to the plugin list
        }
        if($this->pcount==0){    //check to see if any plug-ins have been loaded into the engine
            $this->load();    //if no plug-ins are loaded, call the load() function to load the plug-ins
        }
    }
   
    function load(){    //this function loads the plug-ins from the plug-ins list
        if(is_array($this->plugin_list)){    //make sure that the plug-ins list as an array, to prevent errors
            for($i=0;$i<$this->lcount;$i++){    //start a loop to identify each plug-in in the plug-ins list
                if(file_exists(“{$this->plugin_list['plug_dir'][$i]}/{$this->plugin_list['plug_file'][$i]}/main.plug.php”)){    //make sure the plug-in’s file exists, to prevent errors
                    @include(“{$this->plugin_list['plug_dir'][$i]}/{$this->plugin_list['plug_file'][$i]}/main.plug.php”);    //include the plug-in into the engine
                    $this->pcount++;    //update pcount for each plug-in that loads
                }else{
                    $this->plugin_error[]=”The plug-in file: <b>/{$this->plugin_list['plug_dir'][$i]}/{$this->plugin_list['plug_file'][$i]}/main.plug.php</b> Does not exist”;    //if the plug-in cant load add an error to the error list
                }
            }
        }   
    }
}
?>

Save this as “your_site_dir/inc/plugins.inc.php”. Now that we have the plug-ins class set all up, let’s get the modules class ready to go.

{mospagebreak title=Module Madness}

The modules are loaded in almost the exact same way as the plug-ins. The only difference is that we need to check to see if the plug-in that the module depends on is loaded. There’s not much more to it than that. So let’s take a look at the module class.

<?PHP
class modules{
   
    public $lcount;        //this will hold the number of modules that we actually load into the module list
    public $mcount;        //this will hold the number of modules that we actually load into the engine
    public $module_list;    //this will hold our array of module information
    public $module_error;    //this will hold any errors that are produced by loading a module
    public $module_load;    //this will hold the names of all the modules we’ve loaded
   
    function modules($site_id=””){    //we name the main function the same as the class so that it initializes when the class is called
        global $sql, $site, $plugins;    //this requests the $sql, $site, and $plugins classes as a global variables
        $this->lcount=0;    //set the default of $mcount to 0 because we don’t yet have any modules in the modules list yet
        $this->mcount=0;    //set the default of $mcount to 0 because we don’t yet have any modules loaded
        if($site_id==””){    //check to see if the administrator overrides the $site_id to list modules for other sites
            $site_id = $site->site['ID'];    //if the site_id isn’t overridden set it to the current site’s id
        }
        $modules_list=$sql->_query(“SELECT
                                    DISTINCT
                                         modules.mod_ID,
                                         modules.mod_name,
                                         modules.mod_dir,
                                         modules.mod_file,
                                         modules.plugin_ID
                                    FROM
                                         module_status,
                                         plugin_status,
                                         modules
                                    WHERE
                                         modules.mod_ID = module_status.mod_ID AND
                                         modules.plugin_ID = plugin_status.plugin_ID AND
                                         module_status.mod_status = ‘initialized’ AND
                                         plugin_status.plugin_status = ‘initialized’ AND
                                         module_status.site_ID = ‘$site_id'”);    //select all the initialized module information from the database
        while($module=$sql->_fetch_object($modules_list)){    //start a loop to get the information from the select query using the _fetch_object function
                $this->module_list['mod_ID'][]=$module->mod_ID;    //add the current modules ID to the plugin list
                $this->module_list['mod_name'][]=$module->mod_name;    //add the current modules name to the plugin list
                $this->module_list['mod_dir'][]=$module->mod_dir;    //add the current modules directory to the plugin list
                $this->module_list['mod_file'][]=$module->mod_file;    //add the current modules filename to the plugin list
                $plug_key=array_keys($plugins->plugin_list['plug_ID'],$module->plugin_ID);    //select the plug-in ID from the plug-in list using the array_keys() function with the modules “plugin_id” as a search parameter
                $this->module_list['plug_dir'][]=$plugins->plugin_list['plug_dir'][$plug_key[0]];    //add the current modules dependency’s directory to the plugin list
                $this->module_list['plug_file'][]=$plugins->plugin_list['plug_file'][$plug_key[0]];    //add the current modules dependency’s file to the plugin list
                $this->lcount++;    // update mcount for each module we add to the module list
        }
        if($this->mcount==0){    //check to see if any modules have been loaded into the engine
            $this->load();    //if no modules are loaded, call the load() function to load the modules
        }
    }
   
    function load(){    //this function loads the modules from the modules list
        if(is_array($this->module_list)){    //make sure that the modules list as an array, to prevent errors
            for($i=0;$i<$this->mcount;$i++){    //start a loop to identify each module in the plug-ins list
                if(file_exists(“/{$this->module_list['plug_dir'][$i]}/{$this->module_list['plug_file'][$i]}/{$this->module_list['mod_dir'][$i]}/{$this->module_list['mod_file'][$i]}.mod.php”)){    //make sure the modules file exists, to prevent errors
                    include(“/{$this->module_list['plug_dir'][$i]}/{$this->module_list['plug_file'][$i]}/{$this->module_list['mod_dir'][$i]}/{$this->module_list['mod_file'][$i]}.mod.php”);    //include the module into the engine
                    $this->module_load[]=$this->module_list['mod_name'][$i];    //add the modules name to list of loaded modules
                    $this->mcount++;    //update mcount for each module that’s loaded
                }else{
                    $this->module_error[]=”The module file: <b>/{$this->module_list['plug_dir'][$i]}/{$this->module_list['plug_file'][$i]}/{$this->module_list['mod_dir'][$i]}/{$this->module_list['mod_file'][$i]}.mod.php</b> Does not exist”;    //if the module can’t load add an error to the error list
                }
            }
        }   
    }
   
}
?>

As you can see, it’s not much different from the plug-ins class. In fact it’s frighteningly the same. Nevertheless it all works great and very fast. Save this as “your_site_dir/inc/modules.inc.php”. There is one thing I’d like to point out though; the line that looks like this:

$plug_key=array_keys($plugins->plugin_list['plug_ID'],$module->plugin_ID);

array_keys() is a great function. It’s very useful. It allows you to return an array of the keys from another array. But, that’s not the best part of array_keys(). The best part is that you can specify a search parameter to match. That’s what I’ve done here. I’ve taken the value of $module->plugin_id and used it as the search parameters to search the plug-ins list array and then return the key to the specific plug-in that the particular module depends on. Now that we’ve gotten the plug-ins and module systems set up, all we have left is to put it all together.

{mospagebreak title=Bring it Together}

We have everything here ready to go. Now we just need to put it all together so that it will run. I made a file that basically includes all the files we’ve just put together. That way we only have to include one file on our index page so it doesn’t become all cluttered up. Save this as “your_site_dir/inc/core.inc.php”.

<?PHP

@include(‘inc/config.inc.php’);
$config = new config();

@include(‘inc/sql.inc.php’);
$sql = new sql($config->dbhost,$config->dbuser,$config->dbpass);
$sql->_select_db($config->dbname);

@include(‘inc/site.inc.php’);
$site = new site();

@include(‘inc/plugins.inc.php’);
$plugins = new plugins(“1″);

@include(‘inc/modules.inc.php’);
$modules = new modules(“1″);

?>

Pretty simple and self explanatory. All we did was include all the files in the /inc directory, then we initialized the classes that are defined within them.

Now all we have left is the index page — another simple bit of work. All we really have in the index page is a quite common parse time function and an include. Save this file as “your_site_dir/index.php”.

<?PHP
function getmicrotime()
{    $temparray=split(” “,microtime());
    $returntime=$temparray[0]+$temparray[1];
    return $returntime;
}
$stime=getmicrotime();

@include(‘inc/core.inc.php’);

$etime=getmicrotime();
$ftime=round($etime-$stime,6);
?>

Final thoughts

That’s all we have to do for the plug-in and module systems. In the next article in the series, we’ll go through the authentication system and the block system. I’ll also show you how the database and directories should be set up so you can set up your first plug-in and module and give it all a try. Following that will be an article illustrating how to build the template and loading system of the site engine. Then finally, there will be an article on making an administration page and how to quickly build a site with the site engine.

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