shtumi/useful-bundle
Shtumi Useful Bundle is a grab-bag of practical Symfony utilities that cut boilerplate: handy Twig extensions, custom form types and validators, and Doctrine helpers. Install it to reuse common building blocks and speed up everyday development.
Architecture fit — fails on the first gate: this is not a Laravel package. Despite being catalogued under "Laravel/PHP," shtumi/useful-bundle is a Symfony 2 bundle shipped in the legacy bundle convention (ShtumiUsefulBundle), with DependencyInjection/, Form/Type/, Doctrine/, and Twig/ directories. It has no ServiceProvider, no facade, no Laravel container binding, and no illuminate/* dependency. Its advertised surface maps onto Symfony/Doctrine primitives that Laravel does not share:
| Advertised feature | Symfony 2 substrate | Laravel equivalent |
|---|---|---|
| Custom form types (datepicker, daterange, autocomplete, dependent filtered entity) | Symfony Form component | Blade components + FormRequest rules + JS datepicker (Flatpickr / Tempus Dominus); Livewire for dependent selects |
| DQL functions | Doctrine ORM 2.x | Eloquent scopes, whereRaw/selectRaw, Builder macros — Doctrine only via laravel-doctrine/orm |
| Twig extensions (pluralize, HTML-safe truncate/wordwrap) | Twig 1.x/2.x | Blade @directive or namespaced helper registered via composer.json files |
Roughly one-third of the surface (the Twig text helpers) is portable logic. The rest is either framework-locked (Form types bundle rendering, validation, and data transformation together — Laravel separates them, so a naive port inflates scope) or ORM-locked (DQL functions). As a TPM the read is simple: the architecture-fit question is answered "no" before cost enters the discussion.
Integration feasibility — low, with a cheap and fast failure mode. composer require shtumi/useful-bundle in a Laravel app will not wire anything up, and will most likely fail at dependency resolution, not at runtime: the bundle pins symfony/*: ~2.x constraints, while Laravel 10/11 transitively require Symfony 6/7 components. A resolution conflict at install time is the best possible outcome — it costs minutes rather than a debugging cycle. The only scenario where a direct dependency is genuinely viable is a co-existing Symfony 2.8 service on PHP 7.x, which should itself already be on a decommission path.
Technical risk — high, and the supplied scores must be discounted.
each(), curly-brace string offsets).Key questions for the team:
composer.json/LICENSE — attribution obligations govern any copy-paste port.laravel-doctrine/orm), and does its Doctrine version match the bundle's expected 2.x range?Stack fit — the package does not fit the stack. For any Laravel 10/11 service on PHP 8.1+, the correct posture is do not install; selectively reimplement. State that as the default in the decision record, not as a fallback.
Migration path — feature-by-feature translation, never package adoption.
DependencyInjection/, Form/Type/, Doctrine/, and Twig/ directories rather than trusting the README — the description is deliberately vague ("etc..."). Produce a named list of utilities with rough line counts.FormRequest rules + a maintained JS datepicker. Budget for the semantic gap: Symfony Form couples binding, validation, and rendering; Laravel splits them, so the port is more work than the line count suggests. Dependent filtered-entity selects are the expensive one — evaluate Livewire or an async endpoint before hand-rolling.whereRaw/selectRaw, query scopes, or a custom Builder macro. First confirm the dialect workaround is still needed at all.app/Support/ with attribution and a test — do not take the package as a dependency.Compatibility — assume broken until proven otherwise. Inspect composer.json require constraints for php, symfony/symfony (or per-component), doctrine/orm, and twig/twig. Any pin to symfony/*: ~2.x is an immediate blocker for Laravel 9+. Separately grep for Twig_Extension / Twig_Extension_* class names — removed in Twig 2/3 — since those indicate code written against an API we do not run.
Sequencing:
| Phase | Duration | Output |
|---|---|---|
Spike: clone, read composer.json, attempt suite on PHP 7.4 |
1 day | Go/no-go on any code reuse |
| Capability-gap analysis vs. Laravel-native options | 2–3 days | Named, prioritized utility list |
| Build Laravel equivalents (helpers, Blade, components, rules) | 1–3 weeks, scoped to that list | Owned internal utility package |
| Deprecate/remove any Symfony 2 dependency in the estate | Per service | Decommission plan and owner |
Do not skip the spike — it is one day, and it converts an argument into a fact. Most of the "value" here is a few hundred lines of readable PHP a competent developer can re-derive faster than the dependency can be made to work.
Maintenance — unbounded ownership cost. The package is unmaintained in any practical sense: EOL framework, no security advisory channel, no upgrade path, no upstream to receive fixes from. Every line adopted transfers permanent maintenance liability to us, so "maintenance" really means "we now own a fork." Reimplementation produces code we own by design rather than by accident, with our test coverage and our conventions.
Support — none. No vendor, no SLA, no realistic maintainer response expectation. 110 stars and 0 dependents means no community forum, no Stack Overflow corpus, and nobody to ask. The developer performing the port must write the internal documentation from scratch; budget that time explicitly rather than discovering it late.
Scaling — throughput is not the concern; correctness at volume is. These are thin helpers; CPU and memory impact is negligible. The real scale risk is semantic drift:
Failure modes:
| Mode | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Composer resolution conflict with Laravel's Symfony 6/7 deps | Very high | Blocks install (fast, safe) | Expected default outcome; do not fight it |
| PHP 8 fatals on deprecated syntax in EOL code | High if force-installed | Runtime crash | Reimplement; do not patch |
| Twig 1.x class references removed in Twig 2/3 | High | Fatal | Port to Blade/helpers |
| Silent wrong results from DQL name collision | Medium | Data correctness | Integration test per function |
| Wrong output from mis-ported form data transformation / DST handling | Medium | Data correctness, hard to detect | Behavioral spec + fixtures from the original |
| Maintainer deletes or force-pushes the repo | Low–medium | Build reproducibility loss | Vendor source into our repo if any of it is reused |
| Unpatched vuln in transitively pulled EOL Symfony 2 component | Medium | Security exposure | Never install in a production Laravel service |
Ramp-up — asymmetric, and worth stating as a cost. Reading the code is easy: small surface, low-sophistication PHP. Porting it faithfully is harder, because the developer must hold both Symfony 2 Form/Doctrine semantics and Laravel idioms simultaneously — particularly around form data transformation, validation timing, and date handling. Estimate 1–2 days per utility for a mid-level PHP developer, plus test-writing time. That is the honest comparison baseline against a maintained Laravel-native package or a small first-party helper package, which is closer to near-zero ramp-up.
Recommendation: Do not adopt as a dependency. Run the one-day spike, harvest the Twig-extension logic if the license permits, and reimplement the remainder in Laravel idioms inside an owned internal package. On a TPM scorecard this is a high-risk, low-urgency item to close as "evaluate-and-reimplement," not an open integration — the 9.55 score is unsupported by the adoption data (0 dependents, 110 stars, EOL framework), and a high opportunity score paired with zero dependents is the textbook false positive.
How can I help you explore Laravel packages today?