I'm this is my first CI Project and I am trying to build a login system (3 user groups = admin, member, public). I'm using Ion Auth.
If you want to skip the details..
..my problem is that I am somehow not doing my "require_once" correctly in my home controller, or I am not understanding something about extending classes. Or I am just not as clever as my mom tells me I am. I get this error:
Fatal error: require_once() [function.require]: Failed opening required 'application/Application/Core/public_controller.php' (include_path='.:/Applications/MAMP/bin/php/php5.3.6/lib/php') in /Applications/MAMP/htdocs/NOIR_FINAL/application/controllers/public/home.php on line 4
I referenced this article, as it looks like good practice. Specifically, I extended CI_Controller with MY_Controller (containing an Admin, Member, and Public controllers that all extended CI_Controller).
http://jondavidjohn.com/blog/2011/01/scalable-login-system-for-codeigniter-ion_auth
Then I saw some criticism of "packing" all these 3 admin, member, and public controllers into one "MY_Controller" .. so as per Phil Sturgeon I have tried to separate them into individual classes and use __autoload() to pull them in.
http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
But somehow I get the feeling that I am now just making things unnecessarily complicated.
I want to go through the login, and then depending on the user group send them to one of 3 "home" controllers in dedicated folders. Those home controllers extend Admin_controller, Member_controller, or Public_controller ... and each one of those extends MY_Controller, which in turn extends CI_Controller. So I would have group specific methods in their respective controllers, and some general stuff in MY_Controller ( checking to see if site is live/"open" .. checking user agent .. etc). This, to me, seems to be a pretty nice way of separating user roles.
I also have this in my config, as per Sturgeon's article ..
function __autoload($class)
{
if(strpos($class, 'CI_') !== 0)
{
@include_once( APPPATH . 'core/'. $class . EXT );
}
}
So am I going about this right way at all? Since its my first try at this and I am starting to think this is becoming a bit too "Frankenstein". Here is 'auth/login'...
function login() {
if($_POST) { //clean public facing app input
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() == true)
{
$identity = $this->input->post('email', true);
$password = $this->input->post('password', true);
$remember = $this->input->post('remember');
if($this->ion_auth->login($identity,$password, $remember))
{
if($this->ion_auth->in_group('1'))
{
$this->session->set_flashdata('message','Welcome');
redirect('admin/home','refresh'); // this might have to change @todo
}
elseif($this->ion_auth->in_group('2'))
{
$this->session->set_flashdata('message','Welcome');
redirect('member/home','refresh');
}
else
{
redirect('public/home','refresh');
}
}
}
else
{
// set error flashdata
$this->session->set_flashdata('message','Your login attempt failed.');
redirect('/');
}
}
redirect('/');
}
.. and here is home.php in "controllers/member/" .. basically just setting up the view and translating the flashdata message (if any) into $data{'message']
class Home extends Member_Controller{
require_once(APPPATH.'Application/Core/member_controller.php');
public function __construct()
{
parent::__construct;
}
public function index()
{
// remember that $this->the_user is available in this controller
// as is $the_user available in any view I load
$this->load->model('Member_model');
$this->data['message'] = $this->session->flashdata('message');
$this->data['query'] = $this->Member_model->get_members();
$this->data['title'] = 'Home';
$this->load->view('member_view', $this->data);
}
}
Here is my member controller with some member methods
class Member_Controller extends MY_Controller{
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->load->view('member_view');
}
public function edit_profile(){}
public function delete_profile(){}
}
.. and MY_Controller with some common methods
class MY_Controller extends CI_Controller {
protected $the_user;
public function __construct()
{
parent::__construct();
if( $this->config->item('site_open' ) === FALSE)
{
show_error("Sorry the site is shut right now.");
}
if( $this->ion_auth->logged_in() )
{
$this->the_user = $this->ion_auth->user()->row();
$data->the_user = $this->the_user;
$this->load->vars($data);
}
else
{
redirect('/','refresh');
}
//if the user is using a mobile, use a mobile theme
$this->load->library('user_agent');
if( $this->agent->is_mobile() )
{
$this->template->set_theme('mobile'); // what about admin @todo
}
}
public function index()
{
redirect('/','refresh');
}
}
So am I approaching this correctly? As a bonus question, is it correct to put index methods on classes that are only ever going to be extended? For ex, nobody is going to "land" on MY_Controller. It will always be extended. So do I need to put an index method? Is it just good form? Should I make this an abstract class?