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

Filter Bundle Laravel Package

ruwork/filter-bundle

Symfony bundle that integrates the RuWork filter component, letting you define reusable filters and apply them to Doctrine queries from request parameters. It provides bundle configuration and service wiring to add flexible, maintainable filtering to Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before anything else. This package is effectively unmaintained: low stars, no dependents, no community. The 0.2.0 release is a single-line changelog entry — treat it as evidence of a heartbeat, not of maintenance. It does not come with a support promise, a security policy, or a track record of Symfony/PHP compatibility work. The first step is not composer require — it is deciding whether you actually need it or whether you are reverse-engineering someone's side project.

  1. Read composer.json first. Confirm the PHP and Symfony version constraints. The 0.1.x line targeted roughly PHP 7.1 and Symfony 3.3–4.0; check whether 0.2.0 moved any of that (the changelog suggests it did not). On PHP 8.x or Symfony 6/7, expect composer require to fail on constraints and expect the code to fail on modern deprecations even if you force-install with --ignore-platform-reqs.
  2. Read the 0.1.x → 0.2.0 diff before the docs. One changelog line, so presumably one commit. That commit is the most informative thing in the repository right now: it tells you exactly which class handles form input and what it now skips.
  3. The 0.2.0 note reframes the package as form-driven. "Ignore form submit and valid states" only makes sense if the package reads data out of a Symfony Form. So look first for a form type, a FormTypeExtension, or PRE_SUBMIT/SUBMIT event listeners in src/ — that is the real entry point. Then read DependencyInjection/*Extension.php, the configuration tree, and tests/.
  4. Register the bundle. config/bundles.php on Flex, or AppKernel::registerBundles() on 3.x. Dump the tree with bin/console config:dump-reference <alias> — for a package this size it is probably nearly empty.
  5. Wire one concrete case. The canonical first use case: a filter object described by a Symfony form, applied to a Doctrine QueryBuilder so a listing page can be filtered by a handful of request parameters. Build it on a branch, and include the case where the form is submitted with invalid data.

Minimum viable spike:

composer require ruwork/filter-bundle:0.2.0 --dry-run   # pin exact; read resolution errors carefully

If resolution succeeds, register the bundle, and reproduce the smallest example from tests/ verbatim — then reproduce it again with an invalid form submission, since that is what 0.2.0 changed. If either case does not pass on your platform, stop: you are now maintaining a fork, and you should price that in.

Implementation Patterns

The day-to-day value of a bundle like this is entirely in how it turns request/form input into query constraints. The patterns worth using:

One filter object per use case, hydrated from a form. Keep the filter a plain object (scalars, nullable properties, sensible defaults). Let a FormType map request data onto it. Do the HTTP-side work (handleRequest, reading query params) at the controller boundary, never inside the filter, so the same filter can be built from a console command or a test without faking a request.

Let the form own input, but do not trust it to own correctness. Since 0.2.0 explicitly ignores submit and valid states, the package will happily hand you a partially-populated filter. Validate explicitly — Symfony Validator on the filter object, or a separate isValid() check feeding your error display — and decide deliberately what "no filters applied" means versus "filters rejected."

Apply, don't build. The filter describes intent ("status is active", "created after X"); a separate applier translates that into QueryBuilder calls. Keeping them apart is what makes filters unit-testable: you assert on the filter, and you assert on the builder with a mocked or in-memory connection.

Compose small filters rather than one god-filter. If the package exposes an interface, implement it repeatedly and apply filters in a loop over tagged services. Adding a filter becomes "add a class," not "edit the repository." If collection injection isn't wired out of the box, a small compiler pass is the legitimate extension point and cheaper than forking.

Repository scoping. Apply inside a dedicated repository method (findFiltered(Filter $f, int $page, int $perPage)) rather than in the controller. Pagination, ordering, and filtering live together, and it is obvious where to look when a query goes wrong.

Bound the input. Cap page size, whitelist sortable fields, reject inverted date ranges. A filter bundle gives you no protection here, and unbounded LIMIT/ORDER BY from request data is the usual way these listings become a production incident. This matters more now that the package ignores the form's valid state by design.

Test at three levels. Unit-test the filter (input → normalized values), functionally test one repository method per filter against a real database (SQLite or a test container), and add a test for the invalid submission path — empty form, one bad field, submit button only. That third test is your regression guard on the 0.2.0 behaviour and on any future release.

Isolate the dependency. Wrap the bundle's types behind your own interface in App\Filter. One afternoon of work, and the eventual migration goes from "rewrite every listing" to "swap one applier implementation."

Gotchas and Tips

  • A new release is not a revival. 0.2.0 is one changelog line. There is still no maintainer you can talk to, no security process, and no evidence of modern-stack testing. Pin the exact version (0.2.0, not ^0.2) — 0.x carries no BC promise — commit the lock file, and keep the dependency in your risk register.
  • What "ignore form submit and valid states" actually changes. Before, a submitted form's submit button and/or its validation state likely leaked into the filter data (a button field becoming a filter property, or a filter applied only when isValid() was true). After, those are skipped. Consequences to check: (a) filters now apply from invalid forms, so bad input reaches the QueryBuilder unless you validate; (b) error messages may no longer surface because the package stopped caring about validity; (c) a filter that previously required a fully valid form may now apply partially — verify generated SQL for the half-filled case, not just the happy path.
  • Semver reading. 0.1.x → 0.2.0 is a minor bump on a 0.x package, which conventionally permits breaking changes. Diff the public API before upgrading; do not assume additive.
  • Constraint hell on modern stacks. Expect conflicts with PHP 8 and recent Doctrine. --ignore-platform-reqs installs it and then deprecations bite at runtime; do not do this in production without a full functional test pass that includes the invalid-submission case.
  • The README is not the docs. No blog posts, no Stack Overflow history, nobody to ask. The tests, the DI extension, and the 0.1.x→0.2.0 diff are the only truth. Search src/ for interface and abstract first — those are the seams you can build on.
  • Debugging container wiring. If a filter service is not applied, bin/console debug:container --tag=<tag> and debug:container <service-id> tell you whether it is registered, public, and tagged. Most "the filter does nothing" bugs are missing tags or a compiler pass that never ran.
  • Debugging "the filter applied the wrong thing." With submit/valid states ignored, start by dumping the filter object after hydration and before applying. Most surprises are a button field or a null overwriting a default.
  • Configuration quirks are likely. Old bundles toggle features in the extension's config tree with surprising defaults (registration off, automatic tagging of a directory that no longer exists after a refactor). Dump the reference config and diff it against the extension class.
  • Doctrine version drift is the real runtime risk. Query builder and Expr behaviour changed across ORM 2.5 → 2.13+. If the bundle builds Expr conditions or uses getRootAliases(), re-test every generated query on your actual Doctrine version.
  • Extension points worth knowing. Tagged filter services plus a compiler pass, a custom applier or service decorator, and your own interface implementation are the three ways to extend without editing vendor code. Anything else means forking.
  • Plan the exit. Cheapest migration targets are Doctrine's own filters/Criteria, API Platform query-parameter filters (if you use it), or a ~150-line hand-rolled criteria object applied to a QueryBuilder. Because the surface here is small, the honest recommendation for a new project is to skip the dependency and write those 150 lines — you get better typing, modern PHP, and a maintainer you can talk to.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core