Sunday, April 29, 2012

Create your own CMS-Part 12

So far we have coded all the necessary class files.
Here we will create our first module 'home'.Before creating our first module,let us add two more functions in 'functions.php' in 'main' folder.
/***************************
Builds menu (left)
$menu argument must be an array
****************************/
function build_menu($menu)
{
foreach ($menu as $name=>$link)
{
 show_menu($name,BASE.$link);
}
}
build_menu function is used to build a menu for navigation.It accepts an array $menu as parameter with key indicating the name of the menu and value indicating the link.
Now add another function to show the menu.
/***************************
Shows the menu
****************************/
function show_menu($name,$link)
{
echo '<a href="'.$link.'" class="left_menu">'.$name.'</a>';
}
Creating the homepage
The homepage of our site will contain a register form and login form.
Homepage is theme based .
Open the 'default' themes folder and create 'homepage.php'.
Edit this file with your contents.
Homepage should be simple and attractive.
Download the theme with new homepage from the link below as an example.

Download default theme

Creating the first module

Home module doesn't require the necessary files to be valid.
It is valid by default.The home module, we are going to create will have only two files.
  • view.php              -      content in app_block area.
  • left_menu.php      -      menu for navigation.
Open modules folder.
Create a folder and name it as 'home'.
Create two files as mentioned above.

view.php

You can write whatever here to meet your requirements.

You might love this quote!!!

<div class="content_wrapper">
<h3>
"We've demonstrated a strong track record of being very disciplined with the use of our cash. We don't let it burn a hole in our pocket, we don't allow it to motivate us to do stupid acquisitions. And so I think that we'd like to continue to keep our powder dry, because we do feel that there are one or more strategic opportunities in the future." 
--
</h3>
</div>
<h2>
<a href="http://www.blogger.com/blogger.g?blogID=5175690629178451362">Steve Jobs </a></h2>

left_menu.php

<div id="left_menu">
$menu = array('Photos'=>'/#','Videos'=>'/#');
build_menu($menu);
if(is_admin())
{
echo '<a class="left_menu" href="http://www.blogger.com/'.BASE.'/admin/">Admin</a>';
}

?>
Navigation is created using the two functions we created in the begining of this post.



Thursday, April 26, 2012

Create your own CMS-Part 11

Sorry for the delay!
We are getting into advanced features from this post onwards.
In this post we will learn to create a custom module class.So lets begin...
  • Before we begin to create the class file , let us see the structure of a module directory.The structure given below is created by taking 'blog' module as reference.


The following files are necessary for a module to be valid.
  • 'start.php'
  • 'manifest.xml'
  • 'install.php'
The module class will contain various methods to control a module.The page to be executed (called as base file) depends on the query string in the url.The structure of our url is
http://localhost/stupid/index.php?module=val1&sub=val2&action=val3
val1 =====> any valid module  eg: blog,photos etc
val2 =====> name of sub module  eg: editblog ,viewblog,deleteblog etc
val3 =====> action filename for actions like save,edit etc

Let us create our modules class
  • Open stupid >> include directory.
  • Create a file named 'module_class.php'.
  • Open the file in an editor and write the following code.
<?php
/*
THE STRUCTURE OF OUR MODULE IS AS FOLLOWS.
FOR BETTER UNDERSTANDING BLOG MODULE IS USED AS
A REFERENCE.
NOTE: FILES WITH PREFIX * ARE ESSENTIALLY REQUIRED.

modules/
blog/
extras/
editblog.php
createblog.php
viewblog.php
actions/
save.php
create.php
delete.php
*install.php
*start.php
view.php
menu_left.php
*manifest.xml
image.png

*/

/*
The module class will contain various methods for 
controlling a module.
The structure of our url will be

"http://localhost/stupid/module=val1&sub=val2&action=val3"

val1 =====> any valid module  eg: blog,photos etc
val2 =====> name of sub module  eg: editblog ,viewblog,deleteblog etc
val3 =====> action filename for actions like save,edit etc

*/
?>

<?php
class Modules
{
    
    /**
    $module     : An array with keys name,sub and action.The values is obtained from url through $_GET method.
    $module_dir   : The path of current module  eg: modules/blogs , modules/photos.
    $module_data  : An array used to store the details of the module (obtained from database) .
    $base_file   : The file to fetch and execute .
    $logged_out_menu : The menu for a anonymous user.This will be present in the theme.
    **/
    
    var $module = array();
    var $module_dir;
    var $module_data = array();
    var $module_menu;
    var $base_file;
    var $logged_out_menu;
    
    /**
    Constructor for the modules class.
    The value of base file changes with the values in the query string.
    Have a look at the if else statement for better understanding. 
    **/
    
    function __construct()
    {
        global $theme;
        if (isset($_GET['module'])) {
            $this->module['name'] = $_GET['module'];
        } else {
            $this->module['name'] = 'home';
        }
        $this->module_dir = MODULESPATH . '/' . $this->module['name'];
        if (isset($_GET['sub'])) {
            $this->module['sub'] = $_GET['sub'];
            if (isset($_GET['action'])) {
                $this->module['action'] = $_GET['action'];
                $this->base_file        = $this->module_dir . '/extras/actions/' . $this->module['action'] . '.php';
            } else {
                $this->base_file = $this->module_dir . '/extras/' . $this->module['sub'] . '.php';
            }
        } else {
            $this->module['sub'] = NULL;
            $this->base_file     = $this->module_dir . '/view.php';
        }
        $this->module_data     = $this->get_module_data();
        $this->logged_out_menu = $theme->active_theme . '/menu.php';
    }
    
    /********************************************
    This method is used to get the data of the 
    current module.
    ********************************************/
    
    function get_module_data()
    {
        global $db;
        $res = $db->query("SELECT * FROM `modules` WHERE `name` = '" . $this->module['name'] . "' LIMIT 1");
        return $db->fetch_array($res);
    }
    
    /********************************************
    Returns true if the module is enabled
    $name : The name of the module.
    *********************************************/
    
    function is_active($name)
    {
        global $db;
        $res  = $db->query("SELECT * FROM `modules` WHERE `name` = '" . $name . "' LIMIT 1");
        $data = $db->fetch_array($res);
        if ($data['active'] == 1)
            return true;
        else
            return false;
    }
    
    /******************************************
    Checks whether the module is installed or not
    $name : The name of the module.
    ********************************************/
    
    function is_module_installed($name)
    {
        global $db;
        $res = $db->query("SELECT * FROM `modules` WHERE `name` = '" . $name . "'");
        if ($db->fetch_num($res) == 1)
            return true;
        else
            return false;
    }
    
    /******************************************
    Returs an array of all enabled modules
    ******************************************/
    
    function get_all_enabled_modules()
    {
        global $db;
        $res = $db->query("SELECT * FROM `modules` WHERE `active` = 1");
        while ($all = $db->fetch_array($res)) {
            $enabled_modules[] = $all['name'];
        }
        return $enabled_modules;
    }
    
    /*****************************************
    This is the starter for all enabled modules.
    start.php file from every enabled modules is
    included by this method.
    ******************************************/
    
    function start_all_enabled_modules()
    {
        global $db;
        $enabled_modules = $this->get_all_enabled_modules();
        foreach ($enabled_modules as $e) {
            if ($e != 'admin' && $e != 'home')
                include_once MODULESPATH . '/' . $e . '/start.php';
        }
    }
    
    /*
    This method will be called in engine.php.
    Used to view the module content by building 
    menu.
    */
    
    function view_module()
    {
        if ($this->is_module_installed($this->module['name']) && $this->is_active($this->module['name'])) {
            $this->build_menu();
            $this->view_app();
        } else {
            redirect_to(BASE);
        }
    }
    
    /**
    Builds the necessary menu for the module.
    Includes the menu_left.php
    */
    
    function build_menu()
    {
        if (file_exists($leftmenufile = $this->module_dir . '/menu_left.php')) {
            $this->module_menu = $leftmenufile;
        } else {
            $this->module_menu = MODULESPATH . '/home/menu_left.php';
        }
        
    }
    
    /*
    Views the app in the app block.
    */
    
    function view_app()
    {
        if (is_logged_in()) {
            echo '<div id="canvas">';
            echo '<div id="left">';
            include_once $this->module_menu;
            echo '</div>';
            echo '<div id="app_block">';
            include_once $this->base_file;
            echo '</div>';
            echo '<div class="clear"></div>';
            echo '</div>';
            
        } else {
            if ($this->module['name'] == 'home') {
                global $theme;
                include_once $theme->active_theme . '/homepage.php';
            } else {
                echo '<div id="canvas">';
                echo '<div id="app_block">';
                include_once $this->base_file;
                echo '</div>';
                echo '<div id="left">';
                include_once $this->logged_out_menu;
                echo '</div>';
                echo '<div class="clear"></div>';
                echo '</div>';
            }
        }
    }
    
    /********************************************
    Returns an array of all modules ( enabled and disabled ).
    Obtained by reading the modules directory.
    *********************************************/
    
    function get_modules_list()
    {
        $plugins = array();
        if ($handle = opendir(MODULESPATH)) {
            while ($mod = readdir($handle)) {
                // must be directory and not begin with a .
                if (substr($mod, 0, 1) !== '.' && is_dir(MODULESPATH . "/" . $mod)) {
                    $plugins[] = $mod;
                }
            }
        }
        sort($plugins);
        return $plugins;
    }
    
    // to activate a module
    
    function activate($name)
    {
        global $db;
        $sql = "UPDATE modules SET active='1' WHERE name = '" . $name . "'";
        $db->query($sql);
    }
    
    // to deactivate a module
    
    function deactivate($name)
    {
        global $db;
        $sql = "UPDATE modules SET active='0' WHERE name = '" . $name . "'";
        $db->query($sql);
    }
    
    /*
    To install a module.
    Before installing the installing module is checked for validity.
    */
    
    function install_module($name)
    {
        $valid = $this->check_module($name);
        if ($valid) {
            include_once MODULESPATH . '/' . $name . '/install.php';
        } else {
            show_msg('Invalid', 'This module is not valid');
        }
    }
    
    // To uninstall a module
    
    function uninstall_module($name)
    {
        global $db;
        $sql = 'DROP TABLE IF EXISTS ' . $name . '';
        $db->query($sql);
        $sql = "DELETE FROM modules WHERE name = '" . $name . "'";
        $db->query($sql);
        $sql = "DELETE FROM module_settings WHERE module_name = '" . $name . "'";
        $db->query($sql);
    }
    
    /*
    This method inserts the module into modules table in the database.
    */
    
    function register_module($name)
    {
        global $db;
        $sql = "INSERT INTO modules(name) VALUES('" . $name . "')";
        $db->query($sql);
    }
    
    /**
    Returns true if module is valid.
    A module is valid if it contains the 
    required files.
    **/
    
    function check_module($name, $valid = false)
    {
        if (file_exists(MODULESPATH . '/' . $name . '/install.php') && file_exists(MODULESPATH . '/' . $name . '/view.php') && file_exists(MODULESPATH . '/' . $name . '/manifest.xml'))
            $valid = true;
        return $valid;
    }
    
    // to enable a module
    
    function enable_module($name)
    {
        $this->activate($name);
    }
    
    // to disable module
    
    function disable_module($name)
    {
        $this->deactivate($name);
    }
    
}
?>  
All the methods are named in such way that you can specify the function it does easily.
Also the functions can be easily understood from the comments in the file.So I am skiiping the explanation of each methods specifically.You can just comment below if you need an explanation of any methods.
So we have created our class file successfully.Now its time to create an object of the class.As usual class instantiation is done in 'engine.php' in 'main' folder.The modified 'engine.php' looks like below

<?php
include_once('functions.php');
include_once('config/base.php');
include_once(CLASSPATH . '/database_class.php');
include_once(CLASSPATH . '/session_class.php');
include_once(CLASSPATH . '/user_class.php');
include_once(CLASSPATH . '/theme_class.php');
include_once(CLASSPATH . '/module_class.php');
global $db, $ss, $user, $theme, $module;

$db     = new Database();
$ss     = new Session();
$user   = new User();
$theme  = new Theme();
$module = new Modules();

/**********************************/

/*******************************/
$theme->load_css();
$theme->load_index();

/******************************
to view the module
*******************************/

$module->view_module();
$theme->load_footer();

/*******************************
 *******************************/
include_once('/actions/actions.php');
?>

In the next post , we will be creating our first module 'home'.