Route and Results buttons updated.
[speedfreak] / Server / system / core / Event.php
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.
6  *
7  * $Id: Event.php 4390 2009-06-04 03:05:36Z zombor $
8  *
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
14  */
15 final class Event {
16
17         // Event callbacks
18         private static $events = array();
19
20         // Cache of events that have been run
21         private static $has_run = array();
22
23         // Data that can be processed during events
24         public static $data;
25
26         /**
27          * Add a callback to an event queue.
28          *
29          * @param   string   event name
30          * @param   array    http://php.net/callback
31          * @return  boolean
32          */
33         public static function add($name, $callback)
34         {
35                 if ( ! isset(self::$events[$name]))
36                 {
37                         // Create an empty event if it is not yet defined
38                         self::$events[$name] = array();
39                 }
40                 elseif (in_array($callback, self::$events[$name], TRUE))
41                 {
42                         // The event already exists
43                         return FALSE;
44                 }
45
46                 // Add the event
47                 self::$events[$name][] = $callback;
48
49                 return TRUE;
50         }
51
52         /**
53          * Add a callback to an event queue, before a given event.
54          *
55          * @param   string   event name
56          * @param   array    existing event callback
57          * @param   array    event callback
58          * @return  boolean
59          */
60         public static function add_before($name, $existing, $callback)
61         {
62                 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
63                 {
64                         // Just add the event if there are no events
65                         return self::add($name, $callback);
66                 }
67                 else
68                 {
69                         // Insert the event immediately before the existing event
70                         return self::insert_event($name, $key, $callback);
71                 }
72         }
73
74         /**
75          * Add a callback to an event queue, after a given event.
76          *
77          * @param   string   event name
78          * @param   array    existing event callback
79          * @param   array    event callback
80          * @return  boolean
81          */
82         public static function add_after($name, $existing, $callback)
83         {
84                 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
85                 {
86                         // Just add the event if there are no events
87                         return self::add($name, $callback);
88                 }
89                 else
90                 {
91                         // Insert the event immediately after the existing event
92                         return self::insert_event($name, $key + 1, $callback);
93                 }
94         }
95
96         /**
97          * Inserts a new event at a specfic key location.
98          *
99          * @param   string   event name
100          * @param   integer  key to insert new event at
101          * @param   array    event callback
102          * @return  void
103          */
104         private static function insert_event($name, $key, $callback)
105         {
106                 if (in_array($callback, self::$events[$name], TRUE))
107                         return FALSE;
108
109                 // Add the new event at the given key location
110                 self::$events[$name] = array_merge
111                 (
112                         // Events before the key
113                         array_slice(self::$events[$name], 0, $key),
114                         // New event callback
115                         array($callback),
116                         // Events after the key
117                         array_slice(self::$events[$name], $key)
118                 );
119
120                 return TRUE;
121         }
122
123         /**
124          * Replaces an event with another event.
125          *
126          * @param   string   event name
127          * @param   array    event to replace
128          * @param   array    new callback
129          * @return  boolean
130          */
131         public static function replace($name, $existing, $callback)
132         {
133                 if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name], TRUE)) === FALSE)
134                         return FALSE;
135
136                 if ( ! in_array($callback, self::$events[$name], TRUE))
137                 {
138                         // Replace the exisiting event with the new event
139                         self::$events[$name][$key] = $callback;
140                 }
141                 else
142                 {
143                         // Remove the existing event from the queue
144                         unset(self::$events[$name][$key]);
145
146                         // Reset the array so the keys are ordered properly
147                         self::$events[$name] = array_values(self::$events[$name]);
148                 }
149
150                 return TRUE;
151         }
152
153         /**
154          * Get all callbacks for an event.
155          *
156          * @param   string  event name
157          * @return  array
158          */
159         public static function get($name)
160         {
161                 return empty(self::$events[$name]) ? array() : self::$events[$name];
162         }
163
164         /**
165          * Clear some or all callbacks from an event.
166          *
167          * @param   string  event name
168          * @param   array   specific callback to remove, FALSE for all callbacks
169          * @return  void
170          */
171         public static function clear($name, $callback = FALSE)
172         {
173                 if ($callback === FALSE)
174                 {
175                         self::$events[$name] = array();
176                 }
177                 elseif (isset(self::$events[$name]))
178                 {
179                         // Loop through each of the event callbacks and compare it to the
180                         // callback requested for removal. The callback is removed if it
181                         // matches.
182                         foreach (self::$events[$name] as $i => $event_callback)
183                         {
184                                 if ($callback === $event_callback)
185                                 {
186                                         unset(self::$events[$name][$i]);
187                                 }
188                         }
189                 }
190         }
191
192         /**
193          * Execute all of the callbacks attached to an event.
194          *
195          * @param   string   event name
196          * @param   array    data can be processed as Event::$data by the callbacks
197          * @return  void
198          */
199         public static function run($name, & $data = NULL)
200         {
201                 if ( ! empty(self::$events[$name]))
202                 {
203                         // So callbacks can access Event::$data
204                         self::$data =& $data;
205                         $callbacks  =  self::get($name);
206
207                         foreach ($callbacks as $callback)
208                         {
209                                 call_user_func($callback);
210                         }
211
212                         // Do this to prevent data from getting 'stuck'
213                         $clear_data = '';
214                         self::$data =& $clear_data;
215                 }
216
217                 // The event has been run!
218                 self::$has_run[$name] = $name;
219         }
220
221         /**
222          * Check if a given event has been run.
223          *
224          * @param   string   event name
225          * @return  boolean
226          */
227         public static function has_run($name)
228         {
229                 return isset(self::$has_run[$name]);
230         }
231
232 } // End Event