Skip to content

Update WordPress Coding Standards to 3.4.1 - #759

Closed
obenland wants to merge 1 commit into
trunkfrom
update/wpcs-3
Closed

Update WordPress Coding Standards to 3.4.1#759
obenland wants to merge 1 commit into
trunkfrom
update/wpcs-3

Conversation

@obenland

Copy link
Copy Markdown
Member

Why

wp-coding-standards/wpcs was pinned to 2.*, resolving to 2.3.0 — released March 2020 and the last of the 2.x line. PHPCS itself was already current (3.13.2); only the WordPress standard was stale.

On PHP 8.1+ WPCS 2.3.0 emits an implicit-nullable deprecation from PHPCSHelper::ignore_annotations(), which PHPCS converts into An error occurred during processing; checking has been aborted. Any file hitting that code path was silently skipped instead of linted — so the local lint was quietly under-reporting. On this branch, running the WordPress.Security.* sniffs over the same four directories goes from 27 findings (with themes/…-2024/functions.php never actually scanned) to 34.

What changed

Dependencies

Package From To
wp-coding-standards/wpcs 2.3.0 3.4.1
dealerdirect/phpcodesniffer-composer-installer 0.7.2 1.2.1 (required by WPCS 3.x)
squizlabs/php_codesniffer 3.13.2 3.13.6
phpcsstandards/phpcsutils 1.2.3 (new, transitive)
phpcsstandards/phpcsextra 1.5.1 (new, transitive)

phpcs.xml.dist reconciliation

The upgrade is not drop-in — several existing directives had gone stale, two of them silently:

  • Generic.Arrays.DisallowShortArraySyntaxUniversal.Arrays.DisallowShortArraySyntax (moved to PHPCSExtra). The old exclude no longer matched, so short array syntax was flagged 119 times.
  • WordPress.PHP.DisallowShortTernaryUniversal.Operators.DisallowShortTernary. Same story, 13 hits.
  • customPropertiesWhitelistallowed_custom_properties (renamed in WPCS 3.0). This one is a hard error, not silent.
  • text_domain was passing an array as a comma-separated string — deprecated since PHPCS 3.3.0, removed in 4.0. Now uses <element> nodes.
  • PEAR.Files.IncludingFile.BracketsNotRequired cannot be excluded from inside the WordPress-Core block: the later WordPress-Extra rule re-includes WordPress-Core wholesale and reinstates it. Moved to a <severity>0</severity> rule positioned after WordPress-Extra.
  • PSR12.Files.FileHeader newly excluded — see the judgement call below.

Code (auto-fixed with phpcbf)

The remaining 84 violations all came from sniffs new in 3.x, and are formatting-only except where noted:

  • Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction (39) — function(function ( in closures
  • PSR12.Functions.ReturnTypeDeclaration.SpaceBeforeColon (34) — ) : array): array
  • Modernize.FunctionCalls.Dirname.FileConstant (4) — dirname( __FILE__ )__DIR__; exactly equivalent, verified each call site
  • Universal.ControlStructures.DisallowLonelyIf (1) — else { if }elseif in bin/check-spam.php
  • plus 6 single-instance whitespace/brace fixes

phpcbf mis-indented the elseif it produced in bin/check-spam.php and left a stray blank line; corrected by hand.

Judgement call worth a second opinion

PSR12.Files.FileHeader is new in WPCS 3.0 and accounted for the last 9 violations. It imposes a fixed order on the file header — docblock, declare, namespace, class use, function use, const use — and forbids interleaving them.

This codebase consistently groups imports by what they import rather than by kind, e.g. functions.php:

use function WordPressdotorg\Pattern_Directory\Favorite\{get_favorites, get_favorite_count};
use const WordPressdotorg\Pattern_Directory\Pattern_Post_Type\POST_TYPE;
use const WordPressdotorg\Pattern_Directory\Pattern_Flag_Post_Type\POST_TYPE as FLAG_POST_TYPE;
use function WordPressdotorg\Theme\Pattern_Directory_2024\Block_Config\get_applied_filter_list;

It also reads /** Actions and filters. */ above a block of add_action() calls as a misplaced file docblock, which it isn't.

Satisfying the sniff means reordering imports across 9 files and fighting a preference the ruleset already records — PSR2.Namespaces.NamespaceDeclaration.BlankLineAfter is excluded with the comment "I think it's better to have all the use statements come right after the namespace line", which PSR-12 also forbids. Excluding seemed the coherent choice, but happy to reformat the 9 files instead if you'd rather adopt the rule.

Testing

  • npm run lint:php exits 0 on PHP 8.5.
  • php -l clean across all 31 modified files.
  • ⚠️ PHPUnit was not run — Docker wasn't available locally, so npm run test:php couldn't execute. CI will cover it. The code changes are whitespace plus the two equivalence-preserving rewrites noted above.

Follow-up, not fixed here

phpcs.xml.dist nests a <rule ref="WordPress.Arrays.MultipleStatementAlignment"> inside the <rule ref="WordPress-Core"> block, carrying an @todo This isn't working comment. It still doesn't work — PHPCS doesn't process a nested <rule> as an include, so those alignMultilineItems / ignoreNewlines properties have never applied. Moving it to the top level fixes that, but it's a pre-existing issue unrelated to this upgrade and changes alignment enforcement, so I left it alone. Worth its own PR.

🤖 Generated with Claude Code

WPCS was pinned to `2.*`, resolving to 2.3.0 (released March 2020). On PHP 8.1+
it emits an implicit-nullable deprecation from `PHPCSHelper::ignore_annotations()`,
which PHPCS turns into "checking has been aborted" — files hitting that code path
were silently skipped rather than linted.

Bump `wp-coding-standards/wpcs` to `^3.4` and, as 3.x requires,
`dealerdirect/phpcodesniffer-composer-installer` to `^1.0`. This pulls in
phpcsutils and phpcsextra as transitive dependencies.

Reconcile `phpcs.xml.dist` with the 3.x ruleset:

* Two excluded sniffs moved to PHPCSExtra and were silently no longer matching,
  so the rules they were meant to suppress had come back:
  `Generic.Arrays.DisallowShortArraySyntax` is now
  `Universal.Arrays.DisallowShortArraySyntax` (119 hits) and
  `WordPress.PHP.DisallowShortTernary` is now
  `Universal.Operators.DisallowShortTernary` (13 hits).
* `customPropertiesWhitelist` was renamed to `allowed_custom_properties` in
  WPCS 3.0; the old name is now a hard error.
* `text_domain` was passing an array as a comma-separated string, deprecated
  since PHPCS 3.3.0. Use `<element>` nodes.
* `PEAR.Files.IncludingFile.BracketsNotRequired` cannot be excluded from the
  `WordPress-Core` block, because the later `WordPress-Extra` rule re-includes
  `WordPress-Core` and reinstates it. Silence it after that rule instead.
* Exclude `PSR12.Files.FileHeader`, new in WPCS 3.0. It fixes the order of the
  docblock, namespace and `use` groups and forbids interleaving them, which
  conflicts with the import grouping used throughout this codebase — the same
  preference already recorded for
  `PSR2.Namespaces.NamespaceDeclaration.BlankLineAfter`.

The remaining 84 violations came from sniffs new in 3.x and were fixed with
phpcbf: space after `function` in closures, no space before the return type
colon, `dirname( __FILE__ )` to `__DIR__`, and one `else { if }` to `elseif`.
All are formatting-only except the `dirname()` calls, which are exactly
equivalent. phpcbf mis-indented the `elseif` in `bin/check-spam.php`; corrected
by hand.

`phpcs` now exits 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 18, 2026 00:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@obenland

Copy link
Copy Markdown
Member Author

Closing as a duplicate — #756 already landed the WPCS 3.4.1 upgrade on trunk, which I'd missed before starting this branch. The branches reformat the same files in incompatible directions, so there's nothing here worth rebasing.

@obenland obenland closed this Aug 18, 2026
@obenland
obenland deleted the update/wpcs-3 branch August 18, 2026 00:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants