Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Vipwpcs Laravel Package

automattic/vipwpcs

PHP_CodeSniffer sniffs and rulesets for validating WordPress VIP code. Includes WordPressVIPMinimum for the older WordPress.com VIP platform and WordPress-VIP-Go for VIP Go, flagging errors and warnings per VIP documentation.

View on GitHub
Deep Wiki
Context7

Getting Started

VIPCS is a developer-only Composer package that registers two PHP_CodeSniffer standards (WordPressVIPMinimum for legacy WP.com VIP, WordPress-VIP-Go for VIP Go). It is not a runtime library — treat it like PHPUnit: install to require-dev, wire into CI, and never ship it.

1. Install (Composer 2.2+ requires explicit plugin permission):

composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer require --dev automattic/vipwpcs

That single require pulls PHPCS 3.13.2+, PHPCSUtils, PHPCSExtra, WPCS 3.1.0+ and VariableAnalysis 2.12.0+, and the Composer installer plugin registers the standards with PHPCS automatically.

2. Add a phpcs.xml.dist at the project root (the file is the contract — commit it):

<?xml version="1.0"?>
<ruleset name="Acme VIP">
    <description>VIP Go platform rules for custom plugin/theme code.</description>

    <file>./wp-content/plugins/acme-api</file>
    <file>./wp-content/themes/acme</file>

    <arg name="extensions" value="php"/>
    <arg name="parallel" value="8"/>
    <arg name="cache" value=".phpcs.cache"/>
    <arg name="colors"/>
    <arg value="p"/>

    <exclude-pattern>*/vendor/*</exclude-pattern>
    <exclude-pattern>*/node_modules/*</exclude-pattern>
    <exclude-pattern>*/build/*</exclude-pattern>

    <rule ref="WordPress-VIP-Go"/>
</ruleset>

3. Verify registration, then run:

vendor/bin/phpcs -i                 # should list WordPress-VIP-Go and WordPressVIPMinimum
vendor/bin/phpcs -s                 # -s => append sniff codes, essential for triage

Where to look first:

  • vendor/automattic/vipwpcs/WordPress-VIP-Go/ruleset.xml and WordPressVIPMinimum/ruleset.xml. There is no per-sniff docs directory in the repo — the ruleset XML is the authoritative list of what is enabled and at what severity. Read it before arguing about a violation.
  • vendor/bin/phpcs -e --standard=WordPress-VIP-Go to enumerate every sniff in the standard.
  • The external VIP docs (docs.wpvip.com/php_codesniffer/errors/, /warnings/, and the Code Analysis Bot report page) for the error-vs-warning semantics. That distinction is a platform policy, not a PHPCS detail.

First use case: point it at the one custom plugin that talks to a VIP-only API before your first deploy. The Code Analysis Bot on VIP runs on push/PR and will surface the same sniff codes, so a clean local run is the fastest way to avoid a red deploy gate. Expect the first run on a legacy codebase to be brutal — hundreds of hits, dominated by Performance/WPQueryParams (post__not_in, suppress_filters), Performance/NoPaging, Performance/OrderByRand, and escaping sniffs. That is normal; see triage below.

Implementation Patterns

Triage loop (the actual day-to-day workflow). Never read the full report top-to-bottom. Aggregate by sniff, fix the highest-count / lowest-risk category, re-run:

vendor/bin/phpcs -q --report=source                    # sniff => count, sorted
vendor/bin/phpcs -s --sniffs=WordPressVIPMinimum.Performance.WPQueryParams
vendor/bin/phpcs -s --report=full wp-content/plugins/acme-api/includes/query.php

--report=source first, --report=full -s last. Fixing post__not_in and suppress_filters is usually a genuine performance win, not lint noise, so it doubles as real work.

Mirroring the VIP Code Analysis Bot in CI. The bot fails builds on errors only; warnings are advisory. Reproduce that so your pipeline and the platform agree:

vendor/bin/phpcs -q --report=checkstyle --runtime-set ignore_warnings_on_exit 1 | cs2pr

Keep ignore_warnings_on_exit 1 in CI but omit it in the local/pre-commit run, so warnings are visible to authors without blocking merges. Also pass --cache in CI when you can persist .phpcs.cache between runs — full scans of a large theme are slow even with --parallel.

Scope a Laravel hybrid codebase. If you are running WordPress embedded in a Laravel app (headless content API, johnpbloch/wordpress + Symfony-ish front end, Bedrock-style layout), do not point VIPCS at app/, config/, database/, routes/ or resources/views/. Blade templates parse as PHP and produce pure noise, and Classes/DeclarationCompatibility will fire on Laravel classes that have nothing to do with WP core signatures. Use per-path <file> entries as in the sample above, or run two jobs:

vendor/bin/phpcs --standard=WordPress-VIP-Go wp-content/   # VIP surface
vendor/bin/pint --test app/                                # Laravel surface

VIPCS and Pint (PHP-CS-Fixer) do not conflict at the engine level; they conflict at the policy level. Keep them on disjoint paths and you avoid the "which style wins" argument entirely.

Coexistence with WPCS. VIPCS deliberately contains only the rules VIP classifies as errors/warnings. If you also want formatting/whitespace enforcement, add <rule ref="WordPress-Extra"/> alongside WordPress-VIP-Go — but keep them in separate rulesets if you intend to waive style findings on legacy code while still gating on platform risk.

Suppression with an audit trail. Suppressions survive code review only when they carry a reason:

// phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- small curated ID list, cache-safe.
$query = new WP_Query( [ 'post__not_in' => $featured_ids ] );

Prefer phpcs:ignore on the specific line over phpcs:disable blocks, and never a file-wide disable at the top of a file — the bot still reports it and reviewers will bounce it. When a whole category is genuinely inapplicable (e.g. escaping sniffs on a CLI-only importer), scope it in a separate ruleset for that directory rather than sprinkling ignores.

Extension points. VIPCS is just a standard, so it composes: <rule ref="WordPress-VIP-Go"/> inside your own custom standard, plus your own sniffs registered in the same ruleset. For team-specific bans (a forbidden helper, a required wrapper around remote requests), write one sniff in an internal standard and ref VIPCS beneath it — this is far cheaper than trying to patch VIPCS (GPL-2.0-or-later; forking for local policy is allowed but creates a versioning burden you do not want).

Editor + pre-commit. Wire phpcs into PHPStorm's Quality Tools or the VS Code phpcs extension pointing at phpcs.xml.dist, and add a GrumPHP or CaptainHook task before commit. The feedback latency difference between "pre-commit" and "CI" is the single biggest determinant of whether VIPCS gets adopted or resented.

Version discipline. Pin "automattic/vipwpcs": "^3.0", commit composer.lock, and on upgrade run composer update automattic/vipwpcs --with-dependencies — the 3.0.1 notes are explicit about needing the transitive PHPCS bump to get PHP 8.2/8.3 support. Treat a VIPCS minor bump as a code change: new sniffs can turn a green branch red with no edits on your side.

Gotchas and Tips

  • "ERROR: the WordPress-VIP-Go standard is not installed" almost always means allow-plugins.dealerdirect/phpcodesniffer-composer-installer was never granted, so the plugin never ran and installed_paths was never set. Fix the config, then composer install again — requiring the package alone is not enough on Composer 2.2+.
  • Choosing the wrong ruleset is the most common conceptual error. WordPressVIPMinimum is for the older WP.com VIP platform; WordPress-VIP-Go is for VIP Go. Running both doubles your findings and confuses the gate. Confirm which platform the site is on before you write the ruleset.
  • Sniff codes are not stable across majors. Performance.WPQueryParams.PostNotIn became ...PostNotIn_post__not_in in 3.0.0, and SuppressFiltersTrue became SuppressFilters_suppress_filters. Any phpcs:ignore referencing a retired code silently stops suppressing (and may surface an invalid-annotation warning), so grep your phpcs:ignore comments as part of every major upgrade rather than trusting CI to tell you.
  • Warnings do not block VIP deploys; errors do. Teams that set a blanket "zero violations" gate locally burn time on warnings the platform never gates on. Decide explicitly which severity fails your pipeline and encode it (ignore_warnings_on_exit, or --warning-severity=0 to mute warnings entirely for a first-pass cleanup).
  • Stale cache hides new violations. .phpcs.cache is keyed on file mtime; change the ruleset or bump the package and you can get pre-change results. Delete the cache file when results look wrong, and add it to .gitignore.
  • --parallel needs pcntl. Fine on Linux CI and macOS; unavailable/limited on Windows and some minimal containers. If you see ignored parallel args, that is why. In Laravel Sail/Docker, confirm the PHP image has pcntl compiled in.
  • VariableAnalysis is bundled and configured by the standard. VIPCS removed its own Variables/VariableAnalysis sniff in 3.0.0 and now relies on sirbrillig/phpcs-variable-analysis (config moved into the WordPressVIPMinimum ruleset in 2.3.4). Unused-variable and undefined-variable findings therefore come from a third-party sniff — check its docs, not VIP's, when the message is cryptic.
  • Classes/DeclarationCompatibility tracks WordPress core signatures. It will flag method signatures that diverge from the WP version it was synced against. On a project targeting an older or newer WP core than VIPCS assumes, this produces findings you cannot fix. Scope-exclude it for those files and note the WP version in a comment — do not "fix" the signature to satisfy the sniff.
  • PHP-only. No JS, CSS, or Blade-aware analysis. Front-end and template concerns need a separate toolchain; do not expect parity with an ESLint setup.
  • Blanket exclude-pattern is a trap. Excluding vendor/ and build output is correct; excluding includes/legacy/ to get to green is how a VIP deploy gate surprises you later. If legacy code cannot be fixed, use scoped rulesets with a tracked TODO rather than a global exclusion.
  • No in-repo documentation per sniff and zero Composer dependents (dev dependencies are not counted, so the number is misleading). Debugging means reading ruleset.xml and the sniff class under vendor/automattic/vipwpcs/WordPressVIPMinimum/Sniffs/ — phpcs -e plus --sniffs= to isolate one check is faster than guessing.
  • The ruleset XML is the source of truth for severity. Changing severity or excluding a specific sniff in your project ruleset (<rule ref="WordPress-VIP-Go"><exclude name="..."/></rule>) is the supported extension point; patching files under vendor/ is not and will vanish on the next composer install.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo