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

Lister Bundle Laravel Package

povs/lister-bundle

povs/lister-bundle offers a reusable list-building layer for PHP apps, letting you define columns, filters, sorting, and pagination for query results and render consistent, configurable list views for admin panels and search pages.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to internalize: this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/lister.php. A Laravel developer's "day-to-day leverage" falls into two realistic tracks — (a) you maintain a legacy Symfony app alongside Laravel and want the lister there, or (b) you want to borrow the pattern and re-implement it natively in Laravel. Attempting composer require povs/lister-bundle inside a modern Laravel app is the wrong first move; its Symfony 2/3-era constraints will fight with illuminate/* and modern PHP.

Minimal steps:

  1. Read composer.json first. Check PHP and symfony/* version pins. If it's ~2.3 or ~2.8, treat it as reference code, not a dependency.
  2. Find the core, not the bundle plumbing. Look in Lister/ (or Model/, Manager/) for the base lister class and any ListerManager. That class is the portable part — pagination, sort, filter, export logic. Everything in DependencyInjection/, Resources/config/services.yml, and the bundle class itself is Symfony wiring you won't reuse.
  3. Identify the Doctrine coupling. The lister almost certainly wraps a QueryBuilder. Map that concept to Laravel's Illuminate\Database\Eloquent\Builder + LengthAwarePaginator.
  4. First use case to target: a paginated, sortable, filterable admin index with a CSV export button. That is exactly the bundle's stated sweet spot and the cleanest thing to reproduce.

If you're on the Symfony side: register the bundle in AppKernel, define a lister service pointing at a Doctrine query builder, and pass request params in. If you're on Laravel: skip step 4's install entirely and port the class into app/Support/Listing/.

Implementation Patterns

Adapter around the lister, not direct use. Wrap the lister behind your own interface (ListingInterface with paginate(), sort(), filter(), export()). This lets you start with ported code and swap to native Laravel pagination later without touching controllers.

Query-builder-first, params-second. The idiomatic flow is: build the base query (Doctrine QB / Eloquent builder) → hand it to the lister with a validated params object → lister applies order, offset/limit, and where-clauses → returns rows plus page metadata. Keep the params object validated before it reaches the lister.

Sorting via whitelist. Never pass a raw ?sort= column into the lister. Maintain an explicit map:

$sortable = ['name' => 'users.name', 'created' => 'users.created_at'];
$column = $sortable[$request->sort] ?? 'users.id';
$direction = $request->direction === 'desc' ? 'desc' : 'asc';

Filtering as composable clauses. Mirror the bundle's filter concept with small filter classes or when() chains. Each filter is a (Builder $q, mixed $value): Builder unit — testable independently and reusable between the lister and plain controllers.

Chunked export. Export is where naive ports explode. Always pull the unpaginated query through chunkById(1000) (Laravel) or iterate() (Doctrine) and stream the response:

return response()->streamDownload(function () use ($query) {
    $out = fopen('php://output', 'w');
    $query->chunkById(1000, function ($rows) use ($out) {
        foreach ($rows as $row) fputcsv($out, [...]);
    });
    fclose($out);
}, 'export.csv');

Config-driven listers. The bundle's real value is the idea of declaring per-entity listing config (columns, sortable fields, filters, export format) once and reusing it across index/export/API endpoints. Reproduce that with a small config array or a Lister subclass per entity.

Integration tip — request decoupling. If ported code expects a Symfony Request or returns a Symfony Response, convert at the boundary. Your controller should hand in a plain array of params and receive a LengthAwarePaginator/array — nothing Symfony-shaped should leak into Laravel-land.

Gotchas and Tips

  • Dependency conflicts are the default, not the exception. PHPExcel (dead since 2019) is the usual export dependency in bundles of this vintage; it will not install cleanly on PHP 8. Use league/csv + fputcsv instead.
  • No auto-discovery. Nothing will be registered for you. Any use in Laravel requires manual bind()/singleton() wiring, and the lister may expect container-injected dependencies (entity manager, request stack) you must supply by hand.
  • Pagination metadata is likely Symfony-coupled. Expect a paginator object that knows about Request query strings. Extract total, perPage, currentPage into your own DTO before hitting the view.
  • Param names are opinionated. The bundle probably reads fixed keys (page, sort, order, limit). If your frontend uses sortBy/dir, normalize in a request-mapping layer rather than patching the lister.
  • Debugging: dump the generated query, not the results. Doctrine: $qb->getQuery()->getSQL() with getDQL() for params. Laravel equivalent: ->toSql() + ->getBindings(). Most "wrong page" bugs are offset math or a missing distinct() on a join.
  • Export memory blowups. Unbounded getResult() on a large table will OOM. The bundle may not chunk for you — verify, and if it doesn't, don't trust its exporter.
  • Extension points to inspect: the base lister class (subclass for per-entity behavior), any filter/export driver interfaces, and the DI config for overridable service aliases. Those are the seams you'd repurpose; the controllers and Twig templates are not.
  • Maintenance reality check: 1 star, 0 dependents, Symfony 2-era. Do not add it as a production dependency in a Laravel app. Fork the lister class, strip the bundle wiring, and vendor ~200 lines into app/Support/Listing/ — you get the design without the dead dependency graph.
  • Test the port against edge cases immediately: page 0 / page beyond last, empty sort, filters with nulls, and a sort + pagination + export combination. Those are exactly where hand-ported listing code breaks.
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.
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
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core