PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/mantisbt-1.2.8/core/event_api.php

#
PHP | 333 lines | 166 code | 37 blank | 130 comment | 18 complexity | e565c97477025d6ec064309c2a865cac MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php
  2. # MantisBT - a php based bugtracking system
  3. # MantisBT is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # MantisBT is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with MantisBT. If not, see <http://www.gnu.org/licenses/>.
  15. /**
  16. * Event API
  17. * Handles the event system.
  18. * @version $Id$
  19. * @copyright Copyright (C) 2002 - 2011 MantisBT Team - mantisbt-dev@lists.sourceforge.net
  20. * @link http://www.mantisbt.org
  21. * @package CoreAPI
  22. * @subpackage EventAPI
  23. * @author John Reese
  24. *
  25. * @uses error_api.php
  26. * @uses pluging_api.php
  27. */
  28. /**
  29. *
  30. * @global array $g_event_cache
  31. */
  32. $g_event_cache = array();
  33. /**
  34. * Declare an event of a given type.
  35. * Will do nothing if event already exists.
  36. * @param string Event name
  37. * @param int Event type
  38. * @access public
  39. */
  40. function event_declare( $p_name, $p_type = EVENT_TYPE_DEFAULT ) {
  41. global $g_event_cache;
  42. if( !isset( $g_event_cache[$p_name] ) ) {
  43. $g_event_cache[$p_name] = array(
  44. 'type' => $p_type,
  45. 'callbacks' => array(),
  46. );
  47. }
  48. }
  49. /**
  50. * Convenience function for decleare multiple events.
  51. * @param array Events
  52. * @access public
  53. */
  54. function event_declare_many( $p_events ) {
  55. foreach( $p_events as $t_name => $t_type ) {
  56. event_declare( $t_name, $t_type );
  57. }
  58. }
  59. /**
  60. * Hook a callback function to a given event.
  61. * A plugin's basename must be specified for proper handling of plugin callbacks.
  62. * @param string Event name
  63. * @param string Callback function
  64. * @param string Plugin basename
  65. * @access public
  66. */
  67. function event_hook( $p_name, $p_callback, $p_plugin = 0 ) {
  68. global $g_event_cache;
  69. if( !isset( $g_event_cache[$p_name] ) ) {
  70. error_parameters( $p_name );
  71. trigger_error( ERROR_EVENT_UNDECLARED, WARNING );
  72. return null;
  73. }
  74. $g_event_cache[$p_name]['callbacks'][$p_plugin][] = $p_callback;
  75. }
  76. /**
  77. * Hook multiple callback functions to multiple events.
  78. * @param array Event name/callback pairs
  79. * @param string Plugin basename
  80. * @access public
  81. */
  82. function event_hook_many( $p_hooks, $p_plugin = 0 ) {
  83. if( !is_array( $p_hooks ) ) {
  84. return;
  85. }
  86. foreach( $p_hooks as $t_name => $t_callbacks ) {
  87. if( !is_array( $t_callbacks ) ) {
  88. event_hook( $t_name, $t_callbacks, $p_plugin );
  89. continue;
  90. }
  91. foreach( $t_callbacks as $t_callback ) {
  92. event_hook( $t_name, $t_callback, $p_plugin );
  93. }
  94. }
  95. }
  96. /**
  97. * In the case of errors that halt execution, it is useful to
  98. * clear the list of event callbacks so that no other callbacks
  99. * are executed while the error message is being displayed.
  100. */
  101. function event_clear_callbacks() {
  102. global $g_event_cache;
  103. foreach( $g_event_cache as $t_name => $t_event_info ) {
  104. $g_event_cache[$t_name]['callbacks'] = array();
  105. }
  106. }
  107. /**
  108. * Signal an event to execute and handle callbacks as necessary.
  109. * @param string Event name
  110. * @param multi Event parameters
  111. * @param int Event type override
  112. * @return multi Null if event undeclared, appropriate return value otherwise
  113. * @access public
  114. */
  115. function event_signal( $p_name, $p_params = null, $p_params_dynamic = null, $p_type = null ) {
  116. global $g_event_cache;
  117. if( !isset( $g_event_cache[$p_name] ) ) {
  118. error_parameters( $p_name );
  119. trigger_error( ERROR_EVENT_UNDECLARED, WARNING );
  120. return null;
  121. }
  122. if( is_null( $p_type ) ) {
  123. $t_type = $g_event_cache[$p_name]['type'];
  124. } else {
  125. $t_type = $p_type;
  126. }
  127. $t_callbacks = $g_event_cache[$p_name]['callbacks'];
  128. switch( $t_type ) {
  129. case EVENT_TYPE_EXECUTE:
  130. return event_type_execute( $p_name, $t_callbacks, $p_params );
  131. case EVENT_TYPE_OUTPUT:
  132. return event_type_output( $p_name, $t_callbacks, $p_params );
  133. case EVENT_TYPE_CHAIN:
  134. return event_type_chain( $p_name, $t_callbacks, $p_params, $p_params_dynamic );
  135. case EVENT_TYPE_FIRST:
  136. return event_type_first( $p_name, $t_callbacks, $p_params );
  137. default:
  138. return event_type_default( $p_name, $t_callbacks, $p_params );
  139. }
  140. }
  141. /**
  142. * Executes a plugin's callback function for a given event.
  143. * @param string Event name
  144. * @param string Callback name
  145. * @param string Plugin basename
  146. * @param multi Parameters for event callback
  147. * @return multi Null if callback not found, value from callback otherwise
  148. * @access public
  149. */
  150. function event_callback( $p_event, $p_callback, $p_plugin, $p_params = null ) {
  151. $t_value = null;
  152. if( !is_array( $p_params ) ) {
  153. $p_params = array(
  154. $p_params,
  155. );
  156. }
  157. if( $p_plugin !== 0 ) {
  158. global $g_plugin_cache;
  159. plugin_push_current( $p_plugin );
  160. if( method_exists( $g_plugin_cache[$p_plugin], $p_callback ) ) {
  161. $t_value = call_user_func_array( array( $g_plugin_cache[$p_plugin], $p_callback ), array_merge( array( $p_event ), $p_params ) );
  162. }
  163. plugin_pop_current();
  164. } else {
  165. if( function_exists( $p_callback ) ) {
  166. $t_value = call_user_func_array( $p_callback, array_merge( array( $p_event ), $p_params ) );
  167. }
  168. }
  169. return $t_value;
  170. }
  171. /**
  172. * Process an execute event type.
  173. * All callbacks will be called with parameters, and their
  174. * return values will be ignored.
  175. * @param string Event name
  176. * @param array Array of callback function/plugin basename key/value pairs
  177. * @param array Callback parameters
  178. * @access public
  179. */
  180. function event_type_execute( $p_event, $p_callbacks, $p_params ) {
  181. foreach( $p_callbacks as $t_plugin => $t_callbacks ) {
  182. foreach( $t_callbacks as $t_callback ) {
  183. event_callback( $p_event, $t_callback, $t_plugin, $p_params );
  184. }
  185. }
  186. }
  187. /**
  188. * Process an output event type.
  189. * All callbacks will be called with the given parameters, and their
  190. * return values will be echoed to the client, separated by a given string.
  191. * If there are no callbacks, then nothing will be sent as output.
  192. * @param string Event name
  193. * @param array Array of callback function/plugin basename key/value pairs
  194. * @param multi Output separator (if single string) or indexed array of pre, mid, and post strings
  195. * @access public
  196. */
  197. function event_type_output( $p_event, $p_callbacks, $p_params = null ) {
  198. $t_prefix = '';
  199. $t_separator = '';
  200. $t_postfix = '';
  201. if( is_array( $p_params ) ) {
  202. switch( count( $p_params ) ) {
  203. case 3:
  204. $t_postfix = $p_params[2];
  205. case 2:
  206. $t_separator = $p_params[1];
  207. case 1:
  208. $t_prefix = $p_params[0];
  209. }
  210. } else {
  211. $t_separator = $p_params;
  212. }
  213. $t_output = array();
  214. foreach( $p_callbacks as $t_plugin => $t_callbacks ) {
  215. foreach( $t_callbacks as $t_callback ) {
  216. $t_output[] = event_callback( $p_event, $t_callback, $t_plugin, $p_params );
  217. }
  218. }
  219. if( count( $p_callbacks ) > 0 ) {
  220. echo $t_prefix, implode( $t_separator, $t_output ), $t_postfix;
  221. }
  222. }
  223. /**
  224. * Process a chained event type.
  225. * The first callback with be called with the given input. All following
  226. * callbacks will be called with the previous's output as its input. The
  227. * final callback's return value will be returned to the event origin.
  228. * @param string Event name
  229. * @param array Array of callback function/plugin basename key/value pairs
  230. * @param string Input string
  231. * @return string Output string
  232. * @access public
  233. */
  234. function event_type_chain( $p_event, $p_callbacks, $p_input, $p_params ) {
  235. if( !is_array( $p_params ) ) {
  236. $p_params = array(
  237. $p_params,
  238. );
  239. }
  240. $t_output = $p_input;
  241. foreach( $p_callbacks as $t_plugin => $t_callbacks ) {
  242. foreach( $t_callbacks as $t_callback ) {
  243. if( !is_array( $t_output ) ) {
  244. $t_output = array(
  245. $t_output,
  246. );
  247. }
  248. $t_params = array_merge( $t_output, $p_params );
  249. $t_output = event_callback( $p_event, $t_callback, $t_plugin, $t_params );
  250. }
  251. }
  252. return $t_output;
  253. }
  254. /**
  255. * Process a first-return event.
  256. * Callbacks will be called with the given parameters until a callback
  257. * returns a non-null value; at this point, no other callbacks will be
  258. * processed, and the return value be passed back to the event origin.
  259. * @param string Event name
  260. * @param array Array of callback function/plugin basename key/value pairs
  261. * @param multi Parameters passed to callbacks
  262. * @return multi The first non-null callback result, or null otherwise
  263. * @access public
  264. */
  265. function event_type_first( $p_event, $p_callbacks, $p_params ) {
  266. $t_output = null;
  267. foreach( $p_callbacks as $t_plugin => $t_callbacks ) {
  268. foreach( $t_callbacks as $t_callback ) {
  269. $t_output = event_callback( $p_event, $t_callback, $t_plugin, $p_params );
  270. if( !is_null( $t_output ) ) {
  271. return $t_output;
  272. }
  273. }
  274. }
  275. return null;
  276. }
  277. /**
  278. * Process a default event type.
  279. * All callbacks will be called with the given data parameters. The
  280. * return value of each callback will be appended to an array with the callback's
  281. * basename as the key. This array will then be returned to the event origin.
  282. * @param string Event name
  283. * @param array Array of callback function/plugin basename key/value pairs
  284. * @param multi Data
  285. * @return array Array of callback/return key/value pairs
  286. * @access public
  287. */
  288. function event_type_default( $p_event, $p_callbacks, $p_data ) {
  289. $t_output = array();
  290. foreach( $p_callbacks as $t_plugin => $t_callbacks ) {
  291. foreach( $t_callbacks as $t_callback ) {
  292. $t_output[$t_plugin][$t_callback] = event_callback( $p_event, $t_callback, $t_plugin, $p_data );
  293. }
  294. }
  295. return $t_output;
  296. }