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

Search Bundle Laravel Package

rollerworks/search-bundle

Symfony bundle integrating Rollerworks Search: build user-friendly search forms, parse complex query strings, and translate them into Doctrine ORM/DBAL queries with reusable field definitions, validation, and extensible conditions.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • rollerworks/search-bundle is a Symfony bundle, not a Laravel package. Its value is concentrated in Symfony-specific integration: DI extension/config tree, SearchFieldSet/FieldSet configuration, form types (SearchFieldSetType, SearchFormType), request-to-condition wiring, and a Twig-rendered search form. Laravel has no equivalent bundle/host layer, so roughly the entire integration surface is unusable off-the-shelf.
  • The genuinely portable piece is the underlying rollerworks/search core library: it parses a user-supplied query string into a normalized SearchCondition object, validated against a declared field set (field names, types, patterns, allowed values), then delegates translation to a backend ("condition optimizer/processor") such as Doctrine DBAL/ORM.
  • That core concept — explicit field-set allowlisting before the query is translated — is architecturally sound and is exactly the property Laravel apps typically lack when they hand-roll "dynamic filter" logic. If we adopt anything, we adopt the pattern or the core library, not the bundle.
  • Fit with a modern Laravel 10/11 + PHP 8.2+ codebase is poor: the package targets Symfony 2.8/3.x-era APIs and PHP 7.x, and its Doctrine bridge is written against Doctrine DBAL 2.x / ORM 2.x.

Integration feasibility

  • Composer resolution is the first blocker. The bundle declares Symfony 3.x-era constraints; installing it alongside laravel/framework ^10/^11 and its Symfony 6/7 components will produce conflicts or force --ignore-platform-reqs-style hacks that we should not accept.
  • Even ignoring the bundle, the core library's own constraints (PHP ~7, doctrine/dbal ^2) are likely to collide with current Doctrine 3.x, where fetchAll(), Connection::query() semantics, and various type APIs changed.
  • A realistic path is a fork-and-patch: strip the Symfony bundle, pin the core library at a forked commit, patch PHP 8 deprecations/removals (implicit nullable params, Serializable implementations, dynamic properties, each()-era helpers), and upgrade the Doctrine translation layer to DBAL 3/ORM 3. That is genuine engineering effort with ongoing ownership — not a dependency install.
  • Estimated effort for a fork-and-patch spike that reaches "parses conditions and generates a working Eloquent/query-builder WHERE clause for 80% of field types": 2–4 engineer-weeks, plus test harness and documentation. Non-trivial but bounded; the risk is the tail of field types (date ranges, patterns, !/- negation, sub-groups) and the parser's edge cases.

Technical risk

  • Abandonment is the dominant risk. Last release 2017-10-23, 10 stars, 0 dependents. There is no security response capability, no PHP 8.x support guarantee, and no path to a CVE fix we don't write ourselves.
  • Supply chain / provenance: a near-zero-adoption package with a single historical maintainer means we cannot rely on community scrutiny. We would be the primary consumer and de facto maintainer.
  • Security surface: this library sits directly on user input and emits database queries. A parser bug or a field-set misconfiguration that permits unvalidated field names is an injection vector; deeply nested conditions are a DoS vector (parser recursion + expensive generated SQL). We must treat any adoption as security-sensitive code requiring review and fuzzing.
  • Semantic drift from the maintainer's intent: the docs (rollerworks.github.io) describe the 2017 behavior; there is no living reference for how the parser handles today's expected inputs.
  • Countervailing factor: the scope is small and well-bounded — a parser plus a translation interface. Forking a 2017 library of this size is materially cheaper than forking an active framework. Risk is "we own it forever," not "we can't understand it."

Key questions

  1. Is the pattern (allowlisted field set → normalized condition → backend translator) what we actually want, or do we need this specific implementation? If the former, a ~500-line internal implementation over Laravel's query builder delivers 90% of the value with none of the maintenance tail.
  2. Which backends must be supported — Eloquent/MySQL only, or also Postgres full-text, Meilisearch, Elasticsearch? Rollerworks' translator abstraction is only valuable if we genuinely need ≥2 backends.
  3. Does the product need a query-string search syntax (user-typed field:value AND (a OR b)), or would structured filter UI + validated request parameters suffice? The former justifies a parser; the latter does not.
  4. What is our tolerance for owning a vendored/forked dependency, including a named internal maintainer and a documented patch process?
  5. Are there existing conditions in the codebase (e.g., a SearchRequest/filter DTO) we'd need to interoperate with, and who owns that contract?

Integration Approach

Stack fit

  • Treat this as a standalone PHP library evaluation, not a Laravel package evaluation. Do not attempt to install the Symfony bundle in a Laravel app. If we proceed, we depend on a fork of rollerworks/search (and optionally rollerworks/search-doctrine-dbal), wired manually into a Laravel service provider.
  • Because the core is PSR-friendly and framework-agnostic, container wiring in Laravel is straightforward: bind a SearchFieldSetRegistry and a ConditionToQueryBuilder adapter as singletons; register field sets per domain model in a config file (config/search.php) rather than Symfony YAML.

Migration path

  1. Reference-only phase (recommended default): mine the repository for its field-set model, parser grammar, and condition-optimizer design; reimplement the subset we need internally against Laravel's query builder. Zero ongoing dependency risk, full control of the security boundary.
  2. Vendored-fork phase (if grammar fidelity matters): fork into our VCS under a rollerworks/search replacement name, pin via a Composer VCS/path repository, patch PHP 8.2/8.3 and DBAL/ORM compatibility, and expose only our own SearchService interface to application code. Application code never references Rollerworks\ namespaces directly.
  3. Do not pursue a direct composer require of the Symfony bundle in any Laravel application.

Compatibility

  • Requires an explicit compatibility audit matrix: PHP 8.2/8.3, Laravel 10/11, Doctrine DBAL 3.x/4.x (if the DBAL bridge is used), and any DB driver differences (identifier quoting, LIKE case sensitivity on Postgres vs MySQL, ILIKE handling).
  • The parser itself is likely to surface PHP 8 issues first (implicit nullable parameters, ReflectionParameter::getClass() removal, Serializable deprecation, strlen(null)-style warnings). These are mechanical but numerous; budget for a static-analysis pass (PHPStan level 6+) as the exit criterion.
  • If our data layer is Eloquent-only, the bundled Doctrine translator is dead weight — we write a new translator, and the Doctrine compatibility question disappears entirely.

Sequencing

  1. Week 0–1 — Spike: stand up the fork, get a minimal field set parsing a query string and emitting a query-builder WHERE clause for string, integer, date-range, and enum fields. Time-box hard.
  2. Week 1–2 — Security review + fuzz: adversarial inputs (deep nesting, huge token counts, wildcard abuse, unknown fields, unicode). Establish parser limits (max depth, max tokens, max clauses) as a hard requirement.
  3. Week 2–3 — Translator completeness: implement the remaining field types we need; write a conformance test suite that becomes our regression harness for all future patches.
  4. Week 3–4 — Adapter + rollout: wrap behind an internal SearchService contract, ship to one low-risk read-only listing endpoint behind a feature flag, measure query latency and error rates.
  5. Gate: adopt broadly only if the spike, security review, and single-endpoint rollout all pass. Otherwise revert to the reference-only reimplementation — which the earlier phases will have de-risked considerably.

Operational Impact

Maintenance

  • This is the decisive cost. Post-adoption we are the maintainer of record for a forked 2017 codebase: PHP minor-version bumps, framework upgrades, and dependency churn all land on us. Any future Laravel major (12, 13) triggers a re-audit.
  • Requires a named owner (not a team), a documented patch/rebase procedure, and a standing line in the upgrade runbook. Without that, this becomes an orphaned vendor directory within 12–18 months — a well-known failure pattern.
  • Contrast: an internal implementation of the same field-set/condition pattern has a comparable initial cost but a dramatically lower steady-state cost, because the code is idiomatic to our stack and every engineer can read it.

Support

  • Zero upstream support. No maintainer response, no security advisories, no issue triage. GitHub issues from the 2017 era will remain unanswered.
  • Internal support burden falls on whoever owns it; onboarding documentation must be written by us, because upstream docs describe a 2017 API and a Symfony form integration we will not use.
  • If a parser bug causes incorrect query results (silently wrong filters are worse than a 500), diagnosis requires reading unfamiliar 2017 code under time pressure. Mitigate with a strong conformance test suite from day one.

Scaling

  • Parse/condition-building is CPU-cheap and stateless — it scales horizontally without concern, and field-set definitions can be built once per process and cached.
  • The real scaling risk is query shape: user-composed conditions can generate expensive SQL (unbounded LIKE '%x%', OR-heavy clause trees, deep pagination offsets). The library does not protect against this; we must add clause-count caps, mandatory pagination limits, and query timeouts at the adapter layer.
  • Search-condition objects are plain value objects; serializing them into cache/queue payloads is feasible but versioning becomes our problem if we ever change the field-set schema.

Failure modes

  • Misconfigured field set → either a 500 on unknown field, or worse, a silently permissive filter that exposes rows the caller shouldn't see. Field-set configuration must be treated as an authorization-adjacent artifact with review.
  • Parser DoS → pathological input causing deep recursion or exponential clause generation. Mitigate with hard input length/depth limits before parsing.
  • Silent semantic drift on upgrade → a patched parser that changes how negation or range boundaries are interpreted, producing quietly wrong results. Mitigate with golden-file conformance tests.
  • Dependency break on framework upgrade → a Laravel/PHP bump makes the fork uninstallable, blocking the whole upgrade. This is the most likely real-world failure and the strongest argument for the internal-reimplementation route.
  • Translator/DB divergence → behavior differs between MySQL and Postgres (case sensitivity, date handling, NULL ordering), causing inconsistent UX across environments.

Ramp-up

  • Initial learning curve is moderate: the search-condition model is well-conceived but undocumented in current terms; expect 3–5 days for an engineer to be productive in the fork, longer to be confident in the parser internals.
  • Team-wide cost is the real number: every engineer who touches search must understand that this is vendored, unmaintained code with non-standard idioms — a persistent cognitive tax that does not exist for an internal implementation.
  • Given 10 stars, 0 dependents, a 2017 last release, and a Symfony-only integration surface, the honest TPM position is: do not adopt as a dependency. Use it as a design reference, and if the query-string search grammar is genuinely required, reimplement the field-set/condition pattern internally or evaluate maintained alternatives (Laravel Scout with Meilisearch/Typesense, or a thin allowlisted-filter layer over Eloquent).
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource