Ticket #17817: 17817.3.patch
File 17817.3.patch, 27.5 KB (added by , 11 years ago) |
---|
-
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/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 global $wp_filter; 17 $idx = $wp_filter->build_unique_id($function_to_add, $tag, $priority); 18 $this->callbacks[$priority][$idx] = array( 'function' => $function_to_add, 'accepted_args' => $accepted_args ); 19 $this->notify(); 20 } 21 22 /** 23 * @param string $function_key 24 * @param int $priority 25 * 26 * @return bool Whether the callback existed before it was removed 27 */ 28 public function remove_filter( $function_key, $priority ) { 29 $exists = isset($this->callbacks[$priority][$function_key]); 30 if ( $exists ) { 31 unset($this->callbacks[$priority][$function_key]); 32 if ( empty($this->callbacks[$priority]) ) { 33 unset($this->callbacks[$priority]); 34 } 35 $this->notify(); 36 } 37 return $exists; 38 } 39 40 /** 41 * Check if any action has been registered for a hook. 42 * 43 * @param string $function_key The hashed index of the filter 44 * @return mixed The priority of that hook is returned, or false if the function is not attached. 45 */ 46 public function has_filter( $function_key ) { 47 foreach ( $this->callbacks as $priority => &$callbacks ) { 48 if ( isset($callbacks[$function_key]) ) { 49 return $priority; 50 } 51 } 52 return false; 53 } 54 55 /** 56 * Remove all of the callbacks from the filter. 57 * 58 * @param int|bool $priority The priority number to remove. 59 * @return void 60 */ 61 public function remove_all_filters( $priority = false ) { 62 if ( empty($this->callbacks) ) { 63 return; 64 } 65 if( false !== $priority && isset($this->callbacks[$priority]) ) { 66 unset($this->callbacks[$priority]); 67 } else { 68 $this->callbacks = array(); 69 } 70 $this->notify(); 71 } 72 73 public function get_iterator() { 74 $iterator = new WP_Hook_Iterator( $this ); 75 return $iterator; 76 } 77 78 public function attach( $observer ) { 79 $this->observers[] = $observer; 80 } 81 82 public function detach( $observer ) { 83 foreach ( $this->observers as $key => $o ) { 84 if ( $observer === $o ) { 85 unset($this->observers[$key]); 86 } 87 } 88 } 89 90 public function notify() { 91 foreach ( $this->observers as $o ) { 92 $o->update($this); 93 } 94 } 95 } 96 97 No newline at end of file -
src/wp-includes/class-wp-filters.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
1 <?php 2 3 /** 4 * Class WP_Filters 5 */ 6 class WP_Filters implements ArrayAccess { 7 /** @var WP_Hook[] */ 8 private $hooks = array(); 9 /** @var callable */ 10 private $hasher; 11 12 public function __construct() { 13 $this->setup_hasher(); 14 } 15 16 /** 17 * Decide how we're going to hash object methods 18 * @return void 19 */ 20 private function setup_hasher() { 21 if ( function_exists('spl_object_hash') ) { 22 $this->hasher = array( $this, 'spl_hasher' ); 23 } else { 24 $this->hasher = array( $this, 'nospl_hasher' ); 25 } 26 } 27 28 /** 29 * Build a unique ID for storage and retrieval of a callback. 30 * 31 * @param callback $function Used for creating unique id 32 * @param string $tag Used when SPL is unavailable for counting how many hooks were applied 33 * @param int|bool $priority Used when SPL is unavailable for counting how many hooks were applied. If === false and $function is an object reference, we return the unique id only if it already has one, false otherwise. 34 * @return string|bool Unique ID for usage as array key or false if $priority === false and $function is an object reference, and it does not already have a unique id. 35 */ 36 public function build_unique_id( $function, $tag, $priority ) { 37 if ( is_string($function) ) 38 return $function; 39 40 if ( is_object($function) ) { 41 // Closures are currently implemented as objects 42 $function = array( $function, '' ); 43 } else { 44 $function = (array) $function; 45 } 46 47 if (is_object($function[0]) ) { 48 return call_user_func( $this->hasher, $function, $tag, $priority ); 49 } else if ( is_string($function[0]) ) { 50 // Static Calling 51 return $function[0] . '::' . $function[1]; 52 } 53 } 54 55 private function spl_hasher( $function ) { 56 return spl_object_hash($function[0]) . $function[1]; 57 } 58 59 private function nospl_hasher( $function, $tag, $priority ) { 60 static $filter_id_count = 0; 61 62 $obj_idx = get_class($function[0]).$function[1]; 63 if ( !isset($function[0]->wp_filter_id) ) { 64 if ( false === $priority ) 65 return false; 66 $obj_idx .= isset($this->hooks[$tag]->callbacks[$priority]) ? count((array)$this->hooks[$tag]->callbacks[$priority]) : $filter_id_count; 67 $function[0]->wp_filter_id = $filter_id_count; 68 ++$filter_id_count; 69 } else { 70 $obj_idx .= $function[0]->wp_filter_id; 71 } 72 73 return $obj_idx; 74 } 75 76 /** 77 * Whether a offset exists 78 * @link http://php.net/manual/en/arrayaccess.offsetexists.php 79 * 80 * @param mixed $offset An offset to check for. 81 * 82 * @return boolean true on success or false on failure. 83 */ 84 public function offsetExists( $offset ) { 85 return isset($this->hooks[$offset]); 86 } 87 88 /** 89 * Offset to retrieve 90 * 91 * @link http://php.net/manual/en/arrayaccess.offsetget.php 92 * 93 * @param mixed $offset The offset to retrieve. 94 * 95 * @return WP_Hook Can return all value types. 96 */ 97 public function offsetGet( $offset ) { 98 return isset($this->hooks[$offset]) ? $this->hooks[$offset] : null; 99 } 100 101 /** 102 * Offset to set 103 * 104 * @link http://php.net/manual/en/arrayaccess.offsetset.php 105 * 106 * @param mixed $offset The offset to assign the value to. 107 * @param WP_Hook $value The value to set. 108 * 109 * @return void 110 */ 111 public function offsetSet( $offset, $value ) { 112 if ( is_null($offset) ) { 113 $this->hooks[] = $value; 114 } else { 115 $this->hooks[$offset] = $value; 116 } 117 } 118 119 /** 120 * Offset to unset 121 * 122 * @link http://php.net/manual/en/arrayaccess.offsetunset.php 123 * 124 * @param mixed $offset The offset to unset. 125 * 126 * @return void 127 */ 128 public function offsetUnset( $offset ) { 129 unset($this->hooks[$offset]); 130 } 131 } 132 133 No newline at end of file -
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-filters.php' ); 24 require( ABSPATH . '/wp-includes/class-wp-hook.php' ); 25 require( ABSPATH . '/wp-includes/class-wp-hook-iterator.php' ); 26 global $wp_filter, $wp_actions, $wp_current_filter; 24 27 25 28 if ( ! isset( $wp_filter ) ) 26 $wp_filter = array();29 $wp_filter = new WP_Filters(); 27 30 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 … … 67 67 * @subpackage Plugin 68 68 * 69 69 * @global array $wp_filter A multidimensional array of all hooks and the callbacks hooked to them. 70 * @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.71 70 * 72 71 * @since 0.71 73 72 * … … 80 79 * @return boolean true 81 80 */ 82 81 function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { 83 global $wp_filter, $merged_filters; 82 global $wp_filter; 83 if ( !isset($wp_filter[$tag]) ) { 84 $wp_filter[$tag] = new WP_Hook(); 85 } 86 $wp_filter[$tag]->add_filter( $function_to_add, $priority, $accepted_args, $tag ); 84 87 85 $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);86 $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);87 unset( $merged_filters[ $tag ] );88 88 return true; 89 89 } 90 90 … … 106 106 function has_filter($tag, $function_to_check = false) { 107 107 global $wp_filter; 108 108 109 $has = !empty($wp_filter[$tag]);109 $has = isset($wp_filter[$tag]) && !empty($wp_filter[$tag]->callbacks); 110 110 if ( false === $function_to_check || false == $has ) 111 111 return $has; 112 112 113 113 if ( !$idx = _wp_filter_build_unique_id($tag, $function_to_check, false) ) 114 114 return false; 115 115 116 foreach ( (array) array_keys($wp_filter[$tag]) as $priority ) { 117 if ( isset($wp_filter[$tag][$priority][$idx]) ) 118 return $priority; 119 } 116 return $wp_filter[$tag]->has_filter($idx); 117 } 120 118 121 return false;122 }123 124 119 /** 125 120 * Call the functions added to a filter hook. 126 121 * … … 150 145 * @subpackage Plugin 151 146 * 152 147 * @global array $wp_filter Stores all of the filters 153 * @global array $merged_filters Merges the filter hooks using this function.154 148 * @global array $wp_current_filter stores the list of current filters with the current one last 155 149 * 156 150 * @since 0.71 … … 161 155 * @return mixed The filtered value after all hooked functions are applied to it. 162 156 */ 163 157 function apply_filters( $tag, $value ) { 164 global $wp_filter, $ merged_filters, $wp_current_filter;158 global $wp_filter, $wp_current_filter; 165 159 166 160 $args = array(); 167 161 … … 181 175 if ( !isset($wp_filter['all']) ) 182 176 $wp_current_filter[] = $tag; 183 177 184 // Sort185 if ( !isset( $merged_filters[ $tag ] ) ) {186 ksort($wp_filter[$tag]);187 $merged_filters[ $tag ] = true;188 }189 190 reset( $wp_filter[ $tag ] );191 192 178 if ( empty($args) ) 193 179 $args = func_get_args(); 194 180 195 do {196 foreach( (array) current($wp_filter[$tag]) as $the_ )197 if ( !is_null($the_['function']) ){198 $args[1] = $value;199 $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));200 }181 $iterator = $wp_filter[$tag]->get_iterator(); 182 foreach ( $iterator as $the_ ) { 183 $args[1] = $value; 184 $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args'])); 185 } 186 $iterator->cleanup(); 201 187 202 } while ( next($wp_filter[$tag]) !== false );203 204 188 array_pop( $wp_current_filter ); 205 189 206 190 return $value; … … 216 200 * @subpackage Plugin 217 201 * @since 3.0.0 218 202 * @global array $wp_filter Stores all of the filters 219 * @global array $merged_filters Merges the filter hooks using this function.220 203 * @global array $wp_current_filter stores the list of current filters with the current one last 221 204 * 222 205 * @param string $tag The name of the filter hook. … … 224 207 * @return mixed The filtered value after all hooked functions are applied to it. 225 208 */ 226 209 function apply_filters_ref_array($tag, $args) { 227 global $wp_filter, $ merged_filters, $wp_current_filter;210 global $wp_filter, $wp_current_filter; 228 211 229 212 // Do 'all' actions first 230 213 if ( isset($wp_filter['all']) ) { … … 242 225 if ( !isset($wp_filter['all']) ) 243 226 $wp_current_filter[] = $tag; 244 227 245 // Sort 246 if ( !isset( $merged_filters[ $tag ] ) ) { 247 ksort($wp_filter[$tag]); 248 $merged_filters[ $tag ] = true; 228 $iterator = $wp_filter[$tag]->get_iterator(); 229 foreach ( $iterator as $the_ ) { 230 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 249 231 } 232 $iterator->cleanup(); 250 233 251 reset( $wp_filter[ $tag ] );252 253 do {254 foreach( (array) current($wp_filter[$tag]) as $the_ )255 if ( !is_null($the_['function']) )256 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));257 258 } while ( next($wp_filter[$tag]) !== false );259 260 234 array_pop( $wp_current_filter ); 261 235 262 236 return $args[0]; … … 284 258 * @return boolean Whether the function existed before it was removed. 285 259 */ 286 260 function remove_filter( $tag, $function_to_remove, $priority = 10 ) { 287 $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority);261 global $wp_filter; 288 262 289 $r = isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); 290 291 if ( true === $r) { 292 unset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); 293 if ( empty($GLOBALS['wp_filter'][$tag][$priority]) ) 294 unset($GLOBALS['wp_filter'][$tag][$priority]); 295 unset($GLOBALS['merged_filters'][$tag]); 263 $r = false; 264 if ( isset($wp_filter[$tag]) ) { 265 $function_to_remove = $wp_filter->build_unique_id($function_to_remove, $tag, $priority); 266 $r = $wp_filter[$tag]->remove_filter($function_to_remove, $priority); 296 267 } 297 268 298 269 return $r; … … 308 279 * @return bool True when finished. 309 280 */ 310 281 function remove_all_filters($tag, $priority = false) { 311 global $wp_filter , $merged_filters;282 global $wp_filter; 312 283 313 284 if( isset($wp_filter[$tag]) ) { 314 if( false !== $priority && isset($wp_filter[$tag][$priority]) ) 315 unset($wp_filter[$tag][$priority]); 316 else 317 unset($wp_filter[$tag]); 285 $wp_filter[$tag]->remove_all_filters($priority); 318 286 } 319 287 320 if( isset($merged_filters[$tag]) )321 unset($merged_filters[$tag]);322 323 288 return true; 324 289 } 325 290 … … 384 349 * @return null Will return null if $tag does not exist in $wp_filter array 385 350 */ 386 351 function do_action($tag, $arg = '') { 387 global $wp_filter, $wp_actions, $ merged_filters, $wp_current_filter;352 global $wp_filter, $wp_actions, $wp_current_filter; 388 353 389 354 if ( ! isset($wp_actions[$tag]) ) 390 355 $wp_actions[$tag] = 1; … … 415 380 for ( $a = 2; $a < func_num_args(); $a++ ) 416 381 $args[] = func_get_arg($a); 417 382 418 // Sort 419 if ( !isset( $merged_filters[ $tag ] ) ) { 420 ksort($wp_filter[$tag]); 421 $merged_filters[ $tag ] = true; 383 $iterator = $wp_filter[$tag]->get_iterator(); 384 foreach ( $iterator as $the_ ) { 385 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 422 386 } 387 $iterator->cleanup(); 423 388 424 reset( $wp_filter[ $tag ] );425 426 do {427 foreach ( (array) current($wp_filter[$tag]) as $the_ )428 if ( !is_null($the_['function']) )429 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));430 431 } while ( next($wp_filter[$tag]) !== false );432 433 389 array_pop($wp_current_filter); 434 390 } 435 391 … … 470 426 * @return null Will return null if $tag does not exist in $wp_filter array 471 427 */ 472 428 function do_action_ref_array($tag, $args) { 473 global $wp_filter, $wp_actions, $ merged_filters, $wp_current_filter;429 global $wp_filter, $wp_actions, $wp_current_filter; 474 430 475 431 if ( ! isset($wp_actions[$tag]) ) 476 432 $wp_actions[$tag] = 1; … … 493 449 if ( !isset($wp_filter['all']) ) 494 450 $wp_current_filter[] = $tag; 495 451 496 // Sort 497 if ( !isset( $merged_filters[ $tag ] ) ) { 498 ksort($wp_filter[$tag]); 499 $merged_filters[ $tag ] = true; 452 $iterator = $wp_filter[$tag]->get_iterator(); 453 foreach ( $iterator as $the_ ) { 454 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 500 455 } 456 $iterator->cleanup(); 501 457 502 reset( $wp_filter[ $tag ] );503 504 do {505 foreach( (array) current($wp_filter[$tag]) as $the_ )506 if ( !is_null($the_['function']) )507 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));508 509 } while ( next($wp_filter[$tag]) !== false );510 511 458 array_pop($wp_current_filter); 512 459 } 513 460 … … 731 678 */ 732 679 function _wp_call_all_hook($args) { 733 680 global $wp_filter; 734 735 reset( $wp_filter['all'] ); 736 do { 737 foreach( (array) current($wp_filter['all']) as $the_ ) 738 if ( !is_null($the_['function']) ) 739 call_user_func_array($the_['function'], $args); 740 741 } while ( next($wp_filter['all']) !== false ); 742 } 681 $iterator = $wp_filter['all']->get_iterator(); 682 foreach ( $iterator as $the_ ) { 683 if ( !is_null($the_['function']) ) { 684 call_user_func_array($the_['function'], $args); 685 } 686 } 687 $iterator->cleanup(); 688 } 743 689 744 690 /** 745 691 * Build Unique ID for storage and retrieval. … … 772 718 */ 773 719 function _wp_filter_build_unique_id($tag, $function, $priority) { 774 720 global $wp_filter; 775 static $filter_id_count = 0; 776 777 if ( is_string($function) ) 778 return $function; 779 780 if ( is_object($function) ) { 781 // Closures are currently implemented as objects 782 $function = array( $function, '' ); 783 } else { 784 $function = (array) $function; 785 } 786 787 if (is_object($function[0]) ) { 788 // Object Class Calling 789 if ( function_exists('spl_object_hash') ) { 790 return spl_object_hash($function[0]) . $function[1]; 791 } else { 792 $obj_idx = get_class($function[0]).$function[1]; 793 if ( !isset($function[0]->wp_filter_id) ) { 794 if ( false === $priority ) 795 return false; 796 $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; 797 $function[0]->wp_filter_id = $filter_id_count; 798 ++$filter_id_count; 799 } else { 800 $obj_idx .= $function[0]->wp_filter_id; 801 } 802 803 return $obj_idx; 804 } 805 } else if ( is_string($function[0]) ) { 806 // Static Calling 807 return $function[0] . '::' . $function[1]; 808 } 721 return $wp_filter->build_unique_id($function, $tag, $priority); 809 722 } -
tests/phpunit/tests/actions.php
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8
256 256 function action_self_removal() { 257 257 remove_action( 'test_action_self_removal', array( $this, 'action_self_removal' ) ); 258 258 } 259 260 /** 261 * @ticket 17817 262 */ 263 function test_action_recursion() { 264 $tag = rand_str(); 265 $a = new MockAction(); 266 $b = new MockAction(); 267 268 add_action( $tag, array($a, 'action'), 11, 1 ); 269 add_action( $tag, array($b, 'action'), 13, 1 ); 270 add_action( $tag, array($this, 'action_that_causes_recursion'), 12, 1 ); 271 do_action( $tag, $tag ); 272 273 $this->assertEquals( 2, $a->get_call_count(), 'recursive actions should call all callbacks with earlier priority' ); 274 $this->assertEquals( 2, $b->get_call_count(), 'recursive actions should call callbacks with later priority' ); 275 } 276 277 function action_that_causes_recursion( $tag ) { 278 static $recursing = FALSE; 279 if ( !$recursing ) { 280 $recursing = TRUE; 281 do_action( $tag, $tag ); 282 } 283 $recursing = FALSE; 284 } 285 286 /** 287 * @ticket 9968 288 */ 289 function test_action_callback_manipulation_while_running() { 290 $tag = rand_str(); 291 $a = new MockAction(); 292 $b = new MockAction(); 293 $c = new MockAction(); 294 $d = new MockAction(); 295 $e = new MockAction(); 296 297 add_action( $tag, array($a, 'action'), 11, 2 ); 298 add_action( $tag, array($this, 'action_that_manipulates_a_running_hook'), 12, 2 ); 299 add_action( $tag, array($b, 'action'), 12, 2 ); 300 301 do_action( $tag, $tag, array($a,$b,$c,$d,$e) ); 302 do_action( $tag, $tag, array($a,$b,$c,$d,$e) ); 303 304 $this->assertEquals( 2, $a->get_call_count(), 'callbacks should run unless otherwise instructed' ); 305 $this->assertEquals( 1, $b->get_call_count(), 'callback removed by same priority callback should still get called' ); 306 $this->assertEquals( 1, $c->get_call_count(), 'callback added by same priority callback should not get called' ); 307 $this->assertEquals( 2, $d->get_call_count(), 'callback added by earlier priority callback should get called' ); 308 $this->assertEquals( 1, $e->get_call_count(), 'callback added by later priority callback should not get called' ); 309 } 310 311 function action_that_manipulates_a_running_hook( $tag, $mocks ) { 312 remove_action( $tag, array($mocks[1], 'action'), 12, 2 ); 313 add_action( $tag, array($mocks[2], 'action' ), 12, 2 ); 314 add_action( $tag, array($mocks[3], 'action' ), 13, 2 ); 315 add_action( $tag, array($mocks[4], 'action' ), 10, 2 ); 316 } 259 317 } -
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-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. -
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 $this->rewind(); 23 } 24 25 public function cleanup() { 26 $this->hook->detach($this); 27 } 28 29 /** 30 * Return the current element 31 * 32 * @link http://php.net/manual/en/iterator.current.php 33 * @return mixed Can return any type. 34 */ 35 public function current() { 36 return $this->current_callback; 37 } 38 39 /** 40 * Move forward to next element 41 * @link http://php.net/manual/en/iterator.next.php 42 * @return void Any returned value is ignored. 43 */ 44 public function next() { 45 $this->current_callback = NULL; 46 $this->current_callback_index = NULL; 47 $next = next( $this->callbacks_for_current_priority ); 48 49 if ( $next === FALSE ) { 50 do { 51 $this->increment_priority(); 52 } while ( empty($this->callbacks_for_current_priority) && isset( $this->current_priority) ); 53 54 $next = reset( $this->callbacks_for_current_priority ); 55 } 56 57 if ( !empty($next) ) { 58 $this->current_callback = $next; 59 $this->current_callback_index = key($this->callbacks_for_current_priority); 60 } 61 } 62 63 /** 64 * Setup the callbacks array for the next available priority 65 * @return void 66 */ 67 private function increment_priority() { 68 $this->set_current_priority(); 69 if ( isset($this->current_priority) ) { 70 $this->callbacks_for_current_priority = $this->get_callbacks($this->current_priority); 71 } else { 72 $this->callbacks_for_current_priority = array(); 73 } 74 } 75 76 /** 77 * Move to the next available priority 78 * @return void 79 */ 80 private function set_current_priority() { 81 if ( empty($this->hook->callbacks) ) { 82 $this->all_priorities = array(); 83 $this->current_priority = NULL; 84 return; 85 } 86 87 if ( !isset($this->all_priorities) ) { 88 $this->all_priorities = array_keys($this->hook->callbacks); 89 sort($this->all_priorities); 90 if ( isset($this->current_priority) ) { // callbacks were manipulated while we were running 91 foreach ( $this->all_priorities as $index => &$p ) { // go to the next larger priority 92 if ( $p > $this->current_priority ) { 93 $this->current_priority_index = $index; 94 $this->current_priority = $p; 95 break; 96 } 97 } 98 } else { // starting fresh 99 $this->current_priority_index = 0; 100 $this->current_priority = $this->all_priorities[0]; 101 } 102 return; 103 } 104 105 if ( !isset($this->current_priority_index) ) { 106 $this->current_priority_index = 0; 107 } else { 108 $this->current_priority_index++; 109 } 110 if ( isset($this->all_priorities[$this->current_priority_index]) ) { 111 $this->current_priority = $this->all_priorities[$this->current_priority_index]; 112 return; 113 } 114 115 $this->current_priority = NULL; 116 return; 117 } 118 119 private function get_callbacks( $priority ) { 120 if ( isset($this->hook->callbacks[$priority]) ) { 121 return $this->hook->callbacks[$priority]; 122 } 123 return array(); 124 } 125 126 /** 127 * Return the key of the current element 128 * @link http://php.net/manual/en/iterator.key.php 129 * @return mixed scalar on success, or null on failure. 130 */ 131 public function key() { 132 return $this->current_callback_index; 133 } 134 135 /** 136 * Checks if current position is valid 137 * @link http://php.net/manual/en/iterator.valid.php 138 * @return boolean The return value will be casted to boolean and then evaluated. 139 * Returns true on success or false on failure. 140 */ 141 public function valid() { 142 return isset($this->current_callback); 143 } 144 145 /** 146 * Rewind the Iterator to the first element 147 * @link http://php.net/manual/en/iterator.rewind.php 148 * @return void Any returned value is ignored. 149 */ 150 public function rewind() { 151 $this->current_priority = NULL; 152 $this->current_priority_index = NULL; 153 $this->current_callback = NULL; 154 $this->current_callback_index = NULL; 155 $this->callbacks_for_current_priority = array(); 156 $this->next(); 157 } 158 159 /** 160 * Receive update from subject 161 * 162 * @link http://php.net/manual/en/splobserver.update.php 163 * 164 * @param SplSubject $subject The SplSubject notifying the observer of an update. 165 * 166 * @return void 167 */ 168 public function update( $subject ) { 169 unset($this->all_priorities); 170 unset($this->current_priority_index); 171 } 172 }