diff --git a/WordPressVIPMinimum/Sniffs/Hooks/PreGetPostsSniff.php b/WordPressVIPMinimum/Sniffs/Hooks/PreGetPostsSniff.php index 716889b9..afa81d6c 100644 --- a/WordPressVIPMinimum/Sniffs/Hooks/PreGetPostsSniff.php +++ b/WordPressVIPMinimum/Sniffs/Hooks/PreGetPostsSniff.php @@ -356,16 +356,19 @@ private function isEarlyMainQueryCheck( $stackPtr ): bool { return false; } - $next = $this->phpcsFile->findNext( - [ T_RETURN ], - $this->tokens[ $this->tokens[ $nestedParenthesisEnd ]['parenthesis_owner'] ]['scope_opener'], - $this->tokens[ $this->tokens[ $nestedParenthesisEnd ]['parenthesis_owner'] ]['scope_closer'], - false, - 'return', - true - ); + // Look for a return which belongs to the control structure itself, not to anything nested inside it. + $scopeCloser = $this->tokens[ $owner ]['scope_closer']; + $return = $this->phpcsFile->findNext( T_RETURN, $this->tokens[ $owner ]['scope_opener'] + 1, $scopeCloser ); + while ( $return !== false ) { + $conditionStackPtrs = array_keys( $this->tokens[ $return ]['conditions'] ); + if ( array_pop( $conditionStackPtrs ) === $owner ) { + return true; + } + + $return = $this->phpcsFile->findNext( T_RETURN, $return + 1, $scopeCloser ); + } - return $next !== false; + return false; } /** diff --git a/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.inc b/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.inc index 5cb8c0d4..33f7416b 100644 --- a/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.inc +++ b/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.inc @@ -146,3 +146,38 @@ class short_array_hook_in { } } } + +// The early return does not have to be the first statement in the if. See #902. +add_action( 'pre_get_posts', function( $query ) { + if ( ! $query->is_main_query() ) { + do_log( 'x' ); + return; + } + $query->set( 'cat', '-5' ); // Ok. +} ); + +add_action( 'pre_get_posts', function( $query ) { + if ( ! $query->is_main_query() ) { + if ( is_admin() ) { + return; + } + } + $query->set( 'cat', '-5' ); // Warning - the return is conditional. +} ); + +add_action( 'pre_get_posts', function( $query ) { + if ( ! $query->is_main_query() ) { + $callback = function() { + return; + }; + } + $query->set( 'cat', '-5' ); // Warning - the return belongs to the nested closure. +} ); + +add_action( 'pre_get_posts', function( $query ) { + if ( ! $query->is_main_query() ) : + do_log( 'x' ); + return; + endif; + $query->set( 'cat', '-5' ); // Ok - alternative syntax. +} ); diff --git a/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.php b/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.php index 363f3244..6598375a 100644 --- a/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.php +++ b/WordPressVIPMinimum/Tests/Hooks/PreGetPostsUnitTest.php @@ -41,6 +41,8 @@ public function getWarningList() { 87 => 1, 128 => 1, 133 => 1, + 165 => 1, + 174 => 1, ]; } }