blob: 429d6bceb7129ffffae2b6f4cf41e299f8526b36 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreevf9938a22012-01-07 22:10:47 +02008 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02009 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
Andrey Andreevf9938a22012-01-07 22:10:47 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreevfe9309d2015-01-09 17:48:58 +020032 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
34 * @link http://codeigniter.com
35 * @since Version 1.0.0
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030041 * Hooks Class
Derek Allard2067d1a2008-11-13 22:59:24 +000042 *
Derek Jones6f4d17f2010-03-02 13:34:23 -060043 * Provides a mechanism to extend the base system without hacking.
Derek Allard2067d1a2008-11-13 22:59:24 +000044 *
45 * @package CodeIgniter
46 * @subpackage Libraries
47 * @category Libraries
Derek Jonesf4a4bd82011-10-20 12:18:42 -050048 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000049 * @link http://codeigniter.com/user_guide/libraries/encryption.html
50 */
51class CI_Hooks {
52
David Behler9b5df592011-08-14 21:04:17 +020053 /**
Alex Bilbief512b732012-06-16 11:15:19 +010054 * Determines whether hooks are enabled
David Behler9b5df592011-08-14 21:04:17 +020055 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030056 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020057 */
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030058 public $enabled = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030059
David Behler9b5df592011-08-14 21:04:17 +020060 /**
61 * List of all hooks set in config/hooks.php
62 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030063 * @var array
David Behler9b5df592011-08-14 21:04:17 +020064 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -040065 public $hooks = array();
Andrey Andreev92ebfb62012-05-17 12:49:24 +030066
David Behler9b5df592011-08-14 21:04:17 +020067 /**
Marcos SF Filho0f667c92014-01-07 15:01:56 -020068 * Array with class objects to use hooks methods
69 *
70 * @var array
71 */
Marcos SF Filhobdfef072014-01-08 09:48:09 -020072 protected $_objects = array();
Marcos SF Filho0f667c92014-01-07 15:01:56 -020073
74 /**
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030075 * In progress flag
76 *
Alex Bilbief512b732012-06-16 11:15:19 +010077 * Determines whether hook is in progress, used to prevent infinte loops
David Behler9b5df592011-08-14 21:04:17 +020078 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030079 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020080 */
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030081 protected $_in_progress = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +000082
Derek Allard2067d1a2008-11-13 22:59:24 +000083 /**
Andrey Andreev3e9d2b82012-10-27 14:28:51 +030084 * Class constructor
Derek Allard2067d1a2008-11-13 22:59:24 +000085 *
Derek Allard2067d1a2008-11-13 22:59:24 +000086 * @return void
Barry Mienydd671972010-10-04 16:33:58 +020087 */
Andrey Andreeva5dd2972012-03-26 14:43:01 +030088 public function __construct()
Barry Mienydd671972010-10-04 16:33:58 +020089 {
Derek Jonesc64ca012010-03-07 07:55:56 -060090 $CFG =& load_class('Config', 'core');
Derek Allard2067d1a2008-11-13 22:59:24 +000091
Andrey Andreeva5dd2972012-03-26 14:43:01 +030092 log_message('debug', 'Hooks Class Initialized');
93
Derek Allard2067d1a2008-11-13 22:59:24 +000094 // If hooks are not enabled in the config file
95 // there is nothing else to do
Alex Bilbieed944a32012-06-02 11:07:47 +010096 if ($CFG->item('enable_hooks') === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000097 {
98 return;
99 }
100
101 // Grab the "hooks" definition file.
Andrey Andreev06879112013-01-29 15:05:02 +0200102 if (file_exists(APPPATH.'config/hooks.php'))
Greg Akerd96f8822011-12-27 16:23:47 -0600103 {
104 include(APPPATH.'config/hooks.php');
105 }
106
vlakoff4be16042015-01-04 17:16:20 +0100107 if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
108 {
109 include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
110 }
111
Andrey Andreevf9938a22012-01-07 22:10:47 +0200112 // If there are no hooks, we're done.
Derek Allard2067d1a2008-11-13 22:59:24 +0000113 if ( ! isset($hook) OR ! is_array($hook))
114 {
115 return;
116 }
117
118 $this->hooks =& $hook;
119 $this->enabled = TRUE;
Barry Mienydd671972010-10-04 16:33:58 +0200120 }
121
Derek Allard2067d1a2008-11-13 22:59:24 +0000122 // --------------------------------------------------------------------
123
124 /**
125 * Call Hook
126 *
Andrey Andreevf9938a22012-01-07 22:10:47 +0200127 * Calls a particular hook. Called by CodeIgniter.php.
Derek Allard2067d1a2008-11-13 22:59:24 +0000128 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300129 * @uses CI_Hooks::_run_hook()
130 *
131 * @param string $which Hook name
132 * @return bool TRUE on success or FALSE on failure
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 */
Andrey Andreeva5dd2972012-03-26 14:43:01 +0300134 public function call_hook($which = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 {
136 if ( ! $this->enabled OR ! isset($this->hooks[$which]))
137 {
138 return FALSE;
139 }
140
Andrey Andreev94293ad2014-06-12 11:33:43 +0300141 if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000142 {
143 foreach ($this->hooks[$which] as $val)
144 {
145 $this->_run_hook($val);
146 }
147 }
148 else
149 {
150 $this->_run_hook($this->hooks[$which]);
151 }
152
153 return TRUE;
154 }
155
156 // --------------------------------------------------------------------
157
158 /**
159 * Run Hook
160 *
161 * Runs a particular hook
162 *
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300163 * @param array $data Hook details
164 * @return bool TRUE on success or FALSE on failure
Derek Allard2067d1a2008-11-13 22:59:24 +0000165 */
Andrey Andreevf9938a22012-01-07 22:10:47 +0200166 protected function _run_hook($data)
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 {
Andrey Andreev83514042014-03-06 00:28:55 +0200168 // Closures/lambda functions and array($object, 'method') callables
169 if (is_callable($data))
170 {
171 is_array($data)
172 ? $data[0]->{$data[1]}()
173 : $data();
174
175 return TRUE;
176 }
177 elseif ( ! is_array($data))
Derek Allard2067d1a2008-11-13 22:59:24 +0000178 {
179 return FALSE;
180 }
181
182 // -----------------------------------
183 // Safety - Prevents run-away loops
184 // -----------------------------------
185
186 // If the script being called happens to have the same
187 // hook call within it a loop can happen
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300188 if ($this->_in_progress === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 {
190 return;
191 }
192
193 // -----------------------------------
194 // Set file path
195 // -----------------------------------
196
Andrey Andreeva5dd2972012-03-26 14:43:01 +0300197 if ( ! isset($data['filepath'], $data['filename']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000198 {
199 return FALSE;
200 }
201
202 $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
203
204 if ( ! file_exists($filepath))
205 {
206 return FALSE;
207 }
208
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300209 // Determine and class and/or function names
210 $class = empty($data['class']) ? FALSE : $data['class'];
211 $function = empty($data['function']) ? FALSE : $data['function'];
212 $params = isset($data['params']) ? $data['params'] : '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000213
Andrey Andreevda8c7a52014-01-07 18:08:26 +0200214 if (empty($function))
Derek Allard2067d1a2008-11-13 22:59:24 +0000215 {
216 return FALSE;
217 }
218
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300219 // Set the _in_progress flag
220 $this->_in_progress = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000221
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 // Call the requested class and/or function
Derek Allard2067d1a2008-11-13 22:59:24 +0000223 if ($class !== FALSE)
224 {
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200225 // The object is stored?
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200226 if (isset($this->_objects[$class]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000227 {
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200228 if (method_exists($this->_objects[$class], $function))
229 {
230 $this->_objects[$class]->$function($params);
231 }
232 else
233 {
234 return $this->_in_progress = FALSE;
235 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 }
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200237 else
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200238 {
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200239 class_exists($class, FALSE) OR require_once($filepath);
Derek Allard2067d1a2008-11-13 22:59:24 +0000240
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200241 if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function))
242 {
243 return $this->_in_progress = FALSE;
244 }
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200245
246 // Store the object and execute the method
247 $this->_objects[$class] = new $class();
248 $this->_objects[$class]->$function($params);
Marcos SF Filho0f667c92014-01-07 15:01:56 -0200249 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 }
251 else
252 {
Andrey Andreevda8c7a52014-01-07 18:08:26 +0200253 function_exists($function) OR require_once($filepath);
254
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 if ( ! function_exists($function))
256 {
Andrey Andreevda8c7a52014-01-07 18:08:26 +0200257 return $this->_in_progress = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000258 }
259
260 $function($params);
261 }
262
Andrey Andreev3e9d2b82012-10-27 14:28:51 +0300263 $this->_in_progress = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 return TRUE;
265 }
266
267}
268
Derek Allard2067d1a2008-11-13 22:59:24 +0000269/* End of file Hooks.php */
Marcos SF Filhobdfef072014-01-08 09:48:09 -0200270/* Location: ./system/core/Hooks.php */