Search code examples
codeignitercodeigniter-hmvc

codeigniter HMVC: Check user permissions for individual functions in controller


I am working with HMVC module extension for codeigniter. Read this wonderful article - Scalable Login System for CodeIgniter – Ion_Auth. What this article suggests is that we can create multiple custom controllers and based on the logged in user's role, redirect the user to his respective controllers. For example, for Admin redirect him to a controller that extends Admin_Controller and so on:

class Admin_Controller extends CI_Controller {

    public function __construct() {

        parent::__construct();

        if( ! $this->ion_auth->is_admin()) {
            redirect('/');
        }
    }
}

So, we can apply common rules at the Base controller level itself for all the methods/views within that controller. That is where I have a query: What if i don't want to have global control for all the views within that controller.

Or put in other words - if I need to have specific control for individual views, how to go about it. For example - I have a controller named 'Blog' and methods named - 'view', 'add', 'edit'. Now, view is applicable to all kinds of users, while only Admin should be able to add or edit a blog. Which means I cannot put controller level logic..

class Blog_Controller extends Admin_Controller {
    // should be accessible to both Admin and non-logged in user
    public function view() {..} 

    // Following are only accessible to Admin
    public function edit() {..}
    public function create() {...}
}

One way i can think of is to duplicate code in multiple controllers and handle views specific to the user role.


Solution

  • You could make your Admin_Blog_Controller extend Blog_Controller, load the user data in the User constructor and in the Admin constructor you check for admin access.

    That way your admin controller will also contain the method view from the Blog_Controller.

    class Admin_Blog_Controller extends Blog_Controller {
    
        public function __construct() {
    
            parent::__construct();
    
            if( ! $this->ion_auth->is_admin()) {
                redirect('/');
            }
        }
    
        public function add() {
        }
    
        public function edit() {
        }
    
        // Optional, if you want to make custom behaviour
        // in the view method of admin:
        public function view() {
            // Calling parent (Blog_Controller) view method.
            parent::view();
            // Doing our own stuff.
            // ...
        }
    }
    
    
    class Blog_Controller extends CI_Controller {
    
        protected $the_user;
    
        public function __construct() {
    
            parent::__construct();
    
            if($this->ion_auth->in_group('user') || $this->ion_auth->is_admin()) {
                $this->the_user = $this->ion_auth->user()->row();
                $data->the_user = $this->the_user;
                $this->load->vars($data);
            }
            else {
                redirect('/');
            }
        }
    
        public function view() {
        }
    }
    

    Reading your post again, I realize this was maybe not the exact solution you where asking for, since you want it all in one Controller? I'll not delete my answer regard someone may find it useful still.