Shared PHP code quality configuration for all FernleafSystems projects. One package gives you consistent code style, static analysis, and pre-commit hooks across all your repositories.
composer require --dev fernleafsystems/qaStep 1: Run the setup wizard to generate configuration files:
vendor/bin/qa-setupStep 2: Install the git hooks:
composer installBoth steps are required. The wizard generates config files including captainhook.json. The composer install reads that file and installs the actual git hooks.
The wizard will ask you:
- PHP version (detected from your
composer.json) - Source directory (defaults to
src,lib,appif found) - Whether to include your
testsdirectory - PHPStan strictness level (3 = conservative, 6 = strict)
| File | Purpose |
|---|---|
.php-cs-fixer.php |
Code style rules (non-WordPress projects) |
.phpcs.xml.dist |
WordPress Coding Standards (WordPress projects) |
rector.php |
Automated refactoring rules |
phpstan.neon |
Static analysis configuration |
captainhook.json |
Pre-commit hook configuration |
.gitattributes |
Line endings, diff settings, export-ignore rules |
After setup, run the tools directly via vendor/bin/:
# Code Style (PHP CS Fixer)
vendor/bin/php-cs-fixer fix --allow-risky=yes
vendor/bin/php-cs-fixer fix --dry-run --diff --allow-risky=yes # CI check
# Rector (Automated Refactoring)
vendor/bin/rector process
vendor/bin/rector process --dry-run # CI check
# PHPStan (Static Analysis)
vendor/bin/phpstan analyse
vendor/bin/phpstan analyse --generate-baseline # Generate baseline
# WordPress Projects Only
vendor/bin/phpcs
vendor/bin/phpcbf # Auto-fixFor convenience, add these to your project's composer.json:
{
"scripts": {
"cs": "php-cs-fixer fix --allow-risky=yes",
"cs-check": "php-cs-fixer fix --dry-run --diff --allow-risky=yes",
"rector": "rector process",
"rector-check": "rector process --dry-run",
"phpstan": "phpstan analyse"
}
}Then run: composer cs, composer rector, etc.
Important: Git hooks require TWO steps to install:
- Run
vendor/bin/qa-setup- this generatescaptainhook.json - Run
composer install- this triggers CaptainHook to install the git hooks
Without both steps, hooks will NOT be installed.
Once installed, on every commit:
- Rector runs on staged PHP files (with parallel mode disabled)
- PHP CS Fixer runs on staged PHP files
- If files were modified, the commit is blocked with a message to re-stage
This ensures all committed code meets quality standards.
If you prefer to create configs manually, here's a minimal .php-cs-fixer.php:
<?php declare( strict_types=1 );
use FernleafSystems\QA\PhpCsFixer\ConfigFactory;
use FernleafSystems\QA\PhpCsFixer\RuleSet\Php83;
use PhpCsFixer\Finder;
$finder = Finder::create()
->in( __DIR__.'/src' )
->exclude( 'vendor' );
return ConfigFactory::fromRuleSet( new Php83() )
->withFinder( $finder )
->create();Available rulesets: Php83, Php84, Php85
return ConfigFactory::fromRuleSet( new Php83() )
->withFinder( $finder )
->withCustomRules( [
'some_rule' => true,
'another_rule' => ['option' => 'value'],
] )
->create();Edit the generated config files directly. For example, in rector.php:
->withSkip( [
__DIR__.'/vendor',
__DIR__.'/legacy',
__DIR__.'/generated',
] )Edit phpstan.neon:
parameters:
level: 6 # Change from 3 to 6 for stricter analysisExample GitHub Actions workflow:
name: Code Quality
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
- run: composer install --no-progress
- run: vendor/bin/php-cs-fixer fix --dry-run --diff --allow-risky=yes
- run: vendor/bin/rector process --dry-run
- run: vendor/bin/phpstan analyseRequires PHP 8.3+
- PHP 8.3, 8.4
- PHP 8.5 (forward-compatible, uses 8.4 rules until 8.5-specific rules exist)
This package enforces FernleafSystems coding standards:
- Tabs for indentation
- No spaces in string concatenation:
'foo'.$bar - Spaces inside parentheses:
function( $param ) - Opening braces on same line
- PSR-12 as base with customizations
- Strict types declaration on same line as opening tag
You must complete BOTH steps:
vendor/bin/qa-setup- generatescaptainhook.jsoncomposer install- installs the git hooks
Check that captainhook.json exists in your project root. If not, run vendor/bin/qa-setup.
The hook detected that Rector or CS Fixer modified your files. Run:
git add -u
git commitRun composer install again to trigger the CaptainHook installer.
git commit --no-verify