SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/core/Event.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. /**
  15.  * Process queuing/execution class. Allows an unlimited number of callbacks
  16.  * to be added to 'events'. Events can be run multiple times, and can also
  17.  * process event-specific data. By default, Kohana has several system events.
  18.  *
  19.  * $Id: Event.php 4390 2009-06-04 03:05:36Z zombor $
  20.  *
  21.  * @package Core
  22.  * @author Kohana Team
  23.  * @copyright (c) 2007 Kohana Team
  24.  * @license http://kohanaphp.com/license.html
  25.  * @link http://docs.kohanaphp.com/general/events
  26.  */
  27. final class Event {
  28.  
  29. // Event callbacks
  30. private static $events = array();
  31.  
  32. // Cache of events that have been run
  33. private static $has_run = array();
  34.  
  35. // Data that can be processed during events
  36. public static $data;
  37.  
  38. /**
  39.   * Add a callback to an event queue.
  40.   *
  41.   * @param string event name
  42.   * @param array http://php.net/callback
  43.   * @return boolean
  44.   */
  45. public static function add($name, $callback)
  46. {
  47. if ( ! isset(self::$events[$name]))
  48. {
  49. // Create an empty event if it is not yet defined
  50. self::$events[$name] = array();
  51. }
  52. elseif (in_array($callback, self::$events[$name], TRUE))
  53. {
  54. // The event already exists
  55. return FALSE;
  56. }
  57.  
  58. // Add the event
  59. self::$events[$name][] = $callback;
  60.  
  61. return TRUE;
  62. }
  63.  
  64. /**
  65.   * Add a callback to an event queue, before a given event.
  66.   *
  67.   * @param string event name
  68.   * @param array existing event callback
  69.   * @param array event callback
  70.   * @return boolean
  71.   */
  72. public static function addBefore($name, $existing, $callback)
  73. {
  74. if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
  75. {
  76. // Just add the event if there are no events
  77. return self::add($name, $callback);
  78. }
  79. else
  80. {
  81. // Insert the event immediately before the existing event
  82. return self::insertEvent($name, $key, $callback);
  83. }
  84. }
  85.  
  86. /**
  87.   * Add a callback to an event queue, after a given event.
  88.   *
  89.   * @param string event name
  90.   * @param array existing event callback
  91.   * @param array event callback
  92.   * @return boolean
  93.   */
  94. public static function addAfter($name, $existing, $callback)
  95. {
  96. if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name])) === FALSE)
  97. {
  98. // Just add the event if there are no events
  99. return self::add($name, $callback);
  100. }
  101. else
  102. {
  103. // Insert the event immediately after the existing event
  104. return self::insertEvent($name, $key + 1, $callback);
  105. }
  106. }
  107.  
  108. /**
  109.   * Inserts a new event at a specfic key location.
  110.   *
  111.   * @param string event name
  112.   * @param integer key to insert new event at
  113.   * @param array event callback
  114.   * @return void
  115.   */
  116. private static function insertEvent($name, $key, $callback)
  117. {
  118. if (in_array($callback, self::$events[$name], TRUE))
  119. return FALSE;
  120.  
  121. // Add the new event at the given key location
  122. self::$events[$name] = array_merge
  123. (
  124. // Events before the key
  125. array_slice(self::$events[$name], 0, $key),
  126. // New event callback
  127. array($callback),
  128. // Events after the key
  129. array_slice(self::$events[$name], $key)
  130. );
  131.  
  132. return TRUE;
  133. }
  134.  
  135. /**
  136.   * Replaces an event with another event.
  137.   *
  138.   * @param string event name
  139.   * @param array event to replace
  140.   * @param array new callback
  141.   * @return boolean
  142.   */
  143. public static function replace($name, $existing, $callback)
  144. {
  145. if (empty(self::$events[$name]) OR ($key = array_search($existing, self::$events[$name], TRUE)) === FALSE)
  146. return FALSE;
  147.  
  148. if ( ! in_array($callback, self::$events[$name], TRUE))
  149. {
  150. // Replace the exisiting event with the new event
  151. self::$events[$name][$key] = $callback;
  152. }
  153. else
  154. {
  155. // Remove the existing event from the queue
  156. unset(self::$events[$name][$key]);
  157.  
  158. // Reset the array so the keys are ordered properly
  159. self::$events[$name] = array_values(self::$events[$name]);
  160. }
  161.  
  162. return TRUE;
  163. }
  164.  
  165. /**
  166.   * Get all callbacks for an event.
  167.   *
  168.   * @param string event name
  169.   * @return array
  170.   */
  171. public static function get($name)
  172. {
  173. return empty(self::$events[$name]) ? array() : self::$events[$name];
  174. }
  175.  
  176. /**
  177.   * Clear some or all callbacks from an event.
  178.   *
  179.   * @param string event name
  180.   * @param array specific callback to remove, FALSE for all callbacks
  181.   * @return void
  182.   */
  183. public static function clear($name, $callback = FALSE)
  184. {
  185. if ($callback === FALSE)
  186. {
  187. self::$events[$name] = array();
  188. }
  189. elseif (isset(self::$events[$name]))
  190. {
  191. // Loop through each of the event callbacks and compare it to the
  192. // callback requested for removal. The callback is removed if it
  193. // matches.
  194. foreach (self::$events[$name] as $i => $event_callback)
  195. {
  196. if ($callback === $event_callback)
  197. {
  198. unset(self::$events[$name][$i]);
  199. }
  200. }
  201. }
  202. }
  203.  
  204. /**
  205.   * Execute all of the callbacks attached to an event.
  206.   *
  207.   * @param string event name
  208.   * @param array data can be processed as Event::$data by the callbacks
  209.   * @return void
  210.   */
  211. public static function run($name, & $data = NULL)
  212. {
  213. if ( ! empty(self::$events[$name]))
  214. {
  215. // So callbacks can access Event::$data
  216. self::$data =& $data;
  217. $callbacks = self::get($name);
  218.  
  219. foreach ($callbacks as $callback)
  220. {
  221. call_user_func($callback);
  222. }
  223.  
  224. // Do this to prevent data from getting 'stuck'
  225. $clear_data = '';
  226. self::$data =& $clear_data;
  227. }
  228.  
  229. // The event has been run!
  230. self::$has_run[$name] = $name;
  231. }
  232.  
  233. /**
  234.   * Check if a given event has been run.
  235.   *
  236.   * @param string event name
  237.   * @return boolean
  238.   */
  239. public static function hasRun($name)
  240. {
  241. return isset(self::$has_run[$name]);
  242. }
  243.  
  244. } // End Event
  245.