WordPress.org

Make WordPress Core

Ticket #5231: action_filter.diff

File action_filter.diff, 8.8 KB (added by ryan, 11 years ago)
  • wp-includes/plugin.php

     
    7272function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
    7373        global $wp_filter, $merged_filters;
    7474
    75         $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
     75        $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority, 'filter');
    7676        $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
    7777        unset( $merged_filters[ $tag ] );
    7878        return true;
     
    109109function apply_filters($tag, $value) {
    110110        global $wp_filter, $merged_filters;
    111111
    112         if ( !isset( $merged_filters[ $tag ] ) )
    113                 merge_filters($tag);
     112        // Do 'all' actions first
     113        if ( isset($wp_filter['all']) ) {
     114                reset( $wp_filter['all'] );
     115                do {
     116                        foreach ( (array) current($wp_filter['all']) as $the_ )
     117                                if ( !is_null($the_['function']) )
     118                                        $value = call_user_func_array($the_['function'], $value);
    114119
     120                } while ( next($wp_filter['all']) !== false );
     121        }
     122
    115123        if ( !isset($wp_filter[$tag]) )
    116124                return $value;
    117125
     126        // Sort
     127        if ( !isset( $merged_filters[ $tag ] ) ) {
     128                reset($wp_filter[$tag]);
     129                uksort($wp_filter[$tag], "strnatcasecmp");
     130                $merged_filters[ $tag ] = true;
     131        }
     132
    118133        reset( $wp_filter[ $tag ] );
    119134
    120135        $args = func_get_args();
    121136
    122         do{
     137        do {
    123138                foreach( (array) current($wp_filter[$tag]) as $the_ )
    124139                        if ( !is_null($the_['function']) ){
    125140                                $args[1] = $value;
     
    132147}
    133148
    134149/**
    135  * Merge the filter functions of a specific filter hook with generic filter functions.
    136  *
    137  * It is possible to defined generic filter functions using the filter hook
    138  * <em>all</e>. These functions are called for every filter tag. This function
    139  * merges the functions attached to the <em>all</em> hook with the functions
    140  * of a specific hook defined by <tt>$tag</tt>.
    141  *
    142  * Bugged if you hook into 'all' tag, then you <strong>will</strong> lose all priority
    143  * information. {@link http://trac.wordpress.org/ticket/4715 Bug #4715} for more information.
    144  *
    145  * @package WordPress
    146  * @subpackage Plugin
    147  * @since 1.5
    148  * @global array $wp_filter Stores all of the filters
    149  * @global array $merge_filters Merges the filter hooks using this function.
    150  *
    151  * @param string $tag The filter hook of which the functions should be merged.
    152  */
    153 function merge_filters($tag) {
    154         global $wp_filter, $merged_filters;
    155 
    156         if ( isset($wp_filter['all']) && is_array($wp_filter['all']) )
    157                 $wp_filter[$tag] = array_merge($wp_filter['all'], (array) $wp_filter[$tag]);
    158 
    159         if ( isset($wp_filter[$tag]) ){
    160                 reset($wp_filter[$tag]);
    161                 uksort($wp_filter[$tag], "strnatcasecmp");
    162         }
    163         $merged_filters[ $tag ] = true;
    164 }
    165 
    166 /**
    167150 * Removes a function from a specified filter hook.
    168151 *
    169152 * This function removes a function attached to a specified filter hook. This
     
    185168 * @return boolean Whether the function existed before it was removed.
    186169 */
    187170function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
    188         $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority);
     171        $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority, 'filter');
    189172
    190173        $r = isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]);
    191174
    192         unset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]);
    193         unset($GLOBALS['merged_filters'][$tag]);
     175        if ( true === $r) {
     176                unset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]);
     177                unset($GLOBALS['merged_filters'][$tag]);
     178        }
    194179
    195180        return $r;
    196181}
    197182
     183
    198184/**
    199185 * Hooks a function on to a specific action.
    200186 *
     
    215201 * @param int $accepted_args optional. The number of arguments the function accept (default 1).
    216202 */
    217203function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
    218         add_filter($tag, $function_to_add, $priority, $accepted_args);
     204        global $wp_action, $merged_actions;
     205
     206        $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority, 'action');
     207        $wp_action[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
     208        unset( $merged_actions[ $tag ] );
     209        return true;
    219210}
    220211
     212
    221213/**
    222214 * Execute functions hooked on a specific action hook.
    223215 *
     
    241233 * @return null Will return null if $tag does not exist in $wp_filter array
    242234 */
    243235function do_action($tag, $arg = '') {
    244         global $wp_filter, $wp_actions;
     236        global $wp_action, $wp_actions;
    245237
    246238        if ( is_array($wp_actions) )
    247239                $wp_actions[] = $tag;
     
    256248        for ( $a = 2; $a < func_num_args(); $a++ )
    257249                $args[] = func_get_arg($a);
    258250
    259         merge_filters($tag);
     251        // Do 'all' actions first
     252        if ( isset($wp_action['all']) ) {
     253                do {
     254                        foreach( (array) current($wp_action['all']) as $the_ )
     255                                if ( !is_null($the_['function']) )
     256                                        call_user_func_array($the_['function'], $args[0]);
    260257
    261         if ( !isset($wp_filter[$tag]) )
     258                } while ( next($wp_action['all']) !== false );
     259        }
     260
     261        if ( !isset($wp_action[$tag]) )
    262262                return;
    263263
    264         do{
    265                 foreach( (array) current($wp_filter[$tag]) as $the_ )
     264        // Sort
     265        if ( !isset( $merged_actions[ $tag ] ) ) {
     266                reset($wp_action[$tag]);
     267                uksort($wp_action[$tag], "strnatcasecmp");
     268                $merged_actions[ $tag ] = true;
     269        }
     270
     271        reset( $wp_action[ $tag ] );
     272
     273        do {
     274                foreach ( (array) current($wp_action[$tag]) as $the_ )
    266275                        if ( !is_null($the_['function']) )
    267276                                call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
    268277
    269         } while ( next($wp_filter[$tag]) !== false );
     278        } while ( next($wp_action[$tag]) !== false );
    270279
    271280}
    272281
     
    309318 * @return null Will return null if $tag does not exist in $wp_filter array
    310319 */
    311320function do_action_ref_array($tag, $args) {
    312         global $wp_filter, $wp_actions;
     321        global $wp_action, $wp_actions;
    313322
    314323        if ( !is_array($wp_actions) )
    315324                $wp_actions = array($tag);
    316325        else
    317326                $wp_actions[] = $tag;
    318327
    319         merge_filters($tag);
     328        // Do 'all' actions first
     329        if ( isset($wp_action['all']) ) {
     330                do {
     331                        foreach( (array) current($wp_action['all']) as $the_ )
     332                                if ( !is_null($the_['function']) )
     333                                        call_user_func_array($the_['function'], $args[0]);
    320334
    321         if ( !isset($wp_filter[$tag]) )
     335                } while ( next($wp_action['all']) !== false );
     336        }
     337
     338        if ( !isset($wp_action[$tag]) )
    322339                return;
    323340
    324         do{
    325                 foreach( (array) current($wp_filter[$tag]) as $the_ )
     341        // Sort
     342        if ( !isset( $merged_actions[ $tag ] ) ) {
     343                reset($wp_action[$tag]);
     344                uksort($wp_action[$tag], "strnatcasecmp");
     345                $merged_actions[ $tag ] = true;
     346        }
     347
     348        reset( $wp_action[ $tag ] );
     349
     350        do {
     351                foreach( (array) current($wp_action[$tag]) as $the_ )
    326352                        if ( !is_null($the_['function']) )
    327353                                call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
    328354
    329         } while ( next($wp_filter[$tag]) !== false );
     355        } while ( next($wp_action[$tag]) !== false );
    330356
    331357}
    332358
     
    350376 * @return boolean Whether the function is removed.
    351377 */
    352378function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
    353         return remove_filter($tag, $function_to_remove, $priority, $accepted_args);
     379        $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority);
     380
     381        $r = isset($GLOBALS['wp_action'][$tag][$priority][$function_to_remove]);
     382
     383        if ( true === $r) {
     384                unset($GLOBALS['wp_action'][$tag][$priority][$function_to_remove]);
     385                unset($GLOBALS['merged_actions'][$tag]);
     386        }
     387
     388        return $r;
    354389}
    355390
    356391//
     
    459494 * @param string $tag Used in counting how many hooks were applied
    460495 * @param string|array $function Used for creating unique id
    461496 * @param int $priority Used in counting how many hooks were applied
     497 * @param string $type filter or action
    462498 * @return string Unique ID for usage as array key
    463499 */
    464 function _wp_filter_build_unique_id($tag, $function, $priority = 10)
     500function _wp_filter_build_unique_id($tag, $function, $priority, $type)
    465501{
    466         global $wp_filter;
     502        global $wp_filter, $wp_action;
    467503
    468504        // If function then just skip all of the tests and not overwrite the following.
    469         if( is_string($function) )
     505        if ( is_string($function) )
    470506                return $function;
    471507        // Object Class Calling
    472         else if(is_object($function[0]) )
    473         {
     508        else if (is_object($function[0]) ) {
    474509                $obj_idx = get_class($function[0]).$function[1];
    475                 if( is_null($function[0]->wp_filter_id) ) { // This should be instead of is_null() change to !isset() to fix notice
    476                         $count = count((array)$wp_filter[$tag][$priority]);
     510                if ( !isset($function[0]->wp_filter_id) ) {
     511                        if ( 'filter' == $type )
     512                                $count = count((array)$wp_filter[$tag][$priority]);
     513                        else
     514                                $count = count((array)$wp_action[$tag][$priority]);
    477515                        $function[0]->wp_filter_id = $count;
    478516                        $obj_idx .= $count;
    479517                        unset($count);
     
    482520                return $obj_idx;
    483521        }
    484522        // Static Calling
    485         else if( is_string($function[0]) )
     523        else if ( is_string($function[0]) )
    486524                return $function[0].$function[1];
    487525}
    488526