PhpToolCase
Api Documentation Version 0.9.2
PtcEvent.php
Go to the documentation of this file.
1 <?php
2 
3  /**
4  * PHP TOOLCASE EVENT DISPATCHER CLASS
5  * PHP version 5.3
6  * @category Library
7  * @version 0.9.2
8  * @author Irony <carlo@salapc.com>
9  * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
10  * @link http://phptoolcase.com
11  */
12 
13  class PtcEvent
14  {
15  /**
16  * Alias of PtcEvent::getEvents( ). See @ref getting_events
17  */
18  public static function getEvent( $name = null ){ return static::getEvents( $name ); }
19  /**
20  * Registers the component with a constant for ptc helpers functions. See @ref register_component
21  */
22  public static function register( )
23  {
24  $namespace = @strtoupper( @str_replace( '\\' , '_' , __NAMESPACE__ ) ) . '_';
25  if ( !defined( '_PTCEVENT_' . $namespace ) ) // declare the class namespace
26  {
27  @define( '_PTCEVENT_' . $namespace , get_called_class( ) );
28  }
29  }
30  /**
31  * Adds a listener to an event. See @ref adding_events
32  * @param string $event the event name, ex: "event.sub_event"
33  * @param mixed $callback a valid callback ( closure , function , class )
34  * @param numeric $priority a numeric value, higher values will execute first
35  * @return true if event was added succefully, throws an error otherwise
36  */
37  public static function listen( $event , $callback , $priority = 0 )
38  {
39  static::register( $class = null );
40  $event = explode( '.' , $event );
41  if ( sizeof( $event ) < 1 )
42  {
43  trigger_error( 'Invalid format, all event names must use "."!' , E_USER_ERROR );
44  return false;
45  }
46  if ( $callback instanceof Closure || is_callable( $callback ) ){ $call = $callback; }
47  else
48  {
49  $try = explode( '@' , $callback );
50  if ( @class_exists( $try[ 0 ] ) )
51  {
52  $method = ( sizeof( $try ) > 1 ) ? $try[ 1 ] : 'handle';
53  $call = array( new $try[ 0 ] , $method );
54  }
55  else // no valid callback found
56  {
57  trigger_error( $callback . ' is not a valid callback parameter!' , E_USER_ERROR );
58  return false;
59  }
60  }
61  if ( $event[ 1 ] === '*' ) // add a wildcard
62  {
63  $debug = ' wildcard to ';
64  if ( !array_key_exists( $event[ 0 ] , static::$_wildCards ) )
65  {
66  static::$_wildCards[ $event[ 0 ] ] = array( );
67  $debug =' new wildcard ';
68  }
69  static::$_wildCards[ $event[ 0 ] ][ ] = $call;
70  static::_debug( array( $call ) , 'added ' . $debug .
71  '<b>"' . $event[ 0 ] . '.*"</b>' , 'Event Manager' );
72  return true;
73  }
74  static::_addEvent( $event , $call , $priority ); // add event
75  return true;
76  }
77  /**
78  * Returs the current events. See @ref getting_events
79  * @param string $name previously added event name
80  */
81  public static function getEvents( $name = null )
82  {
83  if ( $name && !array_key_exists( $name , static::$_events ) ){ return false; }
84  return ( $name ) ? static::$_events[ $name ] : static::$_events;
85  }
86  /**
87  * Removes previously added event listeners. See @ref removing_events
88  * @param string $event the name of the event
89  * @param numeric $key the numeric key for the event
90  */
91  public static function remove( $event , $key = null )
92  {
93  $event = explode( '.' , $event );
94  if ( array_key_exists( 1 , $event ) )
95  {
96  if ( is_numeric( $key ) )
97  {
98  if ( !array_key_exists( $key , static::$_events[ $event[ 0 ] ][ $event[ 1 ] ] ) )
99  {
100  trigger_error( $key . ' not found in <b>' . $event[ 0 ] .
101  '.' . $event[ 1 ] . '</b>!' , E_USER_WARNING );
102  return false;
103  }
104  static::_debug( static::$_events[ $event[ 0 ] ][ $event[ 1 ] ][ $key ] ,
105  'removing event <b>' . $event[ 0 ] . '.' . $event[ 1 ] .
106  '[ ' . $key . ' ]</b>' , 'Event Manager' );
107  unset( static::$_events[ $event[ 0 ] ][ $event[ 1 ] ][ $key ] );
108  }
109  else
110  {
111  $debug = array_pop( static::$_events[ $event[ 0 ] ][ $event[ 1 ] ] );
112  static::_debug( $debug , 'removing last event from <b>' .
113  $event[ 0 ] . '.' . $event[ 1 ] . '</b>' , 'Event Manager' );
114  }
115  return true;
116 
117  }
118  if ( @empty( static::$_events[ $event[ 0 ] ][ $event[ 1 ] ] ) )
119  {
120  unset( static::$_events[ $event[ 0 ] ][ $event[ 1 ] ] );
121  }
122  if ( @empty( static::$_events[ $event[ 0 ] ] ) ){ unset( static::$_events[ $event[ 0 ] ] ); }
123  }
124  /**
125  * Fires an event. See @ref firing_events
126  * @param string $event the event name to fire
127  * @param array $data an array with the data you wish to pass to the listeners
128  */
129  public static function fire( $event , $data )
130  {
131  static::register( );
132  $main = $event;
133  $event = explode( '.' , $event );
134  if ( !array_key_exists( $event[ 0 ] , static::$_events ) || sizeof( $event ) < 1 ||
135  !array_key_exists( $event[ 1 ] , static::$_events[ $event[ 0 ] ] ) )
136  {
137  trigger_error( 'No listeners defined named "' . $main . '"!' , E_USER_WARNING );
138  return false;
139  }
140  $events = static::$_events[ $event[ 0 ] ][ $event[ 1 ] ];
141  $events = array_reverse( $events ); // reverse the array before sorting priority
142  uasort( $events , function ( $a , $b ){ return $b[ 'priority' ] - $a[ 'priority' ]; } );
143  $events = array_map( function ( $i ){ return $i[ 'callback' ]; }, $events );
144  if ( array_key_exists( $event[ 0 ] , static::$_wildCards ) ) // run wildcards before events
145  {
146  $a = 0;
147  foreach ( static::$_wildCards[ $event[ 0 ] ] as $wildcard )
148  {
149  $data = ( is_array( $data ) ) ? $data : array( $data );
150  static::_debug( array( 'callback' => $wildcard , 'data' => array( $data , $main ) ) ,
151  'firing wildcard <b>' . $event[ 0 ] . '.' . $event[ 1 ] . '[ ' . $a . ' ]</b>' , 'Event Manager' );
152  $a++;
153  if ( false === static::_run( $wildcard , array( $data , $main ) ) ){ return; }
154  }
155  }
156  $a = 0;
157  foreach ( $events as $sub_event ) // run events
158  {
159  static::_debug( array( 'callback' => $sub_event , 'data' => $data ) ,
160  'firing event <b>' . $event[ 0 ] . '.' . $event[ 1 ] . '[ ' . $a . ' ]</b>' , 'Event Manager' );
161  $a++;
162  if ( false === static::_run( $sub_event , $data ) ){ return; }
163  }
164  return;
165  }
166  /**
167  * Property that holds the events
168  */
169  protected static $_events = array( );
170  /**
171  * Property that holds the wildcards
172  */
173  protected static $_wildCards = array( );
174  /**
175  * Adds events to the class
176  * @param string $event some name for the event
177  * @param mixed $call some valid callback
178  * @param numeric $priority the priority for the event
179  */
180  protected static function _addEvent( $event , $call , $priority = 0 )
181  {
182  $debug = '1 more event to ';
183  if ( !array_key_exists( $event[ 0 ] , static::$_events ) )
184  {
185  static::$_events[ $event[ 0 ] ] = array( );
186  $debug = 'new event ';
187  }
188  if ( !array_key_exists( $event[ 1 ] , static::$_events[ $event[ 0 ] ] ) )
189  {
190  static::$_events[ $event[ 0 ] ][ $event[ 1 ] ] = array( );
191  $debug = 'new event ';
192  }
193  static::$_events[ $event[ 0 ] ][ $event[ 1 ] ][ ] =
194  array( 'priority' => $priority , 'callback' => $call );
195  static::_debug( @end( array_values( static::$_events[ $event[ 0 ] ][ $event[ 1 ] ] ) ) ,
196  'added ' . $debug . '<b>"' . $event[ 0 ] . '.' . $event[ 1 ] . '"</b>' , 'Event Manager' );
197  }
198  /**
199  * Runs an event with call_user_func_array
200  * @param string $event a valid callback
201  * @param mixed $data arguments for the event callbacks
202  */
203  protected static function _run( $event , $data )
204  {
205  $data = ( is_array( $data ) ) ? $data : array( $data );
206  return call_user_func_array( $event , $data );
207  }
208  /**
209  * Send messsages to the PtcDebug class if present
210  * @param mixed $string the string to pass
211  * @param mixed $statement some statement if required
212  * @param string $category a category for the messages panel
213  */
214  protected static function _debug( $string , $statement = null , $category = null )
215  {
216  if ( !defined( '_PTCDEBUG_NAMESPACE_' ) ) { return false; }
217  return @call_user_func_array( array( '\\' . _PTCDEBUG_NAMESPACE_ , 'bufferLog' ) ,
218  array( $string , $statement , $category ) );
219  }
220  }
static _addEvent($event, $call, $priority=0)
Adds events to the class.
Definition: PtcEvent.php:180
static $_events
Property that holds the events.
Definition: PtcEvent.php:169
static $_wildCards
Property that holds the wildcards.
Definition: PtcEvent.php:173
static getEvent($name=null)
Alias of PtcEvent::getEvents( ).
Definition: PtcEvent.php:18
static fire($event, $data)
Fires an event.
Definition: PtcEvent.php:129
static listen($event, $callback, $priority=0)
Adds a listener to an event.
Definition: PtcEvent.php:37
static getEvents($name=null)
Returs the current events.
Definition: PtcEvent.php:81
static _run($event, $data)
Runs an event with call_user_func_array.
Definition: PtcEvent.php:203
static _debug($string, $statement=null, $category=null)
Send messsages to the PtcDebug class if present.
Definition: PtcEvent.php:214