Ticket #14789: 14789.4.patch
File 14789.4.patch, 15.4 KB (added by , 15 years ago) |
---|
-
wp-includes/plugin.php
65 65 function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { 66 66 global $wp_filter, $merged_filters; 67 67 68 $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); 69 $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); 68 $accepted_args = max(0, (int) $accepted_args ); 69 $unique_id = _wp_filter_build_unique_id($tag, $function_to_add, $priority); 70 $wp_filter[$tag][$priority][$unique_id] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); 70 71 unset( $merged_filters[ $tag ] ); 71 72 return true; 72 73 } … … 85 86 */ 86 87 function has_filter($tag, $function_to_check = false) { 87 88 global $wp_filter; 88 89 $has = !empty($wp_filter[$tag]); 90 if ( false === $function_to_check || false == $has ) 91 return $has; 92 93 if ( !$idx = _wp_filter_build_unique_id($tag, $function_to_check, false) ) 89 90 if ( empty( $wp_filter[$tag] ) ) 94 91 return false; 92 93 if ( false === $function_to_check ) 94 return true; 95 96 if ( !( $unique_id = _wp_filter_build_unique_id( $tag, $function_to_check, false ) ) ) 97 return false; 95 98 96 foreach ( (array) array_keys($wp_filter[$tag]) as $priority ) {97 if ( isset( $wp_filter[$tag][$priority][$idx]) )99 foreach ( array_keys( $wp_filter[$tag] ) as $priority ) 100 if ( isset( $wp_filter[$tag][$priority][$unique_id] ) ) 98 101 return $priority; 99 }100 102 101 103 return false; 102 104 } … … 132 134 * @return mixed The filtered value after all hooked functions are applied to it. 133 135 */ 134 136 function apply_filters($tag, $value) { 135 global $wp_filter, $merged_filters, $wp_current_filter; 136 137 $args = array(); 138 $wp_current_filter[] = $tag; 139 140 // Do 'all' actions first 141 if ( isset($wp_filter['all']) ) { 142 $args = func_get_args(); 143 _wp_call_all_hook($args); 144 } 145 146 if ( !isset($wp_filter[$tag]) ) { 147 array_pop($wp_current_filter); 148 return $value; 149 } 150 151 // Sort 152 if ( !isset( $merged_filters[ $tag ] ) ) { 153 ksort($wp_filter[$tag]); 154 $merged_filters[ $tag ] = true; 155 } 156 157 reset( $wp_filter[ $tag ] ); 158 159 if ( empty($args) ) 160 $args = func_get_args(); 161 162 do { 163 foreach( (array) current($wp_filter[$tag]) as $the_ ) 164 if ( !is_null($the_['function']) ){ 165 $args[1] = $value; 166 $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args'])); 167 } 168 169 } while ( next($wp_filter[$tag]) !== false ); 170 171 array_pop( $wp_current_filter ); 172 173 return $value; 137 $args = func_get_args(); 138 $tag = array_shift( $args ); 139 return _wp_call_hook(true, $tag, $args); 174 140 } 175 141 176 142 /** … … 191 157 * @return mixed The filtered value after all hooked functions are applied to it. 192 158 */ 193 159 function apply_filters_ref_array($tag, $args) { 194 global $wp_filter, $merged_filters, $wp_current_filter; 195 196 $wp_current_filter[] = $tag; 197 198 // Do 'all' actions first 199 if ( isset($wp_filter['all']) ) { 200 $all_args = func_get_args(); 201 _wp_call_all_hook($all_args); 202 } 203 204 if ( !isset($wp_filter[$tag]) ) { 205 array_pop($wp_current_filter); 206 return $args[0]; 207 } 208 209 // Sort 210 if ( !isset( $merged_filters[ $tag ] ) ) { 211 ksort($wp_filter[$tag]); 212 $merged_filters[ $tag ] = true; 213 } 214 215 reset( $wp_filter[ $tag ] ); 216 217 do { 218 foreach( (array) current($wp_filter[$tag]) as $the_ ) 219 if ( !is_null($the_['function']) ) 220 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 221 222 } while ( next($wp_filter[$tag]) !== false ); 223 224 array_pop( $wp_current_filter ); 225 226 return $args[0]; 160 return _wp_call_hook( true, $tag, $args ); 227 161 } 228 162 229 163 /** … … 245 179 * @param callback $function_to_remove The name of the function which should be removed. 246 180 * @param int $priority optional. The priority of the function (default: 10). 247 181 * @param int $accepted_args optional. The number of arguments the function accpets (default: 1). 248 * @return boolean Whether the function existed before it was removed.182 * @return boolean True if there was a function to remove, False if not. 249 183 */ 250 184 function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { 251 $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority); 185 global $wp_filter, $merged_filters; 186 187 $unique_id = _wp_filter_build_unique_id($tag, $function_to_remove, $priority); 252 188 253 $r = isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); 189 if ( false === isset( $wp_filter[$tag][$priority][$unique_id] ) ) 190 return false; 254 191 255 if ( true === $r) { 256 unset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); 257 if ( empty($GLOBALS['wp_filter'][$tag][$priority]) ) 258 unset($GLOBALS['wp_filter'][$tag][$priority]); 259 unset($GLOBALS['merged_filters'][$tag]); 260 } 192 unset( $merged_filters[$tag] ); 193 unset( $wp_filter[$tag][$priority][$unique_id] ); 194 195 if ( empty( $wp_filter[$tag][$priority] ) ) 196 unset( $wp_filter[$tag][$priority] ); 261 197 262 return $r;198 return true; 263 199 } 264 200 265 201 /** … … 268 204 * @since 2.7 269 205 * 270 206 * @param string $tag The filter to remove hooks from. 271 * @param int $priority The priority numberto remove.272 * @return bool True when finished.207 * @param int $priority (optional) The priority to remove. 208 * @return bool True 273 209 */ 274 210 function remove_all_filters($tag, $priority = false) { 275 211 global $wp_filter, $merged_filters; 276 277 if( isset($wp_filter[$tag]) ) { 278 if( false !== $priority && isset($wp_filter[$tag][$priority]) ) 279 unset($wp_filter[$tag][$priority]); 280 else 281 unset($wp_filter[$tag]); 212 213 if ( !isset( $wp_filter[$tag] ) ) 214 return true; 215 216 if ( false === $priority ) { 217 unset( $wp_filter[$tag] ); 218 } else { 219 unset( $wp_filter[$tag][$priority] ); 282 220 } 283 221 284 if( isset($merged_filters[$tag]) ) 285 unset($merged_filters[$tag]); 222 unset( $merged_filters[$tag] ); 286 223 287 224 return true; 288 225 } … … 350 287 * @return null Will return null if $tag does not exist in $wp_filter array 351 288 */ 352 289 function do_action($tag, $arg = '') { 353 global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; 354 355 if ( ! isset($wp_actions) ) 356 $wp_actions = array(); 357 358 if ( ! isset($wp_actions[$tag]) ) 359 $wp_actions[$tag] = 1; 360 else 361 ++$wp_actions[$tag]; 362 363 $wp_current_filter[] = $tag; 364 365 // Do 'all' actions first 366 if ( isset($wp_filter['all']) ) { 367 $all_args = func_get_args(); 368 _wp_call_all_hook($all_args); 369 } 370 371 if ( !isset($wp_filter[$tag]) ) { 372 array_pop($wp_current_filter); 373 return; 374 } 375 376 $args = array(); 377 if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this) 378 $args[] =& $arg[0]; 379 else 380 $args[] = $arg; 381 for ( $a = 2; $a < func_num_args(); $a++ ) 382 $args[] = func_get_arg($a); 383 384 // Sort 385 if ( !isset( $merged_filters[ $tag ] ) ) { 386 ksort($wp_filter[$tag]); 387 $merged_filters[ $tag ] = true; 388 } 389 390 reset( $wp_filter[ $tag ] ); 391 392 do { 393 foreach ( (array) current($wp_filter[$tag]) as $the_ ) 394 if ( !is_null($the_['function']) ) 395 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 396 397 } while ( next($wp_filter[$tag]) !== false ); 398 399 array_pop($wp_current_filter); 290 $args = func_get_args(); 291 $tag = array_shift( $args ); 292 _wp_call_hook(false, $tag, $args); 400 293 } 401 294 402 295 /** … … 436 329 * @return null Will return null if $tag does not exist in $wp_filter array 437 330 */ 438 331 function do_action_ref_array($tag, $args) { 439 global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; 440 441 if ( ! isset($wp_actions) ) 442 $wp_actions = array(); 443 444 if ( ! isset($wp_actions[$tag]) ) 445 $wp_actions[$tag] = 1; 446 else 447 ++$wp_actions[$tag]; 448 449 $wp_current_filter[] = $tag; 450 451 // Do 'all' actions first 452 if ( isset($wp_filter['all']) ) { 453 $all_args = func_get_args(); 454 _wp_call_all_hook($all_args); 455 } 456 457 if ( !isset($wp_filter[$tag]) ) { 458 array_pop($wp_current_filter); 459 return; 460 } 461 462 // Sort 463 if ( !isset( $merged_filters[ $tag ] ) ) { 464 ksort($wp_filter[$tag]); 465 $merged_filters[ $tag ] = true; 466 } 467 468 reset( $wp_filter[ $tag ] ); 469 470 do { 471 foreach( (array) current($wp_filter[$tag]) as $the_ ) 472 if ( !is_null($the_['function']) ) 473 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 474 475 } while ( next($wp_filter[$tag]) !== false ); 476 477 array_pop($wp_current_filter); 332 _wp_call_hook( false, $tag, $args ); 478 333 } 479 334 480 335 /** … … 490 345 * @return int|boolean Optionally returns the priority on that hook for the specified function. 491 346 */ 492 347 function has_action($tag, $function_to_check = false) { 493 return has_filter( $tag, $function_to_check);348 return has_filter( $tag, $function_to_check ); 494 349 } 495 350 496 351 /** … … 511 366 * @return boolean Whether the function is removed. 512 367 */ 513 368 function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { 514 return remove_filter( $tag, $function_to_remove, $priority, $accepted_args);369 return remove_filter( $tag, $function_to_remove, $priority, $accepted_args ); 515 370 } 516 371 517 372 /** … … 524 379 * @return bool True when finished. 525 380 */ 526 381 function remove_all_actions($tag, $priority = false) { 527 return remove_all_filters( $tag, $priority);382 return remove_all_filters( $tag, $priority ); 528 383 } 529 384 530 385 // … … 547 402 * @uses WP_PLUGIN_DIR 548 403 */ 549 404 function plugin_basename($file) { 550 $file = str_replace('\\','/',$file); // sanitize for Win32 installs 551 $file = preg_replace('|/+|','/', $file); // remove any duplicate slash 552 $plugin_dir = str_replace('\\','/',WP_PLUGIN_DIR); // sanitize for Win32 installs 553 $plugin_dir = preg_replace('|/+|','/', $plugin_dir); // remove any duplicate slash 554 $mu_plugin_dir = str_replace('\\','/',WPMU_PLUGIN_DIR); // sanitize for Win32 installs 555 $mu_plugin_dir = preg_replace('|/+|','/', $mu_plugin_dir); // remove any duplicate slash 556 $file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . preg_quote($mu_plugin_dir, '#') . '/#','',$file); // get relative path from plugins dir 557 $file = trim($file, '/'); 405 $subject = array ( $file, WP_PLUGIN_DIR, WPMU_PLUGIN_DIR ); 406 407 $subject = str_replace( '\\', '/', $subject ); // sanitize for Win32 installs 408 $subject = preg_replace( '|/+|', '/', $subject ); // remove any duplicate slash 409 410 $file = array_shift($subject); 411 412 // get relative path from plugins dir 413 $subject = array_map( 'preg_quote', $subject, array ( '#', '#' ) ); 414 list ( $plugin_dir, $mu_plugin_dir ) = $subject; 415 $pattern = sprintf( '#^(%s|%s)/#', $plugin_dir, $mu_plugin_dir ); 416 $file = preg_replace( $pattern, '', $file ); 417 418 $file = trim( $file, '/' ); 419 558 420 return $file; 559 421 } 560 422 … … 604 466 * @param callback $function the function hooked to the 'activate_PLUGIN' action. 605 467 */ 606 468 function register_activation_hook($file, $function) { 607 $file = plugin_basename( $file);608 add_action( 'activate_' . $file, $function);469 $file = plugin_basename( $file ); 470 add_action( 'activate_' . $file, $function ); 609 471 } 610 472 611 473 /** … … 629 491 * @param callback $function the function hooked to the 'activate_PLUGIN' action. 630 492 */ 631 493 function register_deactivation_hook($file, $function) { 632 $file = plugin_basename( $file);633 add_action( 'deactivate_' . $file, $function);494 $file = plugin_basename( $file ); 495 add_action( 'deactivate_' . $file, $function ); 634 496 } 635 497 636 498 /** … … 662 524 // The option should not be autoloaded, because it is not needed in most 663 525 // cases. Emphasis should be put on using the 'uninstall.php' way of 664 526 // uninstalling the plugin. 665 $uninstallable_plugins = (array) get_option('uninstall_plugins'); 666 $uninstallable_plugins[plugin_basename($file)] = $callback; 667 update_option('uninstall_plugins', $uninstallable_plugins); 527 $file = plugin_basename($file); 528 $uninstallable_plugins = (array) get_option( 'uninstall_plugins' ); 529 $uninstallable_plugins[$file] = $callback; 530 update_option( 'uninstall_plugins', $uninstallable_plugins ); 668 531 } 669 532 670 533 /** … … 688 551 * @param array $args The collected parameters from the hook that was called. 689 552 * @param string $hook Optional. The hook name that was used to call the 'all' hook. 690 553 */ 691 function _wp_call_all_hook( $args) {554 function _wp_call_all_hook( $args ) { 692 555 global $wp_filter; 556 557 foreach( $wp_filter['all'] as $priority ) 558 foreach( $priority as $the_ ) 559 null !== $the_['function'] 560 && call_user_func_array( $the_['function'], $args ); 561 } 693 562 694 reset( $wp_filter['all'] ); 695 do { 696 foreach( (array) current($wp_filter['all']) as $the_ ) 697 if ( !is_null($the_['function']) ) 698 call_user_func_array($the_['function'], $args); 563 /** 564 * Calls a hook 565 * 566 * @since 3.1 567 * @access private 568 * @param bool $filter True: apply_filter, False: do_action 569 * @param string $tag The name of the filter hook. 570 * @param array $args The arguments supplied to the functions hooked on <tt>$tag</tt> 571 * @return mixed first element of $args, filtered if applicable 572 */ 573 function _wp_call_hook($filter, $tag, $args) { 574 global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; 575 576 // Count actions (not filters) 577 $filter || isset( $wp_actions[$tag] ) && $wp_actions[$tag]++ || $wp_actions[$tag] = 1; 699 578 700 } while ( next($wp_filter['all']) !== false ); 579 // Add hook to stack 580 $wp_current_filter[] = $tag; 581 582 // Do 'all' actions 583 isset( $wp_filter['all'] ) && _wp_call_all_hook( array_merge( array($tag), $args ) ); 584 585 if ( isset( $wp_filter[$tag] ) ) { 586 // Sort 587 isset( $merged_filters[$tag] ) || $merged_filters[$tag] = ksort( $wp_filter[$tag] ); 588 589 for ( $prio = reset( $wp_filter[$tag] ); false !== $prio ; $prio = next( $wp_filter[$tag] ) ) { 590 foreach( $prio as $the_ ) { 591 if ( null === $the_['function'] ) 592 continue; 593 594 $callback = $the_['function']; 595 $parameter = array_slice( $args, 0, $the_['accepted_args'] ); 596 597 $filter 598 ? $args[0] = call_user_func_array( $callback, $parameter) 599 : call_user_func_array( $callback, $parameter); 600 } 601 } 602 } 603 604 // Remove hook from stack 605 array_pop( $wp_current_filter ); 606 return isset( $args[0] ) ? $args[0] : null; 701 607 } 702 608 703 609 /** … … 734 640 global $wp_filter; 735 641 static $filter_id_count = 0; 736 642 737 if ( is_string( $function) )643 if ( is_string( $function ) ) 738 644 return $function; 739 645 740 if ( is_object( $function) ) {646 if ( is_object( $function ) ) { 741 647 // Closures are currently implemented as objects 742 648 $function = array( $function, '' ); 743 649 } else { 744 650 $function = (array) $function; 745 651 } 746 652 747 if ( is_object($function[0]) ) {748 // Object ClassCalling749 if ( function_exists( 'spl_object_hash') ) {750 return spl_object_hash( $function[0]) . $function[1];653 if ( is_object( $function[0] ) ) { 654 // Object Instance Calling 655 if ( function_exists( 'spl_object_hash' ) ) { 656 return spl_object_hash( $function[0] ) . $function[1]; 751 657 } else { 752 $obj_idx = get_class( $function[0]).$function[1];753 if ( !isset( $function[0]->wp_filter_id) ) {658 $obj_idx = get_class( $function[0] ) . $function[1]; 659 if ( !isset( $function[0]->wp_filter_id ) ) { 754 660 if ( false === $priority ) 755 661 return false; 756 $obj_idx .= isset( $wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count;662 $obj_idx .= isset( $wp_filter[$tag][$priority] ) ? count( (array) $wp_filter[$tag][$priority] ) : $filter_id_count; 757 663 $function[0]->wp_filter_id = $filter_id_count; 758 664 ++$filter_id_count; 759 665 } else { … … 762 668 763 669 return $obj_idx; 764 670 } 765 } else if ( is_string( $function[0]) ) {766 // Static Calling671 } else if ( is_string( $function[0] ) ) { 672 // Object Static Calling 767 673 return $function[0].$function[1]; 768 674 } 769 675 }