PageRenderTime 58ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/system/core/Event.php

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