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

Quick Admin Generator Bundle Laravel Package

arkounay/quick-admin-generator-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require arkounay/quick-admin-generator-bundle
    

    Add to config/bundles.php and run php bin/console qag:install.

  2. First CRUD Controller:

    // src/Controller/Admin/CategoryController.php
    namespace App\Controller\Admin;
    use App\Entity\Category;
    use Arkounay\Bundle\QuickAdminGeneratorBundle\Controller\Crud;
    
    class CategoryController extends Crud {
        public function getEntity(): string { return Category::class; }
    }
    
  3. Access Admin Panel: Visit /admin/category (or your configured prefix). The bundle auto-generates routes, forms, and listings.

First Use Case: Quick Entity Management

  • Create a new entity (e.g., Product) with Doctrine annotations.
  • Extend Crud in a controller for Product.
  • Access /admin/product to see auto-generated CRUD operations (list, create, edit, delete).

Implementation Patterns

1. Controller Customization

Workflow:

  • Extend Crud for each entity.
  • Override methods like getName(), getIcon(), or getBadgeNumber() for metadata.
  • Example:
    class ProductController extends Crud {
        public function getName(): string { return 'Shop Product'; }
        public function getIcon(): ?string { return 'package'; }
        public function getBadgeNumber(): ?int { return $this->repository->count(['stock' => 0]); }
    }
    

2. Field Configuration

Patterns:

  • Attributes: Use #[QAG\Field], #[QAG\HideInList], etc., on entity properties.
    #[ORM\Column]
    #[QAG\Field(label: 'Product Name', help: 'Display name for customers')]
    private $name;
    
  • Controller Overrides: Dynamically configure fields in getListingFields() or getFormFields().
    protected function getListingFields(): Fields {
        return parent::getListingFields()
            ->remove('description')
            ->add('price', 'currency', ['currency' => 'EUR']);
    }
    

3. Permissions & Security

Integration Tips:

  • Use isGranted() in permission methods:
    public function isEditable($entity): bool {
        return $this->isGranted('ROLE_EDITOR') && $entity->getUser()->getId() === $this->getUser()->getId();
    }
    
  • Leverage Symfony’s voter system for complex logic.

4. Filters & Query Builder

Workflow:

  • Add filters via getFilters():
    protected function getFilters(): Filters {
        return parent::getFilters()->add('createdAt')->add('category');
    }
    
  • Customize queries in getListQueryBuilder():
    protected function getListQueryBuilder(): QueryBuilder {
        return parent::getListQueryBuilder()->andWhere('e.isActive = true');
    }
    

5. Dependency Injection

Best Practices:

  • Inject services in __construct():
    public function __construct(private MailerInterface $mailer) {}
    
  • Use services in actions:
    public function sendNotificationAction($entity) {
        $this->mailer->send(...);
    }
    

6. Twig Overrides

Extension Points:

  • Override Twig blocks in your templates (e.g., blocks/list_row.html.twig).
  • Example: Customize the list row for a Product:
    {% block product_list_row %}
        <tr>
            <td>{{ product.name }}</td>
            <td class="text-success">{{ product.price|currency }}</td>
        </tr>
    {% endblock %}
    

Gotchas and Tips

Pitfalls

  1. Route Conflicts:

    • Ensure getRoute() returns unique values to avoid conflicts.
    • Debug with php bin/console debug:router | grep qag.
  2. Field Configuration Overrides:

    • Attributes (e.g., #[QAG\Field]) are merged with controller overrides. Explicitly remove() fields if needed:
      $fields->remove('createdAt'); // Overrides attribute-based inclusion.
      
  3. Security Bypass:

    • If hasQuickListQueryBuilderSecurity() is false, users can access filtered-out entities via direct URLs. Always enable it for filtered queries:
      protected function hasQuickListQueryBuilderSecurity(): bool { return true; }
      
  4. Circular Dependencies:

    • Avoid injecting controllers into each other. Use services or the entity manager instead.
  5. Twig Caching:

    • Clear cache after modifying Twig templates:
      php bin/console cache:clear
      

Debugging Tips

  • Log Queries: Enable Doctrine logging in config/packages/dev/doctrine.yaml:
    doctrine:
        dbal:
            logging: true
            profiling: true
    
  • Check Events: Listen to qag.events.entity_to_string or qag.events.field_config for debugging field rendering:
    $event->getSubject(); // Entity instance
    $event->getArgument('response'); // Current __toString value
    

Performance Quirks

  1. Eager-Loading:

    • Use ->leftJoin() in getListQueryBuilder() to avoid N+1 queries for relationships:
      $qb->leftJoin('e.category', 'c');
      
  2. Batch Actions:

    • Disable for large datasets by overriding isBatchDeletable():
      public function isBatchDeletable(): bool { return $this->repository->count([]) < 1000; }
      

Extension Points

  1. Custom Actions:

    • Add actions via getActions():
      protected function getActions(): array {
          return array_merge(parent::getActions(), [
              'publish' => [
                  'type' => 'button',
                  'label' => 'Publish',
                  'icon' => 'brand-github',
                  'action' => 'publishAction',
              ],
          ]);
      }
      
  2. Event Listeners:

    • Subscribe to qag.events.pre_create or qag.events.post_update for pre/post hooks:
      public static function getSubscribedEvents(): array {
          return [
              'qag.events.pre_create' => 'onPreCreate',
          ];
      }
      
  3. Abstract Controllers:

    • Create a base controller for shared logic (e.g., SoftDeletableCrud):
      abstract class SoftDeletableCrud extends Crud {
          public function isDeletable($entity): bool {
              return !$entity->isDeleted();
          }
      }
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui