NaszvadiG
4/17/2014 - 9:03 AM

MY_Controller.php

<?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 */