blob: 767dc4cd91b94ab37fafe62ece4dfc53f051a3bf [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreevf9938a22012-01-07 22:10:47 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreevf9938a22012-01-07 22:10:47 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010021 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030030 * Hooks Class
Derek Allard2067d1a2008-11-13 22:59:24 +000031 *
Derek Jones6f4d17f2010-03-02 13:34:23 -060032 * Provides a mechanism to extend the base system without hacking.
Derek Allard2067d1a2008-11-13 22:59:24 +000033 *
34 * @package CodeIgniter
35 * @subpackage Libraries
36 * @category Libraries
Derek Jonesf4a4bd82011-10-20 12:18:42 -050037 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000038 * @link http://codeigniter.com/user_guide/libraries/encryption.html
39 */
40class CI_Hooks {
41
David Behler9b5df592011-08-14 21:04:17 +020042 /**
Alex Bilbief512b732012-06-16 11:15:19 +010043 * Determines whether hooks are enabled
David Behler9b5df592011-08-14 21:04:17 +020044 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030045 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020046 */
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030047 public $enabled = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030048
David Behler9b5df592011-08-14 21:04:17 +020049 /**
50 * List of all hooks set in config/hooks.php
51 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030052 * @var array
David Behler9b5df592011-08-14 21:04:17 +020053 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -040054 public $hooks = array();
Andrey Andreev92ebfb62012-05-17 12:49:24 +030055
David Behler9b5df592011-08-14 21:04:17 +020056 /**
Marcos SF Filho0f667c92014-01-07 15:01:56 -020057 * Array with class objects to use hooks methods
58 *
59 * @var array
60 */
Marcos SF Filhobdfef072014-01-08 09:48:09 -020061 protected $_objects = array();
Marcos SF Filho0f667c92014-01-07 15:01:56 -020062
63 /**
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030064 * In progress flag
65 *
Alex Bilbief512b732012-06-16 11:15:19 +010066 * Determines whether hook is in progress, used to prevent infinte loops
David Behler9b5df592011-08-14 21:04:17 +020067 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030068 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020069 */
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030070 protected $_in_progress = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +000071
Derek Allard2067d1a2008-11-13 22:59:24 +000072 /**
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030073 * Class constructor
Derek Allard2067d1a2008-11-13 22:59:24 +000074 *
Derek Allard2067d1a2008-11-13 22:59:24 +000075 * @return void
Barry Mienydd671972010-10-04 16:33:58 +020076 */
Andrey Andreeva5dd2972012-03-26 14:43:01 +030077 public function __construct()
Barry Mienydd671972010-10-04 16:33:58 +020078 {
Derek Jonesc64ca012010-03-07 07:55:56 -060079 $CFG =& load_class('Config', 'core');
Derek Allard2067d1a2008-11-13 22:59:24 +000080
Andrey Andreeva5dd2972012-03-26 14:43:01 +030081 log_message('debug', 'Hooks Class Initialized');
82
Derek Allard2067d1a2008-11-13 22:59:24 +000083 // If hooks are not enabled in the config file
84 // there is nothing else to do
Alex Bilbieed944a32012-06-02 11:07:47 +010085 if ($CFG->item('enable_hooks') === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000086 {
87 return;
88 }
89
90 // Grab the "hooks" definition file.
Andrey Andreev06879112013-01-29 15:05:02 +020091 if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
Greg Akerd96f8822011-12-27 16:23:47 -060092 {
93 include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
94 }
Andrey Andreev06879112013-01-29 15:05:02 +020095
96 if (file_exists(APPPATH.'config/hooks.php'))
Greg Akerd96f8822011-12-27 16:23:47 -060097 {
98 include(APPPATH.'config/hooks.php');
99 }
100
Andrey Andreevf9938a22012-01-07 22:10:47 +0200101 // If there are no hooks, we're done.
Derek Allard2067d1a2008-11-13 22:59:24 +0000102 if ( ! isset($hook) OR ! is_array($hook))
103 {
104 return;
105 }
106
107 $this->hooks =& $hook;
108 $this->enabled = TRUE;
Barry Mienydd671972010-10-04 16:33:58 +0200109 }
110
Derek Allard2067d1a2008-11-13 22:59:24 +0000111 // --------------------------------------------------------------------
112
113 /**
114 * Call Hook
115 *
Andrey Andreevf9938a22012-01-07 22:10:47 +0200116 * Calls a particular hook. Called by CodeIgniter.php.
Derek Allard2067d1a2008-11-13 22:59:24 +0000117 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300118 * @uses CI_Hooks::_run_hook()
119 *
120 * @param string $which Hook name
121 * @return bool TRUE on success or FALSE on failure
Derek Allard2067d1a2008-11-13 22:59:24 +0000122 */
Andrey Andreeva5dd2972012-03-26 14:43:01 +0300123 public function call_hook($which = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000124 {
125 if ( ! $this->enabled OR ! isset($this->hooks[$which]))
126 {
127 return FALSE;
128 }
129
Andrey Andreeva5dd2972012-03-26 14:43:01 +0300130 if (isset($this->hooks[$which][0]) && is_array($this->hooks[$which][0]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000131 {
132 foreach ($this->hooks[$which] as $val)
133 {
134 $this->_run_hook($val);
135 }
136 }
137 else
138 {
139 $this->_run_hook($this->hooks[$which]);
140 }
141
142 return TRUE;
143 }
144
145 // --------------------------------------------------------------------
146
147 /**
148 * Run Hook
149 *
150 * Runs a particular hook
151 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300152 * @param array $data Hook details
153 * @return bool TRUE on success or FALSE on failure
Derek Allard2067d1a2008-11-13 22:59:24 +0000154 */
Andrey Andreevf9938a22012-01-07 22:10:47 +0200155 protected function _run_hook($data)
Derek Allard2067d1a2008-11-13 22:59:24 +0000156 {
Andrey Andreev83514042014-03-06 00:28:55 +0200157 // Closures/lambda functions and array($object, 'method') callables
158 if (is_callable($data))
159 {
160 is_array($data)
161 ? $data[0]->{$data[1]}()
162 : $data();
163
164 return TRUE;
165 }
166 elseif ( ! is_array($data))
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 {
168 return FALSE;
169 }
170
171 // -----------------------------------
172 // Safety - Prevents run-away loops
173 // -----------------------------------
174
175 // If the script being called happens to have the same
176 // hook call within it a loop can happen
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300177 if ($this->_in_progress === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000178 {
179 return;
180 }
181
182 // -----------------------------------
183 // Set file path
184 // -----------------------------------
185
Andrey Andreeva5dd2972012-03-26 14:43:01 +0300186 if ( ! isset($data['filepath'], $data['filename']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 {
188 return FALSE;
189 }
190
191 $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
192
193 if ( ! file_exists($filepath))
194 {
195 return FALSE;
196 }
197
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300198 // Determine and class and/or function names
199 $class = empty($data['class']) ? FALSE : $data['class'];
200 $function = empty($data['function']) ? FALSE : $data['function'];
201 $params = isset($data['params']) ? $data['params'] : '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000202
Andrey Andreevda8c7a52014-01-07 18:08:26 +0200203 if (empty($function))
Derek Allard2067d1a2008-11-13 22:59:24 +0000204 {
205 return FALSE;
206 }
207
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300208 // Set the _in_progress flag
209 $this->_in_progress = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000210
Derek Allard2067d1a2008-11-13 22:59:24 +0000211 // Call the requested class and/or function
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 if ($class !== FALSE)
213 {
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200214 // The object is stored?
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200215 if (isset($this->_objects[$class]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 {
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200217 if (method_exists($this->_objects[$class], $function))
218 {
219 $this->_objects[$class]->$function($params);
220 }
221 else
222 {
223 return $this->_in_progress = FALSE;
224 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 }
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200226 else
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200227 {
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200228 class_exists($class, FALSE) OR require_once($filepath);
Derek Allard2067d1a2008-11-13 22:59:24 +0000229
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200230 if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function))
231 {
232 return $this->_in_progress = FALSE;
233 }
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200234
235 // Store the object and execute the method
236 $this->_objects[$class] = new $class();
237 $this->_objects[$class]->$function($params);
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200238 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000239 }
240 else
241 {
Andrey Andreevda8c7a52014-01-07 18:08:26 +0200242 function_exists($function) OR require_once($filepath);
243
Derek Allard2067d1a2008-11-13 22:59:24 +0000244 if ( ! function_exists($function))
245 {
Andrey Andreevda8c7a52014-01-07 18:08:26 +0200246 return $this->_in_progress = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000247 }
248
249 $function($params);
250 }
251
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300252 $this->_in_progress = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000253 return TRUE;
254 }
255
256}
257
Derek Allard2067d1a2008-11-13 22:59:24 +0000258/* End of file Hooks.php */
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200259/* Location: ./system/core/Hooks.php */