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

Adminlist Bundle Laravel Package

kunstmaan/adminlist-bundle

KunstmaanAdminListBundle provides a reusable admin list abstraction for Kunstmaan bundles, letting you define list classes with configurable columns, filters, sorting, pagination, and batch actions to render consistent backend overviews with minimal code.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony 2 bundle, not a Laravel package. If you're coming from Laravel, the closest analogues are Filament, Nova, or Backpack: it renders a paginated, filterable, sortable, CSV-exportable table over a Doctrine entity, plus optional add/edit/delete links. You will only touch it when maintaining a Kunstmaan CMS 2.x site — there is no bridge, and the concepts (service container, Twig, Doctrine QueryBuilder, ACL) do not translate one-to-one.

Minimal path:

  1. Pin the dependency. composer require kunstmaan/adminlist-bundle and then lock the exact 2.x version you get, because the public API moved around between point releases.
  2. Register KunstmaanAdminListBundle in AppKernel::registerBundles(), after KunstmaanAdminBundle — the list templates extend the admin layout, use its menu adaptors, and expect its security helpers to be present.
  3. Create a list class extending AbstractAdminList (or implement AdminListInterface directly) that declares getFields(), getFilters(), getActions(), getExportFields(), and points at an entity.
  4. Expose it from a controller: instantiate via the kunstmaan_adminlist.factory service, call bindRequest($request) so filters/sort/page are read from the query string, and hand it to the template.
  5. Render it by including the bundle's list template from your admin page.
// Controller
public function indexAction(Request $request)
{
    $list = $this->get('kunstmaan_adminlist.factory')->createList(
        new ProductAdminList($this->getDoctrine()->getManager())
    );
    $list->bindRequest($request);

    return $this->render('AppBundle:Admin/Product:index.html.twig', ['adminlist' => $list]);
}
{% extends 'KunstmaanAdminBundle:Default:layout.html.twig' %}
{% block content %}
    {% include 'KunstmaanAdminListBundle:AdminList:list.html.twig' %}
{% endblock %}

Where to look first: the bundle's AdminList/ directory (interface, abstract base, field/filter classes, item actions, bulk actions) and Resources/views/AdminList/. Class names and namespace paths shifted across 2.x releases — grep the vendored code before trusting any tutorial, including this one.

First use case: a read-only report over one entity with a text filter and a CSV export. That exercises every moving part (query building, filter binding, pagination, export) without the ACL and form complexity of full CRUD.

Implementation Patterns

Read-only report list. Extend AbstractAdminList, pass the entity FQCN, add string/date/boolean filters, declare getExportFields(), and return null from getEditUrl() / getDeleteUrl() so no row actions render. This is the pattern that actually earns its keep — it's the least coupled to the rest of the Kunstmaan stack.

CRUD admin list. Implement getAddUrl(), getEditUrl($item), getDeleteUrl($item). These are plain URLs, so wire them to your own controllers; the bundle does not generate CRUD scaffolding for you. Add a RouteItemAction / SimpleItemAction per row for domain operations ("publish", "resend", "duplicate").

Bulk actions. Implement BulkActionInterface::getUrl()/getLabel(). The list template renders checkboxes and POSTs the selected IDs to your route; you own the loop, the transaction, and the flash message. Keep bulk actions idempotent — double submits are common in old admin UIs.

Scoping the query. Override the query-builder hook rather than post-filtering in PHP. This is where you add joins (avoid N+1 on columns rendered per row), tenant/owner constraints, and soft-delete conditions. Anything you filter in PHP after getItems() will break both getCount() and the CSV export.

Export extension. getExportFields() is typically a list of property names resolved through getters. The bundle streams CSV. If you need XLS or a different column order, override the export action/service rather than patching the template. Verify the export respects the current filters; that's the usual bug report.

Menu and permissions. Register the page in the admin sidebar via the Kunstmaan menu adaptor, and gate both the controller and each row action with the ACL PermissionMap. The list itself enforces nothing — hiding an action in Twig is cosmetic; check permission server-side in the target route.

Custom filter types. The extension point is a filter-type class implementing the bundle's filter interface, translating the submitted value into andWhere/setParameter on the QueryBuilder. Write one whenever a filter needs a join (searching a relation) instead of a plain column.

Gotchas and Tips

  • It's abandoned. Last release 2014, 20 stars, zero dependents. Symfony 2 is EOL and unpatchable. Treat this strictly as maintenance work on legacy sites; do not start new features on it, and budget for a migration path out (Symfony 4+/EasyAdmin, or off PHP entirely).
  • Pin the exact version. The bundle's API churned (AbstractAdminList versus configurator/factory-style list definitions). A composer update that floats the constraint can rename half your overridden methods.
  • getCount() diverges from getItems(). With GROUP BY/HAVING or a join that multiplies rows, the count is wrong and pagination lies. Implement getCount() as its own scalar count query — don't clone the list query.
  • Sorting is an injection surface. The sort/order query parameters feed addOrderBy() directly. Whitelist sortable column names against the fields you declared; never pass raw request input into DQL.
  • Filter state lives in the query string. Pagination and sort links must carry the current filters forward. If you customize pagination or the filter form, verify the links preserve filters[...] — otherwise page 2 silently drops the filter and shows different data.
  • CSV is a real security concern. Guard against formula injection (values starting with =, +, -, @) and prefix a UTF-8 BOM if the file is opened in Excel. Also confirm the streamed response isn't buffered into memory on large tables.
  • Entity alias coupling. Field names are assumed to resolve against the query-builder alias (often e). Custom joins need consistent aliases, or columns render blank. When a column is empty, dump $qb->getDQL() first.
  • getEditUrl()/getDeleteUrl() returning null is the intended way to suppress actions — not a template conditional.
  • ACL is opt-in. AbstractAdminList does no permission checks. New rows in the admin menu will happily let a user with no rights hit the route.
  • Template overrides go in app/Resources/KunstmaanAdminListBundle/views/. You must clear the Twig cache after copying a template down, or you'll debug a file that isn't being rendered.
  • Translations run through the admin translation domain; missing keys render raw keys in the UI, which is usually the first symptom that the bundle's resources weren't loaded.
  • Debugging toolkit: the Symfony profiler's Doctrine panel plus a temporary error_log($qb->getDQL() . ' ' . json_encode($qb->getParameters())) in the query hook. Most "filters don't work" bugs are a parameter that never got bound.
  • Testing is awkward. The list is tightly coupled to Request and EntityManager. Favor a functional test with fixtures that asserts filtered row counts over unit tests; mock the request only for the filter-binding logic.
  • Extension points worth knowing: custom filter types, custom item/bulk action classes, getExportFields() overrides, and Twig template overrides. Everything else means subclassing the abstract list and accepting upgrade pain later.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource