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

Admin Bundle Laravel Package

open-dxp/admin-bundle

OpenDXP Admin Bundle provides the backend administration interface for OpenDXP applications, bundling management screens, navigation, and supporting services into a reusable PHP package. It helps teams integrate consistent admin workflows and operate application data more efficiently.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and register the bundle

composer require open-dxp/admin-bundle

Register it in config/bundles.php. Order matters — place it after the OpenDXP core/framework bundles so its routes and security extensions load last:

return [
    // ... OpenDXP core bundles ...
    OpenDxp\Bundle\AdminBundle\OpenDxpAdminBundle::class => ['all' => true],
];

2. Make sure the admin firewall exists

The bundle ships routes/controllers, but authentication is wired by your app. In config/packages/security.yaml, the admin firewall must be declared before your main site firewall, because Symfony matches firewalls in order:

security:
    firewalls:
        admin:
            pattern: ^/admin
            provider: open_dxp_users
            form_login:
                login_path: /admin/login
                check_path: /admin/login
            logout:
                path: /admin/logout
        main:
            pattern: ^/
            # ...

3. Import routes

Check whether a Flex recipe dropped config/routes/open_dxp_admin.yaml for you. If not, import the bundle's route file explicitly (inspect config/ inside the package for the exact resource path — it differs between the XML/YAML/PHP loader styles used across OpenDXP versions):

# config/routes/open_dxp_admin.yaml
open_dxp_admin:
    resource: '@OpenDxpAdminBundle/config/routes.yaml'
    prefix: /admin

4. First run

bin/console cache:clear
bin/console assets:install public --symlink
bin/console debug:router | grep admin

Then open /admin. If you get a 403/redirect loop, it is almost always the firewall pattern or a missing user provider — not the bundle.

Where to look first, in this order

  1. src/Controller/ — see what the base admin controller provides (layout variables, language/session handling, CSRF expectations).
  2. config/ — routes, services.yaml, security extensions, and any tagged-service/event declarations. This is the real API surface.
  3. templates/ — the layout(s) your own admin screens should extend.
  4. src/Event/ and src/EventListener/ — the menu/navigation/settings extension points (names follow the upstream Pimcore lineage; confirm by grepping for dispatch().
  5. CHANGELOG.md / git tags — with a single recent release and no published docs, this is your contract.

First use case to aim for: a custom admin screen inside an existing bundle that extends the admin layout, appears in the navigation, and is protected by the same ^/admin firewall. That exercises routing, templating, assets, auth, and translations in one pass.

Implementation Patterns

Pattern 1 — Adding a custom admin module

Keep it in your own bundle rather than patching the admin bundle:

// src/Controller/Admin/ReportController.php
#[Route('/admin/reports', name: 'app_admin_reports')]
class ReportController extends AbstractController
{
    public function index(): Response
    {
        return $this->render('@App/admin/reports/index.html.twig', [
            'stats' => $this->reportService->summarise(),
        ]);
    }
}

Extend the admin layout rather than base.html.twig so you inherit the chrome, asset includes, and locale switching:

{# templates/admin/reports/index.html.twig #}
{% extends '@OpenDxpAdminBundle/layout.html.twig' %}

{% block content %}
    <h1>{{ 'reports.title'|trans({}, 'admin') }}</h1>
    {{ include('@App/admin/reports/_table.html.twig') }}
{% endblock %}

Verify the actual layout path with bin/console debug:twig | grep -i admin — bundle template layout names are the single most common source of "template not found" during adoption.

Pattern 2 — Hooking into the admin navigation

Prefer events over overriding controllers. Subscribe to the navigation/settings event the bundle dispatches during the index action and append your entry:

class AdminNavigationSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [AdminIndexEvent::class => 'onAdminIndex'];
    }

    public function onAdminIndex(AdminIndexEvent $event): void
    {
        $event->addMenuItem([
            'label' => 'admin.nav.reports',
            'path'  => '/admin/reports',
        ]);
    }
}

Run bin/console debug:event-dispatcher to confirm the concrete event class and whether the handler receives a mutable collection or a dispatcher-scoped config array. If no event exists in your version, the fallback is a service tagged with the bundle's menu tag (declared in config/services.yaml) or a template override — in that order of preference.

Pattern 3 — Translations

Admin strings should live in the admin translation domain so they follow the user's backend locale, and stay separate from frontend strings:

# translations/admin.en.yaml
reports:
    title: 'Reports'

Pattern 4 — Shared identity with the frontend

The most common integration is a single User entity/provider serving both ^/admin and the public site, with roles gating the admin firewall. Keep the role check in an access control rule, not in controllers:

security:
    access_control:
        - { path: ^/admin/login, roles: PUBLIC_ACCESS }
        - { path: ^/admin, roles: ROLE_ADMIN }

Pattern 5 — Local development against the package

When you need to change or debug the bundle itself:

# in your app's composer.json, use a path repository
"repositories": [{ "type": "path", "url": "../admin-bundle" }]
composer require open-dxp/admin-bundle:"@dev"
bin/console assets:install public --symlink

Pattern 6 — Functional tests for admin screens

Symfony's loginUser() is far less brittle than driving the login form:

$client->loginUser($adminUser);
$client->request('GET', '/admin/reports');
self::assertResponseIsSuccessful();

Beware: admin pages often make XHR calls for grids/charts. Assert on the server-rendered shell, not on fully hydrated DOM.

Gotchas and Tips

License is NOASSERTION. This is the single biggest adoption risk. Read the actual LICENSE file in the repo and confirm the terms map to the OpenDXP project license before shipping commercially. Do not assume MIT.

Almost no downstream users (0 dependents, 3 stars). You will not find Stack Overflow answers. Budget for reading source, and pin an exact tag (composer require open-dxp/admin-bundle:^X.Y with a lockfile) rather than floating versions — the release date implies active development and there is no published BC policy.

Firewall order is the #1 operational failure mode. An admin firewall declared after main will silently never match, producing login redirect loops or 403s that look like bundle bugs. Confirm with bin/console debug:router admin_login and debug:firewall.

Route prefix collisions. If you import the bundle without a prefix, or a catch-all site route (/{slug}) is imported first, admin URLs get swallowed. Give admin routes the ^/admin prefix and import them early; check resolution with bin/console debug:router --show-controllers | grep admin.

Don't edit vendor/. For UI tweaks, use Symfony's bundle override convention:

templates/bundles/OpenDxpAdminBundle/<path-relative-to-bundle-templates>/...

Confirm the exact bundle namespace casing from getContainer()->getParameter('kernel.bundles'); a one-character namespace mismatch means your override is silently ignored.

Asset pipeline confusion. After composer update, admin CSS/JS 404s are almost always stale published assets. bin/console assets:install public --symlink then hard-refresh (browser cache holds old hashed bundles). In production, run it without --symlink and clear the HTTP cache in front of the app.

Config and translation caching. Changes to security.yaml or any bundle config require cache:clear in dev, and translation changes require cache:clear too. In prod, deploy must include cache:clear — a warm cache from the previous release will serve old admin service definitions.

CSRF on admin AJAX. Admin grids and inline-edit endpoints typically expect the session CSRF token. Extract it from a meta tag rendered in the layout and send it as a header; hardcoding a token or omitting it yields 419-style failures that look like auth problems.

Don't load admin assets on frontend routes. If the layout is accidentally inherited by a public template, you ship the entire backend JS bundle to anonymous users. Keep admin and site base templates strictly separate.

Extend via decoration or events, never by subclassing controllers. Controller internals are the least stable part of a UI bundle. If you must replace behaviour, decorate the service in services.yaml:

App\Admin\DecoratingFoo:
    decorates: open_dxp.admin.foo
    arguments: ['@.inner']

Debugging checklist when something breaks

bin/console debug:router | grep admin          # routing resolved?
bin/console debug:event-dispatcher             # is my subscriber registered?
bin/console debug:twig | grep -i admin         # is the layout visible?
bin/console debug:container --tag=<menu-tag>   # tagged services picked up?

Check var/log/dev.log for the underlying exception — a missing template, an unresolvable service argument, or a missing ROLE_ADMIN all surface as a generic 500/403 in the browser.

Treat the bundle as infrastructure, not application code. Put your admin customisations in a dedicated App\Admin namespace with its own controllers, templates, and subscribers. That keeps upgrades from the OpenDXP side to a composer update plus a diff review, rather than a merge conflict in a vendored file.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
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