Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c84f469
PR 2708 DB/PreparedSQL: add tests for namespaced names
rodrigoprimo Jul 6, 2026
22a81d2
PR 2714 DB/PreparedSQLPlaceholders: add namespaced tests
rodrigoprimo Mar 24, 2026
54670c6
PR 2716 PrintingFunctionsTrait::is_printing_function(): add tests
rodrigoprimo Dec 4, 2025
7eb2d07
PR 2728 ContextHelper::is_token_namespaced(): add basic tests
rodrigoprimo Aug 18, 2025
3090f20
PR 2731 ValidationHelper::is_validated(): add basic tests
rodrigoprimo Nov 5, 2025
f7da189
PR 2752 ConstantsHelper::is_use_of_global_constant(): add tests
rodrigoprimo Aug 15, 2025
c477c29
PR 2755 EscapingFunctionsTrait: add tests
rodrigoprimo Dec 4, 2025
8ab11c9
PR 2756 SanitizationHelperTrait: add tests for is_sanitizing_function…
rodrigoprimo Jul 6, 2026
72f84d0
PR 2756 SanitizationHelperTrait: add tests for get_sanitizing_functio…
rodrigoprimo Jul 6, 2026
33c4820
PR 2760 WPDBTrait::is_wpdb_method_call(): add tests
rodrigoprimo Jul 7, 2026
ef2e89b
PR 2764 SanitizationHelperTrait::is_sanitized(): add tests
rodrigoprimo Jul 6, 2026
d05b72d
PR 2764 SanitizationHelperTrait::is_only_sanitized(): add tests
rodrigoprimo Jul 6, 2026
e3da696
Tests: update to allow for running the tests on PHPCS 4.x
rodrigoprimo Aug 4, 2025
1600503
Tests: fix testStdIn() methods to work with PHPCS 4.0
rodrigoprimo Oct 21, 2025
ba351a2
ContextHelper::is_in_function_call(): update for PHPCS 4.0
rodrigoprimo Aug 14, 2025
66c28eb
ValidationHelper::is_validated(): update for PHPCS 4.0
rodrigoprimo Aug 14, 2025
171339a
ConstantsHelper::is_use_of_global_constant(): update for PHPCS 4.0
rodrigoprimo Aug 15, 2025
6436e6a
ContextHelper::is_token_namespaced(): update for PHPCS 4.0
rodrigoprimo Aug 18, 2025
337674d
ContextHelper::is_in_array_comparison(): update for PHPCS 4.0
rodrigoprimo Oct 28, 2025
f4407c5
WPDBTrait::is_wpdb_method_call(): update for PHPCS 4.0
rodrigoprimo Aug 7, 2025
cddd8d0
FormattingFunctionsHelper::is_formatting_function(): update for PHPCS…
rodrigoprimo Dec 4, 2025
f2a24bb
PrintingFunctionsTrait::is_printing_function(): update for PHPCS 4.0
rodrigoprimo Mar 23, 2026
d91c3cd
WPHookHelper::get_hook_name_param(): update for PHPCS 4.0
rodrigoprimo Mar 23, 2026
bb916ba
ArrayWalkingFunctionsHelper: update for PHPCS 4.0
rodrigoprimo Dec 4, 2025
e6f0268
UnslashingFunctionsHelper: update for PHPCS 4.0
rodrigoprimo Dec 8, 2025
ce20111
SanitizationHelperTrait: update for PHPCS 4.0
rodrigoprimo Dec 4, 2025
9e7aaf2
EscapingFunctionsTrait: update for PHPCS 4.0
rodrigoprimo Dec 4, 2025
f9e4031
AbstractFunctionRestrictions: update for PHPCS 4.0
rodrigoprimo Aug 13, 2025
76dad45
AbstractClassRestrictions: update for PHPCS 4.0
rodrigoprimo Aug 13, 2025
0a82bb4
DB/DirectDatabaseQuery: update for PHPCS 4.0
rodrigoprimo Aug 7, 2025
b3c6b4d
WP/GlobalVariablesOverride: update for PHPCS 4.0
rodrigoprimo Aug 12, 2025
4780aca
Security/NonceVerification: update for PHPCS 4.0
rodrigoprimo Aug 12, 2025
7cf5923
NamingConventions/ValidHookName: update for PHPCS 4.0
rodrigoprimo Aug 13, 2025
ee9048d
NamingConventions/PrefixAllGlobals: update for PHPCS 4.0
rodrigoprimo Aug 13, 2025
e97318f
PHP/NoSilencedErrors: update for PHPCS 4.0
rodrigoprimo Aug 13, 2025
b4ba52d
WP/CronInterval: update for PHPCS 4.0
rodrigoprimo Aug 14, 2025
5b3b0ef
WP/DiscouragedConstants: update for PHPCS 4.0
rodrigoprimo Aug 18, 2025
0bdc61a
Security/EscapeOutput: update for PHPCS 4.0
rodrigoprimo Aug 19, 2025
0196808
DateTime/CurrentTimeTimestamp: update for PHPCS 4.0
rodrigoprimo Oct 20, 2025
7da5a6a
Utils/I18nTextDomainFixer: update for PHPCS 4.0
rodrigoprimo Oct 21, 2025
78e7949
DB/PreparedSQL: update for PHPCS 4.0
rodrigoprimo Aug 7, 2025
42147be
DB/PreparedSQLPlaceholders: update for PHPCS 4.0
rodrigoprimo Aug 7, 2025
05371c9
Security/ValidatedSanitizedInput: updates for PHPCS 4.0
rodrigoprimo Dec 4, 2025
2681006
PHPCS 4.0: handle converting empty string array values to null
rodrigoprimo Jan 29, 2026
2615b26
Composer: make PHPCS 4.x support official
rodrigoprimo Jul 14, 2026
92dea2c
WordPress-Docs: allow variable comment tags flagged under new PHPCS 4…
rodrigoprimo Jul 16, 2026
3074ccc
AbstractArrayAssignmentRestrictions: reword a comment to avoid a fals…
rodrigoprimo Jul 16, 2026
0491d4b
DELME Temporarily exclude Squiz.Functions.FunctionDuplicateArgument w…
rodrigoprimo Jul 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions .github/workflows/basic-qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,22 @@ concurrency:
cancel-in-progress: true

env:
PHPCS_DEV: '3.x-dev'
PHPCS_3_DEV: '3.x-dev'
PHPCS_4_DEV: '4.x-dev'
UTILS_DEV: 'dev-develop'
EXTRA_DEV: 'dev-develop'

jobs:
# Check code style of sniffs, rulesets and XML documentation.
# Check that all sniffs are feature complete.
sniffs:
name: Run code sniffs
name: "Run code sniffs (PHPCS ${{ matrix.dependencies }})"
runs-on: ubuntu-latest

strategy:
matrix:
dependencies: [ 'phpcs-3-dev', 'phpcs-4-dev' ]

steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
Expand All @@ -45,7 +50,7 @@ jobs:
- name: "Composer: set PHPCS dependencies (dev)"
run: >
composer require --no-update --no-scripts --no-interaction
squizlabs/php_codesniffer:"${{ env.PHPCS_DEV }}"
squizlabs/php_codesniffer:"${{ matrix.dependencies == 'phpcs-3-dev' && env.PHPCS_3_DEV || env.PHPCS_4_DEV }}"
phpcsstandards/phpcsutils:"${{ env.UTILS_DEV }}"
phpcsstandards/phpcsextra:"${{ env.EXTRA_DEV }}"

Expand Down Expand Up @@ -151,7 +156,7 @@ jobs:
strategy:
matrix:
php: [ 'latest' ]
dependencies: [ 'lowest', 'stable', 'dev' ]
dependencies: [ 'lowest', 'stable', 'phpcs-3-dev', 'phpcs-4-dev' ]

name: "Ruleset test: PHP ${{ matrix.php }} on PHPCS ${{ matrix.dependencies }}"

Expand All @@ -170,10 +175,10 @@ jobs:
coverage: none

- name: "Composer: set PHPCS dependencies for tests (dev)"
if: ${{ matrix.dependencies == 'dev' }}
if: ${{ matrix.dependencies == 'phpcs-3-dev' || matrix.dependencies == 'phpcs-4-dev' }}
run: >
composer require --no-update --no-scripts --no-interaction
squizlabs/php_codesniffer:"${{ env.PHPCS_DEV }}"
squizlabs/php_codesniffer:"${{ matrix.dependencies == 'phpcs-3-dev' && env.PHPCS_3_DEV || env.PHPCS_4_DEV }}"
phpcsstandards/phpcsutils:"${{ env.UTILS_DEV }}"
phpcsstandards/phpcsextra:"${{ env.EXTRA_DEV }}"

Expand Down Expand Up @@ -216,21 +221,26 @@ jobs:

# Test for fixer conflicts by running the auto-fixers of the complete WPCS over the test case files.
# This is not an exhaustive test, but should give an early indication for typical fixer conflicts.
# If only fixable errors are found, the exit code will be 1, which can be interpreted as success.
# This check is only run against "dev" as conflicts can not be fixed for already released versions.
# If only fixable errors are found, the exit code will be 1 on PHPCS 3.x and 2 on PHPCS 4.x, nad the test succeeded.
# This check is only run against the dev versions as conflicts can not be fixed for already released versions.
- name: Test for fixer conflicts (fixes expected)
if: ${{ matrix.dependencies == 'dev' }}
if: ${{ matrix.dependencies == 'phpcs-3-dev' || matrix.dependencies == 'phpcs-4-dev' }}
id: phpcbf
continue-on-error: true
run: |
set +e
$(pwd)/vendor/bin/phpcbf -pq ./WordPress/Tests/ --standard=WordPress --extensions=inc --exclude=Generic.PHP.Syntax --report=summary --ignore=/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.7.inc
$(pwd)/vendor/bin/phpcbf -pq ./WordPress/Tests/ --standard=WordPress --extensions=inc --exclude=Generic.PHP.Syntax,Squiz.Functions.FunctionDuplicateArgument --report=summary --ignore=/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.7.inc
exitcode="$?"
echo "EXITCODE=$exitcode" >> "$GITHUB_OUTPUT"
exit "$exitcode"

- name: Fail the build on fixer conflicts and other errors
if: ${{ steps.phpcbf.outputs.EXITCODE != 0 && steps.phpcbf.outputs.EXITCODE != 1 }}
if: >-
${{
steps.phpcbf.outputs.EXITCODE != 0
&& steps.phpcbf.outputs.EXITCODE != 1
&& ! (matrix.dependencies == 'phpcs-4-dev' && steps.phpcbf.outputs.EXITCODE == 2)
}}
run: exit ${{ steps.phpcbf.outputs.EXITCODE }}

phpstan:
Expand Down
24 changes: 18 additions & 6 deletions .github/workflows/quicktest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,25 @@ jobs:
if: ${{ matrix.dependencies == 'stable' }}
run: composer lint

- name: Run the unit tests without code coverage
if: ${{ github.event.repository.fork == true || github.ref_name != 'develop' }}
run: composer run-tests
- name: Grab PHPCS version
id: phpcs_version
run: echo "VERSION=$(vendor/bin/phpcs --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+\.[0-9]+')" >> "$GITHUB_OUTPUT"

- name: Run the unit tests with code coverage
if: ${{ github.event.repository.fork == false && github.ref_name == 'develop' }}
run: composer coverage
- name: Run the unit tests without code coverage (PHPCS 3.x)
if: ${{ (github.event.repository.fork == true || github.ref_name != 'develop') && startsWith( steps.phpcs_version.outputs.VERSION, '3.' ) }}
run: composer run-tests-phpcs3

- name: Run the unit tests without code coverage (PHPCS 4.x)
if: ${{ (github.event.repository.fork == true || github.ref_name != 'develop') && startsWith( steps.phpcs_version.outputs.VERSION, '4.' ) }}
run: composer run-tests-phpcs4

- name: Run the unit tests with code coverage (PHPCS 3.x)
if: ${{ github.event.repository.fork == false && github.ref_name == 'develop' && startsWith( steps.phpcs_version.outputs.VERSION, '3.' ) }}
run: composer coverage-phpcs3

- name: Run the unit tests with code coverage (PHPCS 4.x)
if: ${{ github.event.repository.fork == false && github.ref_name == 'develop' && startsWith( steps.phpcs_version.outputs.VERSION, '4.' ) }}
run: composer coverage-phpcs4

- name: Send coverage report to Codecov
if: ${{ success() && github.event.repository.fork == false && github.ref_name == 'develop' }}
Expand Down
52 changes: 39 additions & 13 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ concurrency:
cancel-in-progress: true

env:
PHPCS_DEV: '3.x-dev'
PHPCS_3_DEV: '3.x-dev'
PHPCS_4_DEV: '4.x-dev'
UTILS_DEV: 'dev-develop'
EXTRA_DEV: 'dev-develop'

Expand Down Expand Up @@ -52,18 +53,31 @@ jobs:

# Test against dev versions of all dependencies with select PHP versions for early detection of issues.
- php: '7.2'
dependencies: 'dev'
dependencies: 'phpcs-3-dev'
extensions: ''
coverage: false
- php: '7.2'
dependencies: 'phpcs-4-dev'
extensions: ''
coverage: false
- php: '8.1'
dependencies: 'phpcs-3-dev'
extensions: ''
coverage: false
- php: '8.1'
dependencies: 'dev'
dependencies: 'phpcs-4-dev'
extensions: ''
coverage: false
- php: '8.4'
dependencies: 'phpcs-3-dev'
extensions: ''
coverage: false
- php: '8.5'
dependencies: 'dev'
dependencies: 'phpcs-4-dev'
extensions: ''
coverage: false


# Add extra build to test against PHPCS 4.
#- php: '7.4'
# dependencies: '4.0.x-dev as 3.99.99'
Expand All @@ -83,7 +97,7 @@ jobs:
- name: Setup ini config
id: set_ini
run: |
if [ "${{ matrix.dependencies }}" != "dev" ]; then
if [ "${{ matrix.dependencies }}" != "phpcs-3-dev" ] && [ "${{ matrix.dependencies }}" != "phpcs-4-dev" ]; then
echo 'PHP_INI=error_reporting=E_ALL & ~E_DEPRECATED, display_errors=On, display_startup_errors=On' >> "$GITHUB_OUTPUT"
else
echo 'PHP_INI=error_reporting=-1, display_errors=On, display_startup_errors=On' >> "$GITHUB_OUTPUT"
Expand All @@ -98,10 +112,10 @@ jobs:
tools: cs2pr

- name: "Composer: set PHPCS dependencies for tests (dev)"
if: ${{ matrix.dependencies == 'dev' }}
if: ${{ matrix.dependencies == 'phpcs-3-dev' || matrix.dependencies == 'phpcs-4-dev' }}
run: >
composer require --no-update --no-scripts --no-interaction
squizlabs/php_codesniffer:"${{ env.PHPCS_DEV }}"
squizlabs/php_codesniffer:"${{ matrix.dependencies == 'phpcs-3-dev' && env.PHPCS_3_DEV || env.PHPCS_4_DEV }}"
phpcsstandards/phpcsutils:"${{ env.UTILS_DEV }}"
phpcsstandards/phpcsextra:"${{ env.EXTRA_DEV }}"

Expand All @@ -127,13 +141,25 @@ jobs:
if: ${{ matrix.dependencies == 'stable' }}
run: composer lint -- --checkstyle | cs2pr

- name: Run the unit tests without code coverage
if: ${{ matrix.coverage == false || github.event.repository.fork == true }}
run: composer run-tests
- name: Grab PHPCS version
id: phpcs_version
run: echo "VERSION=$(vendor/bin/phpcs --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+\.[0-9]+')" >> "$GITHUB_OUTPUT"

- name: Run the unit tests without code coverage (PHPCS 3.x)
if: ${{ startsWith( steps.phpcs_version.outputs.VERSION, '3.' ) && (matrix.coverage == false || github.event.repository.fork == true) }}
run: composer run-tests-phpcs3

- name: Run the unit tests without code coverage (PHPCS 4.x)
if: ${{ startsWith( steps.phpcs_version.outputs.VERSION, '4.' ) && (matrix.coverage == false || github.event.repository.fork == true) }}
run: composer run-tests-phpcs4

- name: Run the unit tests with code coverage (PHPCS 3.x)
if: ${{ startsWith( steps.phpcs_version.outputs.VERSION, '3.' ) && matrix.coverage == true && github.event.repository.fork == false }}
run: composer coverage-phpcs3

- name: Run the unit tests with code coverage
if: ${{ matrix.coverage == true && github.event.repository.fork == false }}
run: composer coverage
- name: Run the unit tests with code coverage (PHPCS 4.x)
if: ${{ startsWith( steps.phpcs_version.outputs.VERSION, '4.' ) && matrix.coverage == true && github.event.repository.fork == false }}
run: composer coverage-phpcs4

- name: Send coverage report to Codecov
if: ${{ success() && matrix.coverage == true && github.event.repository.fork == false }}
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ At this moment, WordPressCS offer the following tools:
- `old_text_domain`: an array with one or more (old) text domain names which need to be replaced;
- `new_text_domain`: the correct (new) text domain as a string.

**Note**: When using PHP_CodeSniffer 4.0+, this sniff will fix the text domain everywhere for plugins, but it will **not** fix the text domain in the CSS file header for themes, as PHP_CodeSniffer 4.0+ does not support scanning CSS files. Manual intervention will be required to update the `Text Domain` header in the theme's CSS file.


## Contributing

Expand Down
10 changes: 10 additions & 0 deletions Tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@
die( 1 );
}

// Alias the PHPCS 3.x test case to the PHPCS 4.x name.
if ( class_exists( 'PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest' ) === true
&& class_exists( 'PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase' ) === false
) {
class_alias(
'PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest',
'PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase'
);
}

/*
* Set the PHPCS_IGNORE_TEST environment variable to ignore tests from other standards.
*/
Expand Down
7 changes: 7 additions & 0 deletions WordPress-Docs/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,15 @@

<!-- WP prefers int and bool instead of integer and boolean -->
<exclude name="Squiz.Commenting.VariableComment.IncorrectVarType"/>

<!-- WP demands a @since tag for class variables -->
<!-- PHPCS 3.x uses a single genereci TagNotAllowed error code. -->
<exclude name="Squiz.Commenting.VariableComment.TagNotAllowed"/>
<!-- PHPCS 4.x split the generic TagNotAllowed error code into per-tag [TagName]TagNotAllowed codes. -->
<exclude name="Squiz.Commenting.VariableComment.SinceTagNotAllowed"/>

<exclude name="Squiz.Commenting.VariableComment.LinkTagNotAllowed"/>
<exclude name="Squiz.Commenting.VariableComment.DeprecatedTagNotAllowed"/>
<!-- WP prefers @since first -->
<exclude name="Squiz.Commenting.VariableComment.VarOrder"/>
</rule>
Expand Down
2 changes: 1 addition & 1 deletion WordPress/AbstractArrayAssignmentRestrictionsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public function process_token( $stackPtr ) {
$inst = array();

/*
* Covers array assignments:
* Covers following forms of array assignments:
* `$foo = array( 'bar' => 'taz' );`
* `$foo['bar'] = $taz;`
*/
Expand Down
14 changes: 11 additions & 3 deletions WordPress/AbstractClassRestrictionsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace WordPressCS\WordPress;

use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\BackCompat\Helper;
use PHPCSUtils\Tokens\Collections;
use PHPCSUtils\Utils\GetTokensAsString;
use PHPCSUtils\Utils\Namespaces;
Expand Down Expand Up @@ -145,13 +146,20 @@ public function is_targetted_token( $stackPtr ) {

if ( \T_DOUBLE_COLON === $token['code'] ) {
$nameEnd = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true );
if ( \T_STRING !== $this->tokens[ $nameEnd ]['code'] ) {
if ( isset( Collections::nameTokens()[ $this->tokens[ $nameEnd ]['code'] ] ) === false ) {
// Hierarchy keyword or object stored in variable.
return false;
}

$nameStart = ( $this->phpcsFile->findPrevious( Collections::namespacedNameTokens(), ( $nameEnd - 1 ), null, true ) + 1 );
$classname = GetTokensAsString::noEmpties( $this->phpcsFile, $nameStart, $nameEnd );
$classname = $this->tokens[ $nameEnd ]['content'];
$nameStart = $nameEnd;

if ( \version_compare( Helper::getVersion(), '3.99.99', '<=' ) === true ) {
// For PHPCS 3.x, a namespaced class name is split over multiple tokens so it is necessary to combine then to get the class name.
$nameStart = ( $this->phpcsFile->findPrevious( Collections::namespacedNameTokens(), ( $nameEnd - 1 ), null, true ) + 1 );
$classname = GetTokensAsString::noEmpties( $this->phpcsFile, $nameStart, $nameEnd );
}

$classname = $this->get_namespaced_classname( $classname, ( $nameStart - 1 ) );
}

Expand Down
3 changes: 2 additions & 1 deletion WordPress/AbstractFunctionParameterSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public function getGroups() {
* @param int $stackPtr The position of the current token in the stack.
* @param string $group_name The name of the group which was matched.
* @param string $matched_content The token content (function name) which was matched
* in lowercase.
* in lowercase. For T_NAME_FULLY_QUALIFIED tokens,
* the leading backslash is removed.
*
* @return int|void Integer stack pointer to skip forward or void to continue
* normal file processing.
Expand Down
22 changes: 18 additions & 4 deletions WordPress/AbstractFunctionRestrictionsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public function register() {

return array(
\T_STRING,
\T_NAME_FULLY_QUALIFIED,
);
}

Expand Down Expand Up @@ -201,10 +202,16 @@ public function process_token( $stackPtr ) {
return;
}

// Preliminary check. If the content of the T_STRING is not one of the functions we're
$content = $this->tokens[ $stackPtr ]['content'];

if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $stackPtr ]['code'] ) {
$content = \ltrim( $content, '\\' );
}

// Preliminary check. If the content of the name token is not one of the functions we're
// looking for, we can bow out before doing the heavy lifting of checking whether
// this is a function call.
if ( preg_match( $this->prelim_check_regex, $this->tokens[ $stackPtr ]['content'] ) !== 1 ) {
if ( preg_match( $this->prelim_check_regex, $content ) !== 1 ) {
return;
}

Expand Down Expand Up @@ -286,7 +293,13 @@ public function is_targetted_token( $stackPtr ) {
* normal file processing.
*/
public function check_for_matches( $stackPtr ) {
$token_content = strtolower( $this->tokens[ $stackPtr ]['content'] );
$content = $this->tokens[ $stackPtr ]['content'];

if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $stackPtr ]['code'] ) {
$content = \ltrim( $content, '\\' );
}

$token_content = strtolower( $content );
$skip_to = array();

foreach ( $this->groups as $groupName => $group ) {
Expand Down Expand Up @@ -319,7 +332,8 @@ public function check_for_matches( $stackPtr ) {
* @param int $stackPtr The position of the current token in the stack.
* @param string $group_name The name of the group which was matched.
* @param string $matched_content The token content (function name) which was matched
* in lowercase.
* in lowercase. For T_NAME_FULLY_QUALIFIED tokens,
* the leading backslash is removed.
*
* @return int|void Integer stack pointer to skip forward or void to continue
* normal file processing.
Expand Down
7 changes: 6 additions & 1 deletion WordPress/Helpers/ArrayWalkingFunctionsHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static function get_functions() {
* @return bool
*/
public static function is_array_walking_function( $functionName ) {
return isset( self::$arrayWalkingFunctions[ strtolower( $functionName ) ] );
return isset( self::$arrayWalkingFunctions[ strtolower( ltrim( $functionName, '\\' ) ) ] );
}

/**
Expand All @@ -94,6 +94,11 @@ public static function get_callback_parameter( File $phpcsFile, $stackPtr ) {
}

$functionName = strtolower( $tokens[ $stackPtr ]['content'] );

if ( \T_NAME_FULLY_QUALIFIED === $tokens[ $stackPtr ]['code'] ) {
$functionName = ltrim( $functionName, '\\' );
}

if ( isset( self::$arrayWalkingFunctions[ $functionName ] ) === false ) {
return false;
}
Expand Down
Loading
Loading