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

Alley Coding Standards Laravel Package

alleyinteractive/alley-coding-standards

A Composer package offering Alley Interactive’s PHP_CodeSniffer coding standards for WordPress and PHP projects. It provides rulesets to enforce consistent style and best practices, helping teams standardize reviews and CI checks.

View on GitHub
Deep Wiki
Context7

Getting Started

alleyinteractive/alley-coding-standards is a PHP_CodeSniffer ruleset (standard name: Alley-Interactive) — a dev-only linting dependency, not a runtime library. It layers Alley's conventions on top of WordPress Coding Standards and PHPCompatibility, so it's most valuable in Laravel projects that talk to WordPress (Sage/Acorn themes, headless WP APIs, filters/actions in mu-plugins).

First steps:

composer require --dev alleyinteractive/alley-coding-standards

Composer will usually prompt to allow dealerdirect/phpcodesniffer-composer-installer — allow it so phpcs -i auto-discovers the Alley-Interactive standard. Verify:

vendor/bin/phpcs -i          # should list Alley-Interactive
vendor/bin/phpcs --standard=Alley-Interactive app/

Add a root phpcs.xml.dist (see patterns below) and wrap it in Composer scripts so nobody types the binary path. Look first at your existing violations summary (--report=summary) before turning this on in CI — a greenfield app/ will pass, a legacy one won't.

First real use case: lint a file that registers WordPress hooks, since that's the domain the standard cares about most:

add_filter( 'myplugin_items', function ( array $items ): array {
    return array_filter( $items );
} );

As of v2.5.0, the first parameter of filter callbacks is expected to be typehinted, so this exact pattern is now enforced rather than optional.

Implementation Patterns

Ruleset file (phpcs.xml.dist) — extend, don't copy:

<?xml version="1.0"?>
<ruleset name="Project">
    <description>Laravel + WordPress project standards.</description>

    <file>app</file>
    <file>src</file>
    <file>config</file>

    <rule ref="Alley-Interactive"/>

    <!-- Laravel-shaped code the WP standard doesn't understand -->
    <exclude-pattern>*/migrations/*</exclude-pattern>
    <exclude-pattern>*/vendor/*</exclude-pattern>
    <exclude-pattern>*.blade.php</exclude-pattern>

    <config name="minimum_supported_wp_version" value="6.4"/>
</ruleset>

Composer scripts (the day-to-day interface):

{
  "scripts": {
    "lint": "phpcs --parallel=8",
    "lint:fix": "phpcbf --parallel=8",
    "lint:summary": "phpcs --report=summary --parallel=8"
  }
}

CI integration — run composer lint as its own job so a style failure doesn't mask a test failure, and cache vendor:

- run: composer install --prefer-dist --no-progress
- run: composer lint

Incremental adoption. Don't flip the whole repo red at once. Either scope <file> to directories you've cleaned, or add a baseline with a third-party tool and ratchet down over time. --report=source is the fastest way to see which sniffs dominate your debt.

Editor feedback loops. VS Code (squizlabs.phpcs / shepherd), PHPStorm's built-in PHPCS inspection, and Neovim (none-ls) all just want the phpcs binary plus --standard=phpcs.xml.dist from the project root. Configure once per repo, not per machine.

Pre-commit gating on changed files only (CaptainHook, lint-staged, or a pre-commit shell hook running phpcs --report=emacs on staged paths). This is where the standard actually earns its keep — CI-only linting gets ignored.

Suppressing deliberately, with a reason:

// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- cache payload, not user input
$payload = serialize( $data );

Always resolve the real sniff code first with phpcs -s — the codes are not guessable.

New in v2.5.0 — filter callback typehints. When you touch a hook registration, typehint the first parameter and keep the return type aligned with what the filter contract promises:

add_filter( 'myplugin_total', fn( float $total ): float => $total * 1.2 );
add_filter( 'myplugin_items', 'myplugin_filter_items' );

function myplugin_filter_items( array $items ): array { /* ... */ }

Because typehint sniffs are additive, treat a bump to v2.5.0 as "CI may go red" rather than a drop-in patch bump — pin the version in composer.json ("^2.4" vs "^2.5") if you need to control when it lands.

Gotchas and Tips

  • v2.5.0 is a new rule, not a bugfix. No API breaks, no deprecations — but any filter callback without a typed first parameter becomes a new violation. Upgrade on a branch, run composer lint:summary, and budget the cleanup.
  • phpcbf will not fix this one. Adding a typehint is a semantic decision (what type does this filter actually pass?), so typehint violations must be fixed by hand or suppressed. Don't assume lint:fix cleans the v2.5.0 fallout.
  • Typehints on filters are a runtime risk, not just style. WordPress filters pass whatever the previous callback returned; a third-party plugin returning null or a scalar will now fatal against function ( array $items ). Typehint the callbacks you control, and use the nullable/union form (?array, array|string) where the contract is genuinely loose.
  • installed_paths breakage. If dealerdirect/phpcodesniffer-composer-installer was blocked (Composer 2.2+ allow-plugins), PHPCS won't find the standard and errors with "Referenced sniff ... does not exist". Fix with an explicit --runtime-set installed_paths vendor/wp-coding-standards/wpcs,vendor/alleyinteractive/alley-coding-standards.
  • Standard name is case-sensitive-ish: --standard=Alley-Interactive, not alley-interactive or the package name.
  • WordPress sniffs fight Laravel idioms. Expect noise on env(), short array syntax, PSR-4 autoloading, and Blade. Exclude config/, resources/views/, database/migrations/ from <file> rather than suppressing sniff-by-sniff.
  • Debugging a rule you can't identify: phpcs -s shows sniff codes; phpcs -e lists everything the standard enables; phpcs -vvv shows ruleset resolution order when an exclusion silently doesn't apply.
  • Ruleset inheritance gotchas. <exclude name="..."> requires the full sniff code (e.g. WordPress.Arrays.ArrayDeclarationSpacing), and excludes must live inside the <rule ref="Alley-Interactive"> block to apply to the inherited standard.
  • Performance. PHPCS is slow on large trees; use --parallel=8 (CI runners often have 2 cores — tune it), and never lint vendor/, node_modules/, or storage/.
  • Pin or float deliberately. A floating ^2.0 constraint means a teammate's composer update can turn CI red mid-sprint. Lock the exact minor in composer.json and bump intentionally so new sniffs (like the v2.5.0 filter-callback rule) arrive as a reviewed change.
  • Extension point: add project-specific sniffs under a phpcs/ directory and register them with <rule ref="./phpcs/MySniff.php"/> — cheaper than suppressing Alley's rules everywhere.
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.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus