$npx -y skills add Lonsdale201/wp-agent-skills --skill wp-phpcs-coding-standardsSet up and run PHP_CodeSniffer with the WordPress Coding Standards (WPCS) and PHPCompatibility on a plugin or theme. Covers the composer dev-dependencies and their exact (and confusingly-named) packages — squizlabs/php_codesniffer, wp-coding-standards/wpcs, `phpcompatibility/
| 1 | # WordPress coding standards with PHPCS |
| 2 | |
| 3 | PHP_CodeSniffer (`phpcs`) checks code against a ruleset; `phpcbf` auto-fixes what it can. The WordPress Coding Standards (WPCS) are the rulesets; PHPCompatibility flags syntax that breaks on your minimum PHP version. This skill wires them up correctly — the package names and the WPCS 3.x renames are where people get stuck. |
| 4 | |
| 5 | ## When to use this skill |
| 6 | |
| 7 | - Adding coding-standards linting to a plugin/theme (or to the `.phpcs.xml.dist` the test scaffolder dropped in). |
| 8 | - Writing or auditing a `phpcs.xml.dist` ruleset. |
| 9 | - Fixing "Referenced sniff … does not exist", "standard not installed", or `allow-plugins` errors. |
| 10 | - Migrating a ruleset from WPCS 2.x to 3.x. |
| 11 | |
| 12 | ## Install (exact packages — names are confusing) |
| 13 | |
| 14 | ```bash |
| 15 | composer config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true |
| 16 | composer require --dev \ |
| 17 | wp-coding-standards/wpcs:"^3.0" \ |
| 18 | phpcompatibility/phpcompatibility-wp:"^2.1" \ |
| 19 | dealerdirect/phpcodesniffer-composer-installer:"^1.0" |
| 20 | ``` |
| 21 | |
| 22 | Three things that trip people up, all verified: |
| 23 | |
| 24 | - **`squizlabs/php_codesniffer` is still the correct Packagist name** even though the project moved to the `PHPCSStandards` GitHub org. WPCS pulls it in transitively, so you usually don't list it. **WPCS 3.x needs PHPCS `3.x`, not 4.x** — don't force `squizlabs/php_codesniffer:^4`. |
| 25 | - **The installer is still `dealerdirect/phpcodesniffer-composer-installer` on Packagist** (the repo is now `PHPCSStandards/composer-installer`, but the package name is unchanged). It auto-registers WPCS and PHPCompatibility with PHPCS, so you never run `phpcs --config-set installed_paths …` by hand. |
| 26 | - **PHPCompatibilityWP: use the stable `^2.1`.** The README advertises `^3.0@dev`, but 3.0 is alpha-only; pin `^2.1` for production unless you deliberately want the alpha. |
| 27 | |
| 28 | Composer 2.2+ refuses to run the installer plugin unless it's in `allow-plugins` — the `composer config` line above does that; without it the standards won't register and `phpcs -i` won't list `WordPress`. |
| 29 | |
| 30 | ## The ruleset (`phpcs.xml.dist`) |
| 31 | |
| 32 | PHPCS auto-discovers `.phpcs.xml`, `phpcs.xml`, `.phpcs.xml.dist`, or `phpcs.xml.dist` in the working dir. Commit the `.dist` default: |
| 33 | |
| 34 | ```xml |
| 35 | <?xml version="1.0"?> |
| 36 | <ruleset name="My Plugin"> |
| 37 | <description>Coding standards for My Plugin.</description> |
| 38 | |
| 39 | <!-- What to scan / skip --> |
| 40 | <file>.</file> |
| 41 | <exclude-pattern>/vendor/*</exclude-pattern> |
| 42 | <exclude-pattern>/node_modules/*</exclude-pattern> |
| 43 | <exclude-pattern>/tests/*</exclude-pattern> |
| 44 | |
| 45 | <!-- Only PHP; show sniff codes + progress --> |
| 46 | <arg name="extensions" value="php"/> |
| 47 | <arg value="sp"/> |
| 48 | |
| 49 | <!-- WordPress standards --> |
| 50 | <rule ref="WordPress"/> |
| 51 | |
| 52 | <!-- PHP version floor for syntax compatibility --> |
| 53 | <config name="testVersion" value="7.4-"/> |
| 54 | <rule ref="PHPCompatibilityWP"/> |
| 55 | |
| 56 | <!-- Minimum WordPress version for deprecation sniffs (WPCS 3.x name) --> |
| 57 | <config name="minimum_wp_version" value="6.5"/> |
| 58 | |
| 59 | <!-- Required: your global prefix(es) so PrefixAllGlobals passes --> |
| 60 | <rule ref="WordPress.NamingConventions.PrefixAllGlobals"> |
| 61 | <properties> |
| 62 | <property name="prefixes" type="array"> |
| 63 | <element value="my_plugin"/> |
| 64 | </property> |
| 65 | </properties> |
| 66 | </rule> |
| 67 | |
| 68 | <!-- Your text domain so the i18n sniff passes --> |
| 69 | <rule ref="WordPress.WP.I18n"> |
| 70 | <properties> |
| 71 | <property name="text_domain" type="array"> |
| 72 | <element value="my-plugin"/> |
| 73 | </property> |
| 74 | </properties> |
| 75 | </rule> |
| 76 | </ruleset> |
| 77 | ``` |
| 78 | |
| 79 | The four standards to choose `ref` from: |
| 80 | |
| 81 | | Standard | Scope | |
| 82 | |---|---| |