Ticket #17817: 17817.4.patch
File 17817.4.patch, 22.4 KB (added by , 11 years ago) |
---|
-
src/wp-includes/class-wp-hook.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
1 <?php 2 3 /** 4 * Class WP_Hook 5 * 6 * TODO: This implements SplSubject. Make that explicit 7 * when we can depend on SPL's presence. 8 */ 9 class WP_Hook { 10 // TODO: When PHP 5.3 is the minimum version, use SplObjectStorage 11 /** @var SplObserver[] */ 12 private $observers = array(); 13 public $callbacks = array(); 14 15 public function add_filter( $function_to_add, $priority, $accepted_args, $tag ) { 16 $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); 17 $this->callbacks[$priority][$idx] = array( 'function' => $function_to_add, 'accepted_args' => $accepted_args ); 18 19 if ( $this->observers ) { 20 $this->notify(); 21 } 22 } 23 24 /** 25 * @param string $function_key 26 * @param int $priority 27 * 28 * @return bool Whether the callback existed before it was removed 29 */ 30 public function remove_filter( $function_key, $priority ) { 31 $exists = isset($this->callbacks[$priority][$function_key]); 32 if ( $exists ) { 33 unset($this->callbacks[$priority][$function_key]); 34 if ( empty($this->callbacks[$priority]) ) { 35 unset($this->callbacks[$priority]); 36 } 37 if ( $this->observers ) { 38 $this->notify(); 39 } 40 } 41 return $exists; 42 } 43 44 /** 45 * Check if any action has been registered for a hook. 46 * 47 * @param string $function_key The hashed index of the filter 48 * @return mixed The priority of that hook is returned, or false if the function is not attached. 49 */ 50 public function has_filter( $function_key ) { 51 foreach ( $this->callbacks as $priority => &$callbacks ) { 52 if ( isset($callbacks[$function_key]) ) { 53 return $priority; 54 } 55 } 56 return false; 57 } 58 59 /** 60 * Remove all of the callbacks from the filter. 61 * 62 * @param int|bool $priority The priority number to remove. 63 * @return void 64 */ 65 public function remove_all_filters( $priority = false ) { 66 if ( empty($this->callbacks) ) { 67 return; 68 } 69 if( false !== $priority && isset($this->callbacks[$priority]) ) { 70 unset($this->callbacks[$priority]); 71 } else { 72 $this->callbacks = array(); 73 } 74 $this->notify(); 75 } 76 77 public function get_iterator() { 78 $iterator = new WP_Hook_Iterator( $this ); 79 return $iterator; 80 } 81 82 public function attach( $observer ) { 83 $this->observers[] = $observer; 84 } 85 86 public function detach( $observer ) { 87 foreach ( $this->observers as $key => $o ) { 88 if ( $observer === $o ) { 89 unset($this->observers[$key]); 90 } 91 } 92 } 93 94 public function notify() { 95 foreach ( $this->observers as &$o ) { 96 $o->update($this); 97 } 98 } 99 } 100 -
tests/phpunit/includes/functions.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
1 1 <?php 2 2 3 // For adding hooks before loading WP4 function tests_add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {5 global $wp_filter, $merged_filters;6 7 $idx = _test_filter_build_unique_id($tag, $function_to_add, $priority);8 $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);9 unset( $merged_filters[ $tag ] );10 return true;11 }12 13 function _test_filter_build_unique_id($tag, $function, $priority) {14 global $wp_filter;15 static $filter_id_count = 0;16 17 if ( is_string($function) )18 return $function;19 20 if ( is_object($function) ) {21 // Closures are currently implemented as objects22 $function = array( $function, '' );23 } else {24 $function = (array) $function;25 }26 27 if (is_object($function[0]) ) {28 return spl_object_hash($function[0]) . $function[1];29 } else if ( is_string($function[0]) ) {30 // Static Calling31 return $function[0].$function[1];32 }33 }34 35 3 function _delete_all_posts() { 36 4 global $wpdb; 37 5 -
src/wp-includes/plugin.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
20 20 */ 21 21 22 22 // Initialize the filter globals. 23 global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; 23 require( ABSPATH . '/wp-includes/class-wp-hook.php' ); 24 require( ABSPATH . '/wp-includes/class-wp-hook-iterator.php' ); 25 /** @var WP_Hook[] $wp_filter */ 26 global $wp_filter, $wp_actions, $wp_current_filter; 24 27 25 28 if ( ! isset( $wp_filter ) ) 26 29 $wp_filter = array(); … … 28 31 if ( ! isset( $wp_actions ) ) 29 32 $wp_actions = array(); 30 33 31 if ( ! isset( $merged_filters ) )32 $merged_filters = array();33 34 34 if ( ! isset( $wp_current_filter ) ) 35 35 $wp_current_filter = array(); 36 36 … … 64 64 * so everything is as quick as possible. 65 65 * 66 66 * @global array $wp_filter A multidimensional array of all hooks and the callbacks hooked to them. 67 * @global array $merged_filters Tracks the tags that need to be merged for later. If the hook is added, it doesn't need to run through that process.68 67 * 69 68 * @since 0.71 70 69 * … … 77 76 * @return boolean true 78 77 */ 79 78 function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { 80 global $wp_filter, $merged_filters; 79 global $wp_filter; 80 if ( !isset($wp_filter[$tag]) ) { 81 $wp_filter[$tag] = new WP_Hook(); 82 } 83 $wp_filter[$tag]->add_filter( $function_to_add, $priority, $accepted_args, $tag ); 81 84 82 $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);83 $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);84 unset( $merged_filters[ $tag ] );85 85 return true; 86 86 } 87 87 … … 102 102 function has_filter($tag, $function_to_check = false) { 103 103 global $wp_filter; 104 104 105 $has = !empty($wp_filter[$tag]);105 $has = isset($wp_filter[$tag]) && !empty($wp_filter[$tag]->callbacks); 106 106 if ( false === $function_to_check || false == $has ) 107 107 return $has; 108 108 109 109 if ( !$idx = _wp_filter_build_unique_id($tag, $function_to_check, false) ) 110 110 return false; 111 111 112 foreach ( (array) array_keys($wp_filter[$tag]) as $priority ) { 113 if ( isset($wp_filter[$tag][$priority][$idx]) ) 114 return $priority; 115 } 112 return $wp_filter[$tag]->has_filter($idx); 113 } 116 114 117 return false;118 }119 120 115 /** 121 116 * Call the functions added to a filter hook. 122 117 * … … 143 138 * </code> 144 139 * 145 140 * @global array $wp_filter Stores all of the filters 146 * @global array $merged_filters Merges the filter hooks using this function.147 141 * @global array $wp_current_filter stores the list of current filters with the current one last 148 142 * 149 143 * @since 0.71 … … 154 148 * @return mixed The filtered value after all hooked functions are applied to it. 155 149 */ 156 150 function apply_filters( $tag, $value ) { 157 global $wp_filter, $ merged_filters, $wp_current_filter;151 global $wp_filter, $wp_current_filter; 158 152 159 153 $args = array(); 160 154 … … 174 168 if ( !isset($wp_filter['all']) ) 175 169 $wp_current_filter[] = $tag; 176 170 177 // Sort178 if ( !isset( $merged_filters[ $tag ] ) ) {179 ksort($wp_filter[$tag]);180 $merged_filters[ $tag ] = true;181 }182 183 reset( $wp_filter[ $tag ] );184 185 171 if ( empty($args) ) 186 172 $args = func_get_args(); 187 173 188 do {189 foreach( (array) current($wp_filter[$tag]) as $the_ )190 if ( !is_null($the_['function']) ){191 $args[1] = $value;192 $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));193 }174 $iterator = $wp_filter[$tag]->get_iterator(); 175 foreach ( $iterator as $the_ ) { 176 $args[1] = $value; 177 $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args'])); 178 } 179 $iterator->cleanup(); 194 180 195 } while ( next($wp_filter[$tag]) !== false );196 197 181 array_pop( $wp_current_filter ); 198 182 199 183 return $value; … … 207 191 * 208 192 * @since 3.0.0 209 193 * @global array $wp_filter Stores all of the filters 210 * @global array $merged_filters Merges the filter hooks using this function.211 194 * @global array $wp_current_filter stores the list of current filters with the current one last 212 195 * 213 196 * @param string $tag The name of the filter hook. … … 215 198 * @return mixed The filtered value after all hooked functions are applied to it. 216 199 */ 217 200 function apply_filters_ref_array($tag, $args) { 218 global $wp_filter, $ merged_filters, $wp_current_filter;201 global $wp_filter, $wp_current_filter; 219 202 220 203 // Do 'all' actions first 221 204 if ( isset($wp_filter['all']) ) { … … 233 216 if ( !isset($wp_filter['all']) ) 234 217 $wp_current_filter[] = $tag; 235 218 236 // Sort 237 if ( !isset( $merged_filters[ $tag ] ) ) { 238 ksort($wp_filter[$tag]); 239 $merged_filters[ $tag ] = true; 219 $iterator = $wp_filter[$tag]->get_iterator(); 220 foreach ( $iterator as $the_ ) { 221 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 240 222 } 223 $iterator->cleanup(); 241 224 242 reset( $wp_filter[ $tag ] );243 244 do {245 foreach( (array) current($wp_filter[$tag]) as $the_ )246 if ( !is_null($the_['function']) )247 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));248 249 } while ( next($wp_filter[$tag]) !== false );250 251 225 array_pop( $wp_current_filter ); 252 226 253 227 return $args[0]; … … 273 247 * @return boolean Whether the function existed before it was removed. 274 248 */ 275 249 function remove_filter( $tag, $function_to_remove, $priority = 10 ) { 276 $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority);250 global $wp_filter; 277 251 278 $r = isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); 279 280 if ( true === $r) { 281 unset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); 282 if ( empty($GLOBALS['wp_filter'][$tag][$priority]) ) 283 unset($GLOBALS['wp_filter'][$tag][$priority]); 284 unset($GLOBALS['merged_filters'][$tag]); 252 $r = false; 253 if ( isset($wp_filter[$tag]) ) { 254 $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority); 255 $r = $wp_filter[$tag]->remove_filter($function_to_remove, $priority); 285 256 } 286 257 287 258 return $r; … … 297 268 * @return bool True when finished. 298 269 */ 299 270 function remove_all_filters($tag, $priority = false) { 300 global $wp_filter , $merged_filters;271 global $wp_filter; 301 272 302 273 if( isset($wp_filter[$tag]) ) { 303 if( false !== $priority && isset($wp_filter[$tag][$priority]) ) 304 unset($wp_filter[$tag][$priority]); 305 else 306 unset($wp_filter[$tag]); 274 $wp_filter[$tag]->remove_all_filters($priority); 307 275 } 308 276 309 if( isset($merged_filters[$tag]) )310 unset($merged_filters[$tag]);311 312 277 return true; 313 278 } 314 279 … … 423 388 * @return null Will return null if $tag does not exist in $wp_filter array 424 389 */ 425 390 function do_action($tag, $arg = '') { 426 global $wp_filter, $wp_actions, $ merged_filters, $wp_current_filter;391 global $wp_filter, $wp_actions, $wp_current_filter; 427 392 428 393 if ( ! isset($wp_actions[$tag]) ) 429 394 $wp_actions[$tag] = 1; … … 454 419 for ( $a = 2; $a < func_num_args(); $a++ ) 455 420 $args[] = func_get_arg($a); 456 421 457 // Sort 458 if ( !isset( $merged_filters[ $tag ] ) ) { 459 ksort($wp_filter[$tag]); 460 $merged_filters[ $tag ] = true; 422 $iterator = $wp_filter[$tag]->get_iterator(); 423 foreach ( $iterator as $the_ ) { 424 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 461 425 } 426 $iterator->cleanup(); 462 427 463 reset( $wp_filter[ $tag ] );464 465 do {466 foreach ( (array) current($wp_filter[$tag]) as $the_ )467 if ( !is_null($the_['function']) )468 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));469 470 } while ( next($wp_filter[$tag]) !== false );471 472 428 array_pop($wp_current_filter); 473 429 } 474 430 … … 507 463 * @return null Will return null if $tag does not exist in $wp_filter array 508 464 */ 509 465 function do_action_ref_array($tag, $args) { 510 global $wp_filter, $wp_actions, $ merged_filters, $wp_current_filter;466 global $wp_filter, $wp_actions, $wp_current_filter; 511 467 512 468 if ( ! isset($wp_actions[$tag]) ) 513 469 $wp_actions[$tag] = 1; … … 530 486 if ( !isset($wp_filter['all']) ) 531 487 $wp_current_filter[] = $tag; 532 488 533 // Sort 534 if ( !isset( $merged_filters[ $tag ] ) ) { 535 ksort($wp_filter[$tag]); 536 $merged_filters[ $tag ] = true; 489 $iterator = $wp_filter[$tag]->get_iterator(); 490 foreach ( $iterator as $the_ ) { 491 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 537 492 } 493 $iterator->cleanup(); 538 494 539 reset( $wp_filter[ $tag ] );540 541 do {542 foreach( (array) current($wp_filter[$tag]) as $the_ )543 if ( !is_null($the_['function']) )544 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));545 546 } while ( next($wp_filter[$tag]) !== false );547 548 495 array_pop($wp_current_filter); 549 496 } 550 497 … … 779 726 */ 780 727 function _wp_call_all_hook($args) { 781 728 global $wp_filter; 782 783 reset( $wp_filter['all'] ); 784 do { 785 foreach( (array) current($wp_filter['all']) as $the_ ) 786 if ( !is_null($the_['function']) ) 787 call_user_func_array($the_['function'], $args); 788 789 } while ( next($wp_filter['all']) !== false ); 729 $iterator = $wp_filter['all']->get_iterator(); 730 foreach ( $iterator as $the_ ) { 731 call_user_func_array($the_['function'], $args); 732 } 733 $iterator->cleanup(); 790 734 } 791 735 792 736 /** -
tests/phpunit/tests/actions.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
356 356 $this->assertTrue( doing_filter( 'testing_nested' ) ); 357 357 $this->assertFalse( doing_filter( 'something_else' ) ); 358 358 } 359 360 /** 361 * @ticket 17817 362 */ 363 function test_action_recursion() { 364 $tag = rand_str(); 365 $a = new MockAction(); 366 $b = new MockAction(); 367 368 add_action( $tag, array($a, 'action'), 11, 1 ); 369 add_action( $tag, array($b, 'action'), 13, 1 ); 370 add_action( $tag, array($this, 'action_that_causes_recursion'), 12, 1 ); 371 do_action( $tag, $tag ); 372 373 $this->assertEquals( 2, $a->get_call_count(), 'recursive actions should call all callbacks with earlier priority' ); 374 $this->assertEquals( 2, $b->get_call_count(), 'recursive actions should call callbacks with later priority' ); 375 } 376 377 function action_that_causes_recursion( $tag ) { 378 static $recursing = FALSE; 379 if ( !$recursing ) { 380 $recursing = TRUE; 381 do_action( $tag, $tag ); 382 } 383 $recursing = FALSE; 384 } 385 386 /** 387 * @ticket 9968 388 */ 389 function test_action_callback_manipulation_while_running() { 390 $tag = rand_str(); 391 $a = new MockAction(); 392 $b = new MockAction(); 393 $c = new MockAction(); 394 $d = new MockAction(); 395 $e = new MockAction(); 396 397 add_action( $tag, array($a, 'action'), 11, 2 ); 398 add_action( $tag, array($this, 'action_that_manipulates_a_running_hook'), 12, 2 ); 399 add_action( $tag, array($b, 'action'), 12, 2 ); 400 401 do_action( $tag, $tag, array($a,$b,$c,$d,$e) ); 402 do_action( $tag, $tag, array($a,$b,$c,$d,$e) ); 403 404 $this->assertEquals( 2, $a->get_call_count(), 'callbacks should run unless otherwise instructed' ); 405 $this->assertEquals( 1, $b->get_call_count(), 'callback removed by same priority callback should still get called' ); 406 $this->assertEquals( 1, $c->get_call_count(), 'callback added by same priority callback should not get called' ); 407 $this->assertEquals( 2, $d->get_call_count(), 'callback added by earlier priority callback should get called' ); 408 $this->assertEquals( 1, $e->get_call_count(), 'callback added by later priority callback should not get called' ); 409 } 410 411 function action_that_manipulates_a_running_hook( $tag, $mocks ) { 412 remove_action( $tag, array($mocks[1], 'action'), 12, 2 ); 413 add_action( $tag, array($mocks[2], 'action' ), 12, 2 ); 414 add_action( $tag, array($mocks[3], 'action' ), 13, 2 ); 415 add_action( $tag, array($mocks[4], 'action' ), 10, 2 ); 416 } 359 417 } -
src/wp-settings.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
72 72 require( ABSPATH . WPINC . '/functions.php' ); 73 73 require( ABSPATH . WPINC . '/class-wp.php' ); 74 74 require( ABSPATH . WPINC . '/class-wp-error.php' ); 75 require ( ABSPATH . WPINC . '/plugin.php' );75 require_once( ABSPATH . WPINC . '/plugin.php' ); 76 76 require( ABSPATH . WPINC . '/pomo/mo.php' ); 77 77 78 78 // Include the wpdb class and, if present, a db.php database drop-in. -
tests/phpunit/includes/bootstrap.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
67 67 68 68 require_once dirname( __FILE__ ) . '/functions.php'; 69 69 70 // load plugin.php out of order so that we can set up 71 // some filters in advance 72 require_once ABSPATH . '/wp-includes/plugin.php'; 73 70 74 // Preset WordPress options defined in bootstrap file. 71 75 // Used to activate themes, plugins, as well as other settings. 72 76 if(isset($GLOBALS['wp_tests_options'])) { … … 76 80 } 77 81 78 82 foreach ( array_keys( $GLOBALS['wp_tests_options'] ) as $key ) { 79 tests_add_filter( 'pre_option_'.$key, 'wp_tests_options' );83 add_filter( 'pre_option_'.$key, 'wp_tests_options' ); 80 84 } 81 85 } 82 86 -
src/wp-includes/class-wp-hook-iterator.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
1 <?php 2 3 /** 4 * Class WP_Hook_Iterator 5 * 6 * TODO: This implements SplObserver. Make that explicit 7 * when we can depend on SPL's presence. 8 */ 9 class WP_Hook_Iterator implements Iterator { 10 /** @var WP_Hook */ 11 private $hook = NULL; 12 private $current_callback = NULL; 13 private $current_callback_index = NULL; 14 private $current_priority = NULL; 15 private $current_priority_index = NULL; 16 private $all_priorities = NULL; 17 private $callbacks_for_current_priority = array(); 18 19 public function __construct( WP_Hook $hook ) { 20 $this->hook = $hook; 21 $this->hook->attach($this); 22 } 23 24 public function cleanup() { 25 $this->hook->detach($this); 26 } 27 28 /** 29 * Return the current element 30 * 31 * @link http://php.net/manual/en/iterator.current.php 32 * @return mixed Can return any type. 33 */ 34 public function current() { 35 return $this->current_callback; 36 } 37 38 /** 39 * Move forward to next element 40 * @link http://php.net/manual/en/iterator.next.php 41 * @return void Any returned value is ignored. 42 */ 43 public function next() { 44 $next = next( $this->callbacks_for_current_priority ); 45 46 if ( $next === FALSE ) { 47 do { 48 $this->increment_priority(); 49 } while ( empty($this->callbacks_for_current_priority) && isset( $this->current_priority) ); 50 51 if ( !$this->callbacks_for_current_priority ) { 52 $this->current_callback = NULL; 53 $this->current_callback_index = NULL; 54 return; 55 } 56 57 $next = reset( $this->callbacks_for_current_priority ); 58 } 59 60 $this->current_callback = $next; 61 $this->current_callback_index = key($this->callbacks_for_current_priority); 62 } 63 64 /** 65 * Setup the callbacks array for the next available priority 66 * @return void 67 */ 68 private function increment_priority() { 69 $this->set_current_priority(); 70 if ( isset($this->current_priority) ) { 71 $this->callbacks_for_current_priority = $this->get_callbacks($this->current_priority); 72 } else { 73 $this->callbacks_for_current_priority = array(); 74 } 75 } 76 77 /** 78 * Move to the next available priority 79 * @return void 80 */ 81 private function set_current_priority() { 82 if ( empty($this->hook->callbacks) ) { // no callbacks on this hook 83 $this->all_priorities = array(); 84 $this->current_priority = NULL; 85 return; 86 } 87 88 if ( !isset($this->all_priorities) ) { 89 $this->all_priorities = array_keys($this->hook->callbacks); 90 sort($this->all_priorities); 91 if ( isset($this->current_priority) ) { // callbacks were manipulated while we were running 92 foreach ( $this->all_priorities as $index => &$p ) { // go to the next larger priority 93 if ( $p > $this->current_priority ) { 94 $this->current_priority_index = $index; 95 $this->current_priority = $p; 96 break; 97 } 98 } 99 } else { // starting fresh 100 $this->current_priority_index = 0; 101 $this->current_priority = $this->all_priorities[0]; 102 } 103 return; 104 } 105 106 if ( !isset($this->current_priority_index) ) { 107 $this->current_priority_index = 0; 108 } else { 109 $this->current_priority_index++; 110 } 111 if ( isset($this->all_priorities[$this->current_priority_index]) ) { 112 $this->current_priority = $this->all_priorities[$this->current_priority_index]; 113 return; 114 } 115 116 $this->current_priority = NULL; 117 return; 118 } 119 120 private function get_callbacks( $priority ) { 121 if ( isset($this->hook->callbacks[$priority]) ) { 122 return $this->hook->callbacks[$priority]; 123 } 124 return array(); 125 } 126 127 /** 128 * Return the key of the current element 129 * @link http://php.net/manual/en/iterator.key.php 130 * @return mixed scalar on success, or null on failure. 131 */ 132 public function key() { 133 return $this->current_callback_index; 134 } 135 136 /** 137 * Checks if current position is valid 138 * @link http://php.net/manual/en/iterator.valid.php 139 * @return boolean The return value will be casted to boolean and then evaluated. 140 * Returns true on success or false on failure. 141 */ 142 public function valid() { 143 return isset($this->current_callback); 144 } 145 146 /** 147 * Rewind the Iterator to the first element 148 * @link http://php.net/manual/en/iterator.rewind.php 149 * @return void Any returned value is ignored. 150 */ 151 public function rewind() { 152 $this->current_priority = NULL; 153 $this->current_priority_index = NULL; 154 $this->current_callback = NULL; 155 $this->current_callback_index = NULL; 156 $this->callbacks_for_current_priority = array(); 157 $this->next(); 158 } 159 160 /** 161 * Receive update from subject 162 * 163 * @link http://php.net/manual/en/splobserver.update.php 164 * 165 * @param SplSubject $subject The SplSubject notifying the observer of an update. 166 * 167 * @return void 168 */ 169 public function update( $subject ) { 170 unset($this->all_priorities); 171 unset($this->current_priority_index); 172 } 173 }