EasyAdmin - Как правильно отобразить собственное свойство Entity, которое использует EntityRepository - PullRequest
0 голосов
/ 21 марта 2019

Я бы хотел показать на EasyAdmin пользовательское свойство, вот пример:

class Book
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    public $id;
    /**
     * @ORM\Column(type="string")
     */
    public $name;
    /**
     * @ORM\Column(type="float")
     */
    public $price;
    public function getBenefit(): float
    {
        // Here the method to retrieve the benefits
    }
}

В этом примере пользовательский параметр benefit не является параметром нашей сущности, и если мы настраиваем EasyAdmin таким образом, он работает!

easy_admin:
    entities:
        Book:
            class: App\Entity\Book
            list:
                fields:
                    - { property: 'title', label: 'Title' }
                    - { property: 'benefit', label: 'Benefits' }

Проблема в том, что если функция немного сложна и требует, например, EntityRepository, становится невозможно соблюдать Controller> Repository> Entities .

У кого-нибудь есть обходной путь, возможно, с помощью AdminController для правильного отображения пользовательских свойств в EasyAdmin?

1 Ответ

1 голос
/ 21 марта 2019

Не следует использовать логику для извлечения преимуществ внутри сущности Book, особенно если она включает внешние зависимости, такие как entityManager.

Возможно, вы могли бы использовать события Доктрины, чтобы достичь этого. Получите преимущества после загрузки сущности Book из БД. Сохраните преимущества до или после сохранения объекта Book в БД.

Подробнее об этом можно узнать здесь https://symfony.com/doc/current/doctrine/event_listeners_subscribers.html

class Book
{
    ...
    public $benefits;
}
// src/EventListener/RetrieveBenefitListener.php
namespace App\EventListener;

use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use App\Entity\Book;

class RetrieveBenefitListener
{
    public function postLoad(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();

        // only act on some "Book" entity
        if (!$entity instanceof Book) {
            return;
        }

        // Your logic to retrieve the benefits
        $entity->benefits = methodToGetTheBenefits();
    }
}
// src/EventListener/SaveBenefitListener.php
namespace App\EventListener;

use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use App\Entity\Book;

class SaveBenefitListener
{
    public function postUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();

        // only act on some "Book" entity
        if (!$entity instanceof Book) {
            return;
        }

        // Your logic to save the benefits
        methodToSaveTheBenefits($entity->benefits);
    }
}
// services.yml
services:
    App\EventListener\RetrieveBenefitListener:
        tags:
            - { name: doctrine.event_listener, event: postLoad }
    App\EventListener\SaveBenefitListener:
        tags:
            - { name: doctrine.event_listener, event: postUpdate }

Это всего лишь пример, я не проверял код. Вам, вероятно, придется добавить логику для события postPersist, если вы создаете новые объекты Book.

В зависимости от логики получения преимуществ (еще один вызов БД - загрузка из внешнего API?), Вы можете по-разному подходить к проблеме (кэширование, загрузка их в вашу БД с помощью задания cron, ...)

...