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

Code Style Laravel Package

ibexa/code-style

Ibexa Code Style packages the coding standards used across Ibexa projects, bundling PHP CS Fixer configuration plus related CI, IDE, Git hook, and GitHub contribution templates. Install it as a dev dependency with a tilde constraint and reuse the Ibexa ruleset in your own projects.

View on GitHub
Deep Wiki
Context7

Getting Started

This is not a Laravel package in the usual sense — there is no service provider, no config file to publish, no runtime integration. It is a dev-only dependency that ships a pre-configured PhpCsFixer\Config factory. You install it, point it at your code, and run php-cs-fixer through it.

1. Install as a dev dependency, pinned with a tilde constraint:

composer require --dev ibexa/code-style:~2.3.1

The tilde is not optional advice — the package explicitly does not follow SemVer across minor releases, only within a single minor. ~2.3.1 gets you 2.3.* patches and nothing else.

2. Create .php-cs-fixer.php in the project root (the "third party packages" template from the README):

<?php

$factory = new Ibexa\CodeStyle\PhpCsFixer\InternalConfigFactory();

// You can omit the call below if you want Ibexa ruleset with no custom rules
$factory->withRules([
    // Your rules go here
]);
$config = $factory->buildConfig();
$config->setFinder(
    PhpCsFixer\Finder::create()
        ->in(__DIR__ . '/src')
        ->in(__DIR__ . '/tests')
        ->files()->name('*.php')
);

return $config;

For a Laravel app that means swapping the in() calls for app, config, database, routes, tests and excluding storage, bootstrap/cache, vendor.

3. Look here first, in order:

  • README.md → the two config templates (third-party vs. Ibexa internal). You want the third-party one.
  • doc/FAQ.md → contribution/usage questions specific to Ibexa packages.
  • Release notes for v2.2.0 and v2.3.1 → they tell you what changed in the ruleset itself (dropped FQCN rule, added import-FQCN rule, multiline method arguments, PHPUnit 11 rule set). These are the diffs that will bite you on upgrade, not the API.
  • InternalConfigFactory itself (vendor/ibexa/code-style/src/PhpCsFixer/InternalConfigFactory.php) — it is the real documentation of which rules are on.

4. First use case — measure before you fix. Never run fix on a mature codebase first. Run:

vendor/bin/php-cs-fixer fix --dry-run --diff

Scoped to one directory first (app/Models) so you can gauge the blast radius. If you see hundreds of files, that's the expected outcome of adopting an opinionated ruleset — plan it as a dedicated "style-only" PR, not as noise inside a feature branch.

Implementation Patterns

Composer scripts as the daily interface. Don't make developers remember flags:

"scripts": {
    "cs:check": "php-cs-fixer fix --dry-run --diff --using-cache=no",
    "cs:fix": "php-cs-fixer fix",
    "cs:fix:parallel": "php-cs-fixer fix --parallel"
}

composer cs:fix becomes the reflex before committing; composer cs:check is what CI runs.

Customise by merging, not forking. withRules() layers your project rules on top of the Ibexa set. This is the intended extension point and keeps you on the upgrade path:

$factory->withRules([
    'declare_strict_types' => true,
    'final_class' => false,
]);

Use the Ibexa defaults for everything you don't have a strong opinion on — the moment you copy the ruleset into your own file, you've taken on the maintenance cost the package exists to remove.

Parallel execution for large repos. Either form works and is worth enabling once fix takes more than a few seconds:

$factory->runInParallel();
// or
InternalConfigFactory::build(runInParallel: true);

Note the second form is the Ibexa-internal shorthand — it skips the setFinder chaining style, so if you use it you still call ->setFinder(...) on the returned config.

CI job — dry-run only, with a machine-readable format:

- run: composer install --no-interaction --prefer-dist
- run: vendor/bin/php-cs-fixer fix --dry-run --diff --using-cache=no --format=checkstyle > cs.xml

--using-cache=no matters in CI: a stale .php-cs-fixer.cache restored from a previous cache key will make the check pass on files it never actually re-parsed. Emit checkstyle/GitLab format so violations annotate the MR/PR instead of dumping a wall of diff into the log.

Pre-commit hook, scoped to changed files. Running the full ruleset on every commit is the fastest way to get developers to --no-verify. Feed only staged PHP files to the fixer:

git diff --cached --name-only --diff-filter=ACM | grep '\.php$' | xargs -r vendor/bin/php-cs-fixer fix --

Pair with php-cs-fixer fix --dry-run on the same file list for the "block the commit" variant. Tools like CaptainHook or brainmaestro/composer-git-hooks work fine here — the package ships its own Git hook tooling as a reference, but you don't need it.

Two-stage rollout for legacy codebases. Adopt the ruleset on new code first by giving the Finder only your newer directories, then widen it in follow-up PRs. This avoids the "one commit reformats 4,000 files and git blame is dead" problem. Alternatively, do the big-bang fix in a single commit whose hash you add to .git-blame-ignore-revs.

IDE integration. Because there is no plugin, wire it as an external tool / file watcher in PhpStorm pointing at vendor/bin/php-cs-fixer fix $FilePathRelativeToProjectRoot$. This is the single highest-leverage daily pattern: style is corrected on save, so composer cs:check in CI almost never fails.

Pair with static analysis, not instead of it. This package is formatting and docblock conventions only. PHPStan/Psalm are separate concerns; the package's own CI plugins are a reasonable template for how Ibexa wires them together.

Gotchas and Tips

The license is the first thing to check, not the last. The README declares a dual license: Ibexa Business Use License (BUL) 2.4+ and GPL v2. Composer reports this as NOASSERTION, which means automated license scanners in most enterprises will flag it and stop the build. GPL-2.0 is a copyleft license — for a proprietary Laravel SaaS or internal commercial product, get legal sign-off before this lands in composer.json, or you may be relying on the BUL path, which requires an Ibexa DXP subscription. This is the single biggest adoption blocker and it has nothing to do with code quality.

SemVer is minor-scoped, so upgrade deliberately. A composer update crossing 2.3 → 2.4 can change formatting rules and produce diffs across the whole repo with no major version bump to warn you. Keep the tilde, and read the release notes before bumping the middle digit.

php-cs-fixer is pinned by this package. It requires a specific friendsofphp/php-cs-fixer range (3.90.0 as of v2.3.1). If your project also depends on php-cs-fixer directly at a different version, expect a Composer conflict. Don't add it separately — use the transitive one and reference vendor/bin/php-cs-fixer. If you genuinely need a newer fixer, you're waiting on an Ibexa release, which is exactly the maintenance cost you signed up for.

Ruleset selection is derived, not configured. The factory guesses which Ibexa rule set to apply from the package version / root branch alias. v2.3.1 specifically fixed it to "pick the rule set from the root branch alias before the guessed version." If your formatting suddenly changes after a composer update with no rule changes on your side, this heuristic is the first suspect — check -vvv output for which rule set was loaded before you start editing .php-cs-fixer.php.

setFinder() is mandatory. buildConfig() returns a Config with no finder attached in the third-party template. Omit it and the fixer exits complaining about missing paths, which reads like a broken install but is just a missing three-line block.

Don't run this alongside Laravel Pint. Both are php-cs-fixer wrappers over the same file set with different rule sets. Running both means each one fights the other's output on every save — infinite re-formatting in a file watcher and a permanently dirty working tree. Pick one. If you're adopting Ibexa rules because you also integrate with Ibexa DXP, remove Pint.

Expect the first diff to be enormous, and don't panic-review it. The v2.2.0 rules (multiline method arguments above one parameter, import-FQCN, no import grouping in ordered_imports per v2.2.1) touch nearly every file. Review the rules, not 3,000 individual lines. Split into: (a) config commit, (b) mechanical fix commit, (c) .git-blame-ignore-revs entry.

Some rules are opinionated in ways reviewers will debate. phpdoc_no_alias_tag is deliberately reconfigured not to rewrite @link; ordered_imports has no groups as of v2.2.1. If your team has an existing import-grouping convention, override it explicitly in withRules() rather than letting it silently churn.

Debug with -vvv and --rules. When a file "isn't being fixed," the cause is almost always the Finder (wrong path, ->name('*.php') missing, an ->exclude() catching it) or an invalid cache. vendor/bin/php-cs-fixer fix --dry-run -vvv path/to/file.php and vendor/bin/php-cs-fixer describe <rule_name> are the two commands that answer 90% of questions. --using-cache=no distinguishes "rule didn't fire" from "cache lied."

Gitignore the cache. .php-cs-fixer.cache should be in .gitignore and in your Docker/CI volume exclusions. A cache copied across container generations causes silently skipped files.

Exit codes are non-zero on dry-run diffs. --dry-run returns 8 when files need fixing, 16 on config errors. Don't || true the CI step — that turns the whole check into decoration.

The returned object is a plain PhpCsFixer\Config. Every upstream API is available on it (setRiskyAllowed, setUsingCache, setCacheFile, setParallelConfig). That's the real extension surface: use withRules() for rules, and the returned config for everything else. Don't subclass InternalConfigFactory.

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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin