Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codeigniter - making my controllers more DRY

In my codeigniter controller function I am using the following code to generate my view and insert all the necessary content:

        $left_column = $this->load->view('widgets/sub_navigation', $subnav_data, true);
        $left_column .= $this->load->view('widgets/search_box', '', true); //Set data to be loaded into columns
        $left_column_base = $this->load->view('widgets/assist_navigation', '', true);
        $center_column = 'this is center column';
        $right_column = $this->load->view('widgets/ask_us_a_question', '', true);
        $right_column .= $this->load->view('widgets/newsletter', '', true);
        $right_column .= $this->load->view('widgets/latest_news', '', true);

        $this->template->inject_partial('left_column', $left_column); //Inject data into the partial columns
        $this->template->inject_partial('left_column_base', $left_column_base);
        $this->template->inject_partial('center_column', $center_column);
        $this->template->inject_partial('right_column', $right_column);
        $this->template->build('template',$data); 

I am using a three column layout and the code above dictates what is shown in each of the columns. It works in a very modular way allowing me to customize each page quickly.

Is there a way of simplifying the above code, using arrays maybe, to cut down on repetetive code, making things more DRY??

like image 614
hairynuggets Avatar asked Dec 01 '11 16:12

hairynuggets


1 Answers

You need to create base controllers that extend the CI_Controller. Then all your controllers extend a certain base controller you created, depending on what needs to be done in all cases that controller is called.

In application/core create a file called MY_controller.php (the prefix can be changed in config):

class MY_Controller extends CI_Controller {


    function __construct()
    {

        parent::__construct();


            /* Widgets are only prepared -- they will be fetched and rendered once layout->render is called.
               This saves the overhead of reading the files on requests where layout isn't rendered.
            */                  


        $this->layout->prepare_widget( "widgets/navigation", "navigation_widget" );
        $this->layout->prepare_widget( "widgets/footer", "footer_widget"  );
        $this->layout->prepare_widget( "widgets/twitter", "twitter_widget" );

    }


}


class Public_Controller extends MY_Controller {

    function __construct()
    {
        parent::__construct();
    }

}

class Admin_Controller extends MY_Controller {

    function __construct()
    {
        parent::__construct();

            if( !$this->user->has_permissions( PERMISSION_ADMIN ) )
            {
                redirect( base_url(), "location", 303 );    
                die();
            }
    }

}

class Member_Controller extends MY_Controller {

    function __construct()
    {
        parent::__construct();


            if( !$this->user->has_permissions( PERMISSION_REGISTERED ) )
            {
                redirect( base_url(), "location", 303 );
                die();
            }
    }

}

As you can see, all sub controllers have the widgets automatically because they extend either public, admin or member. A sub controller extending an admin controller has automatically the permissions checked so you don't need to do that ever again. You can apply this concept to your app.

A sub-controller: (placed in the normal application/controllers)

class Articles extends Member_controller {

    ...

}

Will have automatically ensured that the user is logged in, and the widgets are prepared without doing anything because the parent of parent class already prepared them. All you need to do in articles is to call $this->layout->render if the logic needs layout rendering at the end.

like image 130
Esailija Avatar answered Oct 18 '22 04:10

Esailija