Skip to content

Commit ab5ec28

Browse files
committed
fix: skip return check for known action hooks
WordPress's `add_action()` is a wrapper around `add_filter()`, so some developers use `add_filter()` to register callbacks for action hooks like `pre_get_posts`. The sniff was incorrectly demanding a return value from these callbacks, even though action hooks pass arguments by reference and have no use for a return value. A configurable `$knownActionHooks` property allows the sniff to recognise common WordPress core action hooks and skip the return check. Being public, users can extend the list via their ruleset for custom action hooks. Refs #394.
1 parent af54d9b commit ab5ec28

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

WordPressVIPMinimum/Sniffs/Hooks/AlwaysReturnInFilterSniff.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,26 @@
2020
*/
2121
class AlwaysReturnInFilterSniff extends Sniff {
2222

23+
/**
24+
* Known action hooks that are sometimes registered via `add_filter()`.
25+
*
26+
* Since `add_action()` is a wrapper around `add_filter()` in WordPress,
27+
* some developers use `add_filter()` to register callbacks for action hooks.
28+
* These callbacks are not expected to return a value.
29+
*
30+
* This property is public so it can be extended via a custom ruleset.
31+
*
32+
* @var string[]
33+
*/
34+
public $knownActionHooks = [
35+
'pre_get_posts',
36+
'parse_query',
37+
'pre_get_users',
38+
'pre_get_terms',
39+
'pre_get_comments',
40+
'pre_get_sites',
41+
];
42+
2343
/**
2444
* Filter name pointer.
2545
*
@@ -65,6 +85,13 @@ public function process_token( $stackPtr ) {
6585
return;
6686
}
6787

88+
$filterName = TextStrings::stripQuotes( $this->tokens[ $this->filterNamePtr ]['content'] );
89+
90+
if ( in_array( $filterName, $this->knownActionHooks, true ) ) {
91+
// This is a known action hook, not a filter. No return value expected.
92+
return;
93+
}
94+
6895
$callbackPtr = $this->phpcsFile->findNext(
6996
array_merge( Tokens::$emptyTokens, [ T_COMMA ] ),
7097
$this->filterNamePtr + 1,

WordPressVIPMinimum/Tests/Hooks/AlwaysReturnInFilterUnitTest.inc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,24 @@ add_filter( 'bad_void_return_with_space', function() { // Error.
197197
return ;
198198
} );
199199

200+
// Known action hooks registered via add_filter should not trigger. Ok.
201+
add_filter( 'pre_get_posts', function( $query ) {
202+
$query->set( 'post_type', 'page' );
203+
} );
204+
205+
add_filter( 'pre_get_posts', 'modify_query' );
206+
function modify_query( $query ) {
207+
$query->set( 'posts_per_page', 10 );
208+
}
209+
210+
add_filter( 'parse_query', function( $query ) {
211+
$query->set( 'orderby', 'title' );
212+
} );
213+
214+
add_filter( 'pre_get_users', function( $query ) {
215+
$query->set( 'role', 'editor' );
216+
} );
217+
200218
// Intentional parse error. This has to be the last test in the file!
201219
class parse_error_test {
202220
public function __construct() {

0 commit comments

Comments
 (0)