Skip to content

Commit faf3d46

Browse files
committed
Plugins: Add missing $priority parameter to has_filter() and has_action().
This brings `has_filter()`/`has_action()` in parity with `add_filter()`/`add_action()` and `remove_filter()`/`remove_action()`, all of which support a `$priority` parameter. Props westonruter, swissspidy. Fixes #64186. See #64178. git-svn-id: https://develop.svn.wordpress.org/trunk@61118 602fd350-edb4-49c9-b593-d223f7449a82
1 parent e4bfb31 commit faf3d46

5 files changed

Lines changed: 84 additions & 18 deletions

File tree

src/wp-includes/class-wp-hook.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,16 +223,21 @@ public function remove_filter( $hook_name, $callback, $priority ) {
223223
* that evaluates to false (e.g. 0), so use the `===` operator for testing the return value.
224224
*
225225
* @since 4.7.0
226+
* @since 6.9.0 Added the `$priority` parameter.
226227
*
227228
* @param string $hook_name Optional. The name of the filter hook. Default empty.
228229
* @param callable|string|array|false $callback Optional. The callback to check for.
229230
* This method can be called unconditionally to speculatively check
230231
* a callback that may or may not exist. Default false.
232+
* @param int|false $priority Optional. The specific priority at which to check for the callback.
233+
* Default false.
231234
* @return bool|int If `$callback` is omitted, returns boolean for whether the hook has
232235
* anything registered. When checking a specific function, the priority
233236
* of that hook is returned, or false if the function is not attached.
237+
* If `$callback` and `$priority` are both provided, a boolean is returned
238+
* for whether the specific function is registered at that priority.
234239
*/
235-
public function has_filter( $hook_name = '', $callback = false ) {
240+
public function has_filter( $hook_name = '', $callback = false, $priority = false ) {
236241
if ( false === $callback ) {
237242
return $this->has_filters();
238243
}
@@ -243,9 +248,13 @@ public function has_filter( $hook_name = '', $callback = false ) {
243248
return false;
244249
}
245250

246-
foreach ( $this->callbacks as $priority => $callbacks ) {
251+
if ( is_int( $priority ) ) {
252+
return isset( $this->callbacks[ $priority ][ $function_key ] );
253+
}
254+
255+
foreach ( $this->callbacks as $callback_priority => $callbacks ) {
247256
if ( isset( $callbacks[ $function_key ] ) ) {
248-
return $priority;
257+
return $callback_priority;
249258
}
250259
}
251260

src/wp-includes/plugin.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,25 +267,30 @@ function apply_filters_ref_array( $hook_name, $args ) {
267267
* that evaluates to false (e.g. 0), so use the `===` operator for testing the return value.
268268
*
269269
* @since 2.5.0
270+
* @since 6.9.0 Added the `$priority` parameter.
270271
*
271272
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
272273
*
273274
* @param string $hook_name The name of the filter hook.
274275
* @param callable|string|array|false $callback Optional. The callback to check for.
275276
* This function can be called unconditionally to speculatively check
276277
* a callback that may or may not exist. Default false.
278+
* @param int|false $priority Optional. The specific priority at which to check for the callback.
279+
* Default false.
277280
* @return bool|int If `$callback` is omitted, returns boolean for whether the hook has
278281
* anything registered. When checking a specific function, the priority
279282
* of that hook is returned, or false if the function is not attached.
283+
* If `$callback` and `$priority` are both provided, a boolean is returned
284+
* for whether the specific function is registered at that priority.
280285
*/
281-
function has_filter( $hook_name, $callback = false ) {
286+
function has_filter( $hook_name, $callback = false, $priority = false ) {
282287
global $wp_filter;
283288

284289
if ( ! isset( $wp_filter[ $hook_name ] ) ) {
285290
return false;
286291
}
287292

288-
return $wp_filter[ $hook_name ]->has_filter( $hook_name, $callback );
293+
return $wp_filter[ $hook_name ]->has_filter( $hook_name, $callback, $priority );
289294
}
290295

291296
/**
@@ -574,19 +579,24 @@ function do_action_ref_array( $hook_name, $args ) {
574579
* that evaluates to false (e.g. 0), so use the `===` operator for testing the return value.
575580
*
576581
* @since 2.5.0
582+
* @since 6.9.0 Added the `$priority` parameter.
577583
*
578584
* @see has_filter() This function is an alias of has_filter().
579585
*
580586
* @param string $hook_name The name of the action hook.
581587
* @param callable|string|array|false $callback Optional. The callback to check for.
582588
* This function can be called unconditionally to speculatively check
583589
* a callback that may or may not exist. Default false.
590+
* @param int|false $priority Optional. The specific priority at which to check for the callback.
591+
* Default false.
584592
* @return bool|int If `$callback` is omitted, returns boolean for whether the hook has
585593
* anything registered. When checking a specific function, the priority
586594
* of that hook is returned, or false if the function is not attached.
595+
* If `$callback` and `$priority` are both provided, a boolean is returned
596+
* for whether the specific function is registered at that priority.
587597
*/
588-
function has_action( $hook_name, $callback = false ) {
589-
return has_filter( $hook_name, $callback );
598+
function has_action( $hook_name, $callback = false, $priority = false ) {
599+
return has_filter( $hook_name, $callback, $priority );
590600
}
591601

592602
/**

tests/phpunit/tests/actions.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,23 @@ public function test_remove_action() {
6464
$hook_name = __FUNCTION__;
6565

6666
add_action( $hook_name, array( &$a, 'action' ) );
67+
add_action( $hook_name, array( &$a, 'action' ), 100 );
6768
do_action( $hook_name );
6869

6970
// Make sure our hook was called correctly.
70-
$this->assertSame( 1, $a->get_call_count() );
71-
$this->assertSame( array( $hook_name ), $a->get_hook_names() );
71+
$this->assertSame( 2, $a->get_call_count() );
72+
$this->assertSame( array( $hook_name, $hook_name ), $a->get_hook_names() );
7273

7374
// Now remove the action, do it again, and make sure it's not called this time.
7475
remove_action( $hook_name, array( &$a, 'action' ) );
76+
remove_action( $hook_name, array( &$a, 'action' ), 100 );
7577
do_action( $hook_name );
76-
$this->assertSame( 1, $a->get_call_count() );
77-
$this->assertSame( array( $hook_name ), $a->get_hook_names() );
78+
$this->assertSame( 2, $a->get_call_count() );
79+
$this->assertSame( array( $hook_name, $hook_name ), $a->get_hook_names() );
7880
}
7981

8082
/**
83+
* @ticket 64186
8184
* @covers ::has_action
8285
*/
8386
public function test_has_action() {
@@ -89,8 +92,21 @@ public function test_has_action() {
8992

9093
add_action( $hook_name, $callback );
9194
$this->assertSame( 10, has_action( $hook_name, $callback ) );
95+
$this->assertFalse( has_action( $hook_name, $callback, 9 ) );
9296
$this->assertTrue( has_action( $hook_name ) );
9397

98+
add_action( $hook_name, $callback, 9 );
99+
add_action( $hook_name, $callback, 11 );
100+
$this->assertSame( 9, has_action( $hook_name, $callback ) );
101+
$this->assertTrue( has_action( $hook_name, $callback, 9 ) );
102+
$this->assertTrue( has_action( $hook_name, $callback, 10 ) );
103+
$this->assertTrue( has_action( $hook_name, $callback, 11 ) );
104+
$this->assertTrue( has_action( $hook_name ) );
105+
106+
remove_action( $hook_name, $callback, 9 );
107+
remove_action( $hook_name, $callback, 11 );
108+
$this->assertSame( 10, has_action( $hook_name, $callback ) );
109+
94110
remove_action( $hook_name, $callback );
95111
$this->assertFalse( has_action( $hook_name, $callback ) );
96112
$this->assertFalse( has_action( $hook_name ) );

tests/phpunit/tests/filters.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,34 @@ public function test_simple_filter() {
2525
$this->assertSame( array( $val ), $args );
2626
}
2727

28+
/**
29+
* @covers ::remove_filter
30+
*/
2831
public function test_remove_filter() {
2932
$a = new MockAction();
3033
$hook_name = __FUNCTION__;
3134
$val = __FUNCTION__ . '_val';
3235

3336
add_filter( $hook_name, array( $a, 'filter' ) );
37+
add_filter( $hook_name, array( $a, 'filter' ), 100 );
3438
$this->assertSame( $val, apply_filters( $hook_name, $val ) );
3539

3640
// Make sure our hook was called correctly.
37-
$this->assertSame( 1, $a->get_call_count() );
38-
$this->assertSame( array( $hook_name ), $a->get_hook_names() );
41+
$this->assertSame( 2, $a->get_call_count() );
42+
$this->assertSame( array( $hook_name, $hook_name ), $a->get_hook_names() );
3943

4044
// Now remove the filter, do it again, and make sure it's not called this time.
4145
remove_filter( $hook_name, array( $a, 'filter' ) );
46+
remove_filter( $hook_name, array( $a, 'filter' ), 100 );
4247
$this->assertSame( $val, apply_filters( $hook_name, $val ) );
43-
$this->assertSame( 1, $a->get_call_count() );
44-
$this->assertSame( array( $hook_name ), $a->get_hook_names() );
48+
$this->assertSame( 2, $a->get_call_count() );
49+
$this->assertSame( array( $hook_name, $hook_name ), $a->get_hook_names() );
4550
}
4651

52+
/**
53+
* @ticket 64186
54+
* @covers ::has_filter
55+
*/
4756
public function test_has_filter() {
4857
$hook_name = __FUNCTION__;
4958
$callback = __FUNCTION__ . '_func';
@@ -53,8 +62,21 @@ public function test_has_filter() {
5362

5463
add_filter( $hook_name, $callback );
5564
$this->assertSame( 10, has_filter( $hook_name, $callback ) );
65+
$this->assertFalse( has_filter( $hook_name, $callback, 9 ) );
66+
$this->assertTrue( has_filter( $hook_name ) );
67+
68+
add_filter( $hook_name, $callback, 9 );
69+
add_filter( $hook_name, $callback, 11 );
70+
$this->assertSame( 9, has_filter( $hook_name, $callback ) );
71+
$this->assertTrue( has_filter( $hook_name, $callback, 9 ) );
72+
$this->assertTrue( has_filter( $hook_name, $callback, 10 ) );
73+
$this->assertTrue( has_filter( $hook_name, $callback, 11 ) );
5674
$this->assertTrue( has_filter( $hook_name ) );
5775

76+
remove_filter( $hook_name, $callback, 9 );
77+
remove_filter( $hook_name, $callback, 11 );
78+
$this->assertSame( 10, has_filter( $hook_name, $callback ) );
79+
5880
remove_filter( $hook_name, $callback );
5981
$this->assertFalse( has_filter( $hook_name, $callback ) );
6082
$this->assertFalse( has_filter( $hook_name ) );

tests/phpunit/tests/hooks/hasFilter.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,25 @@
88
*/
99
class Tests_Hooks_HasFilter extends WP_UnitTestCase {
1010

11+
/**
12+
* @ticket 64186
13+
*/
1114
public function test_has_filter_with_function() {
1215
$callback = '__return_null';
1316
$hook = new WP_Hook();
1417
$hook_name = __FUNCTION__;
15-
$priority = 1;
18+
$priority_a = 1;
19+
$priority_b = 10;
1620
$accepted_args = 2;
1721

18-
$hook->add_filter( $hook_name, $callback, $priority, $accepted_args );
22+
$hook->add_filter( $hook_name, $callback, $priority_a, $accepted_args );
23+
$hook->add_filter( $hook_name, $callback, $priority_b, $accepted_args );
1924

20-
$this->assertSame( $priority, $hook->has_filter( $hook_name, $callback ) );
25+
$this->assertSame( $priority_a, $hook->has_filter( $hook_name, $callback ) );
26+
$this->assertTrue( $hook->has_filter( $hook_name, $callback, $priority_a ) );
27+
$this->assertTrue( $hook->has_filter( $hook_name, $callback, $priority_b ) );
28+
$hook->remove_filter( $hook_name, $callback, $priority_a );
29+
$this->assertSame( $priority_b, $hook->has_filter( $hook_name, $callback ) );
2130
}
2231

2332
public function test_has_filter_with_object() {

0 commit comments

Comments
 (0)