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

puntmig/search-bundle

PuntMig SearchBundle integrates full-text search into Symfony apps, letting you index records and run configurable queries through a simple service. It keeps search logic out of controllers, supports paginated results, and offers a lightweight adapter-based setup for fast, flexible discovery.

View on GitHub
Deep Wiki
Context7

Getting Started

puntmig/search-bundle is the Symfony-Drift rewrite of the Apisearch Symfony bundle: it lets one bundle definition run across Symfony 3.4 → 5.x, delegating version-specific plumbing to the symfony-drift helper classes. It was archived in September 2021, so treat it as something to read before maintaining an existing install rather than a package to adopt for new work — for greenfield projects start from the official Apisearch PHP client and wire it yourself.

Minimum steps:

  1. Install:
    composer require puntmig/search-bundle
    
  2. Register the bundle:
    • Symfony 4/5: Puntmig\SearchBundle\PuntmigSearchBundle::class => ['all' => true] in config/bundles.php.
    • Symfony 3.4: register in app/AppKernel.php.
  3. Configure the connection — the exact schema lives in DependencyInjection/Configuration.php; read that file first, the README is thin:
    # config/packages/puntmig_search.yaml
    puntmig_search:
        app_id:  "%env(APISEARCH_APP_ID)%"
        api_key: "%env(APISEARCH_API_KEY)%"
        endpoint: "%env(APISEARCH_ENDPOINT)%"
        index:    "default"
    
  4. Before writing any application code, open the bundle's Resources/config/services.*.yml and DependencyInjection/PuntmigSearchExtension.php. The registered service ids and aliases (typically puntmig_search.repository, puntmig_search.client, plus an alias on Apisearch\Repository\Repository) are what you will actually autowire — there is no other reliable contract.
  5. First use case — index and query from a command:
    use Apisearch\Query\Query;
    
    public function __invoke(Repository $repository): void
    {
        $repository->addObject($myEntity);          // runs the indexing pipeline
        $result = $repository->query(Query::create('*')->paginate(1, 20));
    }
    

Implementation Patterns

Inject the repository, not the client. The bundle's job is service wiring; autowire Apisearch\Repository\Repository and let Apisearch's own APIs do the work. Reach for the raw client only for admin operations (creating indices, resetting, snapshots) that the repository abstraction doesn't expose.

Multiple indices/repositories. The bundle supports more than one named repository (each with its own app_id/index) so multi-tenant search works out of the box. In practice you either (a) inject the default and accept a single index per app, or (b) add a small factory service that pulls the named puntmig_search.repository.<name> per tenant. If you go with (b), pin the service ids in your own config rather than relying on stringly-typed Container::get() lookups — the ids are not considered public API.

Indexing pipeline / event subscribers. Apisearch ships an event-driven IndexBuilder. Subscribe to it (tag your subscriber as an Apisearch subscriber in the bundle's DI, usually apisearch.event_subscriber or the bundle-specific equivalent — check services.yml) to transform, normalize, or drop documents just before they hit the index. This is the pattern for adding soft-delete filters, denormalizing relations, or enriching documents with computed fields, and it keeps that logic out of your entities.

Query building. Use Query::create(...) for simple cases and QueryBuilder when you need filters, aggregations, sorting, or facet configuration. Keep search queries in a dedicated service behind an interface (ProductSearcher) rather than scattering query construction through controllers — the API is churny and you want a single seam to swap in tests.

Testing. Don't boot the bundle in unit tests. Type-hint Apisearch\Repository\Repository in your own services and inject an in-memory fake (ArrayRepository style) in services_test.yaml. For integration tests against a real Apisearch instance, override puntmig_search.endpoint via the test config and reset the index in setUp.

Symfony-Drift awareness. If you extend the bundle with your own commands or config, mirror the Drift pattern (extend the drift base classes rather than Command directly) so your additions stay 3.4/4/5-compatible. If you don't need that matrix, ignore Drift entirely and just use the modern Symfony APIs — nothing in the runtime enforces it.

Gotchas and Tips

  • Archived status is the biggest gotcha. The last release (2021-09-22) predates Symfony 6 and PHP 8.2+. Composer will resolve against legacy Symfony-Drift versions; expect conflicts on modern stacks. If you must install, pin your Symfony version and avoid --ignore-platform-reqs unless you understand the failure mode — it hides PHP-level incompatibilities that surface at runtime.
  • Read Configuration.php before you touch YAML. The config keys are the contract, and the README has not kept up. Misnamed keys silently default rather than erroring — a common source of "it's connecting to localhost:8100 despite my config."
  • API key format. Apisearch's app credentials are an app_id/api_key pair; some setups concatenate them as app_id:api_key. Don't do it twice — supply each value separately as the config schema expects.
  • Endpoint trailing slash and scheme. http://host:8100 and http://host:8100/ are not interchangeable for some client builds. Normalize in your env var.
  • Symfony 3.4 config location. app/config/config.yml, not config/packages/. The bundle runs on both, but the docs and examples skew modern.
  • Private services. If autowiring Apisearch\Repository\Repository fails, add an alias in your app config rather than making the bundle's service public:
    services:
        Apisearch\Repository\Repository: '@puntmig_search.repository'
    
  • Debugging. Point Apisearch at a local container so you can watch the HTTP calls; the client swallows useful detail behind generic Apisearch\Exception\* exceptions. Catch and log at your repository wrapper with the request body included.
  • Extension points you can rely on. Decorate puntmig_search.repository in your own bundle for retries, audit logging, or per-tenant routing — that's stable regardless of the underlying Apisearch version. Avoid subclassing the DI extension; you'll re-do it if Drift is ever updated.
  • Don't build new features on it. For a new project, use apisearch-io/search-bundle (upstream) or wire apisearch-io/php-client yourself. This fork's value is the 3.4→5.x compatibility matrix, which is exactly the thing that is no longer evolving.
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