EasyAdmin - 如何正确显示使用 EntityRepository 的自定义实体 属性

EasyAdmin - How to show custom Entity property properly which use EntityRepository

我想在 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 中正确显示自定义属性?

您不应该将检索收益的逻辑放在 Book 实体中,尤其是当它涉及外部依赖项时,例如 entityManager

您或许可以使用 Doctrine 事件来实现这一点。在从数据库加载 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 }

这只是一个例子,我还没有测试代码。如果您创建新的 Book 对象,您可能必须为 postPersist 事件添加逻辑。

根据检索收益的逻辑(另一个数据库调用?从外部加载 API?),您可能希望以不同的方式解决问题(缓存,通过 cron 将它们加载到您的数据库中工作,...)