<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
/**
* CodeIgniter Hooks Class
*
* Provides a mechanism to extend the base system without hacking.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/encryption.html
*/
//CodeIgniter 的钩子功能使得您可以在不修改系统核心文件的基础上来改变或增加系统的核心运行功能。
//钩子功能可以在全局范围内打开或关闭,您可以在 application/config/config.php 文件中设定:
//$config['enable_hooks'] = TRUE;
class CI_Hooks {
/**
* Determines wether hooks are enabled
*
* @var bool
*/
//开启hook的标志,默认是关闭的。APPPATH/config/config.php中的配置也是默认关闭的,如果想使用hook,要在config.php中开启。
var $enabled = FALSE;
/**
* List of all hooks set in config/hooks.php
*
* @var array
*/
//在_initialize()函数初始化的过程中将APPPATH/config/hook.php中定义的hook数组,引用到$this->hooks;
var $hooks = array();
/**
* Determines wether hook is in progress, used to prevent infinte loops
*
* @var bool
*/
//当一个hook执行的时候,会给标记 $in_process = TRUE ,是为了防止同一个hook被同时调用
var $in_progress = FALSE;
/**
* Constructor
*
*/
function __construct()
{
$this->_initialize();
log_message('debug', "Hooks Class Initialized");
}
// --------------------------------------------------------------------
/**
* Initialize the Hooks Preferences
*
* @access private
* @return void
*/
//初始化hook
function _initialize()
{
//获取配置文件
$CFG =& load_class('Config', 'core');
// If hooks are not enabled in the config file
// there is nothing else to do
如果配置文件中设置了是不允许hooks,则直接返回退出本函数。
if ($CFG->item('enable_hooks') == FALSE)///判断config.php中是否开启hook
{
return;
}
// Grab the "hooks" definition file.
// If there are no hooks, we're done.
//要使用到的钩子,必须在配置目录下的hooks.php里面定义好。否则无法使用。
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
}
elseif (is_file(APPPATH.'config/hooks.php'))
{
include(APPPATH.'config/hooks.php');
}
if ( ! isset($hook) OR ! is_array($hook))
{
return;
}
include(hook.php),将文件里定义的hook数组引用到$this->hooks
$this->hooks =& $hook;
$this->enabled = TRUE;
}
// --------------------------------------------------------------------
/**
* Call Hook
*
* Calls a particular hook
*
* @access private
* @param string the hook name
* @return mixed
*/
//外部其实就是调用这个_call_hook函数进行调用钩子程序。而此方法中再调用_run_hook去执行相应的钩子
function _call_hook($which = '')
{
以pre_system挂钩点为例,当调用_call_hook('pre_system')时
if ( ! $this->enabled OR ! isset($this->hooks[$which]))
{
//确保$this->enable = TRUE && 定义了$this->hooks['pre_system']
return FALSE;
}
//如果是二维数组就遍历,依次_run_hook($this->hooks['pre_system'][$val])
if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
{
foreach ($this->hooks[$which] as $val)
{
$this->_run_hook($val);
}
}
else//如果是一维数组,那么直接_run_hook($this->hooks['pre_system']) //同一个位置可以执行多个hook
{
$this->_run_hook($this->hooks[$which]);
}
return TRUE;
}
// --------------------------------------------------------------------
/**
* Run Hook
*
* Runs a particular hook
*
* @access private
* @param array the hook details
* @return bool
*/
//取得 hook.php中配置并组装成对应的类 函数 参数类执行
function _run_hook($data)
{
//$data 是传递过来的hook数组
if ( ! is_array($data))
{
return FALSE;
}
//$data 就是我们在APPPATH/config/hook.php 定义的hook数组
//$hook['pre_controller'] = array(
//'class' => 'MyClass',
//'function' => 'Myfunction',
//'filename' => 'Myclass.php',
//'filepath' => 'hooks',
//'params' => array('beer', 'wine', 'snacks')
// );
// -----------------------------------
// 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->in_progress == TRUE)
{
return;
}
// -----------------------------------
// Set file path
// -----------------------------------
//判断路径和文件是否存在
if ( ! isset($data['filepath']) OR ! isset($data['filename']))
{
return FALSE;
}
$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
if ( ! file_exists($filepath))
{
return FALSE;
}
// -----------------------------------
// Set class/function name
// -----------------------------------
/**
* 取出data里面的数据,加载 APPPATH.$data['filepath'].$data['filename'];
* 实例化钩子类,调用function。应用到示例中就是
*$this->in_process = TRUE;
*$Hook = new MyClass();
*$Hook->Myfunction($params);
*$this->in_process = FALSE;
*/
$class = FALSE;
$function = FALSE;
$params = '';
if (isset($data['class']) AND $data['class'] != '')
{
$class = $data['class'];
}
if (isset($data['function']))
{
$function = $data['function'];
}
if (isset($data['params']))
{
$params = $data['params'];
}
if ($class === FALSE AND $function === FALSE)
{
return FALSE;
}
// -----------------------------------
// Set the in_progress flag
// -----------------------------------
$this->in_progress = TRUE;
// -----------------------------------
// Call the requested class and/or function
// -----------------------------------
if ($class !== FALSE)
{
if ( ! class_exists($class))
{
require($filepath);
}
$HOOK = new $class;
$HOOK->$function($params);
}
else
{
if ( ! function_exists($function))
{
require($filepath);
}
$function($params);
}
$this->in_progress = FALSE;
return TRUE;
}
}
// END CI_Hooks class
/* End of file Hooks.php */
/* Location: ./system/core/Hooks.php */
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
/**
* CodeIgniter Hooks Class
*
* Provides a mechanism to extend the base system without hacking.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/encryption.html
*/
//CodeIgniter 的钩子功能使得您可以在不修改系统核心文件的基础上来改变或增加系统的核心运行功能。
//钩子功能可以在全局范围内打开或关闭,您可以在 application/config/config.php 文件中设定:
//$config['enable_hooks'] = TRUE;
class CI_Hooks {
/**
* Determines wether hooks are enabled
*
* @var bool
*/
//开启hook的标志,默认是关闭的。APPPATH/config/config.php中的配置也是默认关闭的,如果想使用hook,要在config.php中开启。
var $enabled = FALSE;
/**
* List of all hooks set in config/hooks.php
*
* @var array
*/
//在_initialize()函数初始化的过程中将APPPATH/config/hook.php中定义的hook数组,引用到$this->hooks;
var $hooks = array();
/**
* Determines wether hook is in progress, used to prevent infinte loops
*
* @var bool
*/
//当一个hook执行的时候,会给标记 $in_process = TRUE ,是为了防止同一个hook被同时调用
var $in_progress = FALSE;
/**
* Constructor
*
*/
function __construct()
{
$this->_initialize();
log_message('debug', "Hooks Class Initialized");
}
// --------------------------------------------------------------------
/**
* Initialize the Hooks Preferences
*
* @access private
* @return void
*/
//初始化hook
function _initialize()
{
//获取配置文件
$CFG =& load_class('Config', 'core');
// If hooks are not enabled in the config file
// there is nothing else to do
如果配置文件中设置了是不允许hooks,则直接返回退出本函数。
if ($CFG->item('enable_hooks') == FALSE)///判断config.php中是否开启hook
{
return;
}
// Grab the "hooks" definition file.
// If there are no hooks, we're done.
//要使用到的钩子,必须在配置目录下的hooks.php里面定义好。否则无法使用。
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
}
elseif (is_file(APPPATH.'config/hooks.php'))
{
include(APPPATH.'config/hooks.php');
}
if ( ! isset($hook) OR ! is_array($hook))
{
return;
}
include(hook.php),将文件里定义的hook数组引用到$this->hooks
$this->hooks =& $hook;
$this->enabled = TRUE;
}
// --------------------------------------------------------------------
/**
* Call Hook
*
* Calls a particular hook
*
* @access private
* @param string the hook name
* @return mixed
*/
//外部其实就是调用这个_call_hook函数进行调用钩子程序。而此方法中再调用_run_hook去执行相应的钩子
function _call_hook($which = '')
{
以pre_system挂钩点为例,当调用_call_hook('pre_system')时
if ( ! $this->enabled OR ! isset($this->hooks[$which]))
{
//确保$this->enable = TRUE && 定义了$this->hooks['pre_system']
return FALSE;
}
//如果是二维数组就遍历,依次_run_hook($this->hooks['pre_system'][$val])
if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
{
foreach ($this->hooks[$which] as $val)
{
$this->_run_hook($val);
}
}
else//如果是一维数组,那么直接_run_hook($this->hooks['pre_system']) //同一个位置可以执行多个hook
{
$this->_run_hook($this->hooks[$which]);
}
return TRUE;
}
// --------------------------------------------------------------------
/**
* Run Hook
*
* Runs a particular hook
*
* @access private
* @param array the hook details
* @return bool
*/
//取得 hook.php中配置并组装成对应的类 函数 参数类执行
function _run_hook($data)
{
//$data 是传递过来的hook数组
if ( ! is_array($data))
{
return FALSE;
}
//$data 就是我们在APPPATH/config/hook.php 定义的hook数组
//$hook['pre_controller'] = array(
//'class' => 'MyClass',
//'function' => 'Myfunction',
//'filename' => 'Myclass.php',
//'filepath' => 'hooks',
//'params' => array('beer', 'wine', 'snacks')
// );
// -----------------------------------
// 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->in_progress == TRUE)
{
return;
}
// -----------------------------------
// Set file path
// -----------------------------------
//判断路径和文件是否存在
if ( ! isset($data['filepath']) OR ! isset($data['filename']))
{
return FALSE;
}
$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
if ( ! file_exists($filepath))
{
return FALSE;
}
// -----------------------------------
// Set class/function name
// -----------------------------------
/**
* 取出data里面的数据,加载 APPPATH.$data['filepath'].$data['filename'];
* 实例化钩子类,调用function。应用到示例中就是
*$this->in_process = TRUE;
*$Hook = new MyClass();
*$Hook->Myfunction($params);
*$this->in_process = FALSE;
*/
$class = FALSE;
$function = FALSE;
$params = '';
if (isset($data['class']) AND $data['class'] != '')
{
$class = $data['class'];
}
if (isset($data['function']))
{
$function = $data['function'];
}
if (isset($data['params']))
{
$params = $data['params'];
}
if ($class === FALSE AND $function === FALSE)
{
return FALSE;
}
// -----------------------------------
// Set the in_progress flag
// -----------------------------------
$this->in_progress = TRUE;
// -----------------------------------
// Call the requested class and/or function
// -----------------------------------
if ($class !== FALSE)
{
if ( ! class_exists($class))
{
require($filepath);
}
$HOOK = new $class;
$HOOK->$function($params);
}
else
{
if ( ! function_exists($function))
{
require($filepath);
}
$function($params);
}
$this->in_progress = FALSE;
return TRUE;
}
}
// END CI_Hooks class
/* End of file Hooks.php */
/* Location: ./system/core/Hooks.php */