Commit 1d0d103e1dc for woocommerce
commit 1d0d103e1dcfe23dd4a39b1f578220a2c134106e
Author: Jorge A. Torres <jorge.torres@automattic.com>
Date: Thu May 14 21:44:04 2026 +0100
Fix PHPCS error on PHP 8.5 by switching PSR-4 sniff provider (#64875)
diff --git a/.ai/skills/woocommerce-dev-cycle/php-linting-patterns.md b/.ai/skills/woocommerce-dev-cycle/php-linting-patterns.md
index bd12395d6e3..94e3f439e87 100644
--- a/.ai/skills/woocommerce-dev-cycle/php-linting-patterns.md
+++ b/.ai/skills/woocommerce-dev-cycle/php-linting-patterns.md
@@ -39,7 +39,7 @@ pnpm lint:php:fix
### Quick Reference Table
| Issue | Wrong | Correct |
-|-------|-------|---------|
+| ----- | ----- | ------- |
| **Translators comment** | Before return | Before function call |
| **File docblock (PSR-12)** | After `declare()` | Before `declare()` |
| **Indentation** | Spaces | Tabs only |
@@ -121,7 +121,7 @@ if ( ! class_exists( 'WC_Payments_Utils' ) ) {
* Mock class for testing.
*
* phpcs:disable Squiz.Classes.ClassFileName.NoMatch
- * phpcs:disable Suin.Classes.PSR4.IncorrectClassName
+ * phpcs:disable SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
* phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
*/
class WC_Payments_Utils {
diff --git a/plugins/woocommerce/bin/composer/phpcs/composer.json b/plugins/woocommerce/bin/composer/phpcs/composer.json
index 5cd171ae292..a3af37aabb4 100644
--- a/plugins/woocommerce/bin/composer/phpcs/composer.json
+++ b/plugins/woocommerce/bin/composer/phpcs/composer.json
@@ -3,7 +3,7 @@
"woocommerce/woocommerce-sniffs": "1.0.0",
"phpcompatibility/php-compatibility": "dev-develop#9013cd039fe5740953f9fdeebd19d901b80e26f2 as 9.3.10",
"sirbrillig/phpcs-changed": "^2.11.1",
- "suin/phpcs-psr4-sniff": "^3.0"
+ "slevomat/coding-standard": "^6.3"
},
"config": {
"platform": {
diff --git a/plugins/woocommerce/bin/composer/phpcs/composer.lock b/plugins/woocommerce/bin/composer/phpcs/composer.lock
index 3d99d4bd365..a5d9f2ea007 100644
--- a/plugins/woocommerce/bin/composer/phpcs/composer.lock
+++ b/plugins/woocommerce/bin/composer/phpcs/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "4b7c50b51b5a09878954339be989bfdd",
+ "content-hash": "3b518363dc38fa21955eb79c65519597",
"packages": [],
"packages-dev": [
{
@@ -770,61 +770,6 @@
],
"time": "2025-11-04T16:30:35+00:00"
},
- {
- "name": "suin/phpcs-psr4-sniff",
- "version": "v3.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/suin/phpcs-psr4-sniff.git",
- "reference": "b000ca1e3d04c9876b39c2e56859760b93dfc84d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/suin/phpcs-psr4-sniff/zipball/b000ca1e3d04c9876b39c2e56859760b93dfc84d",
- "reference": "b000ca1e3d04c9876b39c2e56859760b93dfc84d",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "php": ">=7.1",
- "slevomat/coding-standard": ">=4.7 <8.0.0",
- "squizlabs/php_codesniffer": ">=3.3 <4.0.0"
- },
- "type": "phpcodesniffer-standard",
- "autoload": {
- "psr-0": {
- "Suin\\Sniffs\\Classes\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "suin",
- "email": "suinyeze@gmail.com",
- "homepage": "https://github.com/suin",
- "role": "Developer"
- }
- ],
- "description": "PHP_CodeSniffer sniff that checks class name matches PSR-4 project structure.",
- "homepage": "https://github.com/suin/php",
- "keywords": [
- "PSR-4",
- "coding-standards",
- "coding-style",
- "namespace",
- "php-codesniffer",
- "phpcs",
- "static-analysis"
- ],
- "support": {
- "issues": "https://github.com/suin/php/issues",
- "source": "https://github.com/suin/phpcs-psr4-sniff/tree/v3.0.0"
- },
- "time": "2021-06-02T06:16:24+00:00"
- },
{
"name": "woocommerce/woocommerce-sniffs",
"version": "1.0.0",
@@ -950,5 +895,5 @@
"platform-overrides": {
"php": "7.4"
},
- "plugin-api-version": "2.9.0"
+ "plugin-api-version": "2.6.0"
}
diff --git a/plugins/woocommerce/changelog/fix-phpcs-suin-php-8-5 b/plugins/woocommerce/changelog/fix-phpcs-suin-php-8-5
new file mode 100644
index 00000000000..55aa3c0c528
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-phpcs-suin-php-8-5
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Dev: swap unmaintained Suin PSR-4 sniff for Slevomat to keep PHPCS working on PHP 8.5.
diff --git a/plugins/woocommerce/phpcs.xml b/plugins/woocommerce/phpcs.xml
index 4de14ca7520..690df2cbe74 100644
--- a/plugins/woocommerce/phpcs.xml
+++ b/plugins/woocommerce/phpcs.xml
@@ -101,14 +101,17 @@
<exclude-pattern>src/Internal/Api/</exclude-pattern>
</rule>
- <rule ref="Suin.Classes.PSR4">
+ <rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
<include-pattern>src/</include-pattern>
<include-pattern>tests/php/src/</include-pattern>
<exclude-pattern>plugins/woocommerce/src/Admin/Notes/DeprecatedNotes.php</exclude-pattern>
<exclude-pattern>plugins/woocommerce/tests/php/src/Proxies/ExampleClasses/</exclude-pattern>
<exclude-pattern>plugins/woocommerce/tests/php/src/Internal/DependencyManagement/ExampleClasses/</exclude-pattern>
<properties>
- <property name="composerJsonPath" value="composer.json"/>
+ <property name="rootNamespaces" type="array">
+ <element key="src" value="Automattic\WooCommerce"/>
+ <element key="tests/php/src" value="Automattic\WooCommerce\Tests"/>
+ </property>
</properties>
</rule>
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php b/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php
index 3b0a70952c6..a0a50ac1cb7 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/woocommerce-admin/features/payment-gateway-suggestions/evaluate-suggestion.php
@@ -385,7 +385,7 @@ class WC_Admin_Tests_PaymentGatewaySuggestions_EvaluateSuggestion extends WC_Uni
}
}
-//phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, Suin.Classes.PSR4.IncorrectClassName
+//phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
/**
* TestableEvaluateSuggestion class.
*/
@@ -399,4 +399,4 @@ class TestableEvaluateSuggestion extends EvaluateSuggestion {
return self::$memo;
}
}
-//phpcs:enable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, Suin.Classes.PSR4.IncorrectClassName
+//phpcs:enable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/CheckoutSessionsComplete.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/CheckoutSessionsComplete.php
index dea405c4b8a..9b691f32181 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/CheckoutSessionsComplete.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/CheckoutSessionsComplete.php
@@ -845,7 +845,7 @@ class CheckoutSessionsComplete extends ControllerTestCase {
}
}
-// phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, Suin.Classes.PSR4.IncorrectClassName
+// phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
/**
* Mock Agentic Payment Gateway for testing.
diff --git a/plugins/woocommerce/tests/php/src/CLAUDE.md b/plugins/woocommerce/tests/php/src/CLAUDE.md
index c0d7511280e..54ecaab0333 100644
--- a/plugins/woocommerce/tests/php/src/CLAUDE.md
+++ b/plugins/woocommerce/tests/php/src/CLAUDE.md
@@ -8,7 +8,7 @@
### Rule: Use targeted assertions, not full equality checks
| Pattern | Brittle (Wrong) | Resilient (Correct) |
-|---------|-----------------|---------------------|
+| ------- | --------------- | ------------------- |
| Array key + value | `assertSame(['key' => null], $arr)` | `assertArrayHasKey('key', $arr)` + `assertNull($arr['key'])` |
| Single value | `assertSame(['a' => 1, 'b' => 2], $r)` | `assertArrayHasKey('a', $r)` + `assertSame(1, $r['a'])` |
| Nested | `assertSame(['m' => ['e' => null]], $r)` | `assertArrayHasKey('e', $r['m'])` + `assertNull($r['m']['e'])` |
@@ -31,7 +31,7 @@ $this->assertNull( $result['messages']['not_supported'] );
**Priority order**: Most specific → Structure → General
| Assertion | Use | Example |
-|-----------|-----|---------|
+| --------- | --- | ------- |
| `assertSame()` | Strict === | `assertSame(5, $count)` |
| `assertEquals()` | Loose == | `assertEquals('5', $count)` |
| `assertNull()` | Null check | `assertNull($error)` |
@@ -50,7 +50,7 @@ if ( ! class_exists( 'WC_Payments_Utils' ) ) {
* Mock for testing.
*
* phpcs:disable Squiz.Classes.ClassFileName.NoMatch
- * phpcs:disable Suin.Classes.PSR4.IncorrectClassName
+ * phpcs:disable SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
* phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
*/
class WC_Payments_Utils {
@@ -65,7 +65,7 @@ if ( ! class_exists( 'WC_Payments_Utils' ) ) {
**Why ignores needed:**
- `ClassFileName.NoMatch` - Mock doesn't match file name
-- `PSR4.IncorrectClassName` - External class not PSR-4
+- `TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName` - External class not PSR-4
- `ValidClassName.NotCamelCaps` - Uses underscores
## Unused Closure Parameters
@@ -226,7 +226,7 @@ pnpm test:php:env -- --testdox --filter WooPaymentsServiceTest
**Common issues:**
| Error | Cause | Fix |
-|-------|-------|-----|
+| ----- | ----- | --- |
| `Undefined array key` | Missing key | Check code returns key |
| `Arrays not identical` | Extra/missing keys | Use targeted assertions |
| `Mock not called` | Code path skipped | Check test setup |
diff --git a/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php b/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php
index a247fe6ae8e..46eed93d380 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php
@@ -720,7 +720,7 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
}
-//phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, Suin.Classes.PSR4.IncorrectClassName
+//phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
/**
* Mock class that extends RemoteLogger to allow overriding is_dev_or_local_environment.
*/
@@ -748,7 +748,7 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
return $this->is_dev_or_local;
}
}
-//phpcs:enable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, Suin.Classes.PSR4.IncorrectClassName
+//phpcs:enable Generic.Files.OneObjectStructurePerFile.MultipleFound, Squiz.Classes.ClassFileName.NoMatch, SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
}
/**
diff --git a/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Orders/UpdateUtilsTest.php b/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Orders/UpdateUtilsTest.php
index 881aaf99cc2..cf0879aa0ee 100644
--- a/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Orders/UpdateUtilsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Orders/UpdateUtilsTest.php
@@ -75,7 +75,7 @@ class UpdateUtilsTest extends WC_Unit_Test_Case {
*
* phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound
* phpcs:disable Squiz.Classes.ClassFileName.NoMatch
- * phpcs:disable Suin.Classes.PSR4.IncorrectClassName
+ * phpcs:disable SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName
*/
class TestableUpdateUtils extends UpdateUtils {