Weave Code
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

admin-panel/admin-bundle

Admin Bundle is a simple Symfony admin generator for building entity lists and custom actions. Supports Doctrine ORM and Doctrine DBAL. Versioned by Symfony branch (2.7+ and 3.x), with documentation in the doc/ directory.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require admin-panel/admin-bundle
    

    For Symfony 3.0+:

    composer require admin-panel/admin-bundle:^3.0
    
  2. Enable the Bundle Add to config/bundles.php:

    AdminPanel\AdminBundle\AdminPanelAdminBundle::class => ['all' => true],
    
  3. Configure Database Connection Update config/packages/admin_panel_admin.yaml (auto-generated):

    admin_panel_admin:
        connection: default # or your custom Doctrine connection name
    
  4. First Admin Controller Generate a CRUD controller for an entity (e.g., User):

    php bin/console generate:admin:crud --entity=App\Entity\User
    

    This creates:

    • A controller (src/Controller/Admin/UserCrudController.php)
    • A Twig template (templates/admin/user/crud/index.html.twig)
    • A route (/admin/user)
  5. Access the Admin Panel Visit /admin/user in your browser. The bundle auto-generates:

    • List view with pagination
    • Basic CRUD operations (create, edit, delete)
    • Search/filter functionality

First Use Case: Extending a Generated CRUD

Modify the auto-generated controller to add a custom action (e.g., suspend):

// src/Controller/Admin/UserCrudController.php
use AdminPanel\AdminBundle\Action\ActionManager;
use AdminPanel\AdminBundle\Action\Actions;
use AdminPanel\AdminBundle\Action\CrudAction;

class UserCrudController extends AbstractCrudController
{
    public function configureActions(): Actions
    {
        return Actions::create()
            ->add(CrudAction::new()->setRoute('edit'))
            ->add(CrudAction::new('suspend')
                ->setIcon('fa-ban')
                ->setLabel('Suspend')
                ->setCallback([$this, 'suspendUser'])
            );
    }

    public function suspendUser(User $user): void
    {
        $user->setIsActive(false);
        $this->getEntityManager()->flush();
        $this->addFlash('success', 'User suspended');
        return $this->redirectToRoute('admin_user_index');
    }
}

Implementation Patterns

1. Entity Configuration

Define admin-specific metadata for your entity via annotations or YAML:

# config/admin_panel_admin.yaml
admin_panel_admin:
    entities:
        App\Entity\User:
            list:
                fields: [id, email, username, createdAt]
                max_per_page: 20
            form:
                fields: [email, username, roles, isActive]
                validation_groups: [Default, 'admin']

Key Annotations (alternative to YAML):

use AdminPanel\AdminBundle\Annotation\Admin;

/**
 * @Admin\Config(
 *     list = @Admin\ListConfig(fields = {"id", "email"}),
 *     form = @Admin\FormConfig(fields = {"email", "username"})
 * )
 */
class User {}

2. Dynamic Field Rendering

Customize how fields are displayed in lists/forms:

// src/Controller/Admin/UserCrudController.php
protected function configureListFields(): array
{
    return [
        'id' => ListField::new('id')->setLabel('ID'),
        'email' => ListField::new('email')->setLabel('Email Address'),
        'roles' => ListField::new('roles')
            ->setTemplate('admin/user/fields/roles.html.twig')
            ->setLabel('Permissions'),
        'createdAt' => ListField::new('createdAt')
            ->setType('datetime')
            ->setLabel('Registered')
    ];
}

Twig Template Example (templates/admin/user/fields/roles.html.twig):

{% for role in object.roles %}
    <span class="label label-{{ role === 'ROLE_ADMIN' ? 'danger' : 'primary' }}">
        {{ role }}
    </span>
{% endfor %}

3. Bulk Actions

Add bulk operations to the list view:

public function configureActions(): Actions
{
    return Actions::create()
        ->add(BulkAction::new('delete')
            ->setIcon('fa-trash')
            ->setLabel('Delete Selected')
            ->setCallback([$this, 'deleteSelectedUsers'])
        );
}

public function deleteSelectedUsers(Request $request): Response
{
    $ids = $request->request->get('ids', []);
    $users = $this->getEntityManager()->getRepository(User::class)->findBy(['id' => $ids]);

    foreach ($users as $user) {
        $this->getEntityManager()->remove($user);
    }
    $this->getEntityManager()->flush();

    return $this->redirectToRoute('admin_user_index');
}

4. Integration with Symfony Forms

Extend the default form with custom fields:

protected function configureFormFields(): array
{
    return [
        'email' => FormField::new('email')
            ->setType('email')
            ->setLabel('Email'),
        'password' => FormField::new('plainPassword')
            ->setType('password')
            ->setLabel('Password')
            ->setRequired(false),
        'roles' => FormField::new('roles')
            ->setType('entity')
            ->setClass('App\Entity\Role')
            ->setMultiple(true)
            ->setLabel('Roles')
    ];
}

5. Access Control

Restrict admin routes via Symfony security:

# config/packages/security.yaml
access_control:
    - { path: ^/admin/, roles: ROLE_ADMIN }

Or per-controller:

// src/Controller/Admin/UserCrudController.php
public function __construct()
{
    $this->denyAccessUnlessGranted('ROLE_ADMIN');
}

6. Custom Templates

Override default templates by copying them from:

vendor/admin-panel/admin-bundle/Resources/views/

to:

templates/admin_panel_admin/

Gotchas and Tips

1. Doctrine Connection Mismatch

  • Gotcha: If your Doctrine connection name isn’t default, configure it in admin_panel_admin.yaml:
    admin_panel_admin:
        connection: my_custom_connection
    
  • Tip: Verify the connection name with:
    php bin/console doctrine:database:list-connections
    

2. Field Type Conflicts

  • Gotcha: The bundle auto-detects field types, but custom Doctrine types may cause errors. Example: If using Gedmo\Timestampable\TimestampableEntity, ensure the field is mapped correctly.
  • Tip: Explicitly set the field type in the controller:
    ListField::new('createdAt')->setType('datetime')
    

3. Pagination Issues

  • Gotcha: Pagination may break if the max_per_page is set too low or if the query is complex.
  • Tip:
    • Default max_per_page is 30. Adjust in YAML or controller:
      admin_panel_admin:
          entities:
              App\Entity\User:
                  list:
                      max_per_page: 50
      
    • For complex queries, override configureListQuery():
      protected function configureListQuery(): QueryBuilder
      {
          return $this->createQueryBuilder('u')
              ->where('u.isActive = :active')
              ->setParameter('active', true);
      }
      

4. CSRF Token Errors

  • Gotcha: Bulk actions or custom forms may fail with CSRF errors if the token isn’t included.
  • Tip: Ensure your form includes the CSRF token:
    {{ form_start(form, { attr: { 'data-csrf-token': app.request.csrfToken } }) }}
    
    Or for bulk actions, pass the token via JavaScript:
    const token = document.querySelector('meta[name="csrf-token"]').content;
    fetch('/admin/user/bulk-delete', {
        method: 'POST',
        headers: { 'X-CSRF-Token': token },
        body: JSON.stringify({ ids: selectedIds })
    });
    

5. Translation Missing

  • Gotcha: Labels/actions may not translate if the bundle’s translation files aren’t loaded.
  • Tip:
    • Load translations in your config/packages/translation.yaml:
      imports:
          - { resource: '@AdminPanelAdminBundle/Resources/config/translation.yaml' }
      
    • Add custom translations to translations/messages.en.yaml:
      admin:
          user:
              suspend: 'Deactivate Account'
      

6. Performance with Large Datasets

  • Gotcha: Lists with many records may slow down due to eager-loading.
  • Tip:
    • Use ->addSelect() in configureListQuery() to limit loaded fields:
      $qb = $this->createQueryBuilder('u');
      return $qb->addSelect(['u.id', 'u.email',
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware