alterphp/easyadmin-extension-bundle
composer require alterphp/easyadmin-extension-bundle
config/bundles.php:
AlterPHP\EasyAdminExtensionBundle\EasyAdminExtensionBundle::class => ['all' => true],
easy_admin.yaml routes with:
easy_admin_bundle:
resource: '@EasyAdminExtensionBundle/Controller/EasyAdminController.php'
type: annotation
prefix: /admin
Configure filters for an entity (e.g., Animation) in config/packages/easy_admin.yaml:
easy_admin:
entities:
Animation:
class: App\Entity\Animation
list:
form_filters:
- enabled
- { property: type, type_options: { choices: { Challenge: 'challenge', Event: 'event' } } }
Result: A filter form appears above the list view.
form_filters for predefined filters (e.g., boolean, enum, or related entities).
list:
form_filters:
- { property: status, type_options: { choices_static_callback: [getValuesList, [status]] } }
ext_filters to URLs for runtime filtering:
/admin?action=list&entity=Book&ext_filters[entity.releaseDate]=2016
Note: Chaining filters requires array syntax:
ext_filters[entity.releaseDate][]=2015&ext_filters[entity.releaseDate][]=2016
type: embedded_list with auto-guessed options:
form:
fields:
- { property: events, type: embedded_list } # Auto-guesses `entity: Event`
type: embedded_list with template_options:
show:
fields:
- { property: events, type: embedded_list, template_options: { max_results: 5 } }
Tip: Use parent_entity_fqcn/parent_entity_property for custom filters.Enable creation of related entities via autocomplete:
form:
fields:
- { property: promoter, type: easyadmin_autocomplete, type_options: { attr: { create: true } } }
easy_admin_extension:
minimum_role: ROLE_ADMIN
entities:
Product:
list:
role: ROLE_ADMIN_PRODUCT_LIST
new:
role: ROLE_ADMIN_PRODUCT_NEW
Alias form types for cleaner YAML:
easy_admin_extension:
custom_form_types:
enum: App\Form\Type\EnumType
Usage:
form:
fields:
- { property: status, type: enum }
BC Break in ext_filters:
ext_filters (not filters) to avoid conflicts with EasyAdmin’s native dynamic filters.filters to ext_filters.Embedded List Guesser Limitations:
EmbeddedListHelper may fail for non-ORM fields (e.g., computed properties).entity_fqcn or parent_entity_property.Role Inheritance:
Template Overrides:
EasyAdminExtensionBundle:crud/embedded_list.html.twig).Filter Debugging:
ext_filters in the URL or Symfony’s Request object to verify dynamic filters.dump($this->get('easyadmin.extension.list_filter_manager')->getFilters()) in a controller to inspect active filters.Embedded List Issues:
list configuration exists in easy_admin.yaml.parent_entity_fqcn matches the actual entity class (case-sensitive).Permission Denied:
php bin/console cache:clear) after updating roles.ACL errors.Custom Filter Operators:
Extend AlterPHP\EasyAdminExtensionBundle\Model\ListFilter to add operators like between:
const OPERATOR_BETWEEN = 'between';
Override Templates:
Copy templates/crud/ from the bundle to templates/EasyAdminExtensionBundle/crud/ to customize embedded lists or modals.
Event Listeners:
Subscribe to easyadmin.extension.embedded_list.build to modify embedded list queries dynamically:
// src/EventListener/EmbeddedListListener.php
public function onBuildEmbeddedList(EmbeddedListEvent $event) {
$event->getQueryBuilder()->andWhere('e.status = :status')->setParameter('status', 'published');
}
Register in services.yaml:
services:
App\EventListener\EmbeddedListListener:
tags:
- { name: kernel.event_listener, event: easyadmin.extension.embedded_list.build, method: onBuildEmbeddedList }
Form Type Extensions:
Extend AlterPHP\EasyAdminExtensionBundle\Form\Type\EmbeddedListType to add custom options or validation.
max_results or lazy-load via template_options: { pagination: { items_per_page: 10 } }.choices_static_callback for large datasets; pre-compute values in the entity’s static method.validator to validate easy_admin.yaml:
# config/packages/validator.yaml
services:
App\Validator\Constraints\EasyAdminConfig:
tags: [validator.constraint_validator]
Example Constraint:
public function validate($value, Constraint $constraint) {
if (!isset($value['entities']['Product']['list']['form_filters'])) {
$this->context->buildViolation('Missing form_filters for Product')
->atPath('[entities][Product][list]')
->addViolation();
}
}
How can I help you explore Laravel packages today?