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

padam87/search-bundle

Lightweight Symfony bundle for adding search to Doctrine-backed applications. Define searchable fields and filters, build queries from request parameters, and return paginated results with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install (with version pins in mind). The bundle targets Symfony 2.x and PHP 5.x. On a legacy app: composer require padam87/search-bundle. On anything newer the constraint graph usually fails — you either need --ignore-platform-reqs, a manual "padam87/search-bundle": "dev-master" entry, or you accept that this is a legacy-only tool and plan a replacement.
  2. Register the bundle in app/AppKernel.php:
    new Padam87\SearchBundle\Padam87SearchBundle(),
    
    There is typically little to no configuration required; check DependencyInjection/Configuration.php and Resources/config/ for the service IDs and any tunables before assuming defaults.
  3. Read the source before the docs. With 7 stars and a 2014 last release, Resources/doc may be thin or stale. The authoritative references are the Annotation/ directory (what you can put on entity properties), the expression/parser classes (what query syntax is accepted), and Resources/config/services.xml (service IDs to inject).
  4. First use case: make one entity searchable. Annotate a handful of scalar properties on an entity (title, name, etc.) with the bundle's searchable annotation, clear the cache so annotations are re-read, then in a controller pull the bundle's search manager from the container, hand it the entity class plus a raw query string from $request->query->get('q'), and render the resulting query/result.

Start with one entity and one text field. Get a working /search?q=foo endpoint before touching operators, sorting, or joins — the value of the package is the string-to-QueryBuilder translation, and you want to see exactly what it produces early.

Implementation Patterns

Annotation-driven field mapping. The core pattern is declaring which entity properties are searchable, then letting the bundle map user-supplied terms onto those properties. Keep the annotation surface small and intentional — every annotated field is effectively a public query parameter.

Controller as a thin adapter. Keep the controller dumb: read q, read page/sort, call the search service, hand the result to a paginator, render. Business rules (which fields are exposed, who can search what) belong in a dedicated search service or a per-entity configuration, not inline in the action.

Paginate explicitly. This bundle builds a query; it does not paginate. Wire the returned QueryBuilder into KnpPaginatorBundle or Pagerfanta immediately — otherwise you'll be tempted to getResult() on an unbounded query and hit memory limits the first time someone searches for a common word.

One generic search action, many entities. A common day-to-day pattern is a single SearchController::searchAction($entityAlias) that resolves an alias to an entity class, runs the search, and renders a shared template. This keeps search UX consistent across the app and means adding a searchable entity is a config/annotation change, not a new controller.

Search form type. Build a small SearchType with a single q text field plus optional filters. Bind it, use handleRequest, and pass the validated string onward. This gives you CSRF, trimming, and a natural place to normalize input before it reaches the parser.

Repository hooks for anything non-trivial. When a search needs a join (searching a related entity's name), sorting by a computed value, or a WHERE ... IN restriction for permissions, do it in a custom repository method that accepts the search criteria and applies them to a QueryBuilder the bundle started. Don't try to express relational logic in the query string.

Reusable filter/expression handlers. If the bundle exposes operator or expression extension points (check for tagged services or an expression-handler interface), register app-specific operators there — e.g. is:active, owner:me, date ranges. This keeps the query-string grammar expressive without forking the package.

Result decoration. The bundle returns entities, not view models. Map to arrays/DTOs in the controller or a transformer if your templates need highlighting, snippets, or computed display fields — and if you want match highlighting, do it yourself; there's no relevance scoring or snippet extraction here.

Gotchas and Tips

  • It is abandoned. Last release April 2014, Symfony 2 era, zero dependents. Treat it as frozen code you own. Pin the exact commit in composer.json and vendor-fork it if you need a fix, because upstream PRs are not going to land.
  • Annotation cache bites constantly. After adding or renaming a searchable annotation, cache:clear (and in dev, warmup) before debugging. "My field isn't searchable" is almost always a stale metadata cache, not a bug.
  • DQL injection via field names. The query string contains user-controlled field identifiers. Verify the parser validates field names against the annotated whitelist before interpolating into DQL. If it doesn't, add a validation layer — an unrecognized field should throw, not reach the QueryBuilder verbatim.
  • Strict grammar, poor error messages. Users will type unbalanced quotes, trailing operators, or bare colons. Wrap the parse in a try/catch, degrade to a plain full-text-ish search or a friendly "couldn't parse your query" message, and never let a parser exception 500 the page.
  • URL-encode operators. :, >, <, quotes, and spaces in the query string need proper encoding in links and forms. Half of "search is broken" reports are the browser or a hand-built link mangling the expression.
  • No ranking, no full-text index. This is a Doctrine QueryBuilder generator, not a search engine. Performance is entirely your database's indexes. Add indexes on the columns you annotate, and for large tables prefer LIKE 'term%' over LIKE '%term%', or accept that you need Elasticsearch/Algolia.
  • Debugging tip: dump the generated DQL ($qb->getDQL() and getParameters()) before executing. The Doctrine profiler in the Symfony web toolbar shows the SQL, but the DQL is what tells you whether the parser interpreted your query the way you intended.
  • Extension points: look for the search manager service, the metadata/annotation reader, and any expression-handler or operator registry. Overriding the manager service definition in your app's services.yml is usually cleaner than subclassing, and lets you inject app-specific defaults (page size, default sort, field whitelist).
  • Symfony 3/4 migration: you'll need to convert service definitions to autowiring, drop AppKernel registration for a bundle-less config, and verify the annotation reader still works with modern Doctrine annotations. Budget for a replacement (Doctrine filters, a custom QueryBuilder service, or a real search engine) rather than a port.
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.
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
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect