alleyinteractive / alley-coding-standards
PHPCS sniffs for Alley Interactive
Package info
github.com/alleyinteractive/alley-coding-standards
Type:phpcodesniffer-standard
pkg:composer/alleyinteractive/alley-coding-standards
Requires
- automattic/vipwpcs: ^3.0
Requires (Dev)
- phpunit/phpunit: ^12
- symfony/finder: ^7.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-develop
- 2.x-dev
- v2.5.0
- v2.4.1
- v2.4.0
- v2.3.2
- v2.3.1
- v2.3.0
- v2.2.0
- v2.1.0
- v2.0.2
- v2.0.1
- v2.0.0
- 1.x-dev
- v1.0.1
- v1.0.0
- v0.4.1
- v0.4.0
- 0.3.0
- 0.2.0
- 0.1.0
- dev-feature/issue-76/get-block-wrapper-attributes
- dev-feature/fixture-test-expected-errors
- dev-feature/wpcs-3-2
- dev-feature/changelog
- dev-feature/tests-standard
- dev-feature/php-8-1-patch-wpcs-2-3
- dev-feature/try-8-1-support-in-vip-standards
This package is auto-updated.
Last update: 2026-10-20 16:34:44 UTC
README
This is a PHPCS ruleset for Alley Interactive.
Installation
To use this standard in a project, declare it as a dependency.
composer require --dev alleyinteractive/alley-coding-standards
This will install the latest compatible version of PHPCS, WPCS, and VIPCS to your vendor directory in order to run sniffs locally.
You can also manually add this to your project's composer.json file as part of the require property:
{
"require": {
"alleyinteractive/alley-coding-standards": "^2.0"
}
}
Usage
To use this standard with phpcs directly from your command line, use the command:
vendor/bin/phpcs --standard=Alley-Interactive .
Alternatively, you can set this as a composer script, which will automatically reference the correct version of phpcs and the dependent standards.
{
"scripts": {
"phpcs": "phpcs --standard=Alley-Interactive ."
}
}
Then use the following command:
composer run phpcs
You can also pass arguments to the composer phpcs script, following a -- operator like this:
composer run phpcs -- --report=summary
Extending the Ruleset
You can create a custom ruleset for your project that extends or customizes
these rules by creating your own .phpcs.xml file in your project, which
references these rules, like this:
<?xml version="1.0"?> <ruleset> <description>Example project ruleset</description> <!-- Include Alley Rules --> <rule ref="Alley-Interactive" /> <!-- Project customizations go here --> </ruleset>
Custom Sniffs
Alley.PHP.BlockWrapperAttributes
get_block_wrapper_attributes() escapes attribute values, but not the array
keys, which become attribute names. This sniff requires every key to be a string
or integer literal, or to be wrapped entirely in sanitize_key().
When the argument is a variable, the sniff checks every assignment to it in the enclosing function (or file) before the call, or through the end of the loop if the call is inside one.
UnsafeKey
A key is something other than a literal or a whole sanitize_key() call:
// Passes. echo get_block_wrapper_attributes( [ 'data-id' => $id ] ); echo get_block_wrapper_attributes( [ sanitize_key( $key ) => $value ] ); // Fails with UnsafeKey. echo get_block_wrapper_attributes( [ $key => $value ] ); echo get_block_wrapper_attributes( [ 'data-' . $key => $value ] );
UnverifiableKeys
The sniff cannot see the keys. This happens when the argument is not an array literal or a variable, or when the variable:
- is a function, closure, or arrow function parameter
- is assigned something other than an array literal, or changed with
+=or??= - is destructured into, with
[ $attrs ] = ...orlist( ... ) = ... - is passed to another function, which could change it by reference (e.g.
parse_str()) - is a reference, a
global, or aforeachvariable - is never assigned an array in the same scope
// Fails with UnverifiableKeys. echo get_block_wrapper_attributes( array_merge( $defaults, $extra ) ); function render( $attributes ) { return get_block_wrapper_attributes( $attributes ); }
This favors false positives over missed issues: a harmless call like
count( $attrs ) before the call is flagged too. If it is too noisy for your
project, you can exclude that error code alone:
<rule ref="Alley-Interactive"> <exclude name="Alley.PHP.BlockWrapperAttributes.UnverifiableKeys" /> </rule>
Alley.PHP.DisallowShortEchoTag
Disallows the short echo tag (<?=), even when short_open_tag is enabled in
php.ini. Use <?php echo ... ?> instead.
Alley.PHP.FilterCallbackTypehint
Flags a typehint on the first parameter of an add_filter() callback. Core or
other plugins may pass a different type than the one declared, which causes a
fatal error. Check the type inside the callback instead, or use mixed. Only
the first parameter is checked, and add_action() callbacks are not checked.
Closures, arrow functions, named functions, array callbacks, and first-class
callables are supported. Violations can be fixed with phpcbf.
// Passes. add_filter( 'the_title', fn( $title ) => (string) $title ); add_filter( 'the_title', fn( mixed $title ) => (string) $title ); // Fails with ParameterTypehint. add_filter( 'the_title', fn( string $title ) => $title );
Alley.PHP.StrictTypeDeclarationSpacing
Requires declare(strict_types=1); with no whitespace inside the parentheses
or around the equals sign. Violations can be fixed with phpcbf.
Testing
When contributing to this project, modifications to the ruleset should have a
corresponding test in the tests directory. For the most part, this takes the
form of a passing test in tests/fixtures/pass and a failing one in
tests/fixtures/fail.
You can run the tests with composer phpunit. If you
want to run PHPCS against the test fixtures, you can run
composer phpcs:fixtures to ensure that what is passing/failing matches your
expectations.
Special Considerations for failure expectations
For failing fixtures in tests/fixtures/fail, we recommend
keeping the files smaller and focused on the specific sniff being tested.
A corresponding file should be created in tests/fixtures/fail/expectations
referencing the expected source of the failures for that test file. Name the file
the same as you do the fixture (e.g. tests/fixtures/fail/foo.php and tests/fixtures/fail/expectations/foo.php).
To also check where each error is reported, map the source to a list of line numbers. The test then fails unless that source is reported on exactly those lines:
return [ 'Alley.PHP.BlockWrapperAttributes.UnsafeKey' => [ 9, 12, 15 ], ];
Changelog
Please see CHANGELOG for more information on what has changed recently.
Credits
This project is actively maintained by Alley Interactive. Like what you see? Come work with us.
License
The GNU General Public License (GPL) license. Please see License File for more information.