<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Application Base Controller
*
* @package CodeIgniter
* @author Sepehr Lajevardi <me@sepehr.ws>
* @copyright Copyright (c) 2012 Sepehr Lajevardi.
* @license http://codeigniter.com/user_guide/license.html
* @link https://github.com/sepehr/ci-base-controllers
* @version Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
/**
* Application Base Controller
*
* The common shared code for all application controllers should be placed here.
* NOTE: If you're using Modular Extensions and you want the HMVC feature in place,
* you need to alter this to extend MX_Controller instead of CI_Controller.
*
* @package CodeIgniter
* @category Controllers
* @author Sepehr Lajevardi <me@sepehr.ws>
* @link https://github.com/sepehr/ci-base-controllers
* @see http://highermedia.com/articles/nuts_bolts/codeigniter_base_classes_revisited
*/
abstract class Base_Controller extends MX_Controller {
/**
* Stores current user data.
*
* @var object
*/
protected $user;
/**
* Stores the previously viewed page's complete URL.
*
* @var string
*/
protected $previous_page;
/**
* Stores the page requested.
*
* @var string
*/
protected $requested_page;
//--------------------------------------------------------------------
/**
* Application base controller constructor.
*/
public function __construct()
{
Events::trigger('before_controller_constructor', get_class($this));
parent::__construct();
Events::trigger('before_base_controller_constructor', get_class($this));
// Load authentication library (model included)
// It tries to log the remembered user in
$this->load->library('auth/ion_auth', '', 'auth');
// Load form validation libray and workaround its HMVC issues
$this->load->library('form_validation');
$this->form_validation->CI =& $this;
// Load up current user data if she's logged in.
$this->user_load();
// Store user previous and requested page URIs in her session
if ( ! preg_match('/\.(gif|jpg|jpeg|png|css|js|ico|shtml)$/i', $this->uri->uri_string()))
{
$this->previous_page = $this->session->userdata('previous_page');
$this->requested_page = $this->session->userdata('requested_page');
}
// Check environment, and do the housekeepings
if (ENVIRONMENT == 'production')
{
// $this->db->save_queries = FALSE;
$this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
}
else if (ENVIRONMENT == 'development')
{
// Runtime php settings
ini_set('html_errors', 1);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
// Error reporting level is already set by CI;
// Profiler
// @TODO: Make it available to certain anon users with cookie set in production
if ( ! $this->input->is_cli_request() AND ! $this->input->is_ajax_request())
{
$this->load->library('console');
$this->output->enable_profiler(TRUE);
}
$this->load->driver('cache', array('adapter' => 'dummy'));
}
// Trigger events
Events::trigger('after_base_controller_constructor', get_class($this));
log_message('debug', 'Base Controller Class Initialized.');
}
// ------------------------------------------------------------------------
// User/Authentication Helpers
// ------------------------------------------------------------------------
/**
* Loads current user data.
*
* All derived classes should use/extend this API function to load current
* user's data to maintain the behavior across all the child controllers.
*
* NOTE: Ideally this should be moved to the authentication handler class.
*/
protected function user_load($user_id = FALSE)
{
// Load arbitary user
if ($user_id)
{
return $this->auth->where('_id', new MongoId($user_id))->user()->document();
}
// This requires IonAuth module already in place.
if ($this->auth->logged_in() AND $this->user = $this->auth->user()->document())
{
// Set groups
$this->user->groups = $this->auth->get_users_groups($this->user->id)->result();
// Clone identity
$this->user->identity = $this->user->{$this->config->item('identity', 'ion_auth')};
// And gravatar
$this->user->picture = gravatar_link($this->user->email, 22, $this->user->email, "{$this->user->email} Profile", ' ', ' ');
}
// And make the user data available in the views,
$this->load->vars(array('current_user' => $this->user));
return $this->user;
}
// ------------------------------------------------------------------------
/**
* Auth helper: restricts access to anons.
*
* NOTE: Ideally this should be moved to the authentication handler class.
*/
protected function restrict($group, $message = FALSE)
{
$message OR $message = 'You are not authorized to view this page. Please login and try again.';
if ( ! $this->auth->logged_in() OR ! $this->auth->in_group($group))
{
Template::set_message($message, 'warning');
Template::redirect($group . '/login');
}
}
// ------------------------------------------------------------------------
/**
* Auth helper: restricts access to loggedin users.
*
* NOTE: Ideally this should be moved to the authentication handler class.
*
* @todo Merge with restrict() method.
*/
protected function prevent($group, $message = FALSE)
{
$message OR $message = 'You are already logged in. Enjoy!';
if ($this->auth->logged_in() AND $this->auth->in_group($group))
{
Template::no_message() AND Template::set_message($message);
Template::redirect($group . '/account');
}
}
// ------------------------------------------------------------------------
// Custom Validation Callbacks
// ------------------------------------------------------------------------
//
// All custom validation callbacks are defined in our custom extension of
// CI_Form_validation at application/libraries/MY_Form_validation.php except
// for these two.
//
// Both "CV" and "Sectors" fields are partial views (form widgets) not
// actual fields and their value are not populated in the $_POST array
// upon form submission but sessions, etc.
//
// Take a look at codeigniter/libraries/Form_validation.php:488, it says
// if the field is not requried (our case, since we need custom checks and
// error messages) and there's no value set in $_POST, check for callback
// rules or skip. That's why we need to define these two rules as callbacks
// not MY_Form_validation rule methods.
//
// Defining these callbacks here in Base_Controller will provide these rules
// to all other derived controllers. e.g. Front_Controller, REST_Controller
// ------------------------------------------------------------------------
/**
* Custom validation callback to validate CV file upload.
*
* CV files are uploaded via our ajax upload widget and its
* info are saved in the user session. This validation callback
* checks user session for valid CV file.
*
* If uploading via API, the passed $file will contains an array
* of already uploaded file, we first check for that.
*
* The callback only checks file existence, more parameters like
* filesize or type will be checked by system/file_upload library.
*/
public function _check_cv($file = FALSE)
{
// Set callback's custom error message
$this->form_validation->set_message('_check_cv', 'Please upload a valid CV file.');
// Check regular upload (via API)
if (isset($file['tmp_name']) AND file_exists($file['tmp_name']))
{
return TRUE;
}
// Load system file upload config
$this->load->config('system/file_upload');
// Get file upload config directives
$key = $this->config->item('upload_session_filepath_key');
// Check if filepath exists in both session and filesystem
if ($filepath = $this->session->userdata($key) AND file_exists($filepath))
{
return TRUE;
}
return FALSE;
}
// ------------------------------------------------------------------------
/**
* Custom validation callback to validate jobseeker sectors.
*
* @TODO: Check speciality and role number limits.
*/
public function _check_sectors($sector_ids = FALSE)
{
static $checked;
// Set callback's custom error message
$this->form_validation->set_message('_check_sectors', 'Please provide your specialities.');
// Skip same validations in current request
if (! isset($checked))
{
// Get sector IDs from $_POST if not set
$sector_ids OR $sector_ids = $this->input->post('sectors');
// Remove duplicates from sector IDs
// Duplicates may happen on prepopulated speciality fields
is_array($sector_ids) AND $sector_ids = array_unique($sector_ids);
if ( ! is_array($sector_ids) OR empty($sector_ids))
{
$checked = FALSE;
}
else
{
// Load sector model, if not available
class_exists('Sector_model') OR $this->load->model('system/sector_model');
// Validate sector IDs
$sectors = $this->sector_model->get_many($sector_ids);
// Make sure that each single selected sector ID
// is available in our database, also update $_POST data
$checked = $_POST['sectors'] =
count($sector_ids) == count($sectors) ? $sector_ids : FALSE;
}
}
return $checked;
}
// ------------------------------------------------------------------------
}
// End of Base_Controller class
/* End of file MY_Controller.php */
/* Location: ./application/core/MY_Controller.php */