Ticket #17817: 17817.7.diff
File 17817.7.diff, 51.5 KB (added by , 9 years ago) |
---|
-
src/wp-includes/class-wp-hook.php
1 <?php 2 /** 3 * Plugin API: WP_Hook class 4 * 5 * @package WordPress 6 * @subpackage Plugin 7 * @since 4.4.0 8 */ 9 10 /** 11 * Core class used to implement action and filter hook functionality. 12 * 13 * @since 4.4.0 14 * 15 * @see IteratorAggregate 16 * @see ArrayAccess 17 */ 18 final class WP_Hook implements IteratorAggregate, ArrayAccess { 19 20 /** 21 * Hook callbacks. 22 * 23 * @since 4.4.0 24 * @access public 25 * @var array 26 */ 27 public $callbacks = array(); 28 29 /** 30 * The priority keys of actively running iterations of a hook. 31 * 32 * @since 4.4.0 33 * @access private 34 * @var array 35 */ 36 private $iterations = array(); 37 38 /** 39 * Number of levels this hook can be recursively called. 40 * 41 * @since 4.4.0 42 * @access private 43 * @var int 44 */ 45 private $nesting_level = 0; 46 47 /** 48 * Hooks a function or method to a specific filter action. 49 * 50 * @since 4.4.0 51 * @access public 52 * 53 * @param callable $function_to_add The callback to be run when the filter is applied. 54 * @param string $tag The name of the filter to hook the $function_to_add callback to. 55 * @param int $priority Optional. The order in which the functions associated with a 56 * particular action are executed. Lower numbers correspond with 57 * earlier execution, and functions with the same priority are executed 58 * in the order in which they were added to the action. Default 10. 59 * @param int $accepted_args Optional. The number of arguments the function accepts. Default 1. 60 */ 61 public function add_filter( $function_to_add, $tag, $priority, $accepted_args ) { 62 $idx = _wp_filter_build_unique_id( $tag, $function_to_add, $priority ); 63 $priority_existed = isset( $this->callbacks[ $priority ] ); 64 65 $this->callbacks[ $priority ][ $idx ] = array( 66 'function' => $function_to_add, 67 'accepted_args' => $accepted_args 68 ); 69 70 // if we're adding a new priority to the list, put them back in sorted order 71 if ( ! $priority_existed && count( $this->callbacks ) > 1 ) { 72 ksort( $this->callbacks, SORT_NUMERIC ); 73 } 74 75 if ( $this->nesting_level > 0 ) { 76 $this->resort_active_iterations(); 77 } 78 } 79 80 /** 81 * Handles reseting callback priority keys mid-iteration. 82 * 83 * @since 4.4.0 84 * @access private 85 */ 86 private function resort_active_iterations() { 87 $new_priorities = array_keys( $this->callbacks ); 88 89 // If there are no remaining hooks, clear out all running iterations. 90 if ( ! $new_priorities ) { 91 foreach ( $this->iterations as $index => $iteration ) { 92 $this->iterations[ $index ] = $new_priorities; 93 } 94 return; 95 } 96 97 $min = min( $new_priorities ); 98 foreach ( $this->iterations as $index => $iteration ) { 99 $current = current( $iteration ); 100 $this->iterations[ $index ] = $new_priorities; 101 102 if ( $current < $min ) { 103 array_unshift( $this->iterations[ $index ], $current ); 104 continue; 105 } 106 107 while ( current( $this->iterations[ $index ] ) < $current ) { 108 if ( false === next( $this->iterations[ $index ] ) ) { 109 break; 110 }; 111 } 112 } 113 } 114 115 /** 116 * Unhooks a function or method from a specific filter action. 117 * 118 * @since 4.4.0 119 * @access public 120 * 121 * @param callable $function_to_remove The callback to be removed from running when the filter is applied. 122 * @param int $priority The exact priority used when adding the original filter callback. 123 * @param string $tag The filter hook to which the function to be removed is hooked. Used 124 * for building the callback ID when SPL is not available. 125 * @return bool Whether the callback existed before it was removed. 126 */ 127 public function remove_filter( $function_to_remove, $priority, $tag ) { 128 $function_key = _wp_filter_build_unique_id( $tag, $function_to_remove, $priority ); 129 130 $exists = isset( $this->callbacks[ $priority ][ $function_key ] ); 131 if ( $exists ) { 132 unset( $this->callbacks[ $priority ][ $function_key ] ); 133 if ( ! $this->callbacks[ $priority ] ) { 134 unset( $this->callbacks[ $priority ] ); 135 if ( $this->nesting_level > 0 ) { 136 $this->resort_active_iterations(); 137 } 138 } 139 } 140 return $exists; 141 } 142 143 /** 144 * Checks if a specific action has been registered for this hook. 145 * 146 * @since 4.4.0 147 * @access public 148 * 149 * @param callable|bool $function_to_check Optional. The callback to check for. Default false. 150 * @param string $tag Optional. The name of the filter hook. Default empty. 151 * Used for building the callback ID when SPL is not available. 152 * @return bool|int The priority of that hook is returned, or false if the function is not attached. 153 */ 154 public function has_filter( $function_to_check = false, $tag = '' ) { 155 if ( false === $function_to_check ) { 156 return $this->has_filters(); 157 } 158 159 $function_key = _wp_filter_build_unique_id( $tag, $function_to_check, false ); 160 if ( ! $function_key ) { 161 return false; 162 } 163 164 foreach ( $this->callbacks as $priority => $callbacks ) { 165 if ( isset( $callbacks[ $function_key ] ) ) { 166 return $priority; 167 } 168 } 169 170 return false; 171 } 172 173 /** 174 * Checks if any callbacks have been registered for this hook. 175 * 176 * @since 4.4.0 177 * @access public 178 * 179 * @return bool True if callbacks have been registered for the current hook, false otherwise. 180 */ 181 public function has_filters() { 182 foreach ( $this->callbacks as $callbacks ) { 183 if ( $callbacks ) { 184 return true; 185 } 186 } 187 return false; 188 } 189 190 /** 191 * Removes all callbacks from the current filter. 192 * 193 * @since 4.4.0 194 * @access public 195 * 196 * @param int|bool $priority Optional. The priority number to remove. Default false. 197 */ 198 public function remove_all_filters( $priority = false ) { 199 if ( ! $this->callbacks ) { 200 return; 201 } 202 203 if ( false === $priority ) { 204 $this->callbacks = array(); 205 } else if ( isset( $this->callbacks[ $priority ] ) ) { 206 unset( $this->callbacks[ $priority ] ); 207 } 208 209 if ( $this->nesting_level > 0 ) { 210 $this->resort_active_iterations(); 211 } 212 } 213 214 /** 215 * Calls the callback functions added to a filter hook. 216 * 217 * @since 4.4.0 218 * @access public 219 * 220 * @param mixed $value The value to filter. 221 * @param array $args Arguments to pass to callbacks. 222 * @return mixed The filtered value after all hooked functions are applied to it. 223 */ 224 public function apply_filters( $value, $args ) { 225 if ( ! $this->callbacks ) { 226 return $value; 227 } 228 $nesting_level = $this->nesting_level++; 229 230 $this->iterations[ $nesting_level ] = array_keys( $this->callbacks ); 231 $num_args = count( $args ); 232 233 do { 234 $priority = current( $this->iterations[ $nesting_level ] ); 235 236 foreach ( $this->callbacks[ $priority ] as $the_ ) { 237 $args[ 0 ] = $value; 238 239 // Avoid the array_slice if possible. 240 if ( $the_['accepted_args'] == 0 ) { 241 $value = call_user_func_array( $the_['function'], array() ); 242 } elseif ( $the_['accepted_args'] >= $num_args ) { 243 $value = call_user_func_array( $the_['function'], $args ); 244 } else { 245 $value = call_user_func_array( $the_['function'], array_slice( $args, 0, (int)$the_['accepted_args'] ) ); 246 } 247 } 248 } while ( false !== next( $this->iterations[ $nesting_level ] ) ); 249 250 unset( $this->iterations[ $nesting_level ] ); 251 252 $this->nesting_level--; 253 254 return $value; 255 } 256 257 /** 258 * Executes the callback functions hooked on a specific action hook. 259 * 260 * @since 4.4.0 261 * @access public 262 * 263 * @param mixed $args Arguments to pass to the hook callbacks. 264 */ 265 public function do_action( $args ) { 266 if ( ! $this->callbacks ) { 267 return; 268 } 269 $nesting_level = $this->nesting_level++; 270 $this->iterations[ $nesting_level ] = array_keys( $this->callbacks ); 271 $num_args = count( $args ); 272 273 do { 274 $priority = current( $this->iterations[ $nesting_level ] ); 275 276 foreach ( $this->callbacks[ $priority ] as $the_ ) { 277 278 // Avoid the array_slice if possible. 279 if ( $the_['accepted_args'] == 0 ) { 280 call_user_func_array( $the_['function'], array() ); 281 } elseif ( $the_['accepted_args'] >= $num_args ) { 282 call_user_func_array( $the_['function'], $args ); 283 } else { 284 call_user_func_array( $the_['function'], array_slice( $args, 0, (int)$the_['accepted_args'] ) ); 285 } 286 } 287 } while ( next( $this->iterations[ $nesting_level ] ) !== false ); 288 289 unset( $this->iterations[ $nesting_level ] ); 290 $this->nesting_level--; 291 } 292 293 /** 294 * Processes the functions hooked into the 'all' hook. 295 * 296 * @since 4.4.0 297 * @access public 298 * 299 * @param array $args Arguments to pass to the hook callbacks. Passed by reference. 300 */ 301 public function do_all_hook( &$args ) { 302 $nesting_level = $this->nesting_level++; 303 $this->iterations[ $nesting_level ] = array_keys( $this->callbacks ); 304 305 do { 306 $priority = current( $this->iterations[ $nesting_level ] ); 307 foreach ( $this->callbacks[ $priority ] as $the_ ) { 308 call_user_func_array( $the_['function'], $args ); 309 } 310 } while ( false !== next( $this->iterations[ $nesting_level ] ) ); 311 312 unset( $this->iterations[ $nesting_level ] ); 313 $this->nesting_level--; 314 } 315 316 /** 317 * Retrieves an external iterator. 318 * 319 * Provided for backwards compatibility with plugins that iterate over the 320 * $wp_filter global. 321 * 322 * @link http://php.net/manual/en/iteratoraggregate.getiterator.php 323 * 324 * @since 4.4.0 325 * @access public 326 * 327 * @return Traversable An instance of an object implementing Iterator or Traversable. 328 */ 329 public function getIterator() { 330 return new ArrayIterator( $this->callbacks ); 331 } 332 333 /** 334 * Normalizes filters setup before WordPress has initialized to WP_Hook objects. 335 * 336 * @since 4.4.0 337 * @access public 338 * @static 339 * 340 * @param array $filters Filters to normalize. 341 * @return array Array of normalized filters. 342 */ 343 public static function build_preinitialized_hooks( $filters ) { 344 /** @var WP_Hook[] $normalized */ 345 $normalized = array(); 346 347 foreach ( $filters as $tag => $callback_groups ) { 348 if ( is_object( $callback_groups ) && $callback_groups instanceof WP_Hook ) { 349 $normalized[ $tag ] = $callback_groups; 350 continue; 351 } 352 $hook = new WP_Hook(); 353 354 // Loop through callback groups. 355 foreach ( $callback_groups as $priority => $callbacks ) { 356 357 // Loop through callbacks. 358 foreach ( $callbacks as $cb ) { 359 $hook->add_filter( $cb['function'], $tag, $priority, $cb['accepted_args'] ); 360 } 361 } 362 $normalized[ $tag ] = $hook; 363 } 364 return $normalized; 365 } 366 367 /** 368 * Determines whether an offset value exists. 369 * 370 * @since 4.4.0 371 * @access public 372 * 373 * @link http://php.net/manual/en/arrayaccess.offsetexists.php 374 * 375 * @param mixed $offset An offset to check for. 376 * @return bool True if the offset exists, false otherwise. 377 */ 378 public function offsetExists( $offset ) { 379 return isset( $this->callbacks[ $offset ] ); 380 } 381 382 /** 383 * Retrieves a value at a specified offset. 384 * 385 * @since 4.4.0 386 * @access public 387 * 388 * @link http://php.net/manual/en/arrayaccess.offsetget.php 389 * 390 * @param mixed $offset The offset to retrieve. 391 * @return mixed If set, the value at the specified offset, null otherwise. 392 */ 393 public function offsetGet( $offset ) { 394 return isset( $this->callbacks[ $offset ] ) ? $this->callbacks[ $offset ] : null; 395 } 396 397 /** 398 * Sets a value at a specified offset. 399 * 400 * @since 4.4.0 401 * @access public 402 * 403 * @link http://php.net/manual/en/arrayaccess.offsetset.php 404 * 405 * @param mixed $offset The offset to assign the value to. 406 * @param mixed $value The value to set. 407 */ 408 public function offsetSet( $offset, $value ) { 409 if ( is_null( $offset ) ) { 410 $this->callbacks[] = $value; 411 } else { 412 $this->callbacks[ $offset ] = $value; 413 } 414 } 415 416 /** 417 * Unsets a specified offset. 418 * 419 * @since 4.4.0 420 * @access public 421 * 422 * @link http://php.net/manual/en/arrayaccess.offsetunset.php 423 * 424 * @param mixed $offset The offset to unset. 425 */ 426 public function offsetUnset( $offset ) { 427 unset( $this->callbacks[ $offset ] ); 428 } 429 } -
src/wp-includes/plugin.php
20 20 */ 21 21 22 22 // Initialize the filter globals. 23 global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;23 require( ABSPATH . WPINC . '/class-wp-hook.php' ); 24 24 25 if ( ! isset( $wp_filter ) ) 25 /** @var WP_Hook[] $wp_filter */ 26 global $wp_filter, $wp_actions, $wp_current_filter; 27 28 if ( $wp_filter ) { 29 $wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter ); 30 } else { 26 31 $wp_filter = array(); 32 } 27 33 28 34 if ( ! isset( $wp_actions ) ) 29 35 $wp_actions = array(); 30 36 31 if ( ! isset( $merged_filters ) )32 $merged_filters = array();33 34 37 if ( ! isset( $wp_current_filter ) ) 35 38 $wp_current_filter = array(); 36 39 … … 65 68 * @since 0.71 66 69 * 67 70 * @global array $wp_filter A multidimensional array of all hooks and the callbacks hooked to them. 68 * @global array $merged_filters Tracks the tags that need to be merged for later. If the hook is added,69 * it doesn't need to run through that process.70 71 * 71 72 * @param string $tag The name of the filter to hook the $function_to_add callback to. 72 73 * @param callback $function_to_add The callback to be run when the filter is applied. … … 79 80 * @return true 80 81 */ 81 82 function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { 82 global $wp_filter , $merged_filters;83 84 $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);85 $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);86 unset( $merged_filters[ $tag ]);83 global $wp_filter; 84 if ( ! isset( $wp_filter[ $tag ] ) ) { 85 $wp_filter[ $tag ] = new WP_Hook(); 86 } 87 $wp_filter[ $tag ]->add_filter( $function_to_add, $tag, $priority, $accepted_args ); 87 88 return true; 88 89 } 89 90 … … 104 105 * return value. 105 106 */ 106 107 function has_filter($tag, $function_to_check = false) { 107 // Don't reset the internal array pointer 108 $wp_filter = $GLOBALS['wp_filter']; 108 global $wp_filter; 109 109 110 $has = ! empty( $wp_filter[ $tag ] ); 111 112 // Make sure at least one priority has a filter callback 113 if ( $has ) { 114 $exists = false; 115 foreach ( $wp_filter[ $tag ] as $callbacks ) { 116 if ( ! empty( $callbacks ) ) { 117 $exists = true; 118 break; 119 } 120 } 121 122 if ( ! $exists ) { 123 $has = false; 124 } 125 } 126 127 if ( false === $function_to_check || false === $has ) 128 return $has; 129 130 if ( !$idx = _wp_filter_build_unique_id($tag, $function_to_check, false) ) 110 if ( ! isset( $wp_filter[ $tag ] ) ) { 131 111 return false; 132 133 foreach ( (array) array_keys($wp_filter[$tag]) as $priority ) {134 if ( isset($wp_filter[$tag][$priority][$idx]) )135 return $priority;136 112 } 137 113 138 return false;114 return $wp_filter[ $tag ]->has_filter( $function_to_check, $tag ); 139 115 } 140 116 141 117 /** … … 166 142 * @since 0.71 167 143 * 168 144 * @global array $wp_filter Stores all of the filters. 169 * @global array $merged_filters Merges the filter hooks using this function.170 145 * @global array $wp_current_filter Stores the list of current filters with the current one last. 171 146 * 172 147 * @param string $tag The name of the filter hook. … … 175 150 * @return mixed The filtered value after all hooked functions are applied to it. 176 151 */ 177 152 function apply_filters( $tag, $value ) { 178 global $wp_filter, $ merged_filters, $wp_current_filter;153 global $wp_filter, $wp_current_filter; 179 154 180 155 $args = array(); 181 156 … … 195 170 if ( !isset($wp_filter['all']) ) 196 171 $wp_current_filter[] = $tag; 197 172 198 // Sort.199 if ( !isset( $merged_filters[ $tag ] ) ) {200 ksort($wp_filter[$tag]);201 $merged_filters[ $tag ] = true;202 }203 204 reset( $wp_filter[ $tag ] );205 206 173 if ( empty($args) ) 207 174 $args = func_get_args(); 208 175 209 do { 210 foreach ( (array) current($wp_filter[$tag]) as $the_ ) 211 if ( !is_null($the_['function']) ){ 212 $args[1] = $value; 213 $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args'])); 214 } 176 // don't pass the tag name to WP_Hook 177 array_shift( $args ); 215 178 216 } while ( next($wp_filter[$tag]) !== false);179 $filtered = $wp_filter[ $tag ]->apply_filters( $value, $args ); 217 180 218 181 array_pop( $wp_current_filter ); 219 182 220 return $ value;183 return $filtered; 221 184 } 222 185 223 186 /** … … 229 192 * functions hooked to `$tag` are supplied using an array. 230 193 * 231 194 * @global array $wp_filter Stores all of the filters 232 * @global array $merged_filters Merges the filter hooks using this function.233 195 * @global array $wp_current_filter Stores the list of current filters with the current one last 234 196 * 235 197 * @param string $tag The name of the filter hook. … … 237 199 * @return mixed The filtered value after all hooked functions are applied to it. 238 200 */ 239 201 function apply_filters_ref_array($tag, $args) { 240 global $wp_filter, $ merged_filters, $wp_current_filter;202 global $wp_filter, $wp_current_filter; 241 203 242 204 // Do 'all' actions first 243 205 if ( isset($wp_filter['all']) ) { … … 255 217 if ( !isset($wp_filter['all']) ) 256 218 $wp_current_filter[] = $tag; 257 219 258 // Sort 259 if ( !isset( $merged_filters[ $tag ] ) ) { 260 ksort($wp_filter[$tag]); 261 $merged_filters[ $tag ] = true; 262 } 220 $filtered = $wp_filter[ $tag ]->apply_filters( $args[0], $args ); 263 221 264 reset( $wp_filter[ $tag ] );265 266 do {267 foreach ( (array) current($wp_filter[$tag]) as $the_ )268 if ( !is_null($the_['function']) )269 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));270 271 } while ( next($wp_filter[$tag]) !== false );272 273 222 array_pop( $wp_current_filter ); 274 223 275 return $ args[0];224 return $filtered; 276 225 } 277 226 278 227 /** … … 297 246 * @return bool Whether the function existed before it was removed. 298 247 */ 299 248 function remove_filter( $tag, $function_to_remove, $priority = 10 ) { 300 $function_to_remove = _wp_filter_build_unique_id( $tag, $function_to_remove, $priority );249 global $wp_filter; 301 250 302 $r = isset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); 303 304 if ( true === $r ) { 305 unset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); 306 if ( empty( $GLOBALS['wp_filter'][ $tag ][ $priority ] ) ) { 307 unset( $GLOBALS['wp_filter'][ $tag ][ $priority ] ); 251 $r = false; 252 if ( isset( $wp_filter[ $tag ] ) ) { 253 $r = $wp_filter[ $tag ]->remove_filter( $function_to_remove, $priority, $tag ); 254 if ( ! $wp_filter[ $tag ]->callbacks ) { 255 unset( $wp_filter[ $tag ] ); 308 256 } 309 if ( empty( $GLOBALS['wp_filter'][ $tag ] ) ) {310 $GLOBALS['wp_filter'][ $tag ] = array();311 }312 unset( $GLOBALS['merged_filters'][ $tag ] );313 257 } 314 258 315 259 return $r; … … 320 264 * 321 265 * @since 2.7.0 322 266 * 323 * @global array $wp_filter Stores all of the filters 324 * @global array $merged_filters Merges the filter hooks using this function. 267 * @global array $wp_filter Stores all of the filters 325 268 * 326 269 * @param string $tag The filter to remove hooks from. 327 270 * @param int|bool $priority Optional. The priority number to remove. Default false. … … 328 271 * @return true True when finished. 329 272 */ 330 273 function remove_all_filters( $tag, $priority = false ) { 331 global $wp_filter , $merged_filters;274 global $wp_filter; 332 275 333 276 if ( isset( $wp_filter[ $tag ]) ) { 334 if ( false === $priority ) { 335 $wp_filter[ $tag ] = array(); 336 } elseif ( isset( $wp_filter[ $tag ][ $priority ] ) ) { 337 $wp_filter[ $tag ][ $priority ] = array(); 277 $wp_filter[ $tag ]->remove_all_filters( $priority ); 278 if ( ! $wp_filter[ $tag ]->has_filters() ) { 279 unset( $wp_filter[ $tag ] ); 338 280 } 339 281 } 340 282 341 unset( $merged_filters[ $tag ] );342 343 283 return true; 344 284 } 345 285 … … 458 398 * functions hooked to the action. Default empty. 459 399 */ 460 400 function do_action($tag, $arg = '') { 461 global $wp_filter, $wp_actions, $ merged_filters, $wp_current_filter;401 global $wp_filter, $wp_actions, $wp_current_filter; 462 402 463 403 if ( ! isset($wp_actions[$tag]) ) 464 404 $wp_actions[$tag] = 1; … … 489 429 for ( $a = 2, $num = func_num_args(); $a < $num; $a++ ) 490 430 $args[] = func_get_arg($a); 491 431 492 // Sort 493 if ( !isset( $merged_filters[ $tag ] ) ) { 494 ksort($wp_filter[$tag]); 495 $merged_filters[ $tag ] = true; 496 } 432 $wp_filter[ $tag ]->do_action( $args ); 497 433 498 reset( $wp_filter[ $tag ] );499 500 do {501 foreach ( (array) current($wp_filter[$tag]) as $the_ )502 if ( !is_null($the_['function']) )503 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));504 505 } while ( next($wp_filter[$tag]) !== false );506 507 434 array_pop($wp_current_filter); 508 435 } 509 436 … … 542 469 * @param array $args The arguments supplied to the functions hooked to `$tag`. 543 470 */ 544 471 function do_action_ref_array($tag, $args) { 545 global $wp_filter, $wp_actions, $ merged_filters, $wp_current_filter;472 global $wp_filter, $wp_actions, $wp_current_filter; 546 473 547 474 if ( ! isset($wp_actions[$tag]) ) 548 475 $wp_actions[$tag] = 1; … … 565 492 if ( !isset($wp_filter['all']) ) 566 493 $wp_current_filter[] = $tag; 567 494 568 // Sort 569 if ( !isset( $merged_filters[ $tag ] ) ) { 570 ksort($wp_filter[$tag]); 571 $merged_filters[ $tag ] = true; 572 } 495 $wp_filter[ $tag ]->do_action( $args ); 573 496 574 reset( $wp_filter[ $tag ] );575 576 do {577 foreach ( (array) current($wp_filter[$tag]) as $the_ )578 if ( !is_null($the_['function']) )579 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));580 581 } while ( next($wp_filter[$tag]) !== false );582 583 497 array_pop($wp_current_filter); 584 498 } 585 499 … … 843 757 function _wp_call_all_hook($args) { 844 758 global $wp_filter; 845 759 846 reset( $wp_filter['all'] ); 847 do { 848 foreach ( (array) current($wp_filter['all']) as $the_ ) 849 if ( !is_null($the_['function']) ) 850 call_user_func_array($the_['function'], $args); 851 852 } while ( next($wp_filter['all']) !== false ); 760 $wp_filter['all']->do_all_hook( $args ); 853 761 } 854 762 855 763 /** -
tests/phpunit/includes/functions.php
2 2 3 3 // For adding hooks before loading WP 4 4 function tests_add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { 5 global $wp_filter , $merged_filters;5 global $wp_filter; 6 6 7 7 $idx = _test_filter_build_unique_id($tag, $function_to_add, $priority); 8 8 $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); 9 unset( $merged_filters[ $tag ] );10 9 return true; 11 10 } 12 11 13 12 function _test_filter_build_unique_id($tag, $function, $priority) { 14 global $wp_filter;15 static $filter_id_count = 0;16 17 13 if ( is_string($function) ) 18 14 return $function; 19 15 -
tests/phpunit/includes/testcase.php
142 142 * @return void 143 143 */ 144 144 protected function _backup_hooks() { 145 $globals = array( ' merged_filters', 'wp_actions', 'wp_current_filter', 'wp_filter' );145 $globals = array( 'wp_actions', 'wp_current_filter' ); 146 146 foreach ( $globals as $key ) { 147 147 self::$hooks_saved[ $key ] = $GLOBALS[ $key ]; 148 148 } 149 self::$hooks_saved['wp_filter'] = array(); 150 foreach ( $GLOBALS['wp_filter'] as $hook_name => $hook_object ) { 151 self::$hooks_saved['wp_filter'][ $hook_name ] = clone $hook_object; 152 } 149 153 } 150 154 151 155 /** … … 159 163 * @return void 160 164 */ 161 165 protected function _restore_hooks() { 162 $globals = array( ' merged_filters', 'wp_actions', 'wp_current_filter', 'wp_filter' );166 $globals = array( 'wp_actions', 'wp_current_filter' ); 163 167 foreach ( $globals as $key ) { 164 168 if ( isset( self::$hooks_saved[ $key ] ) ) { 165 169 $GLOBALS[ $key ] = self::$hooks_saved[ $key ]; 166 170 } 167 171 } 172 if ( isset( self::$hooks_saved['wp_filter'] ) ) { 173 $GLOBALS['wp_filter'] = array(); 174 foreach ( self::$hooks_saved['wp_filter'] as $hook_name => $hook_object ) { 175 $GLOBALS['wp_filter'][ $hook_name ] = clone $hook_object; 176 } 177 } 168 178 } 169 179 170 180 function flush_cache() { -
tests/phpunit/tests/actions.php
114 114 $this->assertEquals( array( $val1 ), array_pop( $argsvar2 ) ); 115 115 } 116 116 117 /** 118 * Test that multiple callbacks receive the correct number of args even when the number 119 * is less than, or greater than previous hooks. 120 * 121 * @see https://core.trac.wordpress.org/ticket/17817#comment:72 122 * @ticket 17817 123 */ 124 function test_action_args_3() { 125 $a1 = new MockAction(); 126 $a2 = new MockAction(); 127 $a3 = new MockAction(); 128 $tag = rand_str(); 129 $val1 = rand_str(); 130 $val2 = rand_str(); 131 132 // a1 accepts two arguments, a2 doesn't, a3 accepts two arguments 133 add_action( $tag, array( &$a1, 'action' ), 10, 2 ); 134 add_action( $tag, array( &$a2, 'action' ) ); 135 add_action( $tag, array( &$a3, 'action' ), 10, 2 ); 136 // call the action with two arguments 137 do_action( $tag, $val1, $val2 ); 138 139 $call_count = $a1->get_call_count(); 140 // a1 should be called with both args 141 $this->assertEquals( 1, $call_count ); 142 $argsvar1 = $a1->get_args(); 143 $this->assertEquals( array( $val1, $val2 ), array_pop( $argsvar1 ) ); 144 145 // a2 should be called with one only 146 $this->assertEquals( 1, $a2->get_call_count() ); 147 $argsvar2 = $a2->get_args(); 148 $this->assertEquals( array( $val1 ), array_pop( $argsvar2 ) ); 149 150 // a3 should be called with both args 151 $this->assertEquals( 1, $a3->get_call_count() ); 152 $argsvar3 = $a3->get_args(); 153 $this->assertEquals( array( $val1, $val2 ), array_pop( $argsvar3 ) ); 154 } 155 117 156 function test_action_priority() { 118 157 $a = new MockAction(); 119 158 $tag = rand_str(); … … 258 297 } 259 298 260 299 /** 300 * @ticket 17817 301 */ 302 function test_action_recursion() { 303 $tag = rand_str(); 304 $a = new MockAction(); 305 $b = new MockAction(); 306 307 add_action( $tag, array( $a, 'action' ), 11, 1 ); 308 add_action( $tag, array( $b, 'action' ), 13, 1 ); 309 add_action( $tag, array( $this, 'action_that_causes_recursion' ), 12, 1 ); 310 do_action( $tag, $tag ); 311 312 $this->assertEquals( 2, $a->get_call_count(), 'recursive actions should call all callbacks with earlier priority' ); 313 $this->assertEquals( 2, $b->get_call_count(), 'recursive actions should call callbacks with later priority' ); 314 } 315 316 function action_that_causes_recursion( $tag ) { 317 static $recursing = false; 318 if ( ! $recursing ) { 319 $recursing = true; 320 do_action( $tag, $tag ); 321 } 322 $recursing = false; 323 } 324 325 /** 326 * @ticket 9968 327 * @ticket 17817 328 */ 329 function test_action_callback_manipulation_while_running() { 330 $tag = rand_str(); 331 $a = new MockAction(); 332 $b = new MockAction(); 333 $c = new MockAction(); 334 $d = new MockAction(); 335 $e = new MockAction(); 336 337 add_action( $tag, array( $a, 'action' ), 11, 2 ); 338 add_action( $tag, array( $this, 'action_that_manipulates_a_running_hook' ), 12, 2 ); 339 add_action( $tag, array( $b, 'action' ), 12, 2 ); 340 341 do_action( $tag, $tag, array( $a, $b, $c, $d, $e ) ); 342 do_action( $tag, $tag, array( $a, $b, $c, $d, $e ) ); 343 344 $this->assertEquals( 2, $a->get_call_count(), 'callbacks should run unless otherwise instructed' ); 345 $this->assertEquals( 1, $b->get_call_count(), 'callback removed by same priority callback should still get called' ); 346 $this->assertEquals( 1, $c->get_call_count(), 'callback added by same priority callback should not get called' ); 347 $this->assertEquals( 2, $d->get_call_count(), 'callback added by earlier priority callback should get called' ); 348 $this->assertEquals( 1, $e->get_call_count(), 'callback added by later priority callback should not get called' ); 349 } 350 351 function action_that_manipulates_a_running_hook( $tag, $mocks ) { 352 remove_action( $tag, array( $mocks[ 1 ], 'action' ), 12, 2 ); 353 add_action( $tag, array( $mocks[ 2 ], 'action' ), 12, 2 ); 354 add_action( $tag, array( $mocks[ 3 ], 'action' ), 13, 2 ); 355 add_action( $tag, array( $mocks[ 4 ], 'action' ), 10, 2 ); 356 } 357 358 /** 359 * @ticket 17817 360 * 361 * This specificaly addresses the concern raised at 362 * https://core.trac.wordpress.org/ticket/17817#comment:52 363 */ 364 function test_remove_anonymous_callback() { 365 $tag = rand_str(); 366 $a = new MockAction(); 367 add_action( $tag, array( $a, 'action' ), 12, 1 ); 368 $this->assertTrue( has_action( $tag ) ); 369 370 $hook = $GLOBALS['wp_filter'][ $tag ]; 371 372 // From http://wordpress.stackexchange.com/a/57088/6445 373 foreach ( $hook as $priority => $filter ) { 374 foreach ( $filter as $identifier => $function ) { 375 if ( is_array( $function ) 376 && is_a( $function['function'][ 0 ], 'MockAction' ) 377 && 'action' === $function['function'][ 1 ] 378 ) { 379 remove_filter( 380 $tag, 381 array( $function['function'][ 0 ], 'action' ), 382 $priority 383 ); 384 } 385 } 386 } 387 388 $this->assertFalse( has_action( $tag ) ); 389 } 390 391 392 /** 393 * Test the ArrayAccess methods of WP_Hook 394 * 395 * @ticket 17817 396 */ 397 function test_array_access_of_wp_filter_global() { 398 global $wp_filter; 399 $tag = rand_str(); 400 401 add_action( $tag, '__return_null', 11, 1 ); 402 403 $this->assertTrue( isset( $wp_filter[ $tag ][ 11 ] ) ); 404 $this->assertArrayHasKey( '__return_null', $wp_filter[ $tag ][ 11 ] ); 405 406 unset( $wp_filter[ $tag ][ 11 ] ); 407 $this->assertFalse( has_action( $tag, '__return_null' ) ); 408 409 $wp_filter[ $tag ][ 11 ] = array( '__return_null' => array( 'function' => '__return_null', 'accepted_args' => 1 ) ); 410 $this->assertEquals( 11, has_action( $tag, '__return_null' ) ); 411 } 412 413 /** 261 414 * Make sure current_action() behaves as current_filter() 262 415 * 263 416 * @ticket 14994 -
tests/phpunit/tests/filters.php
294 294 remove_all_filters( $tag, 12 ); 295 295 $this->assertFalse( has_filter( $tag ) ); 296 296 } 297 298 /**299 * @ticket 29070300 */301 function test_has_filter_doesnt_reset_wp_filter() {302 add_action( 'action_test_has_filter_doesnt_reset_wp_filter', '__return_null', 1 );303 add_action( 'action_test_has_filter_doesnt_reset_wp_filter', '__return_null', 2 );304 add_action( 'action_test_has_filter_doesnt_reset_wp_filter', '__return_null', 3 );305 add_action( 'action_test_has_filter_doesnt_reset_wp_filter', array( $this, '_action_test_has_filter_doesnt_reset_wp_filter' ), 4 );306 307 do_action( 'action_test_has_filter_doesnt_reset_wp_filter' );308 }309 function _action_test_has_filter_doesnt_reset_wp_filter() {310 global $wp_filter;311 312 has_action( 'action_test_has_filter_doesnt_reset_wp_filter', '_function_that_doesnt_exist' );313 314 $filters = current( $wp_filter['action_test_has_filter_doesnt_reset_wp_filter'] );315 $the_ = current( $filters );316 $this->assertEquals( $the_['function'], array( $this, '_action_test_has_filter_doesnt_reset_wp_filter' ) );317 }318 297 } -
tests/phpunit/tests/hooks/add_filter.php
1 <?php 2 3 4 /** 5 * Test the add_filter method of WP_Hook 6 * 7 * @group hooks 8 */ 9 class Tests_WP_Hook_Add_Filter extends WP_UnitTestCase { 10 11 public function test_add_filter_with_function() { 12 $callback = '__return_null'; 13 $hook = new WP_Hook(); 14 $tag = rand_str(); 15 $priority = rand( 1, 100 ); 16 $accepted_args = rand( 1, 100 ); 17 18 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 19 20 $function_index = _wp_filter_build_unique_id( $tag, $callback, $priority ); 21 $this->assertEquals( $callback, $hook->callbacks[ $priority ][ $function_index ]['function'] ); 22 $this->assertEquals( $accepted_args, $hook->callbacks[ $priority ][ $function_index ]['accepted_args'] ); 23 } 24 25 public function test_add_filter_with_object() { 26 $a = new MockAction(); 27 $callback = array( $a, 'action' ); 28 $hook = new WP_Hook(); 29 $tag = rand_str(); 30 $priority = rand( 1, 100 ); 31 $accepted_args = rand( 1, 100 ); 32 33 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 34 35 $function_index = _wp_filter_build_unique_id( $tag, $callback, $priority ); 36 $this->assertEquals( $callback, $hook->callbacks[ $priority ][ $function_index ]['function'] ); 37 $this->assertEquals( $accepted_args, $hook->callbacks[ $priority ][ $function_index ]['accepted_args'] ); 38 } 39 40 public function test_add_filter_with_static_method() { 41 $callback = array( 'MockAction', 'action' ); 42 $hook = new WP_Hook(); 43 $tag = rand_str(); 44 $priority = rand( 1, 100 ); 45 $accepted_args = rand( 1, 100 ); 46 47 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 48 49 $function_index = _wp_filter_build_unique_id( $tag, $callback, $priority ); 50 $this->assertEquals( $callback, $hook->callbacks[ $priority ][ $function_index ]['function'] ); 51 $this->assertEquals( $accepted_args, $hook->callbacks[ $priority ][ $function_index ]['accepted_args'] ); 52 } 53 54 public function test_add_two_filters_with_same_priority() { 55 $callback_one = '__return_null'; 56 $callback_two = '__return_false'; 57 $hook = new WP_Hook(); 58 $tag = rand_str(); 59 $priority = rand( 1, 100 ); 60 $accepted_args = rand( 1, 100 ); 61 62 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 63 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 64 65 $hook->add_filter( $callback_two, $tag, $priority, $accepted_args ); 66 $this->assertCount( 2, $hook->callbacks[ $priority ] ); 67 } 68 69 public function test_add_two_filters_with_different_priority() { 70 $callback_one = '__return_null'; 71 $callback_two = '__return_false'; 72 $hook = new WP_Hook(); 73 $tag = rand_str(); 74 $priority = rand( 1, 100 ); 75 $accepted_args = rand( 1, 100 ); 76 77 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 78 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 79 80 $hook->add_filter( $callback_two, $tag, $priority + 1, $accepted_args ); 81 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 82 $this->assertCount( 1, $hook->callbacks[ $priority + 1 ] ); 83 } 84 85 public function test_readd_filter() { 86 $callback = '__return_null'; 87 $hook = new WP_Hook(); 88 $tag = rand_str(); 89 $priority = rand( 1, 100 ); 90 $accepted_args = rand( 1, 100 ); 91 92 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 93 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 94 95 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 96 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 97 } 98 99 public function test_readd_filter_with_different_priority() { 100 $callback = '__return_null'; 101 $hook = new WP_Hook(); 102 $tag = rand_str(); 103 $priority = rand( 1, 100 ); 104 $accepted_args = rand( 1, 100 ); 105 106 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 107 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 108 109 $hook->add_filter( $callback, $tag, $priority + 1, $accepted_args ); 110 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 111 $this->assertCount( 1, $hook->callbacks[ $priority + 1 ] ); 112 } 113 114 public function test_sort_after_add_filter() { 115 $a = new MockAction(); 116 $b = new MockAction(); 117 $c = new MockAction(); 118 $hook = new WP_Hook(); 119 $tag = rand_str(); 120 121 $hook->add_filter( array( $a, 'action' ), $tag, 10, 1 ); 122 $hook->add_filter( array( $b, 'action' ), $tag, 5, 1 ); 123 $hook->add_filter( array( $c, 'action' ), $tag, 8, 1 ); 124 125 $this->assertEquals( array( 5, 8, 10 ), array_keys( $hook->callbacks ) ); 126 } 127 } -
tests/phpunit/tests/hooks/apply_filters.php
1 <?php 2 3 /** 4 * Test the apply_filters method of WP_Hook 5 * 6 * @group hooks 7 */ 8 class Tests_WP_Hook_Apply_Filters extends WP_UnitTestCase { 9 10 public function test_apply_filters_with_callback() { 11 $a = new MockAction(); 12 $callback = array( $a, 'filter' ); 13 $hook = new WP_Hook(); 14 $tag = rand_str(); 15 $priority = rand( 1, 100 ); 16 $accepted_args = rand( 1, 100 ); 17 $arg = rand_str(); 18 19 $hook->add_filter( $callback, $priority, $accepted_args, $tag ); 20 21 $returned = $hook->apply_filters( $arg, array( $arg ) ); 22 23 $this->assertEquals( $returned, $arg ); 24 $this->assertEquals( 1, $a->get_call_count() ); 25 } 26 27 public function test_apply_filters_with_multiple_calls() { 28 $a = new MockAction(); 29 $callback = array( $a, 'filter' ); 30 $hook = new WP_Hook(); 31 $tag = rand_str(); 32 $priority = rand( 1, 100 ); 33 $accepted_args = rand( 1, 100 ); 34 $arg = rand_str(); 35 36 $hook->add_filter( $callback, $priority, $accepted_args, $tag ); 37 38 $returned_one = $hook->apply_filters( $arg, array( $arg ) ); 39 $returned_two = $hook->apply_filters( $returned_one, array( $returned_one ) ); 40 41 $this->assertEquals( $returned_two, $arg ); 42 $this->assertEquals( 2, $a->get_call_count() ); 43 } 44 45 } -
tests/phpunit/tests/hooks/do_action.php
1 <?php 2 3 /** 4 * Test the do_action method of WP_Hook 5 * 6 * @group hooks 7 */ 8 class Tests_WP_Hook_Do_Action extends WP_UnitTestCase { 9 private $events = array(); 10 11 public function setUp() { 12 parent::setUp(); 13 $this->events = array(); 14 } 15 16 public function test_do_action_with_callback() { 17 $a = new MockAction(); 18 $callback = array( $a, 'action' ); 19 $hook = new WP_Hook(); 20 $tag = rand_str(); 21 $priority = rand( 1, 100 ); 22 $accepted_args = rand( 1, 100 ); 23 $arg = rand_str(); 24 25 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 26 $hook->do_action( array( $arg ) ); 27 28 $this->assertEquals( 1, $a->get_call_count() ); 29 } 30 31 public function test_do_action_with_multiple_calls() { 32 $a = new MockAction(); 33 $callback = array( $a, 'filter' ); 34 $hook = new WP_Hook(); 35 $tag = rand_str(); 36 $priority = rand( 1, 100 ); 37 $accepted_args = rand( 1, 100 ); 38 $arg = rand_str(); 39 40 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 41 $hook->do_action( array( $arg ) ); 42 $hook->do_action( array( $arg ) ); 43 44 $this->assertEquals( 2, $a->get_call_count() ); 45 } 46 47 public function test_do_action_with_multiple_callbacks_on_same_priority() { 48 $a = new MockAction(); 49 $b = new MockAction(); 50 $callback_one = array( $a, 'filter' ); 51 $callback_two = array( $b, 'filter' ); 52 $hook = new WP_Hook(); 53 $tag = rand_str(); 54 $priority = rand( 1, 100 ); 55 $accepted_args = rand( 1, 100 ); 56 $arg = rand_str(); 57 58 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 59 $hook->add_filter( $callback_two, $tag, $priority, $accepted_args ); 60 $hook->do_action( array( $arg ) ); 61 62 $this->assertEquals( 1, $a->get_call_count() ); 63 $this->assertEquals( 1, $a->get_call_count() ); 64 } 65 66 public function test_do_action_with_multiple_callbacks_on_different_priorities() { 67 $a = new MockAction(); 68 $b = new MockAction(); 69 $callback_one = array( $a, 'filter' ); 70 $callback_two = array( $b, 'filter' ); 71 $hook = new WP_Hook(); 72 $tag = rand_str(); 73 $priority = rand( 1, 100 ); 74 $accepted_args = rand( 1, 100 ); 75 $arg = rand_str(); 76 77 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 78 $hook->add_filter( $callback_two, $tag, $priority, $accepted_args ); 79 $hook->do_action( array( $arg ) ); 80 81 $this->assertEquals( 1, $a->get_call_count() ); 82 $this->assertEquals( 1, $a->get_call_count() ); 83 } 84 85 public function test_do_action_with_no_accepted_args() { 86 $callback = array( $this, '_action_callback' ); 87 $hook = new WP_Hook(); 88 $tag = rand_str(); 89 $priority = rand( 1, 100 ); 90 $accepted_args = 0; 91 $arg = rand_str(); 92 93 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 94 $hook->do_action( array( $arg ) ); 95 96 $this->assertEmpty( $this->events[0]['args'] ); 97 } 98 99 public function test_do_action_with_one_accepted_arg() { 100 $callback = array( $this, '_action_callback' ); 101 $hook = new WP_Hook(); 102 $tag = rand_str(); 103 $priority = rand( 1, 100 ); 104 $accepted_args = 1; 105 $arg = rand_str(); 106 107 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 108 $hook->do_action( array( $arg ) ); 109 110 $this->assertCount( 1, $this->events[0]['args'] ); 111 } 112 113 public function test_do_action_with_more_accepted_args() { 114 $callback = array( $this, '_action_callback' ); 115 $hook = new WP_Hook(); 116 $tag = rand_str(); 117 $priority = rand( 1, 100 ); 118 $accepted_args = 1000; 119 $arg = rand_str(); 120 121 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 122 $hook->do_action( array( $arg ) ); 123 124 $this->assertCount( 1, $this->events[0]['args'] ); 125 } 126 127 /** 128 * Use this rather than MockAction so we can test callbacks with no args 129 */ 130 public function _action_callback() { 131 $args = func_get_args(); 132 $this->events[] = array('action' => __FUNCTION__, 'args'=>$args); 133 } 134 } -
tests/phpunit/tests/hooks/getIterator.php
1 <?php 2 3 /** 4 * Test the IteratorAggregate implementation of WP_Hook 5 * 6 * @group hooks 7 */ 8 class Tests_WP_Hook_Get_Iterator extends WP_UnitTestCase { 9 10 public function test_getIterator() { 11 $callback_one = '__return_null'; 12 $callback_two = '__return_false'; 13 $hook = new WP_Hook(); 14 $tag = rand_str(); 15 $priority = rand( 1, 100 ); 16 $accepted_args = rand( 1, 100 ); 17 18 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 19 $hook->add_filter( $callback_two, $tag, $priority + 1, $accepted_args ); 20 21 $callbacks = $hook->getIterator(); 22 23 $this->assertCount( 2, $callbacks ); 24 $this->assertTrue( isset( $callbacks[ $priority ] ) ); 25 $this->assertTrue( isset( $callbacks[ $priority + 1 ] ) ); 26 27 28 $callback_one_index = _wp_filter_build_unique_id( $tag, $callback_one, $priority ); 29 $callback_two_index = _wp_filter_build_unique_id( $tag, $callback_two, $priority + 1 ); 30 31 $this->assertEquals( $callback_one, $callbacks[ $priority ][ $callback_one_index ][ 'function' ] ); 32 $this->assertEquals( $callback_two, $callbacks[ $priority + 1 ][ $callback_two_index ][ 'function' ] ); 33 } 34 35 36 public function test_foreach() { 37 $callback_one = '__return_null'; 38 $callback_two = '__return_false'; 39 $hook = new WP_Hook(); 40 $tag = rand_str(); 41 $priority = rand( 1, 100 ); 42 $accepted_args = rand( 1, 100 ); 43 44 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 45 $hook->add_filter( $callback_two, $tag, $priority + 1, $accepted_args ); 46 47 $functions = array(); 48 $priorities = array(); 49 foreach ( $hook as $key => $callbacks ) { 50 $priorities[] = $key; 51 foreach ( $callbacks as $function_index => $the_ ) { 52 $functions[] = $the_['function']; 53 } 54 } 55 $this->assertEqualSets( array( $priority, $priority + 1 ), $priorities ); 56 $this->assertEqualSets( array( $callback_one, $callback_two ), $functions ); 57 } 58 } -
tests/phpunit/tests/hooks/has_filter.php
1 <?php 2 3 /** 4 * Test the has_filter method of WP_Hook 5 * 6 * @group hooks 7 */ 8 class Tests_WP_Hook_Has_Filter extends WP_UnitTestCase { 9 10 public function test_has_filter_with_function() { 11 $callback = '__return_null'; 12 $hook = new WP_Hook(); 13 $tag = rand_str(); 14 $priority = rand( 1, 100 ); 15 $accepted_args = rand( 1, 100 ); 16 17 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 18 19 $this->assertEquals( $priority, $hook->has_filter( $callback, $tag ) ); 20 } 21 22 public function test_has_filter_with_object() { 23 $a = new MockAction(); 24 $callback = array( $a, 'action' ); 25 $hook = new WP_Hook(); 26 $tag = rand_str(); 27 $priority = rand( 1, 100 ); 28 $accepted_args = rand( 1, 100 ); 29 30 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 31 32 $this->assertEquals( $priority, $hook->has_filter( $callback, $tag ) ); 33 } 34 35 public function test_has_filter_with_static_method() { 36 $callback = array( 'MockAction', 'action' ); 37 $hook = new WP_Hook(); 38 $tag = rand_str(); 39 $priority = rand( 1, 100 ); 40 $accepted_args = rand( 1, 100 ); 41 42 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 43 44 $this->assertEquals( $priority, $hook->has_filter( $callback, $tag ) ); 45 } 46 47 public function test_has_filter_without_callback() { 48 $callback = '__return_null'; 49 $hook = new WP_Hook(); 50 $tag = rand_str(); 51 $priority = rand( 1, 100 ); 52 $accepted_args = rand( 1, 100 ); 53 54 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 55 56 $this->assertTrue( $hook->has_filter() ); 57 } 58 59 public function test_not_has_filter_without_callback() { 60 $hook = new WP_Hook(); 61 $this->assertFalse( $hook->has_filter() ); 62 } 63 64 public function test_not_has_filter_with_callback() { 65 $callback = '__return_null'; 66 $hook = new WP_Hook(); 67 $tag = rand_str(); 68 69 $this->assertFalse( $hook->has_filter( $callback, $tag ) ); 70 } 71 72 public function test_has_filter_with_wrong_callback() { 73 $callback = '__return_null'; 74 $hook = new WP_Hook(); 75 $tag = rand_str(); 76 $priority = rand( 1, 100 ); 77 $accepted_args = rand( 1, 100 ); 78 79 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 80 81 $this->assertFalse( $hook->has_filter( '__return_false', $tag ) ); 82 } 83 } -
tests/phpunit/tests/hooks/has_filters.php
1 <?php 2 3 /** 4 * Test the has_filters method of WP_Hook 5 * 6 * @group hooks 7 */ 8 class Tests_WP_Hook_Has_Filters extends WP_UnitTestCase { 9 10 public function test_has_filters_with_callback() { 11 $callback = '__return_null'; 12 $hook = new WP_Hook(); 13 $tag = rand_str(); 14 $priority = rand( 1, 100 ); 15 $accepted_args = rand( 1, 100 ); 16 17 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 18 19 $this->assertTrue( $hook->has_filters() ); 20 } 21 22 public function test_has_filters_without_callback() { 23 $hook = new WP_Hook(); 24 $this->assertFalse( $hook->has_filters() ); 25 } 26 27 public function test_not_has_filters_with_removed_callback() { 28 $callback = '__return_null'; 29 $hook = new WP_Hook(); 30 $tag = rand_str(); 31 $priority = rand( 1, 100 ); 32 $accepted_args = rand( 1, 100 ); 33 34 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 35 $hook->remove_filter( $callback, $priority, $tag ); 36 $this->assertFalse( $hook->has_filters() ); 37 } 38 39 public function test_not_has_filter_with_directly_removed_callback() { 40 $callback = '__return_null'; 41 $hook = new WP_Hook(); 42 $tag = rand_str(); 43 $priority = rand( 1, 100 ); 44 $accepted_args = rand( 1, 100 ); 45 46 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 47 $function_key = _wp_filter_build_unique_id( $tag, $callback, $priority ); 48 unset( $hook->callbacks[ $priority ][ $function_key ] ); 49 50 $this->assertFalse( $hook->has_filters() ); 51 } 52 } -
tests/phpunit/tests/hooks/remove_all_filters.php
1 <?php 2 3 /** 4 * Test the remove_all_filters method of WP_Hook 5 * 6 * @group hooks 7 */ 8 class Tests_WP_Hook_Remove_All_Filters extends WP_UnitTestCase { 9 10 public function test_remove_all_filters() { 11 $callback = '__return_null'; 12 $hook = new WP_Hook(); 13 $tag = rand_str(); 14 $priority = rand( 1, 100 ); 15 $accepted_args = rand( 1, 100 ); 16 17 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 18 19 $hook->remove_all_filters(); 20 21 $this->assertFalse( $hook->has_filters() ); 22 } 23 24 public function test_remove_all_filters_with_priority() { 25 $callback_one = '__return_null'; 26 $callback_two = '__return_false'; 27 $hook = new WP_Hook(); 28 $tag = rand_str(); 29 $priority = rand( 1, 100 ); 30 $accepted_args = rand( 1, 100 ); 31 32 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 33 $hook->add_filter( $callback_two, $tag, $priority + 1, $accepted_args ); 34 35 $hook->remove_all_filters( $priority ); 36 37 $this->assertFalse( $hook->has_filter( $callback_one, $tag ) ); 38 $this->assertTrue( $hook->has_filters() ); 39 $this->assertEquals( $priority + 1, $hook->has_filter( $callback_two, $tag ) ); 40 } 41 } -
tests/phpunit/tests/hooks/remove_filter.php
1 <?php 2 3 /** 4 * Test the remove_filter method of WP_Hook 5 * 6 * @group hooks 7 */ 8 class Tests_WP_Hook_Remove_Filter extends WP_UnitTestCase { 9 10 public function test_remove_filter_with_function() { 11 $callback = '__return_null'; 12 $hook = new WP_Hook(); 13 $tag = rand_str(); 14 $priority = rand( 1, 100 ); 15 $accepted_args = rand( 1, 100 ); 16 17 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 18 $hook->remove_filter( $callback, $priority, $tag ); 19 20 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) ); 21 } 22 23 public function test_remove_filter_with_object() { 24 $a = new MockAction(); 25 $callback = array( $a, 'action' ); 26 $hook = new WP_Hook(); 27 $tag = rand_str(); 28 $priority = rand( 1, 100 ); 29 $accepted_args = rand( 1, 100 ); 30 31 $hook->add_filter( $callback, $tag, $priority, $accepted_args ); 32 $hook->remove_filter( $callback, $priority, $tag ); 33 34 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) ); 35 } 36 37 public function test_remove_filter_with_static_method() { 38 $callback = array( 'MockAction', 'action' ); 39 $hook = new WP_Hook(); 40 $tag = rand_str(); 41 $priority = rand( 1, 100 ); 42 $accepted_args = rand( 1, 100 ); 43 44 $hook->add_filter( $callback, $priority, $accepted_args, $tag ); 45 $hook->remove_filter( $callback, $priority, $tag ); 46 47 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) ); 48 } 49 50 public function test_remove_filters_with_another_at_same_priority() { 51 $callback_one = '__return_null'; 52 $callback_two = '__return_false'; 53 $hook = new WP_Hook(); 54 $tag = rand_str(); 55 $priority = rand( 1, 100 ); 56 $accepted_args = rand( 1, 100 ); 57 58 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 59 $hook->add_filter( $callback_two, $tag, $priority, $accepted_args ); 60 61 $hook->remove_filter( $callback_one, $priority, $tag ); 62 63 $this->assertCount( 1, $hook->callbacks[ $priority ] ); 64 } 65 66 public function test_remove_filter_with_another_at_different_priority() { 67 $callback_one = '__return_null'; 68 $callback_two = '__return_false'; 69 $hook = new WP_Hook(); 70 $tag = rand_str(); 71 $priority = rand( 1, 100 ); 72 $accepted_args = rand( 1, 100 ); 73 74 $hook->add_filter( $callback_one, $tag, $priority, $accepted_args ); 75 $hook->add_filter( $callback_two, $tag, $priority + 1, $accepted_args ); 76 77 $hook->remove_filter( $callback_one, $priority, $tag ); 78 $this->assertFalse( isset( $hook->callbacks[ $priority ] ) ); 79 $this->assertCount( 1, $hook->callbacks[ $priority + 1 ] ); 80 } 81 }