Developing Content Managment System with CodeIgniter – Part 3

This post was originally published in 2010
The tips and techniques explained may be outdated.

Hi.
Well, As my development process continues I would like to write you about the features and structure of my application now.

I’ve talked about the basics in my previous posts, I covered the structure of my application [modules], I showed you how I extend CI_Controller and CI_Model. Now I want to share with you the which features I have in my application that makes my live easier AND how I extended Controller and Model even more.

Features

    1. I Followed Phil Sturgeon’s How-To article for Support multiple production environments in CodeIgniter. This way I defined what to log and where, in what level, and the url’s of the local server, development server and production server [and Databases too].
    2. I’ve extended CI_Log class so its sending me email if some Error happens in PRODUCTION server [this is the application that the client is using].
    This way I can easily know what went wrong when I get the phone call from my client.
    3. History Class -> I wrote you in my Must have features in your CMS post about System Restore. So I wrote a simple model that has this method in it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    /**
     * This method writes data to history.
     * @param String $table
     * @param Integer $row
     * @param String $field
     * @param String $oldValue
     * @param String $newValue
     */

    public function write($table,$row, $field, $newValue) {
       
        // select only the field I need
        $this->db->select($field);
        // get the right row
        $data = $this->db->get_where($table, array('ID' => $row));
        // take the row and break to array
        $currentState = $data->row_array();
        // store the old value
        $oldValue = $currentState[$field];
       
        if($oldValue != $newValue) {
            $history = array(
                'TableName' => $table,
                'RowIndex' => $row,
                'FieldName' => $field,
                'OldValue' => $oldValue,
                'NewValue' => $newValue,
                'Created' => time()
            );
            $this->db->insert('history', $history);
            return TRUE;
        } else {
            return FALSE;
        }
    }

*I already see a mistake in this method – I have $this->table property in each model, and I don’t use it here – I write the table name directly in the insert method.*
This method activates before each update() method in my Models. The update() method written once in my MY_Model class, so I don’t really writing data to this “system restore” table myself [by calling this method each time] – everything happens in the background.

Extended CI_Controller

Well, I can’t share with you the whole code [I'm not allowed, I'll share certain methods], But I can write you the properties and methods I have and the purpose of them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    // Module name. gallery/cart/content/contact/users...
    protected $module;

    // Basic authentication and permission system, UserLevel gets the
    // minimum level needed to enter this controller
    protected $userLevel;
   
    // The name of the controller
    protected $controllerName;
   
    public function MY_Controller() {
        parent::Controller();
        if(ENV == 'dev' OR ENV == 'local') $this->output->enable_profiler(TRUE);
        else if(ENV == 'live') $this->output->enable_profiler(FALSE);
        $this->controllerName = get_class($this);      
    }

As you can see, If its a development environment I’m enabling the profiler, I use controllerName for better logging [knowing where error happened or any other message level].

I also have 2 methods that are loading views and models:

1
2
3
4
5
6
7
8
9
    /**
     * This method is a shortcut for loading a view in my controllers.
     * @param String $name The name of the view I want to load, inside the module folder.
     * @param Text $content The HTML content I want the view to show.
     * @param Bool $return Return the view content, or just show it?
     */

    protected function _view($name, $content, $return = FALSE) {
        return $this->load->view($this->module.'/'.$name, $content, $return);
    }

The reason I did it is that I got tired writing

1
$this->load->view($this->module.'/viewName', '', TRUE)

And the current method really saves some time.

Extended CI_Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    // The main table name
    public $table;
    private $modelName;
   
    public function MY_Model() {
        parent::Model();
        $this->table = '';
        $this->modelName = get_class($this);
    }
   
    // Log as Error each time none-existing method called.
    public function __call($name, $arguments) {
        $args = implode(',',$arguments);
        log_message('error', $this->modelName.'-> '.$name.'('.$args.') Not exists.');
        return FALSE;
    }

Well, everything is clear here I believe. I think that most of the developers don’t use __call method, but the use I did here is pretty useful.
Each method I have in the models and ofcourse MY_Model using $this->modelName for logging errors – if I didn’t got any $ID for updating some row its highly important for me to know why and where.

Well, I shared with you as much as I could. I don’t know if I’ll write another post in this area, I’ll see how my project goes and if there is something interesting to write about.

I really think I chose the wrong title for this post series :D but that’s ok.

Hope you learned something new, if you have any questions I’ll be happy to answer.

Related Posts

Tags: CMS Development, CodeIgniter, PHP, Web Development

WordPress SEO fine-tune by Meta SEO Pack from Poradnik Webmastera