Merge branch 'maint/7.0'
[ninja.git] / system / core / Event.php
blobc5b540364b7b82a0e312438ff880500deac753da
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
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 3917 2009-01-21 03:06:22Z zombor $
9 * @package Core
10 * @author Kohana Team
11 * @copyright (c) 2007 Kohana Team
12 * @license http://kohanaphp.com/license.html
13 * @link http://docs.kohanaphp.com/general/events
15 final class Event {
17 // Event callbacks
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
24 public static $data;
26 public static $name;
28 /**
29 * Add a callback to an event queue.
31 * @param string event name
32 * @param array http://php.net/callback
33 * @return boolean
35 public static function add($name, $callback)
37 if ( ! isset(self::$events[$name]))
39 // Create an empty event if it is not yet defined
40 self::$events[$name] = array();
42 elseif (in_array($callback, self::$events[$name], TRUE))
44 // The event already exists
45 return FALSE;
48 // Add the event
49 self::$events[$name][] = $callback;
51 return TRUE;
54 /**
55 * Add a callback to an event queue, before a given event.
57 * @param string event name
58 * @param array existing event callback
59 * @param array event callback
60 * @return boolean
62 public static function add_before($name, $existing, $callback)
64 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
66 // Just add the event if there are no events
67 return self::add($name, $callback);
69 else
71 // Insert the event immediately before the existing event
72 return self::insert_event($name, $key, $callback);
76 /**
77 * Add a callback to an event queue, after a given event.
79 * @param string event name
80 * @param array existing event callback
81 * @param array event callback
82 * @return boolean
84 public static function add_after($name, $existing, $callback)
86 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
88 // Just add the event if there are no events
89 return self::add($name, $callback);
91 else
93 // Insert the event immediately after the existing event
94 return self::insert_event($name, $key + 1, $callback);
98 /**
99 * Inserts a new event at a specfic key location.
101 * @param string event name
102 * @param integer key to insert new event at
103 * @param array event callback
104 * @return void
106 private static function insert_event($name, $key, $callback)
108 if (in_array($callback, self::$events[$name], TRUE))
109 return FALSE;
111 // Add the new event at the given key location
112 self::$events[$name] = array_merge
114 // Events before the key
115 array_slice(self::$events[$name], 0, $key),
116 // New event callback
117 array($callback),
118 // Events after the key
119 array_slice(self::$events[$name], $key)
122 return TRUE;
126 * Replaces an event with another event.
128 * @param string event name
129 * @param array event to replace
130 * @param array new callback
131 * @return boolean
133 public static function replace($name, $existing, $callback)
135 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name], TRUE)) === FALSE)
136 return FALSE;
138 if ( ! in_array($callback, self::$events[$name], TRUE))
140 // Replace the exisiting event with the new event
141 self::$events[$name][$key] = $callback;
143 else
145 // Remove the existing event from the queue
146 unset(self::$events[$name][$key]);
148 // Reset the array so the keys are ordered properly
149 self::$events[$name] = array_values(self::$events[$name]);
152 return TRUE;
156 * Get all callbacks for an event.
158 * @param string event name
159 * @return array
161 public static function get($name)
163 return empty(self::$events[$name]) ? array() : self::$events[$name];
167 * Clear some or all callbacks from an event.
169 * @param string event name
170 * @param array specific callback to remove, FALSE for all callbacks
171 * @return void
173 public static function clear($name, $callback = FALSE)
175 if ($callback === FALSE)
177 self::$events[$name] = array();
179 elseif (isset(self::$events[$name]))
181 // Loop through each of the event callbacks and compare it to the
182 // callback requested for removal. The callback is removed if it
183 // matches.
184 foreach (self::$events[$name] as $i => $event_callback)
186 if ($callback === $event_callback)
188 unset(self::$events[$name][$i]);
195 * Execute all of the callbacks attached to an event.
197 * @param string event name
198 * @param array data can be processed as Event::$data by the callbacks
199 * @return void
201 public static function run($name, & $data = NULL)
203 if ( ! empty(self::$events[$name]))
205 // So callbacks can access Event::$data
206 self::$data =& $data;
207 self::$name =& $name;
208 $callbacks = self::get($name);
210 foreach ($callbacks as $callback)
212 call_user_func($callback);
215 // Do this to prevent data from getting 'stuck'
216 $clear_data = '';
217 self::$data =& $clear_data;
219 // The event has been run!
220 self::$has_run[$name] = $name;
225 * Check if a given event has been run.
227 * @param string event name
228 * @return boolean
230 public static function has_run($name)
232 return isset(self::$has_run[$name]);
235 } // End Event