alterphp/easyadmin-extension-bundle

This bundle provides some extensions to javiereguiluz/easyadmin-bundle

Installs: 25 628

Dependents: 3

Suggesters: 0

Stars: 115

Watchers: 19

Forks: 28

Open Issues: 7

Type:symfony-bundle


README

Latest Stable Version Build Status SensioLabsInsight Coverage Status License

EasyAdmin Extension provides some useful extensions to EasyAdmin admin generator for Symfony.

❗️ Branch 1.x of this bundle requires at least PHP 7.0 and Symfony 3.0 components or stack and is suitable for EasyAdmin 1.x.

❗️ Branch master of this bundle requires at least PHP 7.1 and Symfony 4.1 components or stack and is suitable for EasyAdmin 2.x.

Features

Installation

Step 1: Download the Bundle

$ composer require alterphp/easyadmin-extension-bundle

This command requires you to have Composer installed globally, as explained in the Composer documentation.

Step 2: Enable the Bundle

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new AlterPHP\EasyAdminExtensionBundle\EasyAdminExtensionBundle(),
        );
    }

    // ...
}

Step 3: Replace EasyAdmin controller

Instead of loading routes from EasyAdminBundle EasyAdminController, load them from EasyAdminExtensionBundle EasyAdminController.

# config/routes/easy_admin.yaml
easy_admin_bundle:
    resource: '@EasyAdminExtensionBundle/Controller/EasyAdminController.php'
    type:     annotation
    prefix:   /admin

# ...

If you have defined your own admin controllers, make them extend EasyAdminExtensionBundle EasyAdminController.

Features

Full width theme

New EasyAdmin theme based on Stripe fits content in a max-width body. In order to use as much space as possible, simply add following stylesheet in the design.assets.css config :

easy_admin:
    design:
        assets:
            css:
                - 'bundles/easyadmin/app.css'
                - 'bundles/easyadminextension/stylesheet/full-width.css'

List filters form

Add filters on list views by configuration.

Consider following Animation entity using such ValueListTrait :

class Animation
{
    use ValueListTrait;

    /**
     * @var string
     *
     * @ORM\Id
     * @ORM\Column(type="guid")
     */
    private $id;

    /**
     * @var bool
     *
     * @ORM\Column(type="boolean", nullable=false)
     */
    private $enabled;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=31)
     */
    protected $status;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=31, nullable=false)
     */
    private $type;

    /**
     * @var Organization
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Organization", inversedBy="animations")
     * @ORM\JoinColumn(nullable=false)
     */
    private $organization;

    const STATUS_DRAFT = 'draft';
    const STATUS_PUBLISHED = 'published';
    const STATUS_OPEN = 'open';
    const STATUS_ACTIVE = 'active';
    const STATUS_CLOSED = 'closed';
    const STATUS_ARCHIVED = 'archived';
}

Define your filters under list.form_filters entity configuration

easy_admin:
    design:
        assets:
            css:
                - 'bundles/easyadmin/bootstrap-all.css'
            js:
                # By default, EasyAdminBundle embeds a limited version of Bootstrap JS.
                # For collapsible form filters to work, a full version should be added:
                - 'bundles/easyadmin/bootstrap-all.js'
    entities:
        Animation:
            class: App\Entity\Animation
            list:
                form_filters:
                    - enabled
                    - { property: type, type_options: { choices: { Challenge: challenge, Event: event } } }
                    - { property: status, type_options: { choices_static_callback: [getValuesList, [status, true]] } }
                    - organization

Let's see the result !

Embedded list example

Guesser for list form filters are based on mapped entity property :

  • boolean: guessed filter is a choice list (null, Yes, No)
  • string: guessed filter is multiple choice list that requires either choices (value/label array) or choices_static_callback (static callback from entity class returning a value/label array) in type_options.
  • *-to-one-relation: guessed filter is a multiple autocomplete of relation target entity.

Filters form's method is GET and submitted through form_filter parameter. It is transmitted to the referer used for post update/delete/create redirection AND for search !

Filter list and search on request parameters

  • EasyAdmin allows filtering list with dql_filter configuration entry. But this is not dynamic and must be configured as an apart list in easy_admin configuration.*

This extension allows to dynamically filter lists by adding filters parameter in the URL parameters. Having a list of books at URL <url-to-admin>?action=list&entity=Book with a releaseYear field, you can filter on books releasd in 2016 by requesting <url-to-admin>?action=list&entity=Book&filters[entity.releaseDate]=2016. It only matches exact values, but you can chain them. To request books released in 2015 and 2016, you must request <url-to-admin>?action=list&entity=Book&filters[entity.releaseDate][]=2015&filters[entity.releaseDate][]=2016.

This filters parameter is transmitted to the referer used for post update/delete/create redirection AND for search !

Register your own form types with a short name (aliasing form types)

You have custom form types that you want to use in the EasyAdmin configuration. You can already register them with FQCN ... but it's quite boring and makes the admin massively enlarged. This feature allows you to define your own form types with short names, by configuration.

Let's see how to register them with those 2 examples (enum and statusable) :

easy_admin_extension:
    custom_form_types:
        enum: Admin\Form\Type\EnumType
        statusable: Admin\Form\Type\StatusableType

Embed lists in edit and show views

Edit view

Use pre-configured type embedded_list in the form definition :

easy_admin:
    entities:
        Event:
            class: App\Entity\Event
        Promoter:
            class: App\Entity\Promoter
            form:
                fields:
                    # ...
                    - { type: group, label: Events, css_class: 'col-sm-12', icon: calendar }
                    - { property: events, label: '', type: embedded_list, type_options: { entity: Event, filters: { 'entity.promoter': 'form:parent.data.id' } } }

But in many cases, the EmbeddedListHelper guesses type_options for you, and you just have to write :

easy_admin:
    entities:
        Event:
            class: App\Entity\Event
        Promoter:
            class: App\Entity\Promoter
            form:
                fields:
                    # ...
                    - { type: group, label: Events, css_class: 'col-sm-12', icon: calendar }
                    - { property: events, label: '', type: embedded_list }

Let's see the result !

Embedded list example

Show view

Using guesser for classic *ToMany relations :

easy_admin:
    entities:
        Event:
            class: App\Entity\Event
        Promoter:
            class: App\Entity\Promoter
            show:
                fields:
                    # ...
                    - { property: events, label: '', type: embedded_list }

Use following template_options to build your own embedded list (see field_embedded_list.html.twig) : entity_fqcn, parent_entity_property, filters, entity, sort.

Autocomplete add new option 'create' for modal in new and edit

Configure form type 'easyadmin_autocomplete', add type_options: { attr: { create: true } }

easy_admin:
    entities:
        Promoter:
            class: App\Entity\Promoter
        Event:
            class: App\Entity\Event
            form:
                fields:
                    # ...
                    - { property: 'promoter', type: 'easyadmin_autocomplete', type_options: { attr: { create: true } } }

Define access permissions

Global minimum role access

You can define a minimum role to access the EasyAdmin controller (any action handled by the controller) :

easy_admin_extension:
    minimum_role: ROLE_ADMIN

This is just a global restriction, that should live with a security firewall as described in Symfony documentation.

Per entity action role permissions

You can also define role permissions per entity action :

easy_admin:
    entities:
        Product:
            class: App\Entity\Product
            list:
                role: ROLE_ADMIN_PRODUCT_LIST
            search:
                role: ROLE_ADMIN_PRODUCT_SEARCH
            new:
                role: ROLE_ADMIN_PRODUCT_NEW
            edit:
                role: ROLE_ADMIN_PRODUCT_EDIT
            show:
                role: ROLE_ADMIN_PRODUCT_SHOW
            delete:
                role: ROLE_ADMIN_PRODUCT_DELETE

Above configuration define a required role per action for Product entity. This is too verbose, isn't it ? Let's sum up as following :

easy_admin:
    entities:
        Product:
            class: App\Entity\Product
            role_prefix: ROLE_ADMIN_PRODUCT

Entity role_prefix defines all actions required roles by appending the action name to the prefix.

Hiding not-entity-based menu entries on role option

easy_admin:
        menu:
            - { label: 'Administrator', role: ROLE_SUPER_ADMIN } # Hidden if user is not granted ROLE_SUPER_ADMIN
            - { label: 'App action', route: 'app_action', role: ROLE_ADMIN } # Hidden if user is not granted ROLE_ADMIN

⚠️Beware this ONLY HIDE the menu entry and do not secure secure access to the targeted URL/route !

Per entity field role permissions in form

You can also define role permissions per entity field in a form:

easy_admin:
    entities:
        Product:
            class: App\Entity\Product
            form:
                fields:
                    - { property: enabled, role: ROLE_ADMIN }

If user do not hold the required role, the form field will be disabled.

Confirmation modal for custom POST actions without form

A generic confirmation modal asks for confirmation (or any custom message) for links with data-confirm attribute (that may contain the custom message) and URL in data-href attribute.

Easy configurable with custom list actions by adding a confirm key :

easyadmin:
    entities:
        User:
            list:
                actions:
                    - { name: disable, icon: ban, title: Disable user, label: false, target: _blank, confirm: User will lose any access to the platform ! }

Exclude fields in forms

easyadmin:
    entities:
        User:
            form:
                exclude_fields: ['references']

In such entity:

<?php

class User
{
    public $name;

    public $title;

    public $references;
}

It will show all fields but those mentioned in exclude_fields, equivalent to the following configuration:

easyadmin:
    entities:
        User:
            form:
                fields: ['name', 'title']

Use template show vertical boostrap

Design EasyAdmin configuration:

easy_admin:
    design:
        templates:
            show: '@EasyAdminExtension/default/show_vertical.html.twig'

Run tests

Run following command :

$ ./vendor/phpunit/phpunit/phpunit

OR using Docker and Docker Compose :

$ docker-compose run --rm phpunit

Run code quality tools

PHP CS Fixer

Locally with Docker :

docker-compose run --rm php /app/vendor/bin/php-cs-fixer fix --config=/app/.php_cs /app/src

PHPStan

Locally with Docker :

docker-compose run --rm php /app/vendor/bin/phpstan analyse -c /app/phpstan.neon --level=6 /app/src

License

This software is published under the MIT License