From 2707cc4cc92626be8d9b1033b6af92b0f142db7f Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 16:08:21 -0300 Subject: [PATCH 01/62] Security/EscapeOutput: add tests for namespaced names --- .../Tests/Security/EscapeOutputUnitTest.1.inc | 59 ++++++++++++++++++- .../Tests/Security/EscapeOutputUnitTest.php | 24 +++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/WordPress/Tests/Security/EscapeOutputUnitTest.1.inc b/WordPress/Tests/Security/EscapeOutputUnitTest.1.inc index 52c3a5997..379b11a21 100644 --- a/WordPress/Tests/Security/EscapeOutputUnitTest.1.inc +++ b/WordPress/Tests/Security/EscapeOutputUnitTest.1.inc @@ -258,7 +258,7 @@ echo esc_html_x( $some_nasty_var, 'context' ); // Ok. 1, 19 => 1, @@ -160,10 +163,29 @@ public function getErrorList( $testFile = '' ) { 655 => 1, 657 => 1, 663 => 1, - 664 => 1, + // PHPCS 3.13.3 changed the tokenization of FQN exit/die it impacts directly how this test case + // behaves (see https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/1201). + 664 => version_compare( $phpcs_version, '3.13.3', '>=' ) ? 1 : 0, 672 => 1, 673 => 1, 678 => 1, + 694 => 1, + 699 => 1, + 700 => 1, + 701 => 1, + 707 => 1, + 708 => 1, + 709 => 1, + 714 => 1, + 722 => 1, + 724 => 1, + 725 => 1, + 726 => 1, + 732 => 1, + 733 => 1, + 734 => 1, + 735 => 1, + 744 => 1, ); case 'EscapeOutputUnitTest.6.inc': From 54816d57f105d2e909d089c5fdda086ababcaa50 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 5 Aug 2025 10:49:05 -0300 Subject: [PATCH 02/62] DELME: temporally allow PHPCS 4.x tests to fail while they are not fixed --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index cda909983..2fe0e1177 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -70,7 +70,7 @@ jobs: name: PHP ${{ matrix.php }} on PHPCS ${{ matrix.dependencies }} - continue-on-error: ${{ matrix.php == '8.5' }} + continue-on-error: ${{ matrix.php == '8.5' || matrix.dependencies == 'phpcs-4-dev' }} steps: - name: Checkout repository From 4845e3bc683f8a481da754adb5671fe3690bad37 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Mon, 4 Aug 2025 13:35:26 -0300 Subject: [PATCH 03/62] Tests: update to allow for running the tests on PHPCS 4.x As of PHPCS 4.0, the base sniff test class has been renamed from `AbstractSniffUnitTest` to `AbstractSniffTestCase`. Additionally, the PHPCS test setup no longer uses the outdated custom test suite creation. This means that to allow for the tests to run on both PHPCS 3.x and 4.x, some changes are needed. This commit handles this by: * Changing all test files to `extend` the new test case class and adding a class alias to the test bootstrap for compatibility with PHPCS 3.x. * Adding separate scripts to the `composer.json` file for invoking the tests on PHPCS 3.x vs 4.x. * Updating the minimum PHPUnit 9 version to 9.3.4 as required by the PHPCS 4.x native test framework. * Add jobs to test against PHPCS 4.x to all `test` matrices. * Updating the `quicktest` and `unit-tests` jobs to use the correct Composer script based on the installed PHPCS version. This commit also adds a step `unit-tests` to remove the `PHPCompatibility` dependency. This dependency is not needed in the tests and is currently not (yet) compatible with PHPCS 4.x, so it would block the `composer require`. _Note: even though PHPCS 4.x supports PHPUnit 10 and 11, we cannot widen the version restrictions for PHPUnit (yet) while PHPCS 3.x is also supported as it would lead to PHPUnit 10/11 being installed for PHPCS 3.x on PHP >= 8.1, which would break the test runs._ --------- Co-authored-by: Juliette <663378+jrfnl@users.noreply.github.com> --- .github/workflows/quicktest.yml | 24 ++++++-- .github/workflows/unit-tests.yml | 56 ++++++++++++++----- Tests/bootstrap.php | 10 ++++ .../ArrayDeclarationSpacingUnitTest.php | 4 +- .../Tests/Arrays/ArrayIndentationUnitTest.php | 4 +- .../ArrayKeySpacingRestrictionsUnitTest.php | 4 +- .../MultipleStatementAlignmentUnitTest.php | 4 +- .../AssignmentInTernaryConditionUnitTest.php | 4 +- .../EscapedNotTranslatedUnitTest.php | 4 +- .../Tests/DB/DirectDatabaseQueryUnitTest.php | 4 +- .../DB/PreparedSQLPlaceholdersUnitTest.php | 4 +- WordPress/Tests/DB/PreparedSQLUnitTest.php | 4 +- .../Tests/DB/RestrictedClassesUnitTest.php | 4 +- .../Tests/DB/RestrictedFunctionsUnitTest.php | 4 +- WordPress/Tests/DB/SlowDBQueryUnitTest.php | 4 +- .../DateTime/CurrentTimeTimestampUnitTest.php | 4 +- .../DateTime/RestrictedFunctionsUnitTest.php | 4 +- WordPress/Tests/Files/FileNameUnitTest.php | 4 +- .../PrefixAllGlobalsUnitTest.php | 4 +- .../ValidFunctionNameUnitTest.php | 4 +- .../ValidHookNameUnitTest.php | 4 +- .../ValidPostTypeSlugUnitTest.php | 4 +- .../ValidVariableNameUnitTest.php | 4 +- .../PHP/DevelopmentFunctionsUnitTest.php | 4 +- .../PHP/DiscouragedPHPFunctionsUnitTest.php | 4 +- WordPress/Tests/PHP/DontExtractUnitTest.php | 4 +- WordPress/Tests/PHP/IniSetUnitTest.php | 4 +- .../Tests/PHP/NoSilencedErrorsUnitTest.php | 4 +- .../Tests/PHP/POSIXFunctionsUnitTest.php | 4 +- .../Tests/PHP/PregQuoteDelimiterUnitTest.php | 4 +- .../PHP/RestrictedPHPFunctionsUnitTest.php | 4 +- WordPress/Tests/PHP/StrictInArrayUnitTest.php | 4 +- WordPress/Tests/PHP/TypeCastsUnitTest.php | 4 +- .../Tests/PHP/YodaConditionsUnitTest.php | 4 +- .../Tests/Security/EscapeOutputUnitTest.php | 4 +- .../Security/NonceVerificationUnitTest.php | 4 +- .../Tests/Security/PluginMenuSlugUnitTest.php | 4 +- .../Tests/Security/SafeRedirectUnitTest.php | 4 +- .../ValidatedSanitizedInputUnitTest.php | 4 +- .../Utils/I18nTextDomainFixerUnitTest.php | 4 +- .../Tests/WP/AlternativeFunctionsUnitTest.php | 4 +- WordPress/Tests/WP/CapabilitiesUnitTest.php | 4 +- WordPress/Tests/WP/CapitalPDangitUnitTest.php | 4 +- WordPress/Tests/WP/ClassNameCaseUnitTest.php | 4 +- WordPress/Tests/WP/CronIntervalUnitTest.php | 4 +- .../Tests/WP/DeprecatedClassesUnitTest.php | 4 +- .../Tests/WP/DeprecatedFunctionsUnitTest.php | 4 +- .../WP/DeprecatedParameterValuesUnitTest.php | 4 +- .../Tests/WP/DeprecatedParametersUnitTest.php | 4 +- .../Tests/WP/DiscouragedConstantsUnitTest.php | 4 +- .../Tests/WP/DiscouragedFunctionsUnitTest.php | 4 +- .../WP/EnqueuedResourceParametersUnitTest.php | 4 +- .../Tests/WP/EnqueuedResourcesUnitTest.php | 4 +- WordPress/Tests/WP/GetMetaSingleUnitTest.php | 4 +- .../WP/GlobalVariablesOverrideUnitTest.php | 4 +- WordPress/Tests/WP/I18nUnitTest.php | 4 +- WordPress/Tests/WP/PostsPerPageUnitTest.php | 4 +- .../CastStructureSpacingUnitTest.php | 4 +- .../ControlStructureSpacingUnitTest.php | 4 +- .../ObjectOperatorSpacingUnitTest.php | 4 +- .../WhiteSpace/OperatorSpacingUnitTest.php | 4 +- composer.json | 20 +++++-- 62 files changed, 201 insertions(+), 141 deletions(-) diff --git a/.github/workflows/quicktest.yml b/.github/workflows/quicktest.yml index 5cf6b0fa0..8081fafc7 100644 --- a/.github/workflows/quicktest.yml +++ b/.github/workflows/quicktest.yml @@ -65,13 +65,25 @@ jobs: if: ${{ matrix.dependencies == 'stable' }} run: composer lint - - name: Run the unit tests without code coverage - if: ${{ github.repository_owner != 'WordPress' || 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.repository_owner == 'WordPress' && github.ref_name == 'develop' }} - run: composer coverage + - name: Run the unit tests without code coverage (PHPCS 3.x) + if: ${{ (github.repository_owner != 'WordPress' || 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.repository_owner != 'WordPress' || 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.repository_owner == 'WordPress' && 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.repository_owner == 'WordPress' && github.ref_name == 'develop' && startsWith( steps.phpcs_version.outputs.VERSION, '4.' ) }} + run: composer coverage-phpcs4 - name: Send coverage report to Codecov if: ${{ success() && github.repository_owner == 'WordPress' && github.ref_name == 'develop' }} diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 2fe0e1177..49ebbd12e 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -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' @@ -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: 'dev' + dependencies: 'phpcs-3-dev' + extensions: '' + coverage: false + - php: '8.1' + dependencies: 'phpcs-4-dev' + extensions: '' + coverage: false + - php: '8.4' + dependencies: 'phpcs-3-dev' extensions: '' coverage: false - php: '8.4' - 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' @@ -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" @@ -97,11 +111,15 @@ jobs: coverage: ${{ matrix.coverage && 'xdebug' || 'none' }} tools: cs2pr + # Remove PHPCompatibility as it would (for now) prevent the tests from being able to run against PHPCS 4.x. + - name: 'Composer: remove PHPCompatibility' + run: composer remove --dev phpcompatibility/php-compatibility --no-update --no-interaction + - 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 }}" @@ -127,13 +145,25 @@ jobs: if: ${{ matrix.dependencies == 'stable' }} run: composer lint -- --checkstyle | cs2pr - - name: Run the unit tests without code coverage - if: ${{ matrix.coverage == false || github.repository_owner != 'WordPress' }} - 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.repository_owner != 'WordPress') }} + 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.repository_owner != 'WordPress') }} + 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.repository_owner == 'WordPress' }} + run: composer coverage-phpcs3 - - name: Run the unit tests with code coverage - if: ${{ matrix.coverage == true && github.repository_owner == 'WordPress' }} - 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.repository_owner == 'WordPress' }} + run: composer coverage-phpcs4 - name: Send coverage report to Codecov if: ${{ success() && matrix.coverage == true && github.repository_owner == 'WordPress' }} diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index fd4c95289..219c45f5f 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -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. */ diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index 9a289959e..2f273d568 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Arrays; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ArrayDeclarationSpacing sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\Arrays\ArrayDeclarationSpacingSniff */ -final class ArrayDeclarationSpacingUnitTest extends AbstractSniffUnitTest { +final class ArrayDeclarationSpacingUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php index 2e392f729..650213a99 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Arrays; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ArrayIndentation sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\Arrays\ArrayIndentationSniff */ -final class ArrayIndentationUnitTest extends AbstractSniffUnitTest { +final class ArrayIndentationUnitTest extends AbstractSniffTestCase { /** * The tab width to use during testing. diff --git a/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php b/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php index aa2dc2789..96c8b867a 100644 --- a/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Arrays; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ArrayKeySpacingRestrictions sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\Arrays\ArrayKeySpacingRestrictionsSniff */ -final class ArrayKeySpacingRestrictionsUnitTest extends AbstractSniffUnitTest { +final class ArrayKeySpacingRestrictionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.php b/WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.php index 11a839fc1..6daa1b2a1 100644 --- a/WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.php +++ b/WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Arrays; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the Arrays.MultipleStatementAlignment sniff. @@ -22,7 +22,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\Arrays\MultipleStatementAlignmentSniff */ -final class MultipleStatementAlignmentUnitTest extends AbstractSniffUnitTest { +final class MultipleStatementAlignmentUnitTest extends AbstractSniffTestCase { /** * The tab width to use during testing. diff --git a/WordPress/Tests/CodeAnalysis/AssignmentInTernaryConditionUnitTest.php b/WordPress/Tests/CodeAnalysis/AssignmentInTernaryConditionUnitTest.php index 642a8a70f..4fc10bafe 100644 --- a/WordPress/Tests/CodeAnalysis/AssignmentInTernaryConditionUnitTest.php +++ b/WordPress/Tests/CodeAnalysis/AssignmentInTernaryConditionUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\CodeAnalysis; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the AssignmentInTernaryCondition sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\CodeAnalysis\AssignmentInTernaryConditionSniff */ -final class AssignmentInTernaryConditionUnitTest extends AbstractSniffUnitTest { +final class AssignmentInTernaryConditionUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php b/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php index 4218e90dc..c47dd2dbd 100644 --- a/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php +++ b/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\CodeAnalysis; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the EscapedNotTranslated sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\CodeAnalysis\EscapedNotTranslatedSniff */ -final class EscapedNotTranslatedUnitTest extends AbstractSniffUnitTest { +final class EscapedNotTranslatedUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php b/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php index e43fbb126..e8ab65dfd 100644 --- a/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php +++ b/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DB; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the DirectDatabaseQuery sniff. @@ -21,7 +21,7 @@ * @covers \WordPressCS\WordPress\Helpers\RulesetPropertyHelper * @covers \WordPressCS\WordPress\Sniffs\DB\DirectDatabaseQuerySniff */ -final class DirectDatabaseQueryUnitTest extends AbstractSniffUnitTest { +final class DirectDatabaseQueryUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php index df0bc753b..206474f72 100644 --- a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php +++ b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DB; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PreparedSQLPlaceholders sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\DB\PreparedSQLPlaceholdersSniff */ -final class PreparedSQLPlaceholdersUnitTest extends AbstractSniffUnitTest { +final class PreparedSQLPlaceholdersUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/DB/PreparedSQLUnitTest.php b/WordPress/Tests/DB/PreparedSQLUnitTest.php index 0a296ff98..2cb51f56a 100644 --- a/WordPress/Tests/DB/PreparedSQLUnitTest.php +++ b/WordPress/Tests/DB/PreparedSQLUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DB; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PreparedSQL sniff. @@ -23,7 +23,7 @@ * @covers \WordPressCS\WordPress\Helpers\WPDBTrait * @covers \WordPressCS\WordPress\Sniffs\DB\PreparedSQLSniff */ -final class PreparedSQLUnitTest extends AbstractSniffUnitTest { +final class PreparedSQLUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/DB/RestrictedClassesUnitTest.php b/WordPress/Tests/DB/RestrictedClassesUnitTest.php index a07ace04d..3e8edddde 100644 --- a/WordPress/Tests/DB/RestrictedClassesUnitTest.php +++ b/WordPress/Tests/DB/RestrictedClassesUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DB; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; use WordPressCS\WordPress\AbstractFunctionRestrictionsSniff; /** @@ -23,7 +23,7 @@ * @covers \WordPressCS\WordPress\Helpers\RulesetPropertyHelper * @covers \WordPressCS\WordPress\Sniffs\DB\RestrictedClassesSniff */ -final class RestrictedClassesUnitTest extends AbstractSniffUnitTest { +final class RestrictedClassesUnitTest extends AbstractSniffTestCase { /** * Add a number of extra restricted classes to unit test the abstract diff --git a/WordPress/Tests/DB/RestrictedFunctionsUnitTest.php b/WordPress/Tests/DB/RestrictedFunctionsUnitTest.php index 7b730c5f5..73ab9a2a5 100644 --- a/WordPress/Tests/DB/RestrictedFunctionsUnitTest.php +++ b/WordPress/Tests/DB/RestrictedFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DB; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; use WordPressCS\WordPress\AbstractFunctionRestrictionsSniff; /** @@ -21,7 +21,7 @@ * @covers \WordPressCS\WordPress\AbstractFunctionRestrictionsSniff * @covers \WordPressCS\WordPress\Sniffs\DB\RestrictedFunctionsSniff */ -final class RestrictedFunctionsUnitTest extends AbstractSniffUnitTest { +final class RestrictedFunctionsUnitTest extends AbstractSniffTestCase { /** * Add a number of extra restricted functions to unit test the abstract diff --git a/WordPress/Tests/DB/SlowDBQueryUnitTest.php b/WordPress/Tests/DB/SlowDBQueryUnitTest.php index 46ba3204d..4bd5d67a3 100644 --- a/WordPress/Tests/DB/SlowDBQueryUnitTest.php +++ b/WordPress/Tests/DB/SlowDBQueryUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DB; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the SlowDBQuery sniff. @@ -21,7 +21,7 @@ * @covers \WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff * @covers \WordPressCS\WordPress\Sniffs\DB\SlowDBQuerySniff */ -final class SlowDBQueryUnitTest extends AbstractSniffUnitTest { +final class SlowDBQueryUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php index c667af823..c3b0ed962 100644 --- a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php +++ b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DateTime; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the CurrentTimeTimestamp sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\DateTime\CurrentTimeTimestampSniff */ -final class CurrentTimeTimestampUnitTest extends AbstractSniffUnitTest { +final class CurrentTimeTimestampUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/DateTime/RestrictedFunctionsUnitTest.php b/WordPress/Tests/DateTime/RestrictedFunctionsUnitTest.php index a2f29c236..f4ec71973 100644 --- a/WordPress/Tests/DateTime/RestrictedFunctionsUnitTest.php +++ b/WordPress/Tests/DateTime/RestrictedFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\DateTime; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the DateTime.RestrictedFunctions sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\DateTime\RestrictedFunctionsSniff */ -final class RestrictedFunctionsUnitTest extends AbstractSniffUnitTest { +final class RestrictedFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Files/FileNameUnitTest.php b/WordPress/Tests/Files/FileNameUnitTest.php index c56d3661f..c671695de 100644 --- a/WordPress/Tests/Files/FileNameUnitTest.php +++ b/WordPress/Tests/Files/FileNameUnitTest.php @@ -11,7 +11,7 @@ use PHP_CodeSniffer\Files\DummyFile; use PHP_CodeSniffer\Ruleset; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\TestUtils\ConfigDouble; @@ -24,7 +24,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\Files\FileNameSniff */ -final class FileNameUnitTest extends AbstractSniffUnitTest { +final class FileNameUnitTest extends AbstractSniffTestCase { /** * Error files with the expected nr of errors. diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php index b9beb09ff..babca071a 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\NamingConventions; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PrefixAllGlobals sniff. @@ -20,7 +20,7 @@ * @covers \WordPressCS\WordPress\Helpers\IsUnitTestTrait * @covers \WordPressCS\WordPress\Sniffs\NamingConventions\PrefixAllGlobalsSniff */ -final class PrefixAllGlobalsUnitTest extends AbstractSniffUnitTest { +final class PrefixAllGlobalsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php b/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php index 349091a4d..8168abde4 100644 --- a/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\NamingConventions; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ValidFunctionName sniff. @@ -20,7 +20,7 @@ * @covers \WordPressCS\WordPress\Helpers\DeprecationHelper * @covers \WordPressCS\WordPress\Sniffs\NamingConventions\ValidFunctionNameSniff */ -final class ValidFunctionNameUnitTest extends AbstractSniffUnitTest { +final class ValidFunctionNameUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php index aac97da19..b4b301997 100644 --- a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\NamingConventions; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ValidHookName sniff. @@ -20,7 +20,7 @@ * @covers \WordPressCS\WordPress\Helpers\WPHookHelper * @covers \WordPressCS\WordPress\Sniffs\NamingConventions\ValidHookNameSniff */ -final class ValidHookNameUnitTest extends AbstractSniffUnitTest { +final class ValidHookNameUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php b/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php index 821b73ef2..ce3286bc8 100644 --- a/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\NamingConventions; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PostType sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\NamingConventions\ValidPostTypeSlugSniff */ -final class ValidPostTypeSlugUnitTest extends AbstractSniffUnitTest { +final class ValidPostTypeSlugUnitTest extends AbstractSniffTestCase { /** * Set warnings level to 3 to trigger suggestions as warnings. diff --git a/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.php b/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.php index 0ac884c99..b114521b6 100644 --- a/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\NamingConventions; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ValidVariableName sniff. @@ -20,7 +20,7 @@ * @covers \WordPressCS\WordPress\Helpers\SnakeCaseHelper * @covers \WordPressCS\WordPress\Sniffs\NamingConventions\ValidVariableNameSniff */ -final class ValidVariableNameUnitTest extends AbstractSniffUnitTest { +final class ValidVariableNameUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php b/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php index f3e953545..ec151f59e 100644 --- a/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php +++ b/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PHP_DevelopmentFunctions sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\DevelopmentFunctionsSniff */ -final class DevelopmentFunctionsUnitTest extends AbstractSniffUnitTest { +final class DevelopmentFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/DiscouragedPHPFunctionsUnitTest.php b/WordPress/Tests/PHP/DiscouragedPHPFunctionsUnitTest.php index b9f0e89a1..5e716650a 100644 --- a/WordPress/Tests/PHP/DiscouragedPHPFunctionsUnitTest.php +++ b/WordPress/Tests/PHP/DiscouragedPHPFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PHP_DiscouragedPHPFunctions sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\DiscouragedPHPFunctionsSniff */ -final class DiscouragedPHPFunctionsUnitTest extends AbstractSniffUnitTest { +final class DiscouragedPHPFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/DontExtractUnitTest.php b/WordPress/Tests/PHP/DontExtractUnitTest.php index f9a1df749..038152228 100644 --- a/WordPress/Tests/PHP/DontExtractUnitTest.php +++ b/WordPress/Tests/PHP/DontExtractUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the DontExtract sniff. @@ -20,7 +20,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\DontExtractSniff */ -final class DontExtractUnitTest extends AbstractSniffUnitTest { +final class DontExtractUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/IniSetUnitTest.php b/WordPress/Tests/PHP/IniSetUnitTest.php index fede4955b..477e8234c 100644 --- a/WordPress/Tests/PHP/IniSetUnitTest.php +++ b/WordPress/Tests/PHP/IniSetUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the IniSet sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\IniSetSniff */ -final class IniSetUnitTest extends AbstractSniffUnitTest { +final class IniSetUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php b/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php index 7a576b992..ecc10c46c 100644 --- a/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php +++ b/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PHP.NoSilencedErrors sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\NoSilencedErrorsSniff */ -final class NoSilencedErrorsUnitTest extends AbstractSniffUnitTest { +final class NoSilencedErrorsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/POSIXFunctionsUnitTest.php b/WordPress/Tests/PHP/POSIXFunctionsUnitTest.php index d4086c3e4..75155bb2b 100644 --- a/WordPress/Tests/PHP/POSIXFunctionsUnitTest.php +++ b/WordPress/Tests/PHP/POSIXFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the POSIXFunctions sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\POSIXFunctionsSniff */ -final class POSIXFunctionsUnitTest extends AbstractSniffUnitTest { +final class POSIXFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php b/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php index 63d4e0eb9..402008802 100644 --- a/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php +++ b/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PregQuoteDelimiter sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\PregQuoteDelimiterSniff */ -final class PregQuoteDelimiterUnitTest extends AbstractSniffUnitTest { +final class PregQuoteDelimiterUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.php b/WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.php index 5cfa75ae5..1bc164ee2 100644 --- a/WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.php +++ b/WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PHP_DiscouragedPHPFunctions sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\RestrictedPHPFunctionsSniff */ -final class RestrictedPHPFunctionsUnitTest extends AbstractSniffUnitTest { +final class RestrictedPHPFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/StrictInArrayUnitTest.php b/WordPress/Tests/PHP/StrictInArrayUnitTest.php index 41aa9d37c..f29475e38 100644 --- a/WordPress/Tests/PHP/StrictInArrayUnitTest.php +++ b/WordPress/Tests/PHP/StrictInArrayUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the StrictInArray sniff. @@ -20,7 +20,7 @@ * @covers \WordPressCS\WordPress\AbstractFunctionParameterSniff * @covers \WordPressCS\WordPress\Sniffs\PHP\StrictInArraySniff */ -final class StrictInArrayUnitTest extends AbstractSniffUnitTest { +final class StrictInArrayUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/TypeCastsUnitTest.php b/WordPress/Tests/PHP/TypeCastsUnitTest.php index 878b08992..9c4ac3919 100644 --- a/WordPress/Tests/PHP/TypeCastsUnitTest.php +++ b/WordPress/Tests/PHP/TypeCastsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the TypeCasts sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\TypeCastsSniff */ -final class TypeCastsUnitTest extends AbstractSniffUnitTest { +final class TypeCastsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/PHP/YodaConditionsUnitTest.php b/WordPress/Tests/PHP/YodaConditionsUnitTest.php index 3cb860402..b1cd57c1a 100644 --- a/WordPress/Tests/PHP/YodaConditionsUnitTest.php +++ b/WordPress/Tests/PHP/YodaConditionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\PHP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the YodaConditions sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\PHP\YodaConditionsSniff */ -final class YodaConditionsUnitTest extends AbstractSniffUnitTest { +final class YodaConditionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Security/EscapeOutputUnitTest.php b/WordPress/Tests/Security/EscapeOutputUnitTest.php index b2b7ae21e..fdec9ca73 100644 --- a/WordPress/Tests/Security/EscapeOutputUnitTest.php +++ b/WordPress/Tests/Security/EscapeOutputUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Security; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; use PHPCSUtils\BackCompat\Helper; /** @@ -26,7 +26,7 @@ * @covers \WordPressCS\WordPress\Helpers\PrintingFunctionsTrait * @covers \WordPressCS\WordPress\Sniffs\Security\EscapeOutputSniff */ -final class EscapeOutputUnitTest extends AbstractSniffUnitTest { +final class EscapeOutputUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.php b/WordPress/Tests/Security/NonceVerificationUnitTest.php index aa5e832e8..d9c1121ef 100644 --- a/WordPress/Tests/Security/NonceVerificationUnitTest.php +++ b/WordPress/Tests/Security/NonceVerificationUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Security; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the NonceVerification sniff. @@ -24,7 +24,7 @@ * @covers \WordPressCS\WordPress\Helpers\ContextHelper::is_in_array_comparison * @covers \WordPressCS\WordPress\Sniffs\Security\NonceVerificationSniff */ -final class NonceVerificationUnitTest extends AbstractSniffUnitTest { +final class NonceVerificationUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Security/PluginMenuSlugUnitTest.php b/WordPress/Tests/Security/PluginMenuSlugUnitTest.php index 6741d048a..3d094b885 100644 --- a/WordPress/Tests/Security/PluginMenuSlugUnitTest.php +++ b/WordPress/Tests/Security/PluginMenuSlugUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Security; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PluginMenuSlug sniff. @@ -20,7 +20,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\Security\PluginMenuSlugSniff */ -final class PluginMenuSlugUnitTest extends AbstractSniffUnitTest { +final class PluginMenuSlugUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Security/SafeRedirectUnitTest.php b/WordPress/Tests/Security/SafeRedirectUnitTest.php index 358cdcfdd..42d5eccd1 100644 --- a/WordPress/Tests/Security/SafeRedirectUnitTest.php +++ b/WordPress/Tests/Security/SafeRedirectUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Security; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the Security_SafeRedirect sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\Security\SafeRedirectSniff */ -final class SafeRedirectUnitTest extends AbstractSniffUnitTest { +final class SafeRedirectUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php b/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php index 065162c2a..c670659ae 100644 --- a/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php +++ b/WordPress/Tests/Security/ValidatedSanitizedInputUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\Security; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ValidatedSanitizedInput sniff. @@ -25,7 +25,7 @@ * @covers \WordPressCS\WordPress\Helpers\VariableHelper * @covers \WordPressCS\WordPress\Sniffs\Security\ValidatedSanitizedInputSniff */ -final class ValidatedSanitizedInputUnitTest extends AbstractSniffUnitTest { +final class ValidatedSanitizedInputUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php index a8c7c95e8..d6e880f07 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php @@ -11,7 +11,7 @@ use PHP_CodeSniffer\Files\DummyFile; use PHP_CodeSniffer\Ruleset; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\TestUtils\ConfigDouble; @@ -23,7 +23,7 @@ * @covers \WordPressCS\WordPress\AbstractFunctionParameterSniff::is_targetted_token * @covers \WordPressCS\WordPress\Sniffs\Utils\I18nTextDomainFixerSniff */ -final class I18nTextDomainFixerUnitTest extends AbstractSniffUnitTest { +final class I18nTextDomainFixerUnitTest extends AbstractSniffTestCase { /** * The tab width to use during testing. diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php index b0f1bf96a..abb875643 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the WP_AlternativeFunctions sniff. @@ -20,7 +20,7 @@ * @covers \WordPressCS\WordPress\Helpers\MinimumWPVersionTrait * @covers \WordPressCS\WordPress\Sniffs\WP\AlternativeFunctionsSniff */ -final class AlternativeFunctionsUnitTest extends AbstractSniffUnitTest { +final class AlternativeFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/CapabilitiesUnitTest.php b/WordPress/Tests/WP/CapabilitiesUnitTest.php index 42113c2a2..700553b45 100644 --- a/WordPress/Tests/WP/CapabilitiesUnitTest.php +++ b/WordPress/Tests/WP/CapabilitiesUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; use PHPCSUtils\BackCompat\Helper; /** @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\CapabilitiesSniff */ -final class CapabilitiesUnitTest extends AbstractSniffUnitTest { +final class CapabilitiesUnitTest extends AbstractSniffTestCase { /** * Adjust the config to allow for testing with specific CLI arguments. diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.php b/WordPress/Tests/WP/CapitalPDangitUnitTest.php index ea1cfcf65..d5a9dc279 100644 --- a/WordPress/Tests/WP/CapitalPDangitUnitTest.php +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the CapitalPDangit sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\CapitalPDangitSniff */ -final class CapitalPDangitUnitTest extends AbstractSniffUnitTest { +final class CapitalPDangitUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/ClassNameCaseUnitTest.php b/WordPress/Tests/WP/ClassNameCaseUnitTest.php index 7869ea7f6..01ef4cb6d 100644 --- a/WordPress/Tests/WP/ClassNameCaseUnitTest.php +++ b/WordPress/Tests/WP/ClassNameCaseUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ClassNameCase sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\ClassNameCaseSniff */ -final class ClassNameCaseUnitTest extends AbstractSniffUnitTest { +final class ClassNameCaseUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/CronIntervalUnitTest.php b/WordPress/Tests/WP/CronIntervalUnitTest.php index 81f02c276..66f5d527c 100644 --- a/WordPress/Tests/WP/CronIntervalUnitTest.php +++ b/WordPress/Tests/WP/CronIntervalUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the CronInterval sniff. @@ -20,7 +20,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\CronIntervalSniff */ -final class CronIntervalUnitTest extends AbstractSniffUnitTest { +final class CronIntervalUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/DeprecatedClassesUnitTest.php b/WordPress/Tests/WP/DeprecatedClassesUnitTest.php index 682f144eb..cca29723c 100644 --- a/WordPress/Tests/WP/DeprecatedClassesUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedClassesUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the WP_DeprecatedClasses sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\DeprecatedClassesSniff */ -final class DeprecatedClassesUnitTest extends AbstractSniffUnitTest { +final class DeprecatedClassesUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php index fb53e3723..7fda5f94a 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the WP_DeprecatedFunctions sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\DeprecatedFunctionsSniff */ -final class DeprecatedFunctionsUnitTest extends AbstractSniffUnitTest { +final class DeprecatedFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php index c491b12a4..2fc1deff0 100644 --- a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the DeprecatedParameterValues sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\DeprecatedParameterValuesSniff */ -final class DeprecatedParameterValuesUnitTest extends AbstractSniffUnitTest { +final class DeprecatedParameterValuesUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/DeprecatedParametersUnitTest.php b/WordPress/Tests/WP/DeprecatedParametersUnitTest.php index 3d516ec98..1958014f6 100644 --- a/WordPress/Tests/WP/DeprecatedParametersUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedParametersUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the DeprecatedParameters sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\DeprecatedParametersSniff */ -final class DeprecatedParametersUnitTest extends AbstractSniffUnitTest { +final class DeprecatedParametersUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php index e27fd838c..e497947c3 100644 --- a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the WP_DiscouragedConstants sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\DiscouragedConstantsSniff */ -final class DiscouragedConstantsUnitTest extends AbstractSniffUnitTest { +final class DiscouragedConstantsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/DiscouragedFunctionsUnitTest.php b/WordPress/Tests/WP/DiscouragedFunctionsUnitTest.php index 825ff3970..92ce2acf4 100644 --- a/WordPress/Tests/WP/DiscouragedFunctionsUnitTest.php +++ b/WordPress/Tests/WP/DiscouragedFunctionsUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the WP_DiscouragedFunctions sniff. @@ -22,7 +22,7 @@ * @covers \WordPressCS\WordPress\Helpers\ContextHelper::is_token_namespaced * @covers \WordPressCS\WordPress\Sniffs\WP\DiscouragedFunctionsSniff */ -final class DiscouragedFunctionsUnitTest extends AbstractSniffUnitTest { +final class DiscouragedFunctionsUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php index 4273b3f01..37cfc248a 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the EnqueuedCheck sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\EnqueuedResourceParametersSniff */ -final class EnqueuedResourceParametersUnitTest extends AbstractSniffUnitTest { +final class EnqueuedResourceParametersUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php b/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php index d32954930..0eb9f9050 100644 --- a/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php +++ b/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the EnqueuedResources sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\EnqueuedResourcesSniff */ -final class EnqueuedResourcesUnitTest extends AbstractSniffUnitTest { +final class EnqueuedResourcesUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/GetMetaSingleUnitTest.php b/WordPress/Tests/WP/GetMetaSingleUnitTest.php index f1b328c39..174f01edf 100644 --- a/WordPress/Tests/WP/GetMetaSingleUnitTest.php +++ b/WordPress/Tests/WP/GetMetaSingleUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the GetMetaSingle sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\GetMetaSingleSniff */ -final class GetMetaSingleUnitTest extends AbstractSniffUnitTest { +final class GetMetaSingleUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.php b/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.php index 954b65ee4..513c72c0f 100644 --- a/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.php +++ b/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the GlobalVariables sniff. @@ -23,7 +23,7 @@ * @covers \WordPressCS\WordPress\Helpers\WPGlobalVariablesHelper * @covers \WordPressCS\WordPress\Sniffs\WP\GlobalVariablesOverrideSniff */ -final class GlobalVariablesOverrideUnitTest extends AbstractSniffUnitTest { +final class GlobalVariablesOverrideUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index 3834eb189..15c12f94f 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the I18n sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WP\I18nSniff */ -final class I18nUnitTest extends AbstractSniffUnitTest { +final class I18nUnitTest extends AbstractSniffTestCase { /** * Set CLI values before the file is tested. diff --git a/WordPress/Tests/WP/PostsPerPageUnitTest.php b/WordPress/Tests/WP/PostsPerPageUnitTest.php index bf3296ce2..a25d56f5b 100644 --- a/WordPress/Tests/WP/PostsPerPageUnitTest.php +++ b/WordPress/Tests/WP/PostsPerPageUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WP; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the PostsPerPage sniff. @@ -23,7 +23,7 @@ * @covers \WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff * @covers \WordPressCS\WordPress\Sniffs\WP\PostsPerPageSniff */ -final class PostsPerPageUnitTest extends AbstractSniffUnitTest { +final class PostsPerPageUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php index 5392cf485..bae649d13 100644 --- a/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WhiteSpace; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the CastStructureSpacing sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WhiteSpace\CastStructureSpacingSniff */ -final class CastStructureSpacingUnitTest extends AbstractSniffUnitTest { +final class CastStructureSpacingUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php index e173ae0ec..9590baf6b 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WhiteSpace; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ControlStructureSpacing sniff. @@ -19,7 +19,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WhiteSpace\ControlStructureSpacingSniff */ -final class ControlStructureSpacingUnitTest extends AbstractSniffUnitTest { +final class ControlStructureSpacingUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WhiteSpace/ObjectOperatorSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/ObjectOperatorSpacingUnitTest.php index adfbe1ba9..d86058e99 100644 --- a/WordPress/Tests/WhiteSpace/ObjectOperatorSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/ObjectOperatorSpacingUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WhiteSpace; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the ObjectOperatorSpacing sniff. @@ -18,7 +18,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WhiteSpace\ObjectOperatorSpacingSniff */ -final class ObjectOperatorSpacingUnitTest extends AbstractSniffUnitTest { +final class ObjectOperatorSpacingUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php index d7343f1ec..ff97a5547 100644 --- a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php @@ -9,7 +9,7 @@ namespace WordPressCS\WordPress\Tests\WhiteSpace; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Unit test class for the OperatorSpacing sniff. @@ -21,7 +21,7 @@ * * @covers \WordPressCS\WordPress\Sniffs\WhiteSpace\OperatorSpacingSniff */ -final class OperatorSpacingUnitTest extends AbstractSniffUnitTest { +final class OperatorSpacingUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. diff --git a/composer.json b/composer.json index a5afb55f6..a98caf602 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ }, "require-dev": { "phpcompatibility/php-compatibility": "^9.0", - "phpunit/phpunit": "^8.0 || ^9.0", + "phpunit/phpunit": "^8.0 || ^9.3.4", "phpcsstandards/phpcsdevtools": "^1.2.0", "php-parallel-lint/php-parallel-lint": "^1.4.0", "php-parallel-lint/php-console-highlighter": "^1.0.0" @@ -52,12 +52,18 @@ "fix-cs": [ "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf" ], - "run-tests": [ + "run-tests-phpcs3": [ "@php ./vendor/phpunit/phpunit/phpunit --filter WordPress ./vendor/squizlabs/php_codesniffer/tests/AllTests.php --no-coverage" ], - "coverage": [ + "run-tests-phpcs4": [ + "@php ./vendor/phpunit/phpunit/phpunit --no-coverage" + ], + "coverage-phpcs3": [ "@php ./vendor/phpunit/phpunit/phpunit --filter WordPress ./vendor/squizlabs/php_codesniffer/tests/AllTests.php" ], + "coverage-phpcs4": [ + "@php ./vendor/phpunit/phpunit/phpunit" + ], "check-complete": [ "@php ./vendor/phpcsstandards/phpcsdevtools/bin/phpcs-check-feature-completeness -q ./WordPress" ], @@ -67,7 +73,7 @@ "check-all": [ "@lint", "@check-cs", - "@run-tests", + "if [ -f ./vendor/squizlabs/php_codesniffer/tests/AllTests.php ]; then composer run-tests-phpcs3; else composer run-tests-phpcs4; fi", "@check-complete-strict" ] }, @@ -75,8 +81,10 @@ "lint": "Lint PHP files against parse errors.", "check-cs": "Run the PHPCS script against the entire codebase.", "fix-cs": "Run the PHPCBF script to fix all the autofixable violations on the codebase.", - "run-tests": "Run all the unit tests for the WordPress Coding Standards sniffs without code coverage.", - "coverage": "Run all the unit tests for the WordPress Coding Standards sniffs with code coverage.", + "run-tests-phpcs3": "Run all the unit tests for the WordPress Coding Standards sniffs without code coverage (PHPCS 3.x).", + "run-tests-phpcs4": "Run all the unit tests for the WordPress Coding Standards sniffs without code coverage (PHPCS 4.x).", + "coverage-phpcs3": "Run all the unit tests for the WordPress Coding Standards sniffs with code coverage (PHPCS 3.x).", + "coverage-phpcs4": "Run all the unit tests for the WordPress Coding Standards sniffs with code coverage (PHPCS 4.x).", "check-complete": "Check if all the sniffs have tests.", "check-complete-strict": "Check if all the sniffs have unit tests and XML documentation.", "check-all": "Run all checks (lint, phpcs, feature completeness) and tests." From 522264e12aa3b83c6e7063cf7d841a31ca4dd39e Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 7 Aug 2025 09:03:02 -0300 Subject: [PATCH 04/62] PR 2619 DB/DirectDatabaseQuery: fix handling of namespaced calls to cache functions Before this sniff was not properly differentiating between fully qualified calls to global WP cache functions, and namespaced calls to non-WP functions with the same name as the WP functions. In other words, the sniff was correctly identifying `\wp_cache_get()` as a WP cache function, but it was incorrectly identifying `MyNamespace\wp_cache_get()` as a WP cache function. This commit fixes this issue. --- .../Sniffs/DB/DirectDatabaseQuerySniff.php | 9 ++++ .../DB/DirectDatabaseQueryUnitTest.1.inc | 44 +++++++++++++++++++ .../Tests/DB/DirectDatabaseQueryUnitTest.php | 4 ++ 3 files changed, 57 insertions(+) diff --git a/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php index a600e6ae8..57fa39966 100644 --- a/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php @@ -235,6 +235,15 @@ public function process_token( $stackPtr ) { continue; } + // Skip if this is a non-global namespaced function call. + $prevNonEmpty = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $i - 1 ), null, true ); + if ( \T_NS_SEPARATOR === $this->tokens[ $prevNonEmpty ]['code'] ) { + $prevPrevNonEmpty = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $prevNonEmpty - 1 ), null, true ); + if ( \T_STRING === $this->tokens[ $prevPrevNonEmpty ]['code'] || \T_NAMESPACE === $this->tokens[ $prevPrevNonEmpty ]['code'] ) { + continue; + } + } + $content = strtolower( $this->tokens[ $i ]['content'] ); if ( isset( $this->cacheDeleteFunctions[ $content ] ) ) { diff --git a/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.1.inc b/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.1.inc index 1a6be76a5..a56d37a5e 100644 --- a/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.1.inc +++ b/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.1.inc @@ -379,3 +379,47 @@ function methodNamesSameAsCacheFunctions() { return $listofthings; } + +function fullyQualifiedCallsToCacheFunctions1() { + global $wpdb; + + if ( ! ( $listofthings = \wp_cache_get( $foo ) ) ) { + $listofthings = $wpdb->get_col( 'SELECT something FROM somewhere WHERE someotherthing = 1' ); // Warning direct DB call. + \wp_cache_set( 'foo', $listofthings ); + } + + return $listofthings; +} + +function fullyQualifiedCallsToCacheFunctions2() { + global $wpdb; + + $wpdb->query( 'SELECT X FROM Y' ); // Warning direct DB call. + \wp_cache_delete( 'key', 'group' ); +} + +function callToNamespacedNonGlobalFunctions1() { + global $wpdb; + + $listofthings = MyNamespace\wp_cache_get( $foo ); + $listofthings = \MyNamespace\wp_cache_get( $foo ); + $listofthings = namespace\wp_cache_get( $foo ); // The sniff should start considering this a valid WP cache function once it can resolve relative namespaces. + + if ( ! $listofthings ) { + $listofthings = $wpdb->get_col( 'SELECT something FROM somewhere WHERE someotherthing = 1' ); // Warning x 2. + MyNamespace\wp_cache_set( 'foo', $listofthings ); + \MyNamespace\wp_cache_set( 'foo', $listofthings ); + namespace\wp_cache_set( 'foo', $listofthings ); // The sniff should start considering this a valid WP cache function once it can resolve relative namespaces. + } + + return $listofthings; +} + +function callToNamespacedNonGlobalFunctions2() { + global $wpdb; + + $wpdb->query( 'SELECT X FROM Y' ); // Warning x 2. + MyNamespace\wp_cache_delete( 'key', 'group' ); + \MyNamespace\wp_cache_delete( 'key', 'group' ); + namespace\wp_cache_delete( 'key', 'group' ); // The sniff should start considering this a valid WP cache function once it can resolve relative namespaces. +} diff --git a/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php b/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php index e8ab65dfd..8fbd71c42 100644 --- a/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php +++ b/WordPress/Tests/DB/DirectDatabaseQueryUnitTest.php @@ -99,6 +99,10 @@ public function getWarningList( $testFile = '' ) { 350 => 1, 364 => 2, 376 => 1, + 387 => 1, + 397 => 1, + 409 => 2, + 421 => 2, ); default: return array(); From 0c00842d7e3ac596a68e76012d09432990dfa934 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Fri, 15 Aug 2025 15:21:55 -0300 Subject: [PATCH 05/62] PR 2579 ConstantsHelper::is_use_of_global_constant(): fix false positive in constant alias This method was incorrectly identifying constant alias as the use of a global constant which is incorrect. This change aligns this method with how the sibling method in PHPCompatibility behaves. --- WordPress/Helpers/ConstantsHelper.php | 1 + WordPress/Tests/WP/DiscouragedConstantsUnitTest.php | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/Helpers/ConstantsHelper.php b/WordPress/Helpers/ConstantsHelper.php index 6decbb401..320c6312f 100644 --- a/WordPress/Helpers/ConstantsHelper.php +++ b/WordPress/Helpers/ConstantsHelper.php @@ -79,6 +79,7 @@ public static function is_use_of_global_constant( File $phpcsFile, $stackPtr ) { \T_INSTANCEOF => true, \T_INSTEADOF => true, \T_GOTO => true, + \T_AS => true, ); $tokens_to_ignore += Tokens::$ooScopeTokens; $tokens_to_ignore += Collections::objectOperators(); diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php index e497947c3..133a9887f 100644 --- a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php @@ -49,7 +49,6 @@ public function getWarningList() { 60 => 1, 61 => 1, 63 => 1, - 64 => 1, 66 => 1, 67 => 1, 71 => 1, From 8ff3e3b863100fd49b892ac3a04669b70a4ba076 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 16:47:14 -0300 Subject: [PATCH 06/62] PR 2617 WP/AlternativeFunctions: add tests for namespaced names --- WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc | 8 ++++++++ WordPress/Tests/WP/AlternativeFunctionsUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc index a88e5638a..3336dd0b1 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.inc @@ -147,3 +147,11 @@ file_get_contents( // Not using plugin_dir_path() for reasons. $url ); // Warning. + +/* + * Safeguard support for PHP 8.0+ tokenization of namespaced "names". + */ +\curl_init(); +MyNamespace\curl_init(); +\MyNamespace\curl_init(); +namespace\curl_init(); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php index abb875643..e509e1805 100644 --- a/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php +++ b/WordPress/Tests/WP/AlternativeFunctionsUnitTest.php @@ -89,6 +89,7 @@ public function getWarningList() { 131 => 1, 142 => 1, 146 => 1, + 154 => 1, ); } } From 9d1a1de252d8231c74da1c2ec140cabc8f1c5395 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 19 Aug 2025 14:24:34 -0300 Subject: [PATCH 07/62] PR 2620 Utils/I18nTextDomainFixer: add tests for namespaced names There were already a few tests with namespaced names, so this commit adds only what was missing in the existing tests. --- WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc | 8 ++++++++ .../Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed | 8 ++++++++ WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php | 2 ++ 3 files changed, 18 insertions(+) diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc index d33d0a18e..fb5e1b852 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc @@ -281,5 +281,13 @@ __ ( $args ); +/* + * Safeguard correct handling of namespaced function calls (partially qualified is already tested above). + */ +\MyNamespace\load_textdomain( 'text-domain', '/path/to/file.mo' ); +namespace\load_textdomain( 'text-domain', '/path/to/file.mo' ); +\load_textdomain( 'text-domain', '/path/to/file.mo' ); +\load_textdomain(); + // phpcs:set WordPress.Utils.I18nTextDomainFixer old_text_domain[] // phpcs:set WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed index f7fd2c6f4..f47da4e17 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed @@ -287,5 +287,13 @@ __ ( 'something-else' ); +/* + * Safeguard correct handling of namespaced function calls (partially qualified is already tested above). + */ +\MyNamespace\load_textdomain( 'text-domain', '/path/to/file.mo' ); +namespace\load_textdomain( 'text-domain', '/path/to/file.mo' ); +\load_textdomain( 'something-else', '/path/to/file.mo' ); +\load_textdomain( 'something-else' ); + // phpcs:set WordPress.Utils.I18nTextDomainFixer old_text_domain[] // phpcs:set WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php index d6e880f07..567472098 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php @@ -154,6 +154,8 @@ public function getErrorList( $testFile = '' ) { 245 => 1, 277 => 1, 278 => 1, + 289 => 1, + 290 => 1, ); default: From 0a6510f637c702d102cf26c86df55426d7ec0a95 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 15:18:14 -0300 Subject: [PATCH 08/62] PR 2620 Security/NonceVerification: add tests for namespaced names --- .../Security/NonceVerificationUnitTest.1.inc | 18 ++++++++++++++++++ .../Security/NonceVerificationUnitTest.php | 1 + 2 files changed, 19 insertions(+) diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.1.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.1.inc index aee51ae39..792ccf58d 100644 --- a/WordPress/Tests/Security/NonceVerificationUnitTest.1.inc +++ b/WordPress/Tests/Security/NonceVerificationUnitTest.1.inc @@ -524,3 +524,21 @@ function different_function_name() { update_post_meta( (int) $_POST['id'], 'a_key', $_POST['a_value'] ); } // phpcs:set WordPress.Security.NonceVerification customNonceVerificationFunctions[] + +function test_fully_qualified_call_to_global_nonce_verification_function() { + if ( ! is_numeric ( $_POST['foo'] ) ) { + return; + } + + \wp_verify_nonce( 'some_action' ); // OK. +} + +function test_namespaced_calls_to_incorrect_functions() { + if ( ! is_numeric ( $_POST['foo'] ) ) { + return; + } + + MyNamespace\wp_verify_nonce( 'some_action' ); // Bad. + \MyNamespace\wp_verify_nonce( 'some_action' ); // Bad. + namespace\wp_verify_nonce( 'some_action' ); // Bad, but should become ok once the sniff is able to resolve relative namespaces. +} diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.php b/WordPress/Tests/Security/NonceVerificationUnitTest.php index d9c1121ef..2d5cc16f4 100644 --- a/WordPress/Tests/Security/NonceVerificationUnitTest.php +++ b/WordPress/Tests/Security/NonceVerificationUnitTest.php @@ -75,6 +75,7 @@ public function getErrorList( $testFile = '' ) { 470 => 1, 478 => 1, 524 => 2, + 537 => 1, ); case 'NonceVerificationUnitTest.2.inc': From a2fff27ea59d2a4b628319934bfcb5f792403e05 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 15:24:04 -0300 Subject: [PATCH 09/62] PR 2620 NamingConventions/ValidHookName: add tests for namespaced names --- .../Tests/NamingConventions/ValidHookNameUnitTest.1.inc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc index 830c3552d..ecc8940d3 100644 --- a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc +++ b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc @@ -121,3 +121,10 @@ do_action( 'admin_head_' . $fn( 'UPPERCASE', 'wrong-delimiter' ) . '_action' ); do_action_ref_array( hook: 'My-Hook', args: $args ); // OK. Well, not really, but using the wrong parameter name, so not our concern. do_action_ref_array( args: $args, hook_name: 'my_hook', ); // OK. do_action_ref_array( args: $args, hook_name: 'My-Hook', ); // Error - use lowercase + warning about dash. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +do_action( 'admin_head_' . MyNamespace\my_function('UPPERCASE') . '_action' ); // Ok. +do_action( 'admin_head_' . \MyNamespace\my_function('UPPERCASE') . '_action' ); // Ok. +do_action( 'admin_head_' . namespace\my_function('UPPERCASE') . '_action' ); // Ok. From 22676ccd8fb43f4a8592c9e94f84e17526dbbcd2 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 15:35:33 -0300 Subject: [PATCH 10/62] PR 2620 NamingConventions/PrefixAllGlobals: add tests for namespaced names --- .../NamingConventions/PrefixAllGlobalsUnitTest.1.inc | 8 ++++++++ .../Tests/NamingConventions/PrefixAllGlobalsUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc index 011e250b7..7db871a29 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc @@ -683,4 +683,12 @@ class Acronym_AsymmetricVisibilityProperties { public function __construct(public protected(set) int $foo = 0) {} // Ok. } +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\define('SOME_GLOBAL', [ 1, 2, 3 ]); // Bad. +MyNamespace\define('SOME_GLOBAL', [ 1, 2, 3 ]); // Ok. +\MyNamespace\define('SOME_GLOBAL', [ 1, 2, 3 ]); // Ok. +namespace\define('SOME_GLOBAL', [ 1, 2, 3 ]); // Ok. + // phpcs:set WordPress.NamingConventions.PrefixAllGlobals prefixes[] diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php index babca071a..cb3398383 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php @@ -96,6 +96,7 @@ public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.1.inc' ) { 616 => 1, 617 => 1, 633 => 1, + 689 => 1, ); case 'PrefixAllGlobalsUnitTest.4.inc': From e241175e17307d363cdd3b56c9b9aaf8ffb18940 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 15:40:11 -0300 Subject: [PATCH 11/62] PR 2620 PHP/NoSilencedErrors: add tests for namespaced names --- WordPress/Tests/PHP/NoSilencedErrorsUnitTest.inc | 7 +++++++ WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php | 3 +++ 2 files changed, 10 insertions(+) diff --git a/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.inc b/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.inc index f007d150b..3fc75bc24 100644 --- a/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.inc +++ b/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.inc @@ -84,3 +84,10 @@ $decoded = @hex2bin( $data ); // phpcs:set WordPress.PHP.NoSilencedErrors context_length 0 echo @some_userland_function( $param ); // Bad. // phpcs:set WordPress.PHP.NoSilencedErrors context_length 6 + +/* + * Safeguard correct handling of namespaced function calls (fully qualified is already tested above). + */ +$file = @MyNS\MyClass::file_get_contents( $file ); // Bad. +$file = @namespace\MyNS\MyClass::file_get_contents( $file ); // Bad. +$file = @namespace\file_get_contents( $file ); // The sniff should stop flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php b/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php index ecc10c46c..a0a9acb2d 100644 --- a/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php +++ b/WordPress/Tests/PHP/NoSilencedErrorsUnitTest.php @@ -61,6 +61,9 @@ public function getWarningList() { 71 => 1, 78 => 1, 85 => 1, + 91 => 1, + 92 => 1, + 93 => 1, ); } } From 8dc4fa20966f28b98dff78acfa33388d9deed090 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 15:51:17 -0300 Subject: [PATCH 12/62] PR 2620 WP/CronInterval: add tests for namespaced names --- WordPress/Tests/WP/CronIntervalUnitTest.inc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/WordPress/Tests/WP/CronIntervalUnitTest.inc b/WordPress/Tests/WP/CronIntervalUnitTest.inc index e9541f49d..2dc9379fa 100644 --- a/WordPress/Tests/WP/CronIntervalUnitTest.inc +++ b/WordPress/Tests/WP/CronIntervalUnitTest.inc @@ -165,7 +165,7 @@ add_filter( 'cron_schedules', function ( $schedules ) { class FQNConstants { public function add_schedules() { add_filter( 'cron_schedules', array( $this, 'add_weekly_schedule' ) ); // Ok: > 15 min. - add_filter( 'cron_schedules', array( $this, 'add_eight_minute_schedule' ) ); // Warning: 8 min. + \add_filter( 'cron_schedules', array( $this, 'add_eight_minute_schedule' ) ); // Warning: 8 min. add_filter( 'cron_schedules', array( $this, 'add_hundred_minute_schedule' ) ); // Warning: time undetermined. add_filter( 'cron_schedules', array( $this, 'sneaky_fake_wp_constant_schedule' ) ); // Warning: time undetermined. } @@ -326,3 +326,11 @@ function first_class_six_min_schedule( $schedules ) { } add_filter( 'cron_schedules', first_class_six_min_schedule(...)); // Warning: 6 min. add_filter( 'cron_schedules', 'first_class_six_min_schedule'(...)); // Warning: 6 min. + +/* + * Safeguard correct handling of all types of namespaced function calls (except FQN global function call which is + * handled above). + */ +MyNamespace\add_filter( 'cron_schedules', 'unknown_callback' ); // Ok. +\MyNamespace\add_filter( 'cron_schedules', 'unknown_callback' ); // Ok. +namespace\add_filter( 'cron_schedules', 'unknown_callback' ); // Ok. The sniff should start flagging this once it can resolve relative namespaces. From 2eeb734746daabe2ff8dc08ccad3ad01a609aaf8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Mon, 18 Aug 2025 16:22:44 -0300 Subject: [PATCH 13/62] PR 2620 WP/DiscouragedConstants: add tests for namespaced function calls Add tests safeguarding that namespaced calls to functions named `define` are handled correctly. --- .../Tests/WP/DiscouragedConstantsUnitTest.inc | 8 ++++ .../Tests/WP/DiscouragedConstantsUnitTest.php | 39 ++++++++++--------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc index ea8ae7252..bed0914d5 100644 --- a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc @@ -102,3 +102,11 @@ enum ContainsConst { } echo HEADER_TEXTCOLOR::$var; // OK. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\define( 'STYLESHEETPATH', 'something' ); // Bad. +\MyNamespace\define( 'STYLESHEETPATH', 'something' ); // Ok. +MyNamespace\define( 'STYLESHEETPATH', 'something' ); // Ok. +namespace\define( 'STYLESHEETPATH', 'something' ); // Ok. diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php index 133a9887f..2691ee6ea 100644 --- a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php @@ -36,25 +36,26 @@ public function getErrorList() { */ public function getWarningList() { return array( - 50 => 1, - 51 => 1, - 52 => 1, - 53 => 1, - 54 => 1, - 55 => 1, - 56 => 1, - 57 => 1, - 58 => 1, - 59 => 1, - 60 => 1, - 61 => 1, - 63 => 1, - 66 => 1, - 67 => 1, - 71 => 1, - 72 => 1, - 83 => 1, - 88 => 1, + 50 => 1, + 51 => 1, + 52 => 1, + 53 => 1, + 54 => 1, + 55 => 1, + 56 => 1, + 57 => 1, + 58 => 1, + 59 => 1, + 60 => 1, + 61 => 1, + 63 => 1, + 66 => 1, + 67 => 1, + 71 => 1, + 72 => 1, + 83 => 1, + 88 => 1, + 109 => 1, ); } } From d009a42e4fdb008195d45b33d5b566596bafb701 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 13:33:43 -0300 Subject: [PATCH 14/62] PR 2633 CodeAnalysis/EscapedNotTranslated: add tests for namespaced names --- .../Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.inc | 8 ++++++++ .../Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php | 7 ++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.inc b/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.inc index c451ccc91..d9831fe88 100644 --- a/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.inc +++ b/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.inc @@ -9,3 +9,11 @@ esc_attr( 'text', // Some comment. MY_DOMAIN // More comment. ); // Warning. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\esc_attr( 'text', 'domain' ); +MyNamespace\esc_attr( 'text', 'domain' ); +\MyNamespace\esc_attr( 'text', 'domain' ); +namespace\esc_attr( 'text', 'domain' ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php b/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php index c47dd2dbd..781a8ede8 100644 --- a/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php +++ b/WordPress/Tests/CodeAnalysis/EscapedNotTranslatedUnitTest.php @@ -36,9 +36,10 @@ public function getErrorList() { */ public function getWarningList() { return array( - 6 => 1, - 7 => 1, - 8 => 1, + 6 => 1, + 7 => 1, + 8 => 1, + 16 => 1, ); } } From 876a1093463fbb9040f8c2dc416460b66fc22697 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 13:42:26 -0300 Subject: [PATCH 15/62] PR 2633 DateTime/CurrentTimeTimestamp: add tests for namespaced names --- WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc | 8 ++++++++ .../Tests/DateTime/CurrentTimeTimestampUnitTest.inc.fixed | 8 ++++++++ WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php | 1 + 3 files changed, 17 insertions(+) diff --git a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc index 07634e769..665c7e88b 100644 --- a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc +++ b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc @@ -30,3 +30,11 @@ current_time( gmt: true, type: 'mysql', ); // OK. current_time( type: 'Y-m-d' ); // OK. current_time( gmt: true, type: 'timestamp' ); // Error. current_time( gmt: 0, type : 'U' ); // Warning. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\current_time( 'timestamp', true ); +MyNamespace\current_time( 'timestamp', true ); +\MyNamespace\current_time( 'timestamp', true ); +namespace\current_time( 'timestamp', true ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc.fixed b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc.fixed index 5b2fa7e28..3c01c1ff5 100644 --- a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc.fixed +++ b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.inc.fixed @@ -27,3 +27,11 @@ current_time( gmt: true, type: 'mysql', ); // OK. current_time( type: 'Y-m-d' ); // OK. time(); // Error. current_time( gmt: 0, type : 'U' ); // Warning. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\time(); +MyNamespace\current_time( 'timestamp', true ); +\MyNamespace\current_time( 'timestamp', true ); +namespace\current_time( 'timestamp', true ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php index c3b0ed962..ad7b25e22 100644 --- a/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php +++ b/WordPress/Tests/DateTime/CurrentTimeTimestampUnitTest.php @@ -31,6 +31,7 @@ public function getErrorList() { 11 => 1, 17 => 1, 31 => 1, + 37 => 1, ); } From ebe557f8dbf160ca69609617a9cd0e8a82cab5c3 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 13:51:05 -0300 Subject: [PATCH 16/62] PR 2633 NamingConventions/ValidPostTypeSlug: add tests for namespaced names --- .../NamingConventions/ValidPostTypeSlugUnitTest.1.inc | 8 ++++++++ .../Tests/NamingConventions/ValidPostTypeSlugUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.1.inc b/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.1.inc index 5c0ed5729..724533d85 100644 --- a/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.1.inc +++ b/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.1.inc @@ -68,3 +68,11 @@ register_post_type( // Post type name. $name,// Non string literal. Warning with severity: 3 ); + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\register_post_type( 'my-own-post-type-too-long', array() ); // Bad. +MyNamespace\register_post_type( 'my-own-post-type-too-long', array() ); // Ok. +\MyNamespace\register_post_type( 'my-own-post-type-too-long', array() ); // Ok. +namespace\register_post_type( 'my-own-post-type-too-long', array() ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php b/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php index ce3286bc8..fddd4b4bb 100644 --- a/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidPostTypeSlugUnitTest.php @@ -57,6 +57,7 @@ public function getErrorList( $testFile = '' ) { 52 => 1, 62 => 1, 64 => 1, + 75 => 1, ); case 'ValidPostTypeSlugUnitTest.2.inc': From c3db33160dc17ac603e856ab293888887c6e6ff8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 13:51:30 -0300 Subject: [PATCH 17/62] PR 2633 PHP/IniSet: add tests for namespaced names --- WordPress/Tests/PHP/IniSetUnitTest.inc | 8 ++++++++ WordPress/Tests/PHP/IniSetUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/PHP/IniSetUnitTest.inc b/WordPress/Tests/PHP/IniSetUnitTest.inc index c5ef7295d..652c61c6d 100644 --- a/WordPress/Tests/PHP/IniSetUnitTest.inc +++ b/WordPress/Tests/PHP/IniSetUnitTest.inc @@ -58,3 +58,11 @@ ini_set( // Set the number of decimals. 0 ); // Error. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\ini_set( 'bcmath.scale', 0 ); // Error. +MyNamespace\ini_set( 'bcmath.scale', 0 ); // Ok. +\MyNamespace\ini_set( 'bcmath.scale', 0 ); // Ok. +namespace\ini_set( 'bcmath.scale', 0 ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/PHP/IniSetUnitTest.php b/WordPress/Tests/PHP/IniSetUnitTest.php index 477e8234c..e3b78a65a 100644 --- a/WordPress/Tests/PHP/IniSetUnitTest.php +++ b/WordPress/Tests/PHP/IniSetUnitTest.php @@ -49,6 +49,7 @@ public function getErrorList() { 42 => 1, 51 => 1, 55 => 1, + 65 => 1, ); } From 732f8d1d024cf900da5d0c730ad113af5a3f1c3b Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 14:13:37 -0300 Subject: [PATCH 18/62] PR 2633 Security/PluginMenuSlug: add tests for namespaced names --- WordPress/Tests/Security/PluginMenuSlugUnitTest.inc | 8 ++++++++ WordPress/Tests/Security/PluginMenuSlugUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/Security/PluginMenuSlugUnitTest.inc b/WordPress/Tests/Security/PluginMenuSlugUnitTest.inc index 2c77ee621..8d941a207 100644 --- a/WordPress/Tests/Security/PluginMenuSlugUnitTest.inc +++ b/WordPress/Tests/Security/PluginMenuSlugUnitTest.inc @@ -20,3 +20,11 @@ add_submenu_page( parent_slug: __FILE__, // Bad. capability: $capability, ); + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\add_menu_page( $page_title, $menu_title, $capability, __FILE__, $function, $icon_url, $position ); // Bad. +MyNamespace\add_menu_page( $page_title, $menu_title, $capability, __FILE__, $function, $icon_url, $position ); // Ok. +\MyNamespace\add_menu_page( $page_title, $menu_title, $capability, __FILE__, $function, $icon_url, $position ); // Ok. +namespace\add_menu_page( $page_title, $menu_title, $capability, __FILE__, $function, $icon_url, $position ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/Security/PluginMenuSlugUnitTest.php b/WordPress/Tests/Security/PluginMenuSlugUnitTest.php index 3d094b885..a18a0fca2 100644 --- a/WordPress/Tests/Security/PluginMenuSlugUnitTest.php +++ b/WordPress/Tests/Security/PluginMenuSlugUnitTest.php @@ -42,6 +42,7 @@ public function getWarningList() { 5 => 1, 9 => 2, 20 => 1, + 27 => 1, ); } } From d28fa7ae1d409287220ee0410d5536db2233844b Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 14:14:13 -0300 Subject: [PATCH 19/62] PR 2633 PHP/PregQuoteDelimiter: add tests for namespaced names --- WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.inc | 8 ++++++++ WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.inc b/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.inc index 1942b2b07..3cc54cbeb 100644 --- a/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.inc +++ b/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.inc @@ -13,3 +13,11 @@ preg_quote(delimiter: '#', str: $keywords); // OK. preg_quote(str: $keywords); // Warning. preg_quote(str: $keywords, delimitter: '#'); // Warning (typo in param name). preg_quote(delimiter: '#'); // OK. Invalid function call, but that's not the concern of this sniff. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\preg_quote($keywords); // Warning. +MyNamespace\preg_quote($keywords); // Ok. +\MyNamespace\preg_quote($keywords); // Ok. +namespace\preg_quote($keywords); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php b/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php index 402008802..c78b3c1dd 100644 --- a/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php +++ b/WordPress/Tests/PHP/PregQuoteDelimiterUnitTest.php @@ -40,6 +40,7 @@ public function getWarningList() { 7 => 1, 13 => 1, 14 => 1, + 20 => 1, ); } } From 08ed8ab83027af5f0a849204f7d6d4f754a998cc Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 14:14:47 -0300 Subject: [PATCH 20/62] PR 2633 PHP/StrictInArray: add tests for namespaced names --- WordPress/Tests/PHP/StrictInArrayUnitTest.inc | 8 ++++++++ WordPress/Tests/PHP/StrictInArrayUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/PHP/StrictInArrayUnitTest.inc b/WordPress/Tests/PHP/StrictInArrayUnitTest.inc index fd1e19422..1c18b4163 100644 --- a/WordPress/Tests/PHP/StrictInArrayUnitTest.inc +++ b/WordPress/Tests/PHP/StrictInArrayUnitTest.inc @@ -55,3 +55,11 @@ array_search( $haystack, true // Use strict typing. ); // Ok. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\in_array( 1, array( '1', 2 ) ); // Bad. +MyNamespace\in_array( 1, array( '1', 2 ) ); // Ok. +\MyNamespace\in_array( 1, array( '1', 2 ) ); // Ok. +namespace\in_array( 1, array( '1', 2 ) ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/PHP/StrictInArrayUnitTest.php b/WordPress/Tests/PHP/StrictInArrayUnitTest.php index f29475e38..309f61f32 100644 --- a/WordPress/Tests/PHP/StrictInArrayUnitTest.php +++ b/WordPress/Tests/PHP/StrictInArrayUnitTest.php @@ -52,6 +52,7 @@ public function getWarningList() { 44 => 1, 48 => 1, 49 => 1, + 62 => 1, ); } } From 41a9c3341155acf0a21356796e3c3bcc7facb832 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 14:18:36 -0300 Subject: [PATCH 21/62] PR 2633 WP/Capabilities: move syntax error test to its own file --- WordPress/Tests/WP/CapabilitiesUnitTest.1.inc | 4 ---- WordPress/Tests/WP/CapabilitiesUnitTest.5.inc | 8 ++++++++ 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 WordPress/Tests/WP/CapabilitiesUnitTest.5.inc diff --git a/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc b/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc index ab1fdb9c4..5752f4b54 100644 --- a/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc +++ b/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc @@ -112,7 +112,3 @@ add_menu_page( [] ); // Should bow out because the parameter is not found. $obj->current_user_can( 'foo_bar' ); // Ok. We're not checking for method calls. My\NamespaceS\add_posts_page( 'page_title', 'menu_title', 'administrator', 'menu_slug', 'function' ); // Ok. We're not checking namespaced functions. - -// Parse error, should be handled correctly by bowing out. -// This must be the last test in the file! -add_posts_page( 'page_title', diff --git a/WordPress/Tests/WP/CapabilitiesUnitTest.5.inc b/WordPress/Tests/WP/CapabilitiesUnitTest.5.inc new file mode 100644 index 000000000..d5f8d0d39 --- /dev/null +++ b/WordPress/Tests/WP/CapabilitiesUnitTest.5.inc @@ -0,0 +1,8 @@ + Date: Thu, 16 Oct 2025 17:58:19 -0300 Subject: [PATCH 22/62] PR 2633 WP/Capabilities: add tests for namespaced names --- WordPress/Tests/WP/CapabilitiesUnitTest.1.inc | 7 +++++++ WordPress/Tests/WP/CapabilitiesUnitTest.php | 1 + 2 files changed, 8 insertions(+) diff --git a/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc b/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc index 5752f4b54..698f57228 100644 --- a/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc +++ b/WordPress/Tests/WP/CapabilitiesUnitTest.1.inc @@ -111,4 +111,11 @@ add_menu_page( $p, $t, /* deliberately empty */, $slug, ); add_menu_page( [] ); // Should bow out because the parameter is not found. $obj->current_user_can( 'foo_bar' ); // Ok. We're not checking for method calls. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\add_posts_page( 'page_title', 'menu_title', 'administrator', 'menu_slug', 'function' ); // Bad. My\NamespaceS\add_posts_page( 'page_title', 'menu_title', 'administrator', 'menu_slug', 'function' ); // Ok. We're not checking namespaced functions. +\MyNamespace\add_posts_page( 'page_title', 'menu_title', 'administrator', 'menu_slug', 'function' ); // Ok. +namespace\add_posts_page( 'page_title', 'menu_title', 'administrator', 'menu_slug', 'function' ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/WP/CapabilitiesUnitTest.php b/WordPress/Tests/WP/CapabilitiesUnitTest.php index 700553b45..c2d8768b8 100644 --- a/WordPress/Tests/WP/CapabilitiesUnitTest.php +++ b/WordPress/Tests/WP/CapabilitiesUnitTest.php @@ -73,6 +73,7 @@ public function getErrorList( $testFile = '' ) { 78 => 1, 85 => 1, 106 => 1, + 118 => 1, ); case 'CapabilitiesUnitTest.3.inc': From a38552a0cc2664c9d1c6e327e6d3f2b0c1c01603 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 17:58:45 -0300 Subject: [PATCH 23/62] PR 2633 WP/DeprecatedParameters: add tests for namespaced names --- WordPress/Tests/WP/DeprecatedParametersUnitTest.inc | 8 ++++++++ WordPress/Tests/WP/DeprecatedParametersUnitTest.php | 3 +++ 2 files changed, 11 insertions(+) diff --git a/WordPress/Tests/WP/DeprecatedParametersUnitTest.inc b/WordPress/Tests/WP/DeprecatedParametersUnitTest.inc index 1fc0c27b0..2c0f32cdc 100644 --- a/WordPress/Tests/WP/DeprecatedParametersUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedParametersUnitTest.inc @@ -99,3 +99,11 @@ global_terms( $foo, 'deprecated' ); // All will give an WARNING as they have been deprecated after WP 6.5. inject_ignored_hooked_blocks_metadata_attributes('', 'deprecated'); wp_render_elements_support_styles('deprecated'); + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\add_option( '', '', [] ); // Bad. +MyNamespace\add_option( '', '', [] ); // Ok. +\MyNamespace\add_option( '', '', [] ); // Ok. +namespace\add_option( '', '', [] ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/WP/DeprecatedParametersUnitTest.php b/WordPress/Tests/WP/DeprecatedParametersUnitTest.php index 1958014f6..d922bd41d 100644 --- a/WordPress/Tests/WP/DeprecatedParametersUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedParametersUnitTest.php @@ -42,6 +42,9 @@ public function getErrorList() { $errors[50] = 2; $errors[76] = 2; + // Fully qualified function call. + $errors[106] = 1; + return $errors; } From 0523893a874af6cc9329c93fbb4a01dd6d81bbea Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 17:59:35 -0300 Subject: [PATCH 24/62] PR 2633 WP/DeprecatedParameterValues: rename test case file Doing this to allow for additional testcase files. --- ...> DeprecatedParameterValuesUnitTest.1.inc} | 0 .../WP/DeprecatedParameterValuesUnitTest.php | 82 +++++++++++-------- 2 files changed, 49 insertions(+), 33 deletions(-) rename WordPress/Tests/WP/{DeprecatedParameterValuesUnitTest.inc => DeprecatedParameterValuesUnitTest.1.inc} (100%) diff --git a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.inc b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc similarity index 100% rename from WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.inc rename to WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc diff --git a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php index 2fc1deff0..afc965799 100644 --- a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php @@ -23,47 +23,63 @@ final class DeprecatedParameterValuesUnitTest extends AbstractSniffTestCase { /** * Returns the lines where errors should occur. * + * @param string $testFile The name of the file being tested. + * * @return array Key is the line number, value is the number of expected errors. */ - public function getErrorList() { - return array( - 5 => 1, - 6 => 1, - 7 => 1, - 8 => 1, - 9 => 1, - 10 => 1, - 11 => 1, - 12 => 1, - 13 => 1, - 14 => 1, - 15 => 1, - 16 => 1, - 17 => 1, - 18 => 1, - 35 => 1, - 40 => 1, - 43 => 1, - 44 => 1, - 45 => 1, - 46 => 1, - 47 => 1, - 48 => 1, - 49 => 1, - 50 => 1, - 51 => 1, - ); + public function getErrorList( $testFile = '' ) { + switch ( $testFile ) { + case 'DeprecatedParameterValuesUnitTest.1.inc': + return array( + 5 => 1, + 6 => 1, + 7 => 1, + 8 => 1, + 9 => 1, + 10 => 1, + 11 => 1, + 12 => 1, + 13 => 1, + 14 => 1, + 15 => 1, + 16 => 1, + 17 => 1, + 18 => 1, + 35 => 1, + 40 => 1, + 43 => 1, + 44 => 1, + 45 => 1, + 46 => 1, + 47 => 1, + 48 => 1, + 49 => 1, + 50 => 1, + 51 => 1, + ); + + default: + return array(); + } } /** * Returns the lines where warnings should occur. * + * @param string $testFile The name of the file being tested. + * * @return array Key is the line number, value is the number of expected warnings. */ - public function getWarningList() { - return array( - 55 => 1, - 56 => 1, - ); + public function getWarningList( $testFile = '' ) { + switch ( $testFile ) { + case 'DeprecatedParameterValuesUnitTest.1.inc': + return array( + 55 => 1, + 56 => 1, + ); + + default: + return array(); + } } } From 36ab22d232aa4f76ca088c111ae2e719a1cc8149 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 18:01:18 -0300 Subject: [PATCH 25/62] PR 2633 WP/DeprecatedParameterValues: move syntax error test to its own file --- .../Tests/WP/DeprecatedParameterValuesUnitTest.1.inc | 3 --- .../Tests/WP/DeprecatedParameterValuesUnitTest.2.inc | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.2.inc diff --git a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc index c2f75c874..6c514cc36 100644 --- a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc +++ b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc @@ -54,6 +54,3 @@ update_option(autoload: true, value: $value, option: 'blacklist_keys'); wp_get_typography_font_size_value( $preset, array() ); // OK. wp_get_typography_font_size_value( $preset, true ); // Error. wp_get_typography_font_size_value( $preset, false ); // Error. - -// Live coding/parse error. -get_bloginfo( show: /*to do*/, ); diff --git a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.2.inc b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.2.inc new file mode 100644 index 000000000..b5923d40e --- /dev/null +++ b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.2.inc @@ -0,0 +1,8 @@ + Date: Thu, 16 Oct 2025 18:31:39 -0300 Subject: [PATCH 26/62] PR 2633 WP/DeprecatedParameterValues: add tests for namespaced names --- .../Tests/WP/DeprecatedParameterValuesUnitTest.1.inc | 8 ++++++++ WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php | 1 + 2 files changed, 9 insertions(+) diff --git a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc index 6c514cc36..73345f6d7 100644 --- a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc +++ b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.1.inc @@ -54,3 +54,11 @@ update_option(autoload: true, value: $value, option: 'blacklist_keys'); wp_get_typography_font_size_value( $preset, array() ); // OK. wp_get_typography_font_size_value( $preset, true ); // Error. wp_get_typography_font_size_value( $preset, false ); // Error. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\get_bloginfo( 'home' ); // Bad. +MyNamespace\get_bloginfo( 'home' ); // Ok. +\MyNamespace\get_bloginfo( 'home' ); // Ok. +namespace\get_bloginfo( 'home' ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php index afc965799..cf5bb35db 100644 --- a/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedParameterValuesUnitTest.php @@ -56,6 +56,7 @@ public function getErrorList( $testFile = '' ) { 49 => 1, 50 => 1, 51 => 1, + 61 => 1, ); default: From 65c24d4e4b2c0b4c68e1edc65954d3f28989953e Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 18:31:58 -0300 Subject: [PATCH 27/62] PR 2633 WP/GetMetaSingle: add tests for namespaced names --- WordPress/Tests/WP/GetMetaSingleUnitTest.inc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WordPress/Tests/WP/GetMetaSingleUnitTest.inc b/WordPress/Tests/WP/GetMetaSingleUnitTest.inc index 54ea2fecc..02001afef 100644 --- a/WordPress/Tests/WP/GetMetaSingleUnitTest.inc +++ b/WordPress/Tests/WP/GetMetaSingleUnitTest.inc @@ -46,3 +46,10 @@ $warning = get_metadata( ); $warning = get_metadata_raw( 'post', $post_id, $meta_key ); $warning = get_metadata_default( 'post', $post_id, $meta_key ); + +/* + * Safeguard correct handling of fully qualified and relative namespaced function calls (fully qualified global function + * call and partially qualified namespaced function call are already handled above). + */ +\MyNamespace\get_post_meta( $post_id, $meta_key ); // Ok. +namespace\get_post_meta( $post_id, $meta_key ); // The sniff should start flagging this once it can resolve relative namespaces. From 525c7aa617ce8ba110a7976ed018e341c232378d Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Oct 2025 18:35:44 -0300 Subject: [PATCH 28/62] PR 2633 WP/I18n: add tests for namespaced names I'm adding three different tests for fully qualified global function calls to cover all the global functions that are referenced directly in the `I18nSniff::process_matched_token()` method. --- WordPress/Tests/WP/I18nUnitTest.1.inc | 10 ++++++++++ WordPress/Tests/WP/I18nUnitTest.1.inc.fixed | 10 ++++++++++ WordPress/Tests/WP/I18nUnitTest.php | 3 +++ 3 files changed, 23 insertions(+) diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc b/WordPress/Tests/WP/I18nUnitTest.1.inc index 6256e6d84..a54094ad5 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc @@ -317,4 +317,14 @@ esc_html_e( 'foo', '' ); // Bad: text-domain can not be empty. // PHP 8.0+: safeguard handling of newly introduced placeholders. __( 'There are %1$h monkeys in the %H', 'my-slug' ); // Bad: multiple arguments should be numbered. +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\_( 'foo', 'my-slug' ); // Bad. +\translate( 'foo', 'my-slug' ); // Bad. +\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // Bad. +MyNamespace\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // Ok. +\MyNamespace\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // Ok. +namespace\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // The sniff should start flagging this once it can resolve relative namespaces. + // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed b/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed index b23e9b619..7c595dde5 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed @@ -317,4 +317,14 @@ esc_html_e( 'foo', '' ); // Bad: text-domain can not be empty. // PHP 8.0+: safeguard handling of newly introduced placeholders. __( 'There are %1$h monkeys in the %H', 'my-slug' ); // Bad: multiple arguments should be numbered. +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\_( 'foo', 'my-slug' ); // Bad. +\translate( 'foo', 'my-slug' ); // Bad. +\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // Bad. +MyNamespace\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // Ok. +\MyNamespace\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // Ok. +namespace\translate_with_gettext_context( 'foo', 'bar', 'my-slug' ); // The sniff should start flagging this once it can resolve relative namespaces. + // phpcs:enable WordPress.WP.I18n.MissingTranslatorsComment diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index 15c12f94f..586bdcf75 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -148,6 +148,7 @@ public function getErrorList( $testFile = '' ) { 311 => 1, 315 => 1, 318 => 1, + 323 => 1, ); case 'I18nUnitTest.2.inc': @@ -217,6 +218,8 @@ public function getWarningList( $testFile = '' ) { 300 => 1, 301 => 1, 302 => 1, + 324 => 1, + 325 => 1, ); case 'I18nUnitTest.2.inc': From fd53b8664d14fb555924bcaca0d97b6f1a947283 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 7 Aug 2025 10:42:26 -0300 Subject: [PATCH 29/62] DB/DirectDatabaseQuery: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization of fully qualified function calls to this sniff when searching for cache function calls. --- WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php index 57fa39966..b57ba909f 100644 --- a/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/DB/DirectDatabaseQuerySniff.php @@ -228,7 +228,7 @@ public function process_token( $stackPtr ) { $scopeEnd = $this->tokens[ $scope_function ]['scope_closer']; for ( $i = ( $scopeStart + 1 ); $i < $scopeEnd; $i++ ) { - if ( \T_STRING === $this->tokens[ $i ]['code'] ) { + if ( \T_STRING === $this->tokens[ $i ]['code'] || \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] ) { $nextNonEmpty = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $i + 1 ), null, true ); if ( \T_OPEN_PARENTHESIS !== $this->tokens[ $nextNonEmpty ]['code'] ) { @@ -246,6 +246,10 @@ public function process_token( $stackPtr ) { $content = strtolower( $this->tokens[ $i ]['content'] ); + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] ) { + $content = ltrim( $content, '\\' ); + } + if ( isset( $this->cacheDeleteFunctions[ $content ] ) ) { if ( \in_array( $method, array( 'query', 'update', 'replace', 'delete' ), true ) ) { From 2d100104c073fcda781d689bfc5ad23162c8ff96 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 7 Aug 2025 12:02:04 -0300 Subject: [PATCH 30/62] CHECK WPDBTrait::is_wpdb_method_call(): update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization of fully qualified calls to WPDB methods. As there are no dedicated tests for this trait, a test will be added in a later commit that will update the `PreparedSQLPlaceholders` sniff for PHPCS 4.0. The test can't be added now because the sniff code needs to be updated as well to handle the new PHPCS 4.0 tokenization. CHECK: I might end up adding dedicated tests for this method. --- WordPress/Helpers/WPDBTrait.php | 5 ++++- WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/WordPress/Helpers/WPDBTrait.php b/WordPress/Helpers/WPDBTrait.php index afa6ffc54..722de66fe 100644 --- a/WordPress/Helpers/WPDBTrait.php +++ b/WordPress/Helpers/WPDBTrait.php @@ -53,9 +53,12 @@ final protected function is_wpdb_method_call( File $phpcsFile, $stackPtr, array return false; } + $contentLC = strtolower( $tokens[ $stackPtr ]['content'] ); + // Check for wpdb. if ( ( \T_VARIABLE === $tokens[ $stackPtr ]['code'] && '$wpdb' !== $tokens[ $stackPtr ]['content'] ) - || ( \T_STRING === $tokens[ $stackPtr ]['code'] && 'wpdb' !== strtolower( $tokens[ $stackPtr ]['content'] ) ) + || ( \T_STRING === $tokens[ $stackPtr ]['code'] && 'wpdb' !== $contentLC ) + || ( \T_NAME_FULLY_QUALIFIED === $tokens[ $stackPtr ]['code'] && '\wpdb' !== $contentLC ) ) { return false; } diff --git a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php index 206474f72..6937395a0 100644 --- a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php +++ b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php @@ -17,6 +17,7 @@ * @since 0.14.0 * * @covers \WordPressCS\WordPress\Sniffs\DB\PreparedSQLPlaceholdersSniff + * @covers \WordPressCS\WordPress\Helpers\WPDBTrait::is_wpdb_method_call */ final class PreparedSQLPlaceholdersUnitTest extends AbstractSniffTestCase { From 3f8f121dc7240e1a57fa7e77c015920c7268520b Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 12 Aug 2025 14:53:59 -0300 Subject: [PATCH 31/62] WP/GlobalVariablesOverride: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization of fully qualified function/method calls when checking if the sniff can determine the key used to retrieve a value from the `$GLOBALS` array. The sniff was already handling this correct by chance due to a check that happens later in the code execution to bow out if `$var_name` is empty. --- WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php b/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php index 934c3e686..985f5d281 100644 --- a/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php +++ b/WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php @@ -219,14 +219,15 @@ protected function process_variable_assignment( $stackPtr, $in_list = false ) { $var_name = ''; $start = ( $bracketPtr + 1 ); for ( $ptr = $start; $ptr < $this->tokens[ $bracketPtr ]['bracket_closer']; $ptr++ ) { + $ignored_tokens = Collections::nameTokens(); + $ignored_tokens[ \T_VARIABLE ] = \T_VARIABLE; + $ignored_tokens[ \T_DOUBLE_QUOTED_STRING ] = \T_DOUBLE_QUOTED_STRING; + /* * If the globals array key contains a variable, constant, function call * or interpolated variable, bow out. */ - if ( \T_VARIABLE === $this->tokens[ $ptr ]['code'] - || \T_STRING === $this->tokens[ $ptr ]['code'] - || \T_DOUBLE_QUOTED_STRING === $this->tokens[ $ptr ]['code'] - ) { + if ( isset( $ignored_tokens[ $this->tokens[ $ptr ]['code'] ] ) === true ) { return; } From 45cd93bb1357be33579834f0ce5cfa398b7ac29a Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 12 Aug 2025 15:37:14 -0300 Subject: [PATCH 32/62] Security/NonceVerification: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization of fully qualified function calls when checking if a nonce verification function is used in the code. --- WordPress/Sniffs/Security/NonceVerificationSniff.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/Security/NonceVerificationSniff.php b/WordPress/Sniffs/Security/NonceVerificationSniff.php index 06b941fc7..2da979d31 100644 --- a/WordPress/Sniffs/Security/NonceVerificationSniff.php +++ b/WordPress/Sniffs/Security/NonceVerificationSniff.php @@ -305,12 +305,16 @@ private function has_nonce_check( $stackPtr, array $cache_keys, $allow_nonce_aft } // If this isn't a function name, skip it. - if ( \T_STRING !== $this->tokens[ $i ]['code'] ) { + if ( \T_STRING !== $this->tokens[ $i ]['code'] && \T_NAME_FULLY_QUALIFIED !== $this->tokens[ $i ]['code'] ) { continue; } $content_lc = \strtolower( $this->tokens[ $i ]['content'] ); + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] ) { + $content_lc = \ltrim( $content_lc, '\\' ); + } + // If this is one of the nonce verification functions, we can bail out. if ( isset( $this->nonceVerificationFunctions[ $content_lc ] ) ) { /* From fc0136263215509942a85129591019f4fa044d98 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 13 Aug 2025 11:12:19 -0300 Subject: [PATCH 33/62] NamingConventions/ValidHookName: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when skipping over function calls while checking the hook name. --- WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php index 55dee3bd6..42936fca9 100644 --- a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php @@ -10,6 +10,7 @@ namespace WordPressCS\WordPress\Sniffs\NamingConventions; use PHP_CodeSniffer\Util\Tokens; +use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\TextStrings; use WordPressCS\WordPress\AbstractFunctionParameterSniff; use WordPressCS\WordPress\Helpers\WPHookHelper; @@ -137,7 +138,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p // Skip over parameters passed to function calls. if ( \T_OPEN_PARENTHESIS === $this->tokens[ $i ]['code'] - && ( \T_STRING === $this->tokens[ $last_non_empty ]['code'] + && ( isset( Collections::nameTokens()[ $this->tokens[ $last_non_empty ]['code'] ] ) || \T_VARIABLE === $this->tokens[ $last_non_empty ]['code'] ) && isset( $this->tokens[ $i ]['parenthesis_closer'] ) ) { From 30e7dc3ce4e2352c1ed79accf73fab2ae95b4763 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 13 Aug 2025 11:49:27 -0300 Subject: [PATCH 34/62] AbstractFunctionRestrictions: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when checking if a given fully qualified function is a target function. In those cases, the leading backslash is removed from the token content to allow for the function name comparisons to continue working as they worked in PHPCS 3.x. --- WordPress/AbstractFunctionParameterSniff.php | 3 ++- .../AbstractFunctionRestrictionsSniff.php | 22 +++++++++++++++---- .../Sniffs/Security/EscapeOutputSniff.php | 3 ++- .../Sniffs/WP/AlternativeFunctionsSniff.php | 3 ++- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 3 ++- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/WordPress/AbstractFunctionParameterSniff.php b/WordPress/AbstractFunctionParameterSniff.php index 7b369583c..e9a2226f1 100644 --- a/WordPress/AbstractFunctionParameterSniff.php +++ b/WordPress/AbstractFunctionParameterSniff.php @@ -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. diff --git a/WordPress/AbstractFunctionRestrictionsSniff.php b/WordPress/AbstractFunctionRestrictionsSniff.php index 7f300cbc3..b9961efc0 100644 --- a/WordPress/AbstractFunctionRestrictionsSniff.php +++ b/WordPress/AbstractFunctionRestrictionsSniff.php @@ -125,6 +125,7 @@ public function register() { return array( \T_STRING, + \T_NAME_FULLY_QUALIFIED, ); } @@ -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; } @@ -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 ) { @@ -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. diff --git a/WordPress/Sniffs/Security/EscapeOutputSniff.php b/WordPress/Sniffs/Security/EscapeOutputSniff.php index e0714e36c..17e574178 100644 --- a/WordPress/Sniffs/Security/EscapeOutputSniff.php +++ b/WordPress/Sniffs/Security/EscapeOutputSniff.php @@ -367,7 +367,8 @@ public function process_token( $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. diff --git a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php index 40fb0c61c..5e4f2cb14 100644 --- a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php +++ b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php @@ -213,7 +213,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. diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 745b9ea20..464ac39f1 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -1733,7 +1733,8 @@ public function getGroups() { * @param string $group_name The name of the group which was matched. Will * always be 'deprecated_functions'. * @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 void */ From 60f2eb9083a750db1d8a81d7a6147fd3ab2582a6 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 13 Aug 2025 11:54:15 -0300 Subject: [PATCH 35/62] NamingConventions/PrefixAllGlobals: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when checking for calls to `define()` and hook functions to handle fully qualified calls correctly. --- WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index 686075042..edebe84c3 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -456,6 +456,7 @@ public function register() { $parent = parent::register(); if ( ! empty( $parent ) ) { $targets[] = \T_STRING; + $targets[] = \T_NAME_FULLY_QUALIFIED; } return $targets; @@ -548,7 +549,9 @@ public function process_token( $stackPtr ) { return $this->tokens[ $stackPtr ]['scope_closer']; } - if ( \T_STRING === $this->tokens[ $stackPtr ]['code'] ) { + if ( \T_STRING === $this->tokens[ $stackPtr ]['code'] + || \T_NAME_FULLY_QUALIFIED === $this->tokens[ $stackPtr ]['code'] + ) { // Disallow excluding function groups for this sniff. $this->exclude = array(); From 88ee1b709babd021822c1f591baeda0b016aa4bd Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 13 Aug 2025 15:04:27 -0300 Subject: [PATCH 36/62] AbstractClassRestrictions: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when checking if a given token is a target token. --- WordPress/AbstractClassRestrictionsSniff.php | 14 +++++++++++--- WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc | 3 +++ WordPress/Tests/DB/RestrictedClassesUnitTest.php | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/WordPress/AbstractClassRestrictionsSniff.php b/WordPress/AbstractClassRestrictionsSniff.php index e0f1c8580..8b7360cc1 100644 --- a/WordPress/AbstractClassRestrictionsSniff.php +++ b/WordPress/AbstractClassRestrictionsSniff.php @@ -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; @@ -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 ) ); } diff --git a/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc b/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc index 4449a0395..bd0c41470 100644 --- a/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc +++ b/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc @@ -115,3 +115,6 @@ $anon = new readonly class { $anon = new readonly class() extends PDOStatement {}; // Error. $anon = new #[MyAttribute] readonly class {}; + +echo namespace\DBlayer::VERSION; // Ok - resolves to \DBlayer. +echo namespace\PDO::getAvailableDrivers(); // Bad - resolves to \PDO::getAvailableDrivers(). diff --git a/WordPress/Tests/DB/RestrictedClassesUnitTest.php b/WordPress/Tests/DB/RestrictedClassesUnitTest.php index 3e8edddde..f97bee7f1 100644 --- a/WordPress/Tests/DB/RestrictedClassesUnitTest.php +++ b/WordPress/Tests/DB/RestrictedClassesUnitTest.php @@ -102,6 +102,7 @@ public function getErrorList( $testFile = '' ) { 103 => 1, 106 => 1, 115 => 1, + 120 => 1, ); case 'RestrictedClassesUnitTest.2.inc': From fc3fab7d8fe0ceb0b4b00c1a0ab74999e1cbdd40 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 13 Aug 2025 15:24:27 -0300 Subject: [PATCH 37/62] PHP/NoSilencedErrors: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when checking function calls after the `T_ASPERAND` token. --- WordPress/Sniffs/PHP/NoSilencedErrorsSniff.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/PHP/NoSilencedErrorsSniff.php b/WordPress/Sniffs/PHP/NoSilencedErrorsSniff.php index 400da4a6d..0df5ab6a3 100644 --- a/WordPress/Sniffs/PHP/NoSilencedErrorsSniff.php +++ b/WordPress/Sniffs/PHP/NoSilencedErrorsSniff.php @@ -11,6 +11,7 @@ use PHP_CodeSniffer\Util\Tokens; use PHPCSUtils\BackCompat\BCFile; +use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\GetTokensAsString; use WordPressCS\WordPress\Helpers\RulesetPropertyHelper; use WordPressCS\WordPress\Sniff; @@ -194,10 +195,15 @@ public function process_token( $stackPtr ) { * to allow the metrics to be more informative. */ $next_non_empty = $this->phpcsFile->findNext( $this->empty_tokens, ( $stackPtr + 1 ), null, true, null, true ); - if ( false !== $next_non_empty && \T_STRING === $this->tokens[ $next_non_empty ]['code'] ) { + if ( false !== $next_non_empty && isset( Collections::nameTokens()[ $this->tokens[ $next_non_empty ]['code'] ] ) === true ) { $has_parenthesis = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $next_non_empty + 1 ), null, true, null, true ); if ( false !== $has_parenthesis && \T_OPEN_PARENTHESIS === $this->tokens[ $has_parenthesis ]['code'] ) { $function_name = strtolower( $this->tokens[ $next_non_empty ]['content'] ); + + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $next_non_empty ]['code'] ) { + $function_name = \ltrim( $function_name, '\\' ); + } + if ( ( true === $this->usePHPFunctionsList && isset( $this->allowedFunctionsList[ $function_name ] ) === true ) || ( ! empty( $this->customAllowedFunctionsList ) From e6e1c27782fc5fe46eb4c8e5ff4db7f9b49fed4f Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 14 Aug 2025 15:13:11 -0300 Subject: [PATCH 38/62] ContextHelper::is_in_function_call(): update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when determining the name of the function being called. --- WordPress/Helpers/ContextHelper.php | 35 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/WordPress/Helpers/ContextHelper.php b/WordPress/Helpers/ContextHelper.php index b90006fde..31870610d 100644 --- a/WordPress/Helpers/ContextHelper.php +++ b/WordPress/Helpers/ContextHelper.php @@ -113,6 +113,19 @@ final class ContextHelper { ), ); + /** + * List of tokens representing qualified names. + * + * @since 3.3.0 + * + * @var array + */ + private static $qualifiedNameTokens = array( + \T_NAME_FULLY_QUALIFIED => true, + \T_NAME_QUALIFIED => true, + \T_NAME_RELATIVE => true, + ); + /** * Check if a particular token acts - statically or non-statically - on an object. * @@ -186,7 +199,7 @@ public static function is_token_namespaced( File $phpcsFile, $stackPtr ) { * * For example: this function could be used to determine if the variable `$foo` is used * in a global function call to the function `is_foo()`. - * In that case, a call to this function would return the stackPtr to the T_STRING `is_foo` + * In that case, a call to this function would return the stackPtr to the name token `is_foo` * for code like: `is_foo( $foo, 'some_other_param' )`, while it would return `false` for * the following code `is_bar( $foo, 'some_other_param' )`. * @@ -214,7 +227,7 @@ public static function is_token_namespaced( File $phpcsFile, $stackPtr ) { * or only `strtolower( $var )`. * Defaults to `false`. * - * @return int|bool Stack pointer to the function call T_STRING token or false otherwise. + * @return int|bool Stack pointer to the function call name token or false otherwise. */ public static function is_in_function_call( File $phpcsFile, $stackPtr, array $valid_functions, $global_function = true, $allow_nested = false ) { $tokens = $phpcsFile->getTokens(); @@ -229,11 +242,25 @@ public static function is_in_function_call( File $phpcsFile, $stackPtr, array $v foreach ( $nested_parenthesis as $open => $close ) { $prev_non_empty = $phpcsFile->findPrevious( Tokens::$emptyTokens, ( $open - 1 ), null, true ); - if ( false === $prev_non_empty || \T_STRING !== $tokens[ $prev_non_empty ]['code'] ) { + if ( false === $prev_non_empty || isset( Collections::nameTokens()[ $tokens[ $prev_non_empty ]['code'] ] ) === false ) { continue; } - if ( isset( $valid_functions[ strtolower( $tokens[ $prev_non_empty ]['content'] ) ] ) === false ) { + $functionNameLC = \strtolower( $tokens[ $prev_non_empty ]['content'] ); + + if ( true === $global_function + && \T_NAME_FULLY_QUALIFIED === $tokens[ $prev_non_empty ]['code'] + ) { + $functionNameLC = \ltrim( $functionNameLC, '\\' ); + } + + if ( false === $global_function + && isset( self::$qualifiedNameTokens[ $tokens[ $prev_non_empty ]['code'] ] ) === true + ) { + $functionNameLC = \substr( $functionNameLC, \strrpos( $functionNameLC, '\\' ) + 1 ); + } + + if ( isset( $valid_functions[ $functionNameLC ] ) === false ) { if ( false === $allow_nested ) { // Function call encountered, but not to one of the allowed functions. return false; From d36c3eaa1b36ddcba0c39b5e6977454c7a4a940a Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 14 Aug 2025 10:07:34 -0300 Subject: [PATCH 39/62] WP/CronInterval: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when checking if a WP time constant was used. --- WordPress/Sniffs/WP/CronIntervalSniff.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/WP/CronIntervalSniff.php b/WordPress/Sniffs/WP/CronIntervalSniff.php index fd48e1a2f..ce6e5d2a0 100644 --- a/WordPress/Sniffs/WP/CronIntervalSniff.php +++ b/WordPress/Sniffs/WP/CronIntervalSniff.php @@ -233,7 +233,13 @@ public function process_token( $stackPtr ) { continue; } - $value .= $this->tokens[ $j ]['content']; + $content = $this->tokens[ $j ]['content']; + + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $j ]['code'] ) { + $content = \ltrim( $content, '\\' ); + } + + $value .= $content; } if ( $parentheses_count > 0 ) { From 724aa4d5ac94dda3c07fd8367c4883f9b23f42c0 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 14 Aug 2025 15:55:10 -0300 Subject: [PATCH 40/62] ValidationHelper::is_validated(): update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when checking if a PHP native array key exists function was used. --- WordPress/Helpers/ValidationHelper.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/WordPress/Helpers/ValidationHelper.php b/WordPress/Helpers/ValidationHelper.php index d5a22d7d5..eb0ef679b 100644 --- a/WordPress/Helpers/ValidationHelper.php +++ b/WordPress/Helpers/ValidationHelper.php @@ -35,11 +35,12 @@ final class ValidationHelper { * @var array */ private static $targets = array( - \T_ISSET => 'construct', - \T_EMPTY => 'construct', - \T_STRING => 'function_call', - \T_COALESCE => 'coalesce', - \T_COALESCE_EQUAL => 'coalesce', + \T_ISSET => 'construct', + \T_EMPTY => 'construct', + \T_STRING => 'function_call', + \T_NAME_FULLY_QUALIFIED => 'function_call', + \T_COALESCE => 'coalesce', + \T_COALESCE_EQUAL => 'coalesce', ); /** @@ -218,8 +219,14 @@ public static function is_validated( File $phpcsFile, $stackPtr, $array_keys = a break; case 'function_call': + $contentLC = \strtolower( $tokens[ $i ]['content'] ); + + if ( \T_NAME_FULLY_QUALIFIED === $tokens[ $i ]['code'] ) { + $contentLC = \ltrim( $contentLC, '\\' ); + } + // Only check calls to array_key_exists() and key_exists(). - if ( isset( self::$key_exists_functions[ strtolower( $tokens[ $i ]['content'] ) ] ) === false ) { + if ( isset( self::$key_exists_functions[ $contentLC ] ) === false ) { continue 2; } From 30983d9b7fc6d944bf2b8160140bb6afcbc875b5 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Fri, 15 Aug 2025 16:28:19 -0300 Subject: [PATCH 41/62] ConstantsHelper::is_use_of_global_constant(): update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when determining if a constant is global or not. --- WordPress/Helpers/ConstantsHelper.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/WordPress/Helpers/ConstantsHelper.php b/WordPress/Helpers/ConstantsHelper.php index 320c6312f..8ef2b77d2 100644 --- a/WordPress/Helpers/ConstantsHelper.php +++ b/WordPress/Helpers/ConstantsHelper.php @@ -34,7 +34,8 @@ final class ConstantsHelper { /** - * Determine whether an arbitrary T_STRING token is the use of a global constant. + * Determine whether an arbitrary T_STRING or T_NAME_FULLY_QUALIFIED token is the use of a + * global constant. * * @since 1.0.0 * @since 3.0.0 - Moved from the Sniff class to this class. @@ -42,7 +43,7 @@ final class ConstantsHelper { * - The `$phpcsFile` parameter was added. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the T_STRING token. + * @param int $stackPtr The position of the T_STRING or T_NAME_FULLY_QUALIFIED token. * * @return bool */ @@ -55,7 +56,9 @@ public static function is_use_of_global_constant( File $phpcsFile, $stackPtr ) { } // Is this one of the tokens this function handles ? - if ( \T_STRING !== $tokens[ $stackPtr ]['code'] ) { + if ( \T_STRING !== $tokens[ $stackPtr ]['code'] + && \T_NAME_FULLY_QUALIFIED !== $tokens[ $stackPtr ]['code'] + ) { return false; } @@ -91,6 +94,14 @@ public static function is_use_of_global_constant( File $phpcsFile, $stackPtr ) { return false; } + // If the token is a fully qualified name, ensure it does not include a namespace path. + if ( \T_NAME_FULLY_QUALIFIED === $tokens[ $stackPtr ]['code'] ) { + $trimmed = \ltrim( $tokens[ $stackPtr ]['content'], '\\' ); + if ( \strpos( $trimmed, '\\' ) !== false ) { + return false; + } + } + if ( ContextHelper::is_token_namespaced( $phpcsFile, $stackPtr ) === true ) { // Namespaced constant of the same name. return false; From a261a24f395f93a90489bba779cc2109601c0db3 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Mon, 18 Aug 2025 16:06:25 -0300 Subject: [PATCH 42/62] WP/DiscouragedConstants: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when checking the name of a given constants to see if it is one of the discouraged constants and when checking if `define()` was called. --- WordPress/Sniffs/WP/DiscouragedConstantsSniff.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php b/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php index 7db5a3785..9788f3578 100644 --- a/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php +++ b/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php @@ -72,7 +72,13 @@ final class DiscouragedConstantsSniff extends AbstractFunctionParameterSniff { * normal file processing. */ public function process_token( $stackPtr ) { - if ( isset( $this->target_functions[ strtolower( $this->tokens[ $stackPtr ]['content'] ) ] ) ) { + $content_lc = strtolower( $this->tokens[ $stackPtr ]['content'] ); + + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $stackPtr ]['code'] ) { + $content_lc = \ltrim( $content_lc, '\\' ); + } + + if ( isset( $this->target_functions[ $content_lc ] ) ) { // Disallow excluding function groups for this sniff. $this->exclude = array(); @@ -84,7 +90,8 @@ public function process_token( $stackPtr ) { } /** - * Process an arbitrary T_STRING token to determine whether it is one of the target constants. + * Process an arbitrary T_STRING or T_NAME_FULLY_QUALIFIED token to determine whether it is one + * of the target constants. * * @since 0.14.0 * @@ -95,6 +102,10 @@ public function process_token( $stackPtr ) { public function process_arbitrary_tstring( $stackPtr ) { $content = $this->tokens[ $stackPtr ]['content']; + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $stackPtr ]['code'] ) { + $content = \ltrim( $content, '\\' ); + } + if ( ! isset( $this->discouraged_constants[ $content ] ) ) { return; } From e263c42c93792377c408d3ff2de1d631ccc41a81 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 19 Aug 2025 15:23:01 -0300 Subject: [PATCH 43/62] Security/EscapeOutput: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization to this sniff. --- WordPress/Sniffs/Security/EscapeOutputSniff.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/WordPress/Sniffs/Security/EscapeOutputSniff.php b/WordPress/Sniffs/Security/EscapeOutputSniff.php index 17e574178..0b8a602a5 100644 --- a/WordPress/Sniffs/Security/EscapeOutputSniff.php +++ b/WordPress/Sniffs/Security/EscapeOutputSniff.php @@ -187,6 +187,7 @@ public function process_token( $stackPtr ) { $start = ( $stackPtr + 1 ); switch ( $this->tokens[ $stackPtr ]['code'] ) { + case \T_NAME_FULLY_QUALIFIED: case \T_STRING: // Prevent exclusion of any of the function groups. $this->exclude = array(); @@ -575,9 +576,15 @@ protected function check_code_is_escaped( $start, $end, $code = 'OutputNotEscape continue; } + $content = $this->tokens[ $i ]['content']; + + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] ) { + $content = \ltrim( $content, '\\' ); + } + // Ignore safe PHP native constants. - if ( \T_STRING === $this->tokens[ $i ]['code'] - && isset( $this->safe_php_constants[ $this->tokens[ $i ]['content'] ] ) + if ( ( \T_STRING === $this->tokens[ $i ]['code'] || \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] ) + && isset( $this->safe_php_constants[ $content ] ) && ConstantsHelper::is_use_of_global_constant( $this->phpcsFile, $i ) ) { continue; @@ -613,7 +620,7 @@ protected function check_code_is_escaped( $start, $end, $code = 'OutputNotEscape } // Check for use of *::class. - if ( \T_STRING === $this->tokens[ $i ]['code'] + if ( isset( Collections::nameTokens()[ $this->tokens[ $i ]['code'] ] ) || \T_VARIABLE === $this->tokens[ $i ]['code'] || isset( Collections::ooHierarchyKeywords()[ $this->tokens[ $i ]['code'] ] ) || \T_NAMESPACE === $this->tokens[ $i ]['code'] @@ -679,9 +686,9 @@ protected function check_code_is_escaped( $start, $end, $code = 'OutputNotEscape } // Now check that the next token is a function call. - if ( \T_STRING === $this->tokens[ $i ]['code'] ) { + if ( \T_STRING === $this->tokens[ $i ]['code'] || \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] ) { $ptr = $i; - $functionName = $this->tokens[ $i ]['content']; + $functionName = $content; $function_opener = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $i + 1 ), null, true ); $is_formatting_function = FormattingFunctionsHelper::is_formatting_function( $functionName ); From 253d25c3ef20e2fb8d024aba4e9dd2627ab3c5a9 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 6 Aug 2025 15:01:55 -0300 Subject: [PATCH 44/62] WIP NamingConventions/PrefixAllGlobals: improve prefix validation Add a new error when validating prefixes if a prefix is not a string or is an empty string. This is necessary in preparation for PHPCS 4.0. Starting with this version, array properties can have types other than string, and the sniff needs to be updated to handle non-string prefixes. Using the same error when the string is empty made sense as before the sniff would generate an error complaining about the length of the prefix. TODO: the value of the prefix is type casted to a string when displaying the error message. For example, `true` becomes `1`. I need to think if this is a problem or not. Also, if `true` is passed as the first and only element of an array property there seems to be an error in PHPCS. Check how https://github.com/PHPCSStandards/PHP_CodeSniffer/pull/1172 and https://github.com/PHPCSStandards/PHP_CodeSniffer/pull/1193 impact this commit. --- .../Sniffs/NamingConventions/PrefixAllGlobalsSniff.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index edebe84c3..d4ac5a519 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -1224,6 +1224,16 @@ private function validate_prefixes() { $prefixes = array(); $ns_prefixes = array(); foreach ( $this->prefixes as $key => $prefix ) { + if ( is_string( $prefix ) === false || trim( $prefix ) === '' ) { + $this->phpcsFile->addError( + 'The prefix must be a non-empty string. Found: "%s".', + 0, + 'InvalidPrefixPassed', + array( $prefix ) + ); + continue; + } + $prefixLC = strtolower( $prefix ); if ( isset( $this->prefix_blocklist[ $prefixLC ] ) ) { From 077c71ad2988d0e69037617e8c8161b1143f3f8b Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 14 Aug 2025 15:10:26 -0300 Subject: [PATCH 45/62] WIP ContextHelper::is_in_function_call(): add basic tests Check the way the tests are structured. There is for sure room to improve their organization. Also check the way that I'm running the tests in the WordPress/Util/Tests in composer.json and the need to add a custom autoloader to bootstrap.php. There is probably a better way to achieve both. --- Tests/bootstrap.php | 15 ++ .../IsInFunctionCallUnitTest.inc | 57 ++++++ .../IsInFunctionCallUnitTest.php | 165 ++++++++++++++++++ composer.json | 6 +- phpunit.xml.dist | 5 +- 5 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.inc create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.php diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 219c45f5f..9cc9feaf8 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -45,6 +45,21 @@ ) { require_once $phpcsDir . $ds . 'autoload.php'; require_once $phpcsDir . $ds . 'tests' . $ds . 'bootstrap.php'; // PHPUnit 6.x+ support. + + spl_autoload_register( + function ( $className ) { + // Only try & load our own classes. + if ( stripos( $className, 'WordPressCS' ) !== 0 ) { + return; + } + + $file = realpath( dirname( __DIR__ ) ) . DIRECTORY_SEPARATOR . strtr( str_replace( 'WordPressCS\\', '', $className ), '\\', DIRECTORY_SEPARATOR ) . '.php'; + + if ( file_exists( $file ) ) { + include_once $file; + } + } + ); } else { echo 'Uh oh... can\'t find PHPCS. diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.inc b/WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.inc new file mode 100644 index 000000000..36f11ca22 --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.inc @@ -0,0 +1,57 @@ +my_function( /* test inside function pointer 11 */ $a ); +/* test function call 12 */ $obj?->my_function( /* test inside function pointer 12 */ $a ); + +/* + * Make sure that tokens inside a function call are correctly identified when `$allow_nested` is + * set to true. + * + * The below should be recognized as inside a function call to one of the valid functions. + */ +/* test function call 13 */ my_function( another_function( /* test inside function pointer 13 */ $a ) ); +another_function( /* test function call 14 */ my_function( /* test inside function pointer 14 */ $a ) ); +/* test function call 15 */ my_function( middle_function( inner_function( /* test inside function pointer 15 */ $a ) ) ); diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.php b/WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.php new file mode 100644 index 000000000..0389cfd67 --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsInFunctionCallUnitTest.php @@ -0,0 +1,165 @@ +getTargetToken( $commentString, $tokenType ); + $result = ContextHelper::is_in_function_call( self::$phpcsFile, $stackPtr, array( 'my_function' => true ) ); + $this->assertFalse( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInFunctionCallShouldReturnFalse() + */ + public static function dataIsInFunctionCallShouldReturnFalse() { + return array( + array( '/* test return false 1 */', \T_CONSTANT_ENCAPSED_STRING ), + array( '/* test return false 2 */', \T_VARIABLE ), + array( '/* test return false 3 */', \T_VARIABLE ), + array( '/* test return false 4 */', \T_VARIABLE ), + array( '/* test return false 5 */', \T_VARIABLE ), + array( '/* test return false 6 */', \T_VARIABLE ), + array( '/* test return false 7 */', \T_VARIABLE ), + array( '/* test return false 8 */', \T_VARIABLE ), + ); + } + + /** + * Test is_in_function_call() returns pointer to function name if given token is inside a function call. + * + * @dataProvider dataIsInFunctionCallShouldReturnFunctionPointer + * + * @param string $insideFunctionCommentString The comment which prefaces the target token inside a function in the test file. + * @param int|string $insideFunctionTokenType The token type to search for. + * @param string $functionCallCommentString The comment which prefaces the function call token in the test file. + * + * @return void + */ + public function testIsInFunctionCallShouldReturnFunctionPointer( $insideFunctionCommentString, $insideFunctionTokenType, $functionCallCommentString ) { + $insideFunctionPtr = $this->getTargetToken( $insideFunctionCommentString, $insideFunctionTokenType ); + $functionNamePtr = $this->getTargetToken( $functionCallCommentString, Collections::nameTokens() ); + $result = ContextHelper::is_in_function_call( self::$phpcsFile, $insideFunctionPtr, array( 'my_function' => true ) ); + $this->assertSame( $result, $functionNamePtr ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInFunctionCallShouldReturnFunctionPointer() + */ + public static function dataIsInFunctionCallShouldReturnFunctionPointer() { + return array( + array( '/* test inside function pointer 1 */', \T_VARIABLE, '/* test function call 1 */' ), + array( '/* test inside function pointer 2 */', \T_VARIABLE, '/* test function call 2 */' ), + array( '/* test inside function pointer 3 */', \T_VARIABLE, '/* test function call 3 */' ), + ); + } + + /** + * Test is_in_function_call() returns pointer to function name if given token is inside a + * function call when `$global_functions` is set to false. + * + * @dataProvider dataIsInFunctionCallShouldReturnFunctionPointerWhenGlobalIsFalse + * + * @param string $insideFunctionCommentString The comment which prefaces the target token inside a function in the test file. + * @param int|string $insideFunctionTokenType The token type to search for. + * @param string $functionCallCommentString The comment which prefaces the function call token in the test file. + * + * @return void + */ + public function testIsInFunctionCallShouldReturnFunctionPointerWhenGlobalIsFalse( $insideFunctionCommentString, $insideFunctionTokenType, $functionCallCommentString ) { + $insideFunctionPtr = $this->getTargetToken( $insideFunctionCommentString, $insideFunctionTokenType ); + $functionNamePtr = $this->getTargetToken( $functionCallCommentString, Collections::nameTokens() ); + $result = ContextHelper::is_in_function_call( self::$phpcsFile, $insideFunctionPtr, array( 'my_function' => true ), false ); + $this->assertSame( $result, $functionNamePtr ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInFunctionCallShouldReturnFunctionPointerWhenGlobalIsFalse() + */ + public static function dataIsInFunctionCallShouldReturnFunctionPointerWhenGlobalIsFalse() { + return array( + array( '/* test inside function pointer 4 */', \T_VARIABLE, '/* test function call 4 */' ), + array( '/* test inside function pointer 5 */', \T_VARIABLE, '/* test function call 5 */' ), + array( '/* test inside function pointer 6 */', \T_VARIABLE, '/* test function call 6 */' ), + array( '/* test inside function pointer 7 */', \T_VARIABLE, '/* test function call 7 */' ), + array( '/* test inside function pointer 8 */', \T_VARIABLE, '/* test function call 8 */' ), + array( '/* test inside function pointer 9 */', \T_VARIABLE, '/* test function call 9 */' ), + array( '/* test inside function pointer 10 */', \T_VARIABLE, '/* test function call 10 */' ), + array( '/* test inside function pointer 11 */', \T_VARIABLE, '/* test function call 11 */' ), + array( '/* test inside function pointer 12 */', \T_VARIABLE, '/* test function call 12 */' ), + ); + } + + /** + * Test is_in_function_call() returns pointer to function name if given token is inside a + * function call when `$allow_nested` is set to true. + * + * @dataProvider dataIsInFunctionCallShouldReturnFunctionPointerWhenAllowNestedIsTrue + * + * @param string $insideFunctionCommentString The comment which prefaces the target token inside a function in the test file. + * @param int|string $insideFunctionTokenType The token type to search for. + * @param string $functionCallCommentString The comment which prefaces the function call token in the test file. + * + * @return void + */ + public function testIsInFunctionCallShouldReturnFunctionPointerWhenAllowNestedIsTrue( $insideFunctionCommentString, $insideFunctionTokenType, $functionCallCommentString ) { + $insideFunctionPtr = $this->getTargetToken( $insideFunctionCommentString, $insideFunctionTokenType ); + $functionNamePtr = $this->getTargetToken( $functionCallCommentString, Collections::nameTokens() ); + $result = ContextHelper::is_in_function_call( self::$phpcsFile, $insideFunctionPtr, array( 'my_function' => true ), true, true ); + $this->assertSame( $result, $functionNamePtr ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInFunctionCallShouldReturnFunctionPointerWhenAllowNestedIsTrue() + */ + public static function dataIsInFunctionCallShouldReturnFunctionPointerWhenAllowNestedIsTrue() { + return array( + array( '/* test inside function pointer 13 */', \T_VARIABLE, '/* test function call 13 */' ), + array( '/* test inside function pointer 14 */', \T_VARIABLE, '/* test function call 14 */' ), + array( '/* test inside function pointer 15 */', \T_VARIABLE, '/* test function call 15 */' ), + ); + } +} diff --git a/composer.json b/composer.json index a98caf602..d448cec01 100644 --- a/composer.json +++ b/composer.json @@ -53,13 +53,15 @@ "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf" ], "run-tests-phpcs3": [ - "@php ./vendor/phpunit/phpunit/phpunit --filter WordPress ./vendor/squizlabs/php_codesniffer/tests/AllTests.php --no-coverage" + "@php ./vendor/phpunit/phpunit/phpunit --filter WordPress ./vendor/squizlabs/php_codesniffer/tests/AllTests.php --no-coverage", + "@php ./vendor/phpunit/phpunit/phpunit WordPress/Util/Tests/ --no-coverage" ], "run-tests-phpcs4": [ "@php ./vendor/phpunit/phpunit/phpunit --no-coverage" ], "coverage-phpcs3": [ - "@php ./vendor/phpunit/phpunit/phpunit --filter WordPress ./vendor/squizlabs/php_codesniffer/tests/AllTests.php" + "@php ./vendor/phpunit/phpunit/phpunit --filter WordPress ./vendor/squizlabs/php_codesniffer/tests/AllTests.php", + "@php ./vendor/phpunit/phpunit/phpunit WordPress/Util/Tests/" ], "coverage-phpcs4": [ "@php ./vendor/phpunit/phpunit/phpunit" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a7a2b1401..757c96fec 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -13,7 +13,10 @@ forceCoversAnnotation="true"> - + + ./WordPress/Util/Tests/ + + ./WordPress/Tests/ From bd8a4f00f1fcc929034b234fe891926554af3519 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Fri, 15 Aug 2025 15:23:30 -0300 Subject: [PATCH 46/62] WIP ConstantHelper::is_use_of_global_constant(): add basic tests Check the way the tests are structured. There is for sure room to improve their organization. --- .../IsUseOfGlobalConstantUnitTest.inc | 86 ++++++++++ .../IsUseOfGlobalConstantUnitTest.php | 152 ++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.inc create mode 100644 WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.php diff --git a/WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.inc b/WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.inc new file mode 100644 index 000000000..0534dd86f --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.inc @@ -0,0 +1,86 @@ +PHP_OS; +/* test return false 19 */ $obj?->PHP_OS; +class YetAnotherClass { + use MyTrait { + /* test return false 20 */ + foo as private PHP_OS; + /* test return false 21 */ + bar as protected PHP_OS; + /* test return false 22 */ + baz as public PHP_OS; + } +} +/* test return false 23 */ \My\Ns\PHP_OS; +/* test return false 24 */ My\Ns\PHP_OS; +/* test return false 25 */ namespace\Ns\PHP_OS; +class Foo { + /* test return false 26 */ const PHP_OS = 1; +} +/* test return false 27 */use const SomeNamespace\PHP_OS as EOL; +/* test return false 28 */use const ABC as PHP_OS; +/* test return false 29 */use const SomeNamespace\{PHP_OS, PHP_VERSION_ID}; + +/* + * The below should be recognized as use of a global constant. + */ + +/* test return true 1 */ +echo PHP_OS; + +/* test return true 2 */ +echo \PHP_OS; + +$folder = basename( /* test return true 3 */ PHP_OS ); + +/* test return true 4 */ +include PHP_OS . '/js/myfile.js'; + +/* test return true 5 */ +use const PHP_OS as SSP; + +/* test return true 6 */ +switch( PHP_OS ) { + /* test return true 7 */ + case PHP_OS: + break; +} + +/* test return true 8 */ +const PHP_OS = 'something'; + +/* test return true 9 */ +$array[PHP_OS] = 'something'; + +/* test return true 10 */ +const ABC = '123', + DEF = '456', + PHP_OS = 'something', + GHI = 789; diff --git a/WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.php b/WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.php new file mode 100644 index 000000000..73537d4b2 --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ConstantsHelper/IsUseOfGlobalConstantUnitTest.php @@ -0,0 +1,152 @@ +assertFalse( + ConstantsHelper::is_use_of_global_constant( + self::$phpcsFile, + -1 + ) + ); + } + + /** + * Test is_use_of_global_constant() returns false for non-constant contexts. + * + * @dataProvider dataIsUseOfGlobalConstantShouldReturnFalse + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int $tokenType The token type to use for the target token. + * @param string|null $tokenContent The token content to use for the target token. + * + * @return void + */ + public function testIsUseOfGlobalConstantShouldReturnFalse( $commentString, $tokenType = null, $tokenContent = null ) { + if ( null === $tokenType ) { + $tokenType = Collections::nameTokens(); + + $isPhpcs3 = version_compare( Helper::getVersion(), '3.99.99', '<=' ); + + if ( null === $tokenContent || $isPhpcs3 ) { + $tokenContent = 'PHP_OS'; + } + } + + $stackPtr = $this->getTargetToken( $commentString, $tokenType, $tokenContent ); + $this->assertFalse( ConstantsHelper::is_use_of_global_constant( self::$phpcsFile, $stackPtr ) ); + } + + /** + * Data provider. + * + * @return array + * @see testIsUseOfGlobalConstantShouldReturnFalse() + */ + public static function dataIsUseOfGlobalConstantShouldReturnFalse() { + return array( + array( '/* test return false 1 */', \T_VARIABLE ), + array( '/* test return false 2 */' ), + array( '/* test return false 3 */', null, 'PHP_OS\Ns\SomeClass' ), + array( '/* test return false 4 */' ), + array( '/* test return false 5 */' ), + array( '/* test return false 6 */' ), + array( '/* test return false 7 */' ), + array( '/* test return false 8 */' ), + array( '/* test return false 9 */' ), + array( '/* test return false 10 */' ), + array( '/* test return false 11 */' ), + array( '/* test return false 12 */' ), + array( '/* test return false 13 */' ), + array( '/* test return false 14 */' ), + array( '/* test return false 15 */' ), + array( '/* test return false 16 */' ), + array( '/* test return false 17 */' ), + array( '/* test return false 18 */' ), + array( '/* test return false 19 */' ), + array( '/* test return false 20 */' ), + array( '/* test return false 21 */' ), + array( '/* test return false 22 */' ), + array( '/* test return false 23 */', null, '\My\Ns\PHP_OS' ), + array( '/* test return false 24 */', null, 'My\Ns\PHP_OS' ), + array( '/* test return false 25 */', null, 'namespace\Ns\PHP_OS' ), + array( '/* test return false 26 */' ), + array( '/* test return false 27 */', null, 'SomeNamespace\PHP_OS' ), + array( '/* test return false 28 */' ), + array( '/* test return false 29 */' ), + ); + } + + /** + * Test is_use_of_global_constant() returns true for use of global constants. + * + * @dataProvider dataIsUseOfGlobalConstantShouldReturnTrue + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param string|null $tokenContent The token content to use for the target token. + * + * @return void + */ + public function testIsUseOfGlobalConstantShouldReturnTrue( $commentString, $tokenContent = null ) { + $isPhpcs3 = version_compare( Helper::getVersion(), '3.99.99', '<=' ); + + if ( null === $tokenContent || $isPhpcs3 ) { + $tokenContent = 'PHP_OS'; + } + + $tokenTypes = array( + \T_STRING => \T_STRING, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + ); + + $stackPtr = $this->getTargetToken( $commentString, $tokenTypes, $tokenContent ); + $this->assertTrue( ConstantsHelper::is_use_of_global_constant( self::$phpcsFile, $stackPtr ) ); + } + + /** + * Data provider. + * + * @return array + * @see testIsUseOfGlobalConstantShouldReturnTrue() + */ + public static function dataIsUseOfGlobalConstantShouldReturnTrue() { + return array( + array( '/* test return true 1 */' ), + array( '/* test return true 2 */', '\PHP_OS' ), + array( '/* test return true 3 */' ), + array( '/* test return true 4 */' ), + array( '/* test return true 5 */' ), + array( '/* test return true 6 */' ), + array( '/* test return true 7 */' ), + array( '/* test return true 8 */' ), + array( '/* test return true 9 */' ), + array( '/* test return true 10 */' ), + ); + } +} From cece698ae899d2139804c7877615eda7c55bab08 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 24 Sep 2025 12:18:30 +0100 Subject: [PATCH 47/62] WIP ContextHelper::is_in_isset_or_empty(): add basic tests Check the way the tests are structured. There is for sure room to improve their organization. This commit is just the basic structured generated by Claude. Everything needs to be reviewed. --- .../IsInIssetOrEmptyUnitTest.inc | 54 +++++++++ .../IsInIssetOrEmptyUnitTest.php | 107 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInIssetOrEmptyUnitTest.inc create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInIssetOrEmptyUnitTest.php diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsInIssetOrEmptyUnitTest.inc b/WordPress/Util/Tests/Helpers/ContextHelper/IsInIssetOrEmptyUnitTest.inc new file mode 100644 index 000000000..6c819227a --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsInIssetOrEmptyUnitTest.inc @@ -0,0 +1,54 @@ +getTargetToken( $commentString, $tokenType ); + $result = ContextHelper::is_in_isset_or_empty( self::$phpcsFile, $stackPtr ); + $this->assertFalse( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInIssetOrEmptyShouldReturnFalse() + */ + public static function dataIsInIssetOrEmptyShouldReturnFalse() { + return array( + array( '/* test return false 1 */', \T_VARIABLE ), + array( '/* test return false 2 */', \T_VARIABLE ), + array( '/* test return false 3 */', \T_VARIABLE ), + array( '/* test return false 4 */', \T_VARIABLE ), + array( '/* test return false 5 */', \T_VARIABLE ), + array( '/* test return false 6 */', \T_VARIABLE ), + array( '/* test return false 7 */', \T_VARIABLE ), + array( '/* test return false 8 */', \T_VARIABLE ), + array( '/* test return false 9 */', \T_VARIABLE ), + array( '/* test return false 10 */', \T_VARIABLE ), + array( '/* test return false 11 */', \T_VARIABLE ), + array( '/* test return false 12 */', \T_VARIABLE ), + array( '/* test return false 13 */', \T_VARIABLE ), + ); + } + + /** + * Test is_in_isset_or_empty() returns true if given token is inside isset() or empty(). + * + * @dataProvider dataIsInIssetOrEmptyShouldReturnTrue + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int|string $tokenType The token type to search for. + * + * @return void + */ + public function testIsInIssetOrEmptyShouldReturnTrue( $commentString, $tokenType ) { + $stackPtr = $this->getTargetToken( $commentString, $tokenType ); + $result = ContextHelper::is_in_isset_or_empty( self::$phpcsFile, $stackPtr ); + $this->assertTrue( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInIssetOrEmptyShouldReturnTrue() + */ + public static function dataIsInIssetOrEmptyShouldReturnTrue() { + return array( + array( '/* test return true 1 */', \T_VARIABLE ), + array( '/* test return true 2 */', \T_VARIABLE ), + array( '/* test return true 3 */', \T_VARIABLE ), + array( '/* test return true 4 */', \T_VARIABLE ), + array( '/* test return true 5 */', \T_VARIABLE ), + array( '/* test return true 6 */', \T_VARIABLE ), + array( '/* test return true 7 */', \T_VARIABLE ), + array( '/* test return true 8 */', \T_VARIABLE ), + array( '/* test return true 9 */', \T_VARIABLE ), + array( '/* test return true 10 */', \T_VARIABLE ), + array( '/* test return true 11 */', \T_VARIABLE ), + array( '/* test return true 12 */', \T_VARIABLE ), + array( '/* test return true 13 */', \T_VARIABLE ), + array( '/* test return true 14 */', \T_VARIABLE ), + array( '/* test return true 15 */', \T_VARIABLE ), + array( '/* test return true 16 */', \T_VARIABLE ), + ); + } +} \ No newline at end of file From 080027e40c96cfbb31cda5223d017a1ef4b00e95 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 30 Sep 2025 15:29:20 -0300 Subject: [PATCH 48/62] WIP ContextHelper::is_in_array_comparison(): add basic tests Check the way the tests are structured. There is for sure room to improve their organization. This commit is just the basic structured generated by Claude. Everything needs to be reviewed. --- .../IsInArrayComparisonUnitTest.inc | 64 +++++++++++ .../IsInArrayComparisonUnitTest.php | 107 ++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.inc create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.php diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.inc b/WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.inc new file mode 100644 index 000000000..0380c3535 --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.inc @@ -0,0 +1,64 @@ +in_array( /* test return false 6 */ $needle, $haystack ); +// Static method call +ArrayHelper::in_array( /* test return false 7 */ $needle, $haystack ); +// array_keys without filter_value parameter +array_keys( /* test return false 8 */ $array ); +// array_keys with wrong parameter name (should be filter_value) +array_keys( array: /* test return false 9 */ $array, search_value: 'value', strict: true ); +// Variable not inside an array comparison function +some_other_function( /* test return false 10 */ $variable ); +// Relative namespace function call +namespace\in_array( /* test return false 11 */ $needle, $haystack ); + +// Test cases that should return true + +// Basic in_array usage +in_array( /* test return true 1 */ $needle, $haystack ); +in_array( /* test return true 2 */ $needle, $haystack, true ); + +// Basic array_search usage +array_search( /* test return true 3 */ $needle, $haystack ); +array_search( /* test return true 4 */ $needle, $haystack, true ); + +// array_keys with filter_value parameter (second parameter) +array_keys( $array, /* test return true 5 */ $filter_value ); +array_keys( $array, /* test return true 6 */ $filter_value, true ); + +// array_keys with named parameters +array_keys( array: $array, filter_value: /* test return true 7 */ $search_value ); +array_keys( array: $array, filter_value: /* test return true 8 */ $search_value, strict: true ); + +// Case insensitive function names +IN_ARRAY( /* test return true 9 */ $needle, $haystack ); +Array_Search( /* test return true 10 */ $needle, $haystack ); +ARRAY_KEYS( $array, /* test return true 11 */ $filter_value ); + +// Fully qualified global function calls +\in_array( /* test return true 12 */ $needle, $haystack ); +\array_search( /* test return true 13 */ $needle, $haystack ); +\array_keys( $array, /* test return true 14 */ $filter_value ); + +// Complex expressions as parameters +in_array( /* test return true 15 */ $obj->property, $haystack ); +array_search( /* test return true 16 */ $array['key'], $haystack ); +array_keys( $data, /* test return true 17 */ get_value() ); + +// Multiple variables in the same function call +in_array( /* test return true 18 */ $needle1, $haystack ); +in_array( $needle2, /* test return true 19 */ $haystack ); + +// Nested array access +array_keys( /* test return true 20 */ $nested['array']['data'], $filter ); \ No newline at end of file diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.php b/WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.php new file mode 100644 index 000000000..1bc64245a --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsInArrayComparisonUnitTest.php @@ -0,0 +1,107 @@ +getTargetToken( $commentString, $tokenType ); + $result = ContextHelper::is_in_array_comparison( self::$phpcsFile, $stackPtr ); + $this->assertFalse( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInArrayComparisonShouldReturnFalse() + */ + public static function dataIsInArrayComparisonShouldReturnFalse() { + return array( + array( '/* test return false 1 */', \T_VARIABLE ), + array( '/* test return false 2 */', \T_VARIABLE ), + array( '/* test return false 3 */', \T_VARIABLE ), + array( '/* test return false 4 */', \T_VARIABLE ), + array( '/* test return false 5 */', \T_VARIABLE ), + array( '/* test return false 6 */', \T_VARIABLE ), + array( '/* test return false 7 */', \T_VARIABLE ), + array( '/* test return false 8 */', \T_VARIABLE ), + array( '/* test return false 9 */', \T_VARIABLE ), + array( '/* test return false 11 */', \T_VARIABLE ), + ); + } + + /** + * Test is_in_array_comparison() returns true if given token is inside an array comparison function. + * + * @dataProvider dataIsInArrayComparisonShouldReturnTrue + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int|string $tokenType The token type to search for. + * + * @return void + */ + public function testIsInArrayComparisonShouldReturnTrue( $commentString, $tokenType ) { + $stackPtr = $this->getTargetToken( $commentString, $tokenType ); + $result = ContextHelper::is_in_array_comparison( self::$phpcsFile, $stackPtr ); + $this->assertTrue( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInArrayComparisonShouldReturnTrue() + */ + public static function dataIsInArrayComparisonShouldReturnTrue() { + return array( + array( '/* test return true 1 */', \T_VARIABLE ), + array( '/* test return true 2 */', \T_VARIABLE ), + array( '/* test return true 3 */', \T_VARIABLE ), + array( '/* test return true 4 */', \T_VARIABLE ), + array( '/* test return true 5 */', \T_VARIABLE ), + array( '/* test return true 6 */', \T_VARIABLE ), + array( '/* test return true 7 */', \T_VARIABLE ), + array( '/* test return true 8 */', \T_VARIABLE ), + array( '/* test return true 9 */', \T_VARIABLE ), + array( '/* test return true 10 */', \T_VARIABLE ), + array( '/* test return true 11 */', \T_VARIABLE ), + array( '/* test return true 12 */', \T_VARIABLE ), + array( '/* test return true 13 */', \T_VARIABLE ), + array( '/* test return true 14 */', \T_VARIABLE ), + array( '/* test return true 15 */', \T_VARIABLE ), + array( '/* test return true 16 */', \T_VARIABLE ), + array( '/* test return true 17 */', \T_STRING ), + array( '/* test return true 18 */', \T_VARIABLE ), + array( '/* test return true 19 */', \T_VARIABLE ), + array( '/* test return true 20 */', \T_VARIABLE ), + ); + } +} From e99c7be2d2e323b28a78662c9ff23dad7d2d99b5 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Tue, 30 Sep 2025 15:29:42 -0300 Subject: [PATCH 49/62] WIP ContextHelper::is_in_type_test(): add basic tests Check the way the tests are structured. There is for sure room to improve their organization. This commit is just the basic structured generated by Claude. Everything needs to be reviewed. --- .../ContextHelper/IsInTypeTestUnitTest.inc | 65 ++++++++++ .../ContextHelper/IsInTypeTestUnitTest.php | 116 ++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.inc create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.php diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.inc b/WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.inc new file mode 100644 index 000000000..3b2cf8479 --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.inc @@ -0,0 +1,65 @@ +is_string( /* test return false 6 */ $value ); +// Static method call +TypeChecker::is_int( /* test return false 7 */ $value ); +// Function that is not a type test +strlen( /* test return false 8 */ $string ); +// Relative namespace function call +namespace\is_bool( /* test return false 9 */ $value ); +// Custom function with similar name +my_is_numeric( /* test return false 10 */ $value ); + +// Test cases that should return true + +// Basic type test functions +is_array( /* test return true 1 */ $data ); +is_bool( /* test return true 2 */ $flag ); +is_callable( /* test return true 3 */ $callback ); +is_countable( /* test return true 4 */ $items ); +is_double( /* test return true 5 */ $number ); +is_float( /* test return true 6 */ $decimal ); +is_int( /* test return true 7 */ $count ); +is_integer( /* test return true 8 */ $id ); +is_iterable( /* test return true 9 */ $collection ); +is_long( /* test return true 10 */ $timestamp ); +is_null( /* test return true 11 */ $optional ); +is_numeric( /* test return true 12 */ $value ); +is_object( /* test return true 13 */ $instance ); +is_real( /* test return true 14 */ $coefficient ); +is_resource( /* test return true 15 */ $handle ); +is_scalar( /* test return true 16 */ $primitive ); +is_string( /* test return true 17 */ $text ); + +// Case insensitive function names +IS_ARRAY( /* test return true 18 */ $data ); +Is_Bool( /* test return true 19 */ $flag ); +IS_NUMERIC( /* test return true 20 */ $value ); + +// Fully qualified global function calls +\is_array( /* test return true 21 */ $data ); +\is_string( /* test return true 22 */ $text ); +\is_numeric( /* test return true 23 */ $value ); + +// Complex expressions as parameters +is_array( /* test return true 24 */ $obj->property ); +is_string( /* test return true 25 */ $array['key'] ); +is_numeric( /* test return true 26 */ get_value() ); + +// Multiple variables in the same function call (though type test functions typically have one param) +is_callable( /* test return true 27 */ $callback, false ); + +// Nested array/object access +is_array( /* test return true 28 */ $nested['data']['items'] ); +is_object( /* test return true 29 */ $config->settings ); \ No newline at end of file diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.php b/WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.php new file mode 100644 index 000000000..f4fd0c4ff --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsInTypeTestUnitTest.php @@ -0,0 +1,116 @@ +getTargetToken( $commentString, $tokenType ); + $result = ContextHelper::is_in_type_test( self::$phpcsFile, $stackPtr ); + $this->assertFalse( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInTypeTestShouldReturnFalse() + */ + public static function dataIsInTypeTestShouldReturnFalse() { + return array( + array( '/* test return false 1 */', \T_VARIABLE ), + array( '/* test return false 2 */', \T_VARIABLE ), + array( '/* test return false 3 */', \T_VARIABLE ), + array( '/* test return false 4 */', \T_VARIABLE ), + array( '/* test return false 5 */', \T_VARIABLE ), + array( '/* test return false 6 */', \T_VARIABLE ), + array( '/* test return false 7 */', \T_VARIABLE ), + array( '/* test return false 8 */', \T_VARIABLE ), + array( '/* test return false 9 */', \T_VARIABLE ), + array( '/* test return false 10 */', \T_VARIABLE ), + ); + } + + /** + * Test is_in_type_test() returns true if given token is inside a type test function. + * + * @dataProvider dataIsInTypeTestShouldReturnTrue + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int|string $tokenType The token type to search for. + * + * @return void + */ + public function testIsInTypeTestShouldReturnTrue( $commentString, $tokenType ) { + $stackPtr = $this->getTargetToken( $commentString, $tokenType ); + $result = ContextHelper::is_in_type_test( self::$phpcsFile, $stackPtr ); + $this->assertTrue( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsInTypeTestShouldReturnTrue() + */ + public static function dataIsInTypeTestShouldReturnTrue() { + return array( + array( '/* test return true 1 */', \T_VARIABLE ), + array( '/* test return true 2 */', \T_VARIABLE ), + array( '/* test return true 3 */', \T_VARIABLE ), + array( '/* test return true 4 */', \T_VARIABLE ), + array( '/* test return true 5 */', \T_VARIABLE ), + array( '/* test return true 6 */', \T_VARIABLE ), + array( '/* test return true 7 */', \T_VARIABLE ), + array( '/* test return true 8 */', \T_VARIABLE ), + array( '/* test return true 9 */', \T_VARIABLE ), + array( '/* test return true 10 */', \T_VARIABLE ), + array( '/* test return true 11 */', \T_VARIABLE ), + array( '/* test return true 12 */', \T_VARIABLE ), + array( '/* test return true 13 */', \T_VARIABLE ), + array( '/* test return true 14 */', \T_VARIABLE ), + array( '/* test return true 15 */', \T_VARIABLE ), + array( '/* test return true 16 */', \T_VARIABLE ), + array( '/* test return true 17 */', \T_VARIABLE ), + array( '/* test return true 18 */', \T_VARIABLE ), + array( '/* test return true 19 */', \T_VARIABLE ), + array( '/* test return true 20 */', \T_VARIABLE ), + array( '/* test return true 21 */', \T_VARIABLE ), + array( '/* test return true 22 */', \T_VARIABLE ), + array( '/* test return true 23 */', \T_VARIABLE ), + array( '/* test return true 24 */', \T_VARIABLE ), + array( '/* test return true 25 */', \T_VARIABLE ), + array( '/* test return true 26 */', \T_STRING ), + array( '/* test return true 27 */', \T_VARIABLE ), + array( '/* test return true 28 */', \T_VARIABLE ), + array( '/* test return true 29 */', \T_VARIABLE ), + ); + } +} From f352544866d7c3320e1d7a172f509746a5d5dbe9 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Mon, 18 Aug 2025 15:00:58 -0300 Subject: [PATCH 50/62] WIP ContextHelper::is_token_namespaced(): add basic tests Check the way the tests are structured. There is for sure room to improve their organization. --- .../IsTokenNamespacedUnitTest.inc | 22 +++++ .../IsTokenNamespacedUnitTest.php | 96 +++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.inc create mode 100644 WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.php diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.inc b/WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.inc new file mode 100644 index 000000000..57af0b8fb --- /dev/null +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.inc @@ -0,0 +1,22 @@ +assertFalse( ContextHelper::is_token_namespaced( self::$phpcsFile, -1 ) ); + } + + /** + * Test is_token_namespaced() returns false for non-namespaced contexts. + * + * @dataProvider dataIsTokenNamespacedShouldReturnFalse + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param string $tokenContent The token content to use for the target token. + * + * @return void + */ + public function testIsTokenNamespacedShouldReturnFalse( $commentString, $tokenContent ) { + $stackPtr = $this->getTargetToken( $commentString, Collections::nameTokens(), $tokenContent ); + $this->assertFalse( ContextHelper::is_token_namespaced( self::$phpcsFile, $stackPtr ) ); + } + + /** + * Data provider. + * + * @return array + * @see testIsTokenNamespacedShouldReturnFalse() + */ + public static function dataIsTokenNamespacedShouldReturnFalse() { + return array( + array( '/* test return false 1 */', 'my_function' ), + array( '/* test return false 2 */', 'my_function' ), + array( '/* test return false 3 */', 'MyClass' ), + array( '/* test return false 4 */', 'MyClass' ), + array( '/* test return false 5 */', 'MY_CONSTANT' ), + array( '/* test return false 6 */', 'MY_CONSTANT' ), + ); + } + + /** + * Test is_token_namespaced() returns true for namespaced contexts. + * + * @dataProvider dataIsTokenNamespacedShouldReturnTrue + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param string $tokenContent The token content to use for the target token. + * + * @return void + */ + public function testIsTokenNamespacedShouldReturnTrue( $commentString, $tokenContent ) { + $stackPtr = $this->getTargetToken( $commentString, Collections::nameTokens(), $tokenContent ); + $this->assertTrue( ContextHelper::is_token_namespaced( self::$phpcsFile, $stackPtr ) ); + } + + /** + * Data provider. + * + * @return array + * @see testIsTokenNamespacedShouldReturnTrue() + */ + public static function dataIsTokenNamespacedShouldReturnTrue() { + return array( + array( '/* test return true 1 */', 'my_function' ), + array( '/* test return true 2 */', 'my_function' ), + array( '/* test return true 3 */', 'my_function' ), + array( '/* test return true 4 */', 'MyClass' ), + array( '/* test return true 5 */', 'MY_CONSTANT' ), + ); + } +} From 096c87bf918076164bee01bc4d80cee2df0b5a8b Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Mon, 18 Aug 2025 15:34:58 -0300 Subject: [PATCH 51/62] WIP ContextHelper::is_token_namespaced(): update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization when determining if a token is namespaced or not. Since the tokenization of namespaced names changed between PHPCS 3 and 4, it was necessary to use different logic depending on the PHPCS version. TODO check if the approach to support both PHPCS 3 and 4 is good. --- WordPress/Helpers/ContextHelper.php | 52 +++++++++++++++++++ .../IsTokenNamespacedUnitTest.php | 21 +++++--- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/WordPress/Helpers/ContextHelper.php b/WordPress/Helpers/ContextHelper.php index 31870610d..3518f513d 100644 --- a/WordPress/Helpers/ContextHelper.php +++ b/WordPress/Helpers/ContextHelper.php @@ -11,6 +11,7 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; +use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\Parentheses; use PHPCSUtils\Utils\PassedParameters; @@ -176,6 +177,28 @@ public static function is_token_namespaced( File $phpcsFile, $stackPtr ) { return false; } + $isPhpcs3 = version_compare( Helper::getVersion(), '3.99.99', '<=' ); + + if ( true === $isPhpcs3 ) { + return self::is_token_namespaced_phpcs3( $phpcsFile, $stackPtr ); + } else { + return self::is_token_namespaced_phpcs4( $phpcsFile, $stackPtr ); + } + } + + /** + * Check if a particular token is prefixed with a namespace when running PHPCS <= 3. Different + * methods are necessary because, the tokenization of namespaced names changed between PHPCS 3 + * and 4. + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The index of the token in the stack. + * + * @return bool + */ + private static function is_token_namespaced_phpcs3( File $phpcsFile, $stackPtr ) { + $tokens = $phpcsFile->getTokens(); + $prev = $phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); if ( \T_NS_SEPARATOR !== $tokens[ $prev ]['code'] ) { @@ -192,6 +215,35 @@ public static function is_token_namespaced( File $phpcsFile, $stackPtr ) { return true; } + /** + * Check if a particular token is prefixed with a namespace when running PHPCS <= 4. Different + * methods are necessary because, the tokenization of namespaced names changed between PHPCS 3 + * and 4. + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The index of the token in the stack. + * + * @return bool + */ + private static function is_token_namespaced_phpcs4( File $phpcsFile, $stackPtr ) { + $tokens = $phpcsFile->getTokens(); + + if ( \T_NAME_QUALIFIED === $tokens[ $stackPtr ]['code'] + || \T_NAME_RELATIVE === $tokens[ $stackPtr ]['code'] + ) { + return true; + } + + // If the token is a fully qualified name, this methods consider it as namespaced if it + // contains more than one namespace separator (i.e., not in the global namespace). + if ( \T_NAME_FULLY_QUALIFIED === $tokens[ $stackPtr ]['code'] + && \substr_count( $tokens[ $stackPtr ]['content'], '\\' ) > 1 ) { + return true; + } + + return false; + } + /** * Check if a token is (part of) a parameter for a function call to a select list of functions. * diff --git a/WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.php b/WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.php index 918b38691..a42ce2fa9 100644 --- a/WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.php +++ b/WordPress/Util/Tests/Helpers/ContextHelper/IsTokenNamespacedUnitTest.php @@ -9,6 +9,7 @@ namespace WordPressCS\WordPress\Util\Tests\Helpers\ContextHelper; +use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use WordPressCS\WordPress\Helpers\ContextHelper; use PHPCSUtils\TestUtils\UtilityMethodTestCase; @@ -53,13 +54,15 @@ public function testIsTokenNamespacedShouldReturnFalse( $commentString, $tokenCo * @see testIsTokenNamespacedShouldReturnFalse() */ public static function dataIsTokenNamespacedShouldReturnFalse() { + $isPhpcs3 = version_compare( Helper::getVersion(), '3.99.99', '<=' ); + return array( array( '/* test return false 1 */', 'my_function' ), - array( '/* test return false 2 */', 'my_function' ), + array( '/* test return false 2 */', ( $isPhpcs3 ? 'my_function' : '\my_function' ) ), array( '/* test return false 3 */', 'MyClass' ), - array( '/* test return false 4 */', 'MyClass' ), + array( '/* test return false 4 */', ( $isPhpcs3 ? 'MyClass' : '\MyClass' ) ), array( '/* test return false 5 */', 'MY_CONSTANT' ), - array( '/* test return false 6 */', 'MY_CONSTANT' ), + array( '/* test return false 6 */', ( $isPhpcs3 ? 'MY_CONSTANT' : '\MY_CONSTANT' ) ), ); } @@ -85,12 +88,14 @@ public function testIsTokenNamespacedShouldReturnTrue( $commentString, $tokenCon * @see testIsTokenNamespacedShouldReturnTrue() */ public static function dataIsTokenNamespacedShouldReturnTrue() { + $isPhpcs3 = version_compare( Helper::getVersion(), '3.99.99', '<=' ); + return array( - array( '/* test return true 1 */', 'my_function' ), - array( '/* test return true 2 */', 'my_function' ), - array( '/* test return true 3 */', 'my_function' ), - array( '/* test return true 4 */', 'MyClass' ), - array( '/* test return true 5 */', 'MY_CONSTANT' ), + array( '/* test return true 1 */', ( $isPhpcs3 ? 'my_function' : 'MyNamespace\my_function' ) ), + array( '/* test return true 2 */', ( $isPhpcs3 ? 'my_function' : '\MyNamespace\my_function' ) ), + array( '/* test return true 3 */', ( $isPhpcs3 ? 'my_function' : 'namespace\my_function' ) ), + array( '/* test return true 4 */', ( $isPhpcs3 ? 'MyClass' : 'MyNamespace\MyClass' ) ), + array( '/* test return true 5 */', ( $isPhpcs3 ? 'MY_CONSTANT' : 'MyNamespace\MY_CONSTANT' ) ), ); } } From b4901b66b52c0ff3dbea52cc8918aaf965ce53a9 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 2 Oct 2025 17:32:22 -0300 Subject: [PATCH 52/62] WIP WPDBTrait::is_wpdb_method_call(): add basic tests Check the way the tests are structured. There is for sure room to improve their organization. This commit is just the basic structured generated by Claude. Everything needs to be reviewed. --- .../WPDBTrait/IsWpdbMethodCallUnitTest.inc | 74 +++++++ .../WPDBTrait/IsWpdbMethodCallUnitTest.php | 195 ++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.inc create mode 100644 WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.php diff --git a/WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.inc b/WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.inc new file mode 100644 index 000000000..260e6959b --- /dev/null +++ b/WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.inc @@ -0,0 +1,74 @@ +prepare( 'SELECT * FROM table' ); +/* test return false 2 */ $custom_db->query( 'SELECT * FROM table' ); + +// WPDB variable but not a method call. +/* test return false 3 */ $wpdb; +/* test return false 4 */ $wpdb['key']; +/* test return false 5 */ $wpdb = new wpdb(); + +// Property access (not method calls) - definitely no parentheses. +/* test return false 6 */ echo $wpdb->table_name; +/* test return false 7 */ echo $wpdb->insert_id; + +// Function calls, not object method calls. +/* test return false 8 */ $result = wpdb( 'SELECT * FROM table' ); + +// Not WPDB class references. +/* test return false 9 */ wpdb_custom(); +/* test return false 10 */ \wpdb_custom(); + +// Method calls on different variables. +/* test return false 11 */ $database->prepare( 'SELECT * FROM table' ); +/* test return false 12 */ $custom->query( 'SELECT * FROM table' ); + +// WPDB variable but no parentheses (property access). +/* test return false 13 */ echo $wpdb->last_error; +/* test return false 14 */ echo $wpdb->num_rows; +/* test return false 15 */ echo $wpdb->prefix; + +/* + * Test cases that should be recognized as WPDB method calls. + */ + +// Standard WPDB method calls. +/* test return true 1 */ $wpdb->prepare( 'SELECT * FROM table WHERE id = %d', $id ); +/* test return true 2 */ $wpdb->query( 'DELETE FROM table WHERE id = 1' ); +/* test return true 3 */ $wpdb->prepare( 'INSERT INTO table (name) VALUES (%s)', $name ); +/* test return true 4 */ $wpdb->query( $sql ); + +// WPDB method calls with whitespace. +/* test return true 5 */ $wpdb -> prepare( 'SELECT * FROM table' ); + +// Static WPDB method calls. +/* test return true 6 */ $wpdb::prepare( 'SELECT * FROM table WHERE id = %d', $id ); + +// Global WPDB class references. +/* test return true 7 */ \wpdb::prepare( 'SELECT * FROM table WHERE id = %d', $id ); + +/* + * Test cases for methods that are not in the target methods list. + */ + +// WPDB method calls but not target methods. +/* test non-target method 1 */ $wpdb->insert( 'table', array( 'name' => 'value' ) ); +/* test non-target method 2 */ $wpdb->update( 'table', array( 'name' => 'value' ), array( 'id' => 1 ) ); + +/* + * Test cases for namespaced calls (should handle correctly). + */ + +// Global namespace (should work). +/* test namespaced 1 */ wpdb::prepare( 'SELECT * FROM table' ); +/* test namespaced 2 */ \wpdb::prepare( 'SELECT * FROM table' ); + +// Custom namespaces (should not work). +/* test namespaced 3 */ MyNamespace\wpdb::prepare( 'SELECT * FROM table' ); +/* test namespaced 4 */ \MyNamespace\wpdb::prepare( 'SELECT * FROM table' ); +/* test namespaced 5 */ SomeNamespace\wpdb::prepare( 'SELECT * FROM table' ); \ No newline at end of file diff --git a/WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.php b/WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.php new file mode 100644 index 000000000..06ef6750f --- /dev/null +++ b/WordPress/Util/Tests/Helpers/WPDBTrait/IsWpdbMethodCallUnitTest.php @@ -0,0 +1,195 @@ +is_wpdb_method_call( $phpcsFile, $stackPtr, $target_methods ); + } + }; + } + + /** + * Test is_wpdb_method_call() returns false if given token is not a WPDB method call. + * + * @dataProvider dataIsWpdbMethodCallShouldReturnFalse + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int|string $tokenType The token type to search for. + * + * @return void + */ + public function testIsWpdbMethodCallShouldReturnFalse( $commentString, $tokenType ) { + $stackPtr = $this->getTargetToken( $commentString, $tokenType ); + $result = self::$testClass->testIsWpdbMethodCall( self::$phpcsFile, $stackPtr, array( 'prepare' => true, 'query' => true ) ); + $this->assertFalse( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsWpdbMethodCallShouldReturnFalse() + */ + public static function dataIsWpdbMethodCallShouldReturnFalse() { + return array( + array( '/* test return false 1 */', \T_VARIABLE ), + array( '/* test return false 2 */', \T_VARIABLE ), + array( '/* test return false 3 */', \T_VARIABLE ), + array( '/* test return false 4 */', \T_VARIABLE ), + array( '/* test return false 5 */', \T_VARIABLE ), + array( '/* test return false 6 */', \T_VARIABLE ), + array( '/* test return false 7 */', \T_VARIABLE ), + array( '/* test return false 8 */', \T_VARIABLE ), + array( '/* test return false 9 */', \T_STRING ), + array( '/* test return false 10 */', \T_STRING ), + array( '/* test return false 11 */', \T_VARIABLE ), + array( '/* test return false 12 */', \T_VARIABLE ), + array( '/* test return false 13 */', \T_VARIABLE ), + array( '/* test return false 14 */', \T_VARIABLE ), + array( '/* test return false 15 */', \T_VARIABLE ), + ); + } + + /** + * Test is_wpdb_method_call() returns true for valid WPDB method calls. + * + * @dataProvider dataIsWpdbMethodCallShouldReturnTrue + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int|string $tokenType The token type to search for. + * + * @return void + */ + public function testIsWpdbMethodCallShouldReturnTrue( $commentString, $tokenType ) { + $stackPtr = $this->getTargetToken( $commentString, $tokenType ); + $result = self::$testClass->testIsWpdbMethodCall( self::$phpcsFile, $stackPtr, array( 'prepare' => true, 'query' => true ) ); + $this->assertTrue( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsWpdbMethodCallShouldReturnTrue() + */ + public static function dataIsWpdbMethodCallShouldReturnTrue() { + return array( + array( '/* test return true 1 */', \T_VARIABLE ), + array( '/* test return true 2 */', \T_VARIABLE ), + array( '/* test return true 3 */', \T_VARIABLE ), + array( '/* test return true 4 */', \T_VARIABLE ), + array( '/* test return true 5 */', \T_VARIABLE ), + array( '/* test return true 6 */', \T_VARIABLE ), + array( '/* test return true 7 */', \T_STRING ), + ); + } + + /** + * Test is_wpdb_method_call() returns false for WPDB method calls with non-target methods. + * + * @dataProvider dataIsWpdbMethodCallShouldReturnFalseForNonTargetMethods + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int|string $tokenType The token type to search for. + * + * @return void + */ + public function testIsWpdbMethodCallShouldReturnFalseForNonTargetMethods( $commentString, $tokenType ) { + $stackPtr = $this->getTargetToken( $commentString, $tokenType ); + $result = self::$testClass->testIsWpdbMethodCall( self::$phpcsFile, $stackPtr, array( 'prepare' => true ) ); + $this->assertFalse( $result ); + } + + /** + * Data provider. + * + * @return array + * @see testIsWpdbMethodCallShouldReturnFalseForNonTargetMethods() + */ + public static function dataIsWpdbMethodCallShouldReturnFalseForNonTargetMethods() { + return array( + array( '/* test non-target method 1 */', \T_VARIABLE ), + array( '/* test non-target method 2 */', \T_VARIABLE ), + ); + } + + /** + * Test is_wpdb_method_call() correctly handles namespaced calls. + * + * @dataProvider dataIsWpdbMethodCallShouldHandleNamespacedCalls + * + * @param string $commentString The comment which prefaces the target token in the test file. + * @param int|string $tokenType The token type to search for. + * @param bool $expected Whether the result should be true or false. + * + * @return void + */ + public function testIsWpdbMethodCallShouldHandleNamespacedCalls( $commentString, $tokenType, $expected ) { + $stackPtr = $this->getTargetToken( $commentString, $tokenType ); + $result = self::$testClass->testIsWpdbMethodCall( self::$phpcsFile, $stackPtr, array( 'prepare' => true, 'query' => true ) ); + + if ( $expected ) { + $this->assertTrue( $result ); + } else { + $this->assertFalse( $result ); + } + } + + /** + * Data provider. + * + * @return array + * @see testIsWpdbMethodCallShouldHandleNamespacedCalls() + */ + public static function dataIsWpdbMethodCallShouldHandleNamespacedCalls() { + return array( + array( '/* test namespaced 1 */', \T_STRING, true ), + array( '/* test namespaced 2 */', \T_STRING, true ), + array( '/* test namespaced 3 */', \T_STRING, false ), + array( '/* test namespaced 4 */', \T_STRING, false ), + array( '/* test namespaced 5 */', \T_STRING, false ), + ); + } +} \ No newline at end of file From bb574748391515506ed57bf5ea30bc115af4c6e1 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 15 Oct 2025 14:21:10 -0300 Subject: [PATCH 53/62] PR 2631 WP/EnqueuedResourceParameters: fix some inaccuracies and typos in code comments --- .../Sniffs/WP/EnqueuedResourceParametersSniff.php | 11 ++++++----- .../Tests/WP/EnqueuedResourceParametersUnitTest.1.inc | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php b/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php index 578517238..6ad938a29 100644 --- a/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php +++ b/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php @@ -18,7 +18,7 @@ * This checks the enqueued 4th and 5th parameters to make sure the version and in_footer are set. * * If a source ($src) value is passed, then version ($ver) needs to have non-falsy value. - * If a source ($src) value is passed a check for in footer ($in_footer), warn the user if the value is falsy. + * If a source ($src) value is passed, then it is recommended to explicitly set the $in_footer parameter. * * @link https://developer.wordpress.org/reference/functions/wp_register_script/ * @link https://developer.wordpress.org/reference/functions/wp_enqueue_script/ @@ -66,7 +66,7 @@ final class EnqueuedResourceParametersSniff extends AbstractFunctionParameterSni /** * Token codes which are "safe" to accept to determine whether a version would evaluate to `false`. * - * This array is enriched with the several of the PHPCS token arrays in the register() method. + * This array is enriched with several of the PHPCS token arrays in the register() method. * * @var array */ @@ -88,7 +88,8 @@ final class EnqueuedResourceParametersSniff extends AbstractFunctionParameterSni /** * Returns an array of tokens this test wants to listen for. * - * Overloads and calls the parent method to allow for adding additional tokens to the $safe_tokens property. + * Overloads and calls the parent method to allow for adding additional tokens to the + * $false_tokens and $safe_tokens properties. * * @return array */ @@ -165,8 +166,8 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p /* * In footer Check * - * Check to make sure that $in_footer is set to true. - * It will warn the user to make sure it is intended. + * Check to make sure that $in_footer is explicitly set. + * Warn the user if it is not set. * * Only wp_register_script and wp_enqueue_script need this check, * as this parameter is not available to wp_register_style and wp_enqueue_style. diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc index 4a73b458d..3b20ccc5d 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc @@ -29,7 +29,7 @@ wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), function() { }, true ); // OK. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), $version, true ); // OK. -wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0' ); // Warning - In Footer is set to a falsy (default) value. +wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0' ); // Warning - $in_footer is not explicitly set. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0', false ); // OK. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0', null ); // OK. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0', 0 ); // OK. From 69372b1259ac4bddcafdb2b85ad0e82e0b0c8bef Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 15 Oct 2025 15:04:32 -0300 Subject: [PATCH 54/62] PR 2631 WP/EnqueuedResourceParameters: fix handling of non-lowercased `null` This commit fixes how the sniff handles non-lowercased `null` when passed as the value of the `$ver` parameter. Now the sniff consistently handles `null` regardless of the case and always returns a warning. Before, it would return a warning only for lower-cased `null` and an error for all other variations of `null`. --- .../WP/EnqueuedResourceParametersSniff.php | 2 +- .../WP/EnqueuedResourceParametersUnitTest.1.inc | 3 +++ .../WP/EnqueuedResourceParametersUnitTest.php | 17 +++++++++-------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php b/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php index 6ad938a29..53b97a577 100644 --- a/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php +++ b/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php @@ -140,7 +140,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p } } - if ( false === $version_param || 'null' === $version_param['clean'] ) { + if ( false === $version_param || 'null' === strtolower( $version_param['clean'] ) ) { $type = 'script'; if ( strpos( $matched_content, '_style' ) !== false ) { $type = 'style'; diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc index 3b20ccc5d..1a51b8f32 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc @@ -95,3 +95,6 @@ wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), (double) 0, true ); // Error - 0, false or NULL are not allowed. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), (binary) 0, true ); // Error - 0, false or NULL are not allowed. + +// Safeguard handling of non-lowercase `null`. +wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), NULL, true ); // Error - 0, false or NULL are not allowed. diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php index 37cfc248a..b823b9507 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php @@ -70,14 +70,15 @@ public function getWarningList( $testFile = '' ) { switch ( $testFile ) { case 'EnqueuedResourceParametersUnitTest.1.inc': return array( - 3 => 2, - 11 => 1, - 32 => 1, - 39 => 2, - 42 => 1, - 45 => 1, - 66 => 2, - 77 => 1, + 3 => 2, + 11 => 1, + 32 => 1, + 39 => 2, + 42 => 1, + 45 => 1, + 66 => 2, + 77 => 1, + 100 => 1, ); default: From bd7382e4671986226a6d406f325c747fde8750a1 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 14 Aug 2025 09:20:57 -0300 Subject: [PATCH 55/62] WP/EnqueuedResourceParameters: handle fully qualified `\false` and `\null` correctly Before this change passing `\false` or `\null` as the `$ver` parameter would result in a false negative. --- .../WP/EnqueuedResourceParametersSniff.php | 9 +++-- .../EnqueuedResourceParametersUnitTest.1.inc | 10 ++++++ .../WP/EnqueuedResourceParametersUnitTest.php | 35 ++++++++++--------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php b/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php index 53b97a577..3b9ba77bf 100644 --- a/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php +++ b/WordPress/Sniffs/WP/EnqueuedResourceParametersSniff.php @@ -53,14 +53,15 @@ final class EnqueuedResourceParametersSniff extends AbstractFunctionParameterSni ); /** - * False + the empty tokens array. + * False + T_NS_SEPARATOR + the empty tokens array. * * This array is enriched with the $emptyTokens array in the register() method. * * @var array */ private $false_tokens = array( - \T_FALSE => \T_FALSE, + \T_FALSE => \T_FALSE, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, // Needed to handle fully qualified \false (PHPCS 3.x). ); /** @@ -140,7 +141,9 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p } } - if ( false === $version_param || 'null' === strtolower( $version_param['clean'] ) ) { + $version_clean_lc = ( false !== $version_param ) ? strtolower( $version_param['clean'] ) : ''; + + if ( false === $version_param || 'null' === $version_clean_lc || '\null' === $version_clean_lc ) { $type = 'script'; if ( strpos( $matched_content, '_style' ) !== false ) { $type = 'style'; diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc index 1a51b8f32..f55224929 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc @@ -98,3 +98,13 @@ wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array // Safeguard handling of non-lowercase `null`. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), NULL, true ); // Error - 0, false or NULL are not allowed. + +/* + * Safeguard handling of fully qualified \true, \false and \null. + * Also safeguard that adding T_NS_SEPARATOR to $false_tokens doesn't cause false positives due to problems in is_falsy(). + */ +wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \FALSE, true ); // Error - 0, false or NULL are not allowed. +wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \null, true ); // Error - 0, false or NULL are not allowed. +wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \Null, true ); // Error - 0, false or NULL are not allowed. +wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \true, true ); // Ok. +wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \get_version(), true ); // OK. diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php index b823b9507..06e5e3172 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php @@ -31,22 +31,23 @@ public function getErrorList( $testFile = '' ) { switch ( $testFile ) { case 'EnqueuedResourceParametersUnitTest.1.inc': return array( - 6 => 1, - 9 => 1, - 10 => 1, - 12 => 1, - 13 => 1, - 14 => 1, - 22 => 1, - 54 => 1, - 57 => 1, - 61 => 1, - 82 => 1, - 85 => 1, - 89 => 1, - 92 => 1, - 95 => 1, - 97 => 1, + 6 => 1, + 9 => 1, + 10 => 1, + 12 => 1, + 13 => 1, + 14 => 1, + 22 => 1, + 54 => 1, + 57 => 1, + 61 => 1, + 82 => 1, + 85 => 1, + 89 => 1, + 92 => 1, + 95 => 1, + 97 => 1, + 106 => 1, ); case 'EnqueuedResourceParametersUnitTest.2.inc': @@ -79,6 +80,8 @@ public function getWarningList( $testFile = '' ) { 66 => 2, 77 => 1, 100 => 1, + 107 => 1, + 108 => 1, ); default: From 09c4f6fbb9102dac892489d1627eb0fea01e7f90 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 15 Oct 2025 20:00:52 -0300 Subject: [PATCH 56/62] WP/EnqueuedResourceParameters: add tests for namespaced names I'm adding two different tests for fully qualified global function calls to cover all the global functions that are referenced directly in the `EnqueuedResourceParametersSniff::process_parameters` method. --- .../Tests/WP/EnqueuedResourceParametersUnitTest.1.inc | 9 +++++++++ .../Tests/WP/EnqueuedResourceParametersUnitTest.php | 2 ++ 2 files changed, 11 insertions(+) diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc index f55224929..3e15b7162 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.1.inc @@ -108,3 +108,12 @@ wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \Null, true ); // Error - 0, false or NULL are not allowed. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \true, true ); // Ok. wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), \get_version(), true ); // OK. + +/* + * Safeguard correct handling of all types of namespaced function calls. + */ +\wp_enqueue_script( 'script-name', 'https://example.com/someScript.js', false, '1.1.0' ); // Error - missing $in_footer. +\wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0' ); // Error - missing $in_footer. +MyNamespace\wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0' ); // Ok. +\MyNamespace\wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0' ); // Ok. +namespace\wp_register_script( 'someScript-js', 'https://example.com/someScript.js' , array( 'jquery' ), '1.1.0' ); // The sniff should start flagging this once it can resolve relative namespaces. diff --git a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php index 06e5e3172..d81931880 100644 --- a/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php +++ b/WordPress/Tests/WP/EnqueuedResourceParametersUnitTest.php @@ -82,6 +82,8 @@ public function getWarningList( $testFile = '' ) { 100 => 1, 107 => 1, 108 => 1, + 115 => 1, + 116 => 1, ); default: From d48edcb966da834c58e30e83f45b6a34b61624cb Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 11:15:17 -0300 Subject: [PATCH 57/62] WIP DB/PreparedSQLPlaceholders: add namespaced tests Need to complete the list of tests --- .../Tests/DB/PreparedSQLPlaceholdersUnitTest.inc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc index 601877bfa..53673af6d 100644 --- a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc +++ b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc @@ -80,7 +80,7 @@ $where = $wpdb->prepare( ); // OK. $where = $wpdb->prepare( - sprintf( + \sprintf( "{$wpdb->posts}.post_type IN (%s) AND {$wpdb->posts}.post_status IN (%s)", implode( ',', array_fill( 0, count($post_types), '%s' ), ), @@ -518,3 +518,16 @@ $where = $wpdb->prepare( */ $callback = $wpdb->prepare(...); // OK. +/* + * Safeguard correct handling of namespaced function calls. + */ +//$sql = MyNamespace\WPDB::prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s" ); +//$sql = \MyNamespace\WPDB::prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s" ); +//$sql = namespace\WPDB::prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s" ); // The sniff should start flagging this once it can resolve relative namespaces. +//$where = $wpdb->prepare( +// MyNamespace\sprintf( +// "{$wpdb->posts}.post_type IN (%s)", +// MyNamespace\implode( ',', MyNamespace\array_fill( 0, count($post_types), '%s' ) ) +// ), +// $post_types +//); From a05889ca4162a502bf448f4c05825559f7aab110 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 7 Aug 2025 12:03:42 -0300 Subject: [PATCH 58/62] DB/PreparedSQLPlaceholders: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization of fully qualified static calls to `wpdb::prepare()`, `sprintf()` and `implode()`. --- .../DB/PreparedSQLPlaceholdersSniff.php | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php b/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php index ba72cabc3..ecc24e3a3 100644 --- a/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php +++ b/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php @@ -165,6 +165,7 @@ public function register() { return array( \T_VARIABLE, \T_STRING, + \T_NAME_FULLY_QUALIFIED, ); } @@ -224,9 +225,16 @@ public function process_token( $stackPtr ) { } // Detect a specific pattern for variable replacements in combination with `IN`. - if ( \T_STRING === $this->tokens[ $i ]['code'] ) { + if ( \T_STRING === $this->tokens[ $i ]['code'] + || \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] + ) { + $content_lowercase = \strtolower( $this->tokens[ $i ]['content'] ); - if ( 'sprintf' === strtolower( $this->tokens[ $i ]['content'] ) ) { + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $i ]['code'] ) { + $content_lowercase = \ltrim( $content_lowercase, '\\' ); + } + + if ( 'sprintf' === $content_lowercase ) { $sprintf_parameters = PassedParameters::getParameters( $this->phpcsFile, $i ); if ( ! empty( $sprintf_parameters ) ) { @@ -265,7 +273,7 @@ public function process_token( $stackPtr ) { } unset( $sprintf_parameters, $valid_sprintf, $last_param ); - } elseif ( 'implode' === strtolower( $this->tokens[ $i ]['content'] ) ) { + } elseif ( 'implode' === $content_lowercase ) { $ignore_tokens = Tokens::$emptyTokens + array( \T_STRING_CONCAT => \T_STRING_CONCAT, \T_NS_SEPARATOR => \T_NS_SEPARATOR, @@ -679,10 +687,17 @@ protected function analyse_sprintf( $sprintf_params ) { $sprintf_param['end'], true ); + if ( \T_STRING === $this->tokens[ $implode ]['code'] - && 'implode' === strtolower( $this->tokens[ $implode ]['content'] ) + || \T_NAME_FULLY_QUALIFIED === $this->tokens[ $implode ]['code'] ) { - if ( $this->analyse_implode( $implode ) === true ) { + $content_lowercase = \strtolower( $this->tokens[ $implode ]['content'] ); + + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $implode ]['code'] ) { + $content_lowercase = \ltrim( $content_lowercase, '\\' ); + } + + if ( 'implode' === $content_lowercase && $this->analyse_implode( $implode ) === true ) { ++$found; } } @@ -738,11 +753,21 @@ protected function analyse_implode( $implode_token ) { ); if ( \T_STRING !== $this->tokens[ $array_fill ]['code'] - || 'array_fill' !== strtolower( $this->tokens[ $array_fill ]['content'] ) + && \T_NAME_FULLY_QUALIFIED !== $this->tokens[ $array_fill ]['code'] ) { return false; } + $content_lowercase = strtolower( $this->tokens[ $array_fill ]['content'] ); + + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $array_fill ]['code'] ) { + $content_lowercase = \ltrim( $content_lowercase, '\\' ); + } + + if ( 'array_fill' !== $content_lowercase ) { + return false; + } + $array_fill_value_param = PassedParameters::getParameter( $this->phpcsFile, $array_fill, 3, 'value' ); if ( false === $array_fill_value_param ) { return false; From 8cd96e9c0e5fbfd6120cb4ed4e18400370eeeb94 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 7 Aug 2025 15:25:04 -0300 Subject: [PATCH 59/62] DB/PreparedSQL: move intentional syntax error test to its own file --- WordPress/Tests/DB/PreparedSQLUnitTest.1.inc | 3 --- WordPress/Tests/DB/PreparedSQLUnitTest.3.inc | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 WordPress/Tests/DB/PreparedSQLUnitTest.3.inc diff --git a/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc b/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc index 1f1a49076..c6dce05c2 100644 --- a/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc +++ b/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc @@ -142,6 +142,3 @@ echo $wpdb::CONSTANT_NAME; // Not an identifiable method call. $wpdb->{$methodName}('query'); - -// Don't throw an error during live coding. -wpdb::prepare( "SELECT * FROM $wpdb->posts diff --git a/WordPress/Tests/DB/PreparedSQLUnitTest.3.inc b/WordPress/Tests/DB/PreparedSQLUnitTest.3.inc new file mode 100644 index 000000000..4047216b8 --- /dev/null +++ b/WordPress/Tests/DB/PreparedSQLUnitTest.3.inc @@ -0,0 +1,8 @@ +posts From 966f4d92ef35fcc6c526ca14cb609413df2ff929 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 21 Aug 2025 15:08:41 -0300 Subject: [PATCH 60/62] WIP DB/PreparedSQL: add tests for namespaced names --- WordPress/Tests/DB/PreparedSQLUnitTest.1.inc | 15 ++++++++++++++- WordPress/Tests/DB/PreparedSQLUnitTest.php | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc b/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc index c6dce05c2..86de1994f 100644 --- a/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc +++ b/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc @@ -117,7 +117,7 @@ $wpdb $wpdb?->query( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . (int) $foo . "';" ); // OK. $wpdb?->query( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); // Bad. -WPDB::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); // Bad. +\WPDB::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); // Bad. $wpdb->Query( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); // Bad. $wpdb->query( "SELECT * FROM $wpdb->posts WHERE value = " . {$foo} . ";" ); // Bad - on $foo, not on the {}. @@ -142,3 +142,16 @@ echo $wpdb::CONSTANT_NAME; // Not an identifiable method call. $wpdb->{$methodName}('query'); + +// TODO: the below currently is flagged but it shouldn't be. +/* +MyNamespace\WPDB::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); +\MyNamespace\WPDB::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); +namespace\WPDB::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); // This should be flagged in the future once the sniff is able to resolve relative namespaces. +*/ + +$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . MyNamespace\absint( $foo ) ); +$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . \MyNamespace\absint( $foo ) ); +$wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . namespace\absint( $foo ) ); // This should NOT be flagged in the future once the sniff is able to resolve relative namespaces. + +// TODO: add similar namespace tests as the ones above for PreparedSQLSniff::$SQLAutoEscapedFunctions and FormattingFunctionsHelper::$formattingFunctions. diff --git a/WordPress/Tests/DB/PreparedSQLUnitTest.php b/WordPress/Tests/DB/PreparedSQLUnitTest.php index 2cb51f56a..98f40b123 100644 --- a/WordPress/Tests/DB/PreparedSQLUnitTest.php +++ b/WordPress/Tests/DB/PreparedSQLUnitTest.php @@ -66,6 +66,9 @@ public function getErrorList( $testFile = '' ) { 124 => 1, 128 => 1, 132 => 2, + 153 => 1, + 154 => 1, + 155 => 1, ); case 'PreparedSQLUnitTest.2.inc': From 64f1bfdb6c111e7b3ed832f1587d0b6650ef3367 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Mon, 11 Aug 2025 15:14:46 -0300 Subject: [PATCH 61/62] WIP DB/PreparedSQL: the sniff currently doesn't handle well the added cases both in PHPCS 3 and 4 In 3 there is only one error because it treats MyNamespace as T_STRING and generates an error and then thinks `esc_sql()` as a valid call to the global function which is incorrect. --- WordPress/Tests/DB/PreparedSQLUnitTest.1.inc | 16 ++++++++++++++++ WordPress/Tests/DB/PreparedSQLUnitTest.php | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc b/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc index 86de1994f..5b08c46d6 100644 --- a/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc +++ b/WordPress/Tests/DB/PreparedSQLUnitTest.1.inc @@ -155,3 +155,19 @@ $wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . \MyNamespace\absint( $f $wpdb->query( "SELECT * FROM $wpdb->posts WHERE ID = " . namespace\absint( $foo ) ); // This should NOT be flagged in the future once the sniff is able to resolve relative namespaces. // TODO: add similar namespace tests as the ones above for PreparedSQLSniff::$SQLAutoEscapedFunctions and FormattingFunctionsHelper::$formattingFunctions. + +/** +$wpdb->query( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . namespace\esc_sql( $foo ) . "';" ); // TODO: should the sniff code be updated to handle this case? Currently it is an error, but it shouldn't as this is a call to the global esc_sql() function. +$wpdb->query( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . \MyNamespace\esc_sql( $foo ) . "';" ); // Bad. + +$sql = $wpdb->prepare( namespace\sprintf( + 'SELECT `post_id`, `meta_value` FROM `%s` WHERE `meta_key` = "sort_order" AND `post_id` IN (%s)', + $wpdb->postmeta, + implode( ',', array_fill( 0, count( $post_ids ), '%d' ) ) +), $post_ids ); // Bad, but maybe it shouldn't be (check TODO above). +$sql = $wpdb->prepare( \MyNamespace\sprintf( + 'SELECT `post_id`, `meta_value` FROM `%s` WHERE `meta_key` = "sort_order" AND `post_id` IN (%s)', + $wpdb->postmeta, + implode( ',', array_fill( 0, count( $post_ids ), '%d' ) ) +), $post_ids ); // Bad. +*/ diff --git a/WordPress/Tests/DB/PreparedSQLUnitTest.php b/WordPress/Tests/DB/PreparedSQLUnitTest.php index 98f40b123..ab4a494a3 100644 --- a/WordPress/Tests/DB/PreparedSQLUnitTest.php +++ b/WordPress/Tests/DB/PreparedSQLUnitTest.php @@ -69,6 +69,16 @@ public function getErrorList( $testFile = '' ) { 153 => 1, 154 => 1, 155 => 1, + + // phpcs:disable Squiz.PHP.CommentedOutCode.Found + + /* + 147 => 1, + 148 => 1, + 155 => 1, + 160 => 1, + */ + // phpcs:enable Squiz.PHP.CommentedOutCode.Found ); case 'PreparedSQLUnitTest.2.inc': From 3e1ea764811a75ad92eee31b1fcf22aaa1b39a51 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 7 Aug 2025 15:32:28 -0300 Subject: [PATCH 62/62] DB/PreparedSQL: update for PHPCS 4.0 The tokenization of (namespaced) "names" has changed in PHP 8.0, and this new tokenization will come into effect for PHP_CodeSniffer as of version 4.0.0. This commit adds handling for the new tokenization of fully qualified function calls and static method calls to this sniff. --- WordPress/Sniffs/DB/PreparedSQLSniff.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/DB/PreparedSQLSniff.php b/WordPress/Sniffs/DB/PreparedSQLSniff.php index 05f0efc0d..7c49c5335 100644 --- a/WordPress/Sniffs/DB/PreparedSQLSniff.php +++ b/WordPress/Sniffs/DB/PreparedSQLSniff.php @@ -145,6 +145,7 @@ public function register() { return array( \T_VARIABLE, \T_STRING, + \T_NAME_FULLY_QUALIFIED, ); } @@ -206,9 +207,15 @@ static function ( $symbol ) { } } - if ( \T_STRING === $this->tokens[ $this->i ]['code'] ) { + if ( \T_STRING === $this->tokens[ $this->i ]['code'] + || \T_NAME_FULLY_QUALIFIED === $this->tokens[ $this->i ]['code'] + ) { $content_lowercase = strtolower( $this->tokens[ $this->i ]['content'] ); + if ( \T_NAME_FULLY_QUALIFIED === $this->tokens[ $this->i ]['code'] ) { + $content_lowercase = \ltrim( $content_lowercase, '\\' ); + } + if ( isset( $this->SQLEscapingFunctions[ $content_lowercase ] ) || isset( $this->SQLAutoEscapedFunctions[ $content_lowercase ] ) @@ -225,7 +232,7 @@ static function ( $symbol ) { $this->i = $this->tokens[ $opening_paren ]['parenthesis_closer']; continue; } - } elseif ( FormattingFunctionsHelper::is_formatting_function( $this->tokens[ $this->i ]['content'] ) ) { + } elseif ( FormattingFunctionsHelper::is_formatting_function( $content_lowercase ) ) { continue; } }