[wp-hackers] Clarification of merge_filters?

Jacob Santos dragonwing at dragonu.net
Tue Aug 7 05:51:04 GMT 2007


While writing tests for merge_filters, I came across something strange. 
This might belong in wp-testers, but I'm not sure it is a bug or the 
intended result.

Work flow:

merge_filters('tag');

1: Get globals
2: Does $wp_filter['all'] exist?

Yes: merge $wp_filter['all'] to the array of $wp-filter['tag']. (#1).

3: Is $wp_filter[$tag] set? (#2)

Yes:
1: reset($wp_filter['tag'])
2: sort by key using *strnatcasecmp* function (#3)

4: Set $merge_filters['tag'] to true


#1: I suppose it is the intended result because array_merge does not 
preserve keys and everything in $wp_filter['all'] will be inserted at 
the beginning  of $wp_filter['tag'].

$wp_filter['all'] = array(
    4 => array(    // Priority
        'ID1' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    10 => array(    // Priority
        'ID2' => array('function' => 'whatever', 'args' => 'whatever')
    )
);

$wp_filter['tag'] = array(
    1 => array(    // Priority
        'ID3' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    5 => array(    // Priority
        'ID4' => array('function' => 'whatever', 'args' => 'whatever')
    )
);

The result will be:

$wp_filter['tag'] = array(
    0 => array(    // Priority
        'ID1' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    1 => array(    // Priority
        'ID2' => array('function' => 'whatever', 'args' => 'whatever')
    )
    2=> array(    // Priority
        'ID3' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    3 => array(    // Priority
        'ID4' => array('function' => 'whatever', 'args' => 'whatever')
    )
);

I would have assumed the result should have been

$wp_filter['tag'] = array(
    0 => array(    // Priority
        'ID3' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    1 => array(    // Priority
        'ID1' => array('function' => 'whatever', 'args' => 'whatever')
    )
    2=> array(    // Priority
        'ID4' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    3 => array(    // Priority
        'ID2' => array('function' => 'whatever', 'args' => 'whatever')
    )
);

or prefer:

$wp_filter['tag'] = array(
    1 => array(    // Priority
        'ID3' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    4 => array(    // Priority
        'ID1' => array('function' => 'whatever', 'args' => 'whatever')
    )
    5=> array(    // Priority
        'ID4' => array('function' => 'whatever', 'args' => 'whatever')
    ),
    10 => array(    // Priority
        'ID2' => array('function' => 'whatever', 'args' => 'whatever')
    )
);

#2

Even if $wp_filter['tag'] is not added (by add_filter), it is be set if 
$wp_filter['all'] (if it is also set). This from the code and 
apply_filters code, is so that even if the tag doesn't exist (wasn't 
added), but ['all'] is set, it will still get the hooks from ['all'], 
which is expected and correct. However, if $wp_filters['all'] is not set 
and $wp_filters['tag'] is not set, $merge_filters['tag'] is still set to 
true? Why is this?

#3

By all accounts, I would assume all keys would be numbers, unless some 
fool decided to set the priority of 'first' expecting something to come 
of it? That makes for an interesting feature. The documentation states 
that the priority should be number, however support for strings has been 
added.

Has any thought been given to extend such a feature to allow for 'first' 
to be run first and 'last' to run at the absolute last?


More information about the wp-hackers mailing list