sqli/eztoolbox
EZToolbox is a Laravel/PHP utility package that bundles handy helpers and tools for everyday development. It aims to cut boilerplate by providing reusable functions and conveniences you can drop into your projects, keeping code cleaner and workflows faster.
First, settle the framework question. The repository description describes a Symfony bundle (it aggregates bundles — Entities Manager, ContentType Installer, Command Toolbox — plus Twig operators), while the package blurb claims Laravel/PHP. This matters more than anything else on day one: it decides whether you register a Bundle in config/bundles.php or rely on Laravel package discovery. Open composer.json in the package and check the require block for symfony/framework-bundle / symfony/twig-bundle versus laravel/framework / illuminate/support. Everything below assumes the Symfony shape; the Laravel equivalent is noted where it differs.
Minimal steps (Symfony path):
composer require sqli/eztoolbox:^5.0
config/bundles.php (or confirm Flex did it):
Sqli\EzToolbox\EzToolboxBundle::class => ['all' => true],
bin/console debug:container --tag=twig.extension | grep -i ez
bin/console debug:config eztoolbox # confirms the config alias, if any
bin/console cache:clear && bin/console cache:warmup
composer require sqli/eztoolbox, confirm the service provider is auto-discovered (php artisan about or vendor/composer/installed.json), then php artisan vendor:publish --provider="Sqli\EzToolbox\..." if a config file ships.Where to look first, in order: the package's own README.md → src/ directory listing (DependencyInjection/, Twig/, Command/, Helper/) → tests/ if present. The src/Twig/ and src/Command/ folders are the fastest inventory of what you actually get; they are also the most reliable documentation for a package with this little README surface.
Your first use case is almost certainly one of two things:
debug:twig lists operators, filters, and functions the bundle contributes — filter for the package namespace).Pick one, get it running in a scratch controller/template, and defer the rest. Do not try to adopt the whole toolbox in a single pass.
Treat the toolbox as four independent packages that happen to ship together. In practice you will adopt Entities Manager heavily, the Twig operators lightly, and the Command Toolbox only where you'd otherwise write boilerplate. Adopt them separately so you can drop one later without unwinding the others.
Inject services, never reach for statics. If a helper class exposes static methods, wrap it behind a small application-level interface and inject that:
// App\Toolbox\SluggerInterface — your seam, not theirs
final class AppToolboxSlugger implements SluggerInterface
{
public function __construct(private \Sqli\EzToolbox\Helper\SomeHelper $inner) {}
public function slug(string $value): string
{
return $this->inner->slugify($value);
}
}
This costs ten minutes and buys you a one-file swap if the package stalls (see gotchas: one star, zero dependents, no support policy). It also makes the helper unit-testable without booting a kernel.
Same trick for Twig: wrap operators in your own extension. Register a AbstractExtension in your app that delegates to theirs. It feels redundant, but it gives you a single place to rename, guard, or reimplement when a major version lands.
Register content types as an idempotent, environment-aware command. The ContentType Installer exists to be run repeatedly. Wire it into your deploy/CI script rather than into a controller:
# CI / deploy, after migrations
bin/console sqli:content-type:install --env=$APP_ENV
Guard it so it is safe to run on every deploy (check-then-create, never blind-create) and assert the expected content type count in a smoke test so a silently-failing installer surfaces in CI rather than in production.
Compose the Command Toolbox rather than inheriting from it. If it provides base command classes or traits, prefer decorating or copying the useful method bodies into your own commands over extending their base class. Extending couples your command signature to their abstraction; copying is cheap and reversible.
Integration tips that pay off across the codebase:
config/packages/eztoolbox.yaml with every option you rely on spelled out. Implicit defaults in a low-traffic package change without a changelog entry you'll read.self::getContainer()->get(...) in a KernelTestCase), so an autowiring regression (the class of bug fixed in 5.0.3) fails the build.CommandTester against a test database."sqli/eztoolbox": "5.0.3") rather than ^5.0 while you are learning its surface area; loosen to ^5.0 only after you have the regression tests above in place.The identity ambiguity is the biggest gotcha. Every generated assessment you'll see about this package is extrapolated from a one-line release note ("Fix autowiring error"). No README, no supported-versions policy, no visible changelog history. Do not let a plan that says "Laravel integration and configuration" drive adoption decisions until you have personally confirmed the framework, the PHP/Laravel or Symfony version constraints, and what src/ actually contains. Verify, then plan.
5.0.3 is a correctness fix on a fresh major. Three patches into a 5.x line means the first months are a stabilization window. Read the diff for the autowiring fix and confirm it matches a symptom you can reproduce — upgrading blind buys a version bump, not a risk reduction.
Container cache is the #1 false alarm. Symptom: an operator/service "doesn't exist" after composer update. Cause: stale compiled container or Twig cache. Fix: cache:clear, cache:warmup, and in dev confirm twig.debug/kernel.debug are on. Before filing anything, run debug:container --tag=twig.extension and debug:twig to prove whether registration or usage is broken.
Bundle ordering in config/bundles.php matters if Entities Manager or ContentType Installer hooks into Doctrine or into another bundle's compiler pass. If services silently don't exist, try moving the bundle entry relative to DoctrineBundle before debugging anything else.
Twig operator traps:
Twig\Markup bypasses escaping; returning a plain string does not. If output looks double-escaped or HTML appears raw, this is why. Decide per operator and assert it in a render test.strict_variables: true; add defaults at the call site, not by loosening the setting.ContentType Installer is state, not code. It writes to the database. Treat it as a migration: version it, run it in the deploy pipeline, never in a request, and make it idempotent. A re-run on an environment where someone hand-edited a content type is where you'll find the package's sharpest edges — test that scenario explicitly.
Helper statics are a testing tax. If helpers are static, you cannot fake them in a unit test. Do not paper over this with a kernel-booting test for everything; wrap the static behind an injected service (pattern above) for anything you touch more than twice.
Extension points worth knowing: decorate rather than fork. Symfony's services.yaml lets you decorates: any service the bundle exposes, and Twig extensions can be tagged/replaced. If a helper is nearly right, decoration keeps you upgradable; a vendored fork of a one-star package you now own forever is the expensive option.
Vendor risk, stated plainly. One star, zero dependents, an internal-to-consultancy bundle, and no disclosure process. It may carry useful plumbing, but you are the maintainer of last resort. Concretely: pin the version, keep the wrapping seams described above, note in your dependency register which services rely on the toolbox's container behaviour, and have a one-page plan for "replace with 200 lines of our own code" — which is realistically the size of the surface you'll actually use.
How can I help you explore Laravel packages today?