-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Dynamic Hooking
Intro I was writing a Session class and looking thought CI's default Session class and noticed it would set a new cookie every time you set/unset and userdata or flashdata and i started to think about the hooking feature and thought why not make it dynamic so any class can insert a hook on the fly. With this ability the session class could add a hook 'post_controller' so it would be able to send only one cookie. The best part is you don't have to enable hooking for this to work. Just drop the file in to your application's library directory. It works as an extension of CI's hooks class.
The bad news You can only hook the hooks that haven't happened yet.
Hooks that can be hooked.. 1: scaffolding_override, post_controller_constructor, post_controller, display_override, and post_system 2: pre_controller 3: hook cache_override
Most of the places you can hook list 1. If hooking from an extended CI class you can hook others. If you extended Input, or Language you can hook lists 1 and 2. If you extended Config, URI, Router, or Output you can hook lists 1, 2, and 3.
Example
$hook['classref'] = &$this;
$hook['method'] = 'sess_write';
$hook['params'] = '';
if($GLOBALS['EXT']->add_hook('post_controller', $hook) == false)
log_message('error', "Presence class could not set a dynamic hook");
Files MY_Hooks.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* MY_Hooks Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Miscallenous
* @author dazoe
* @link http://codeigniter.com/wiki/Dynamic_Hooking
*/
class MY_Hooks extends CI_Hooks {
var $myhooks = array();
var $my_in_progress = false;
function MY_Hooks() {
parent::CI_Hooks();
}
/**
* --Add Hook--
* Adds a particular hook
* @access public
* @param string the hook name
* @param array(classref, method, params)
* @return mixed
*/
function add_hook($hookwhere, $hook) {
if (is_array($hook)) {
if (isset($hook['classref']) AND isset($hook['method']) AND isset($hook['params'])) {
if (is_object($hook['classref']) AND method_exists($hook['classref'], $hook['method'])) {
$this->myhooks[$hookwhere][] = $hook;
return true;
}
}
}
return false;
}
function _call_hook($which = '') {
if (!isset($this->myhooks[$which])) {
return parent::_call_hook($which);
}
if (isset($this->myhooks[$which][0]) AND is_array($this->myhooks[$which][0])) {
foreach ($this->myhooks[$which] as $val) {
$this->_my_run_hook($val);
}
} else {
$this->_my_run_hook($this->myhooks[$which]);
}
return parent::_call_hook($which);
}
function _my_run_hook($data)
{
if ( ! is_array($data)) {
return FALSE;
}
// -----------------------------------
// Safety - Prevents run-away loops
// -----------------------------------
// If the script being called happens to have the same
// hook call within it a loop can happen
if ($this->my_in_progress == TRUE) {
return;
}
// -----------------------------------
// Set class/method name
// -----------------------------------
$class = NULL;
$method = NULL;
$params = '';
if (isset($data['classref'])) {
$class =& $data['classref'];
}
if (isset($data['method'])) {
$method = $data['method'];
}
if (isset($data['params'])) {
$params = $data['params'];
}
if (!is_object($class) OR !method_exists($class, $method)) {
return FALSE;
}
// -----------------------------------
// Set the in_progress flag
// -----------------------------------
$this->my_in_progress = TRUE;
// -----------------------------------
// Call the requested class and/or function
// -----------------------------------
$class->$method($params);
$this->my_in_progress = FALSE;
return TRUE;
}
}
If there are any bugs and question feel free to pm/email me. Author: dazoe