/system/classes/core/event.php

https://github.com/barkerja/EightPHP · PHP · 202 lines · 80 code · 23 blank · 99 comment · 12 complexity · 98f3fc90ccd1dcb3006ed5fc872be1e3 MD5 · raw file

  1. <?php
  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, Eight has several system events.
  6. *
  7. * @package System
  8. * @subpackage Core
  9. * @author EightPHP Development Team
  10. * @copyright (c) 2009-2010 EightPHP
  11. * @license http://license.eightphp.com
  12. */
  13. final class Event {
  14. // Event callbacks
  15. private static $events = array();
  16. // Cache of events that have been run
  17. private static $has_run = array();
  18. // Data that can be processed during events
  19. public static $data;
  20. /**
  21. * Add a callback to an event queue.
  22. *
  23. * @param string event name
  24. * @param array http://php.net/callback
  25. * @return boolean
  26. */
  27. public static function add($name, $callback) {
  28. if(!isset(self::$events[$name])) {
  29. // Create an empty event if it is not yet defined
  30. self::$events[$name] = array();
  31. } elseif(in_array($callback, self::$events[$name], YES)) {
  32. // The event already exists
  33. return NO;
  34. }
  35. // Add the event
  36. self::$events[$name][] = $callback;
  37. return YES;
  38. }
  39. /**
  40. * Add a callback to an event queue, before a given event.
  41. *
  42. * @param string event name
  43. * @param array existing event callback
  44. * @param array event callback
  45. * @return boolean
  46. */
  47. public static function add_before($name, $existing, $callback) {
  48. if(empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === NO) {
  49. // Just add the event if there are no events
  50. return self::add($name, $callback);
  51. } else {
  52. // Insert the event immediately before the existing event
  53. return self::insert_event($name, $key, $callback);
  54. }
  55. }
  56. /**
  57. * Add a callback to an event queue, after a given event.
  58. *
  59. * @param string event name
  60. * @param array existing event callback
  61. * @param array event callback
  62. * @return boolean
  63. */
  64. public static function add_after($name, $existing, $callback) {
  65. if(empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === NO) {
  66. // Just add the event if there are no events
  67. return self::add($name, $callback);
  68. } else {
  69. // Insert the event immediately after the existing event
  70. return self::insert_event($name, $key + 1, $callback);
  71. }
  72. }
  73. /**
  74. * Inserts a new event at a specfic key location.
  75. *
  76. * @param string event name
  77. * @param integer key to insert new event at
  78. * @param array event callback
  79. * @return void
  80. */
  81. private static function insert_event($name, $key, $callback) {
  82. if(in_array($callback, self::$events[$name], YES))
  83. return NO;
  84. // Add the new event at the given key location
  85. self::$events[$name] = array_merge
  86. (
  87. // Events before the key
  88. array_slice(self::$events[$name], 0, $key),
  89. // New event callback
  90. array($callback),
  91. // Events after the key
  92. array_slice(self::$events[$name], $key)
  93. );
  94. return YES;
  95. }
  96. /**
  97. * Replaces an event with another event.
  98. *
  99. * @param string event name
  100. * @param array event to replace
  101. * @param array new callback
  102. * @return boolean
  103. */
  104. public static function replace($name, $existing, $callback) {
  105. if(empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name], YES)) === NO)
  106. return NO;
  107. if(!in_array($callback, self::$events[$name], YES)) {
  108. // Replace the exisiting event with the new event
  109. self::$events[$name][$key] = $callback;
  110. } else {
  111. // Remove the existing event from the queue
  112. unset(self::$events[$name][$key]);
  113. // Reset the array so the keys are ordered properly
  114. self::$events[$name] = array_values(self::$events[$name]);
  115. }
  116. return YES;
  117. }
  118. /**
  119. * Get all callbacks for an event.
  120. *
  121. * @param string event name
  122. * @return array
  123. */
  124. public static function get($name) {
  125. return empty(self::$events[$name]) ? array() : self::$events[$name];
  126. }
  127. /**
  128. * Clear some or all callbacks from an event.
  129. *
  130. * @param string event name
  131. * @param array specific callback to remove, NO for all callbacks
  132. * @return void
  133. */
  134. public static function clear($name, $callback = NO) {
  135. if($callback === NO) {
  136. self::$events[$name] = array();
  137. } elseif(isset(self::$events[$name])) {
  138. // Loop through each of the event callbacks and compare it to the
  139. // callback requested for removal. The callback is removed if it
  140. // matches.
  141. foreach(self::$events[$name] as $i => $event_callback) {
  142. if($callback === $event_callback) {
  143. unset(self::$events[$name][$i]);
  144. }
  145. }
  146. }
  147. }
  148. /**
  149. * Execute all of the callbacks attached to an event.
  150. *
  151. * @param string event name
  152. * @param array data can be processed as Event::$data by the callbacks
  153. * @return void
  154. */
  155. public static function run($name, & $data = nil) {
  156. if(!empty(self::$events[$name])) {
  157. // So callbacks can access Event::$data
  158. self::$data =& $data;
  159. $callbacks = self::get($name);
  160. foreach($callbacks as $callback) {
  161. call_user_func($callback);
  162. }
  163. // Do this to prevent data from getting 'stuck'
  164. $clear_data = '';
  165. self::$data =& $clear_data;
  166. // The event has been run!
  167. self::$has_run[$name] = $name;
  168. }
  169. }
  170. /**
  171. * Check if a given event has been run.
  172. *
  173. * @param string event name
  174. * @return boolean
  175. */
  176. public static function has_run($name) {
  177. return isset(self::$has_run[$name]);
  178. }
  179. } // End Event