1 <?php defined('SYSPATH') OR die('No direct access allowed.');
3 * Process queuing/execution class. Allows an unlimited number of callbacks
4 * to be added to 'events'. Events can be run multiple times, and can also
5 * process event-specific data. By default, Kohana has several system events.
7 * $Id: Event.php 4390 2009-06-04 03:05:36Z zombor $
11 * @copyright (c) 2007 Kohana Team
12 * @license http://kohanaphp.com/license.html
13 * @link http://docs.kohanaphp.com/general/events
18 private static $events = array();
20 // Cache of events that have been run
21 private static $has_run = array();
23 // Data that can be processed during events
27 * Add a callback to an event queue.
29 * @param string event name
30 * @param array http://php.net/callback
33 public static function add($name, $callback)
35 if ( ! isset(self::$events[$name]))
37 // Create an empty event if it is not yet defined
38 self::$events[$name] = array();
40 elseif (in_array($callback, self::$events[$name], TRUE))
42 // The event already exists
47 self::$events[$name][] = $callback;
53 * Add a callback to an event queue, before a given event.
55 * @param string event name
56 * @param array existing event callback
57 * @param array event callback
60 public static function add_before($name, $existing, $callback)
62 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
64 // Just add the event if there are no events
65 return self::add($name, $callback);
69 // Insert the event immediately before the existing event
70 return self::insert_event($name, $key, $callback);
75 * Add a callback to an event queue, after a given event.
77 * @param string event name
78 * @param array existing event callback
79 * @param array event callback
82 public static function add_after($name, $existing, $callback)
84 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
86 // Just add the event if there are no events
87 return self::add($name, $callback);
91 // Insert the event immediately after the existing event
92 return self::insert_event($name, $key + 1, $callback);
97 * Inserts a new event at a specfic key location.
99 * @param string event name
100 * @param integer key to insert new event at
101 * @param array event callback
104 private static function insert_event($name, $key, $callback)
106 if (in_array($callback, self::$events[$name], TRUE))
109 // Add the new event at the given key location
110 self::$events[$name] = array_merge
112 // Events before the key
113 array_slice(self::$events[$name], 0, $key),
114 // New event callback
116 // Events after the key
117 array_slice(self::$events[$name], $key)
124 * Replaces an event with another event.
126 * @param string event name
127 * @param array event to replace
128 * @param array new callback
131 public static function replace($name, $existing, $callback)
133 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name], TRUE)) === FALSE)
136 if ( ! in_array($callback, self::$events[$name], TRUE))
138 // Replace the exisiting event with the new event
139 self::$events[$name][$key] = $callback;
143 // Remove the existing event from the queue
144 unset(self::$events[$name][$key]);
146 // Reset the array so the keys are ordered properly
147 self::$events[$name] = array_values(self::$events[$name]);
154 * Get all callbacks for an event.
156 * @param string event name
159 public static function get($name)
161 return empty(self::$events[$name]) ? array() : self::$events[$name];
165 * Clear some or all callbacks from an event.
167 * @param string event name
168 * @param array specific callback to remove, FALSE for all callbacks
171 public static function clear($name, $callback = FALSE)
173 if ($callback === FALSE)
175 self::$events[$name] = array();
177 elseif (isset(self::$events[$name]))
179 // Loop through each of the event callbacks and compare it to the
180 // callback requested for removal. The callback is removed if it
182 foreach (self::$events[$name] as $i => $event_callback)
184 if ($callback === $event_callback)
186 unset(self::$events[$name][$i]);
193 * Execute all of the callbacks attached to an event.
195 * @param string event name
196 * @param array data can be processed as Event::$data by the callbacks
199 public static function run($name, & $data = NULL)
201 if ( ! empty(self::$events[$name]))
203 // So callbacks can access Event::$data
204 self::$data =& $data;
205 $callbacks = self::get($name);
207 foreach ($callbacks as $callback)
209 call_user_func($callback);
212 // Do this to prevent data from getting 'stuck'
214 self::$data =& $clear_data;
217 // The event has been run!
218 self::$has_run[$name] = $name;
222 * Check if a given event has been run.
224 * @param string event name
227 public static function has_run($name)
229 return isset(self::$has_run[$name]);