dualmedia/symfony-doctrine-event-converter-bundle

一个用于从 Doctrine 变更创建 symfony 事件的 symfony 扩展包

2.3.1 2024-09-19 08:37 UTC

This package is auto-updated.

Last update: 2024-09-19 08:37:47 UTC


README

Code Coverage Packagist Downloads

此扩展包旨在无缝地在 Doctrine 和 symfony 事件之间进行转换,同时允许创建具有自己需求和检查的子事件

它允许您直接使用 symfony 简化 Doctrine 操作,而无需实现 Doctrine 的监听器和事件逻辑。

所有的工作都已经完成,只需声明您的实体,在它们上实现 EntityInterface,然后创建一个抽象事件类。

安装

简单地运行 composer require dualmedia/symfony-doctrine-event-converter-bundle

然后按照以下方式将扩展包添加到您的 config/bundles.php 文件中

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    // other bundles ...
    DualMedia\DoctrineEventDistributorBundle\DoctrineEventConverterBundle::class => ['all' => true],
];

使用方法

实体

创建一个由 Doctrine 管理的实体,同时实现 DualMedia\DoctrineEventDistributorBundle\Interfaces\EntityInterface

use Doctrine\ORM\Mapping as ORM;
use DualMedia\DoctrineEventDistributorBundle\Interfaces\EntityInterface;

 #[ORM\Entity]
class Item implements EntityInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    #[ORM\Column(type: 'smallint')]
    private ?int $status = null;

    public function getId()
    {
        return $this->id;
    }

    public function getStatus(): ?int
    {
        return $this->status;
    }

    public function setStatus(
        int $status
    ): self {
        $this->status = $status;

        return $this;
    }
}

事件

创建一个事件类(非最终),然后在某个时刻扩展 DualMedia\DoctrineEventDistributorBundle\Event\AbstractEntityEvent,使用适当的注解标记此类,可以是基本注解之一或子事件

use DualMedia\DoctrineEventDistributorBundle\Attributes\PrePersistEvent;
use DualMedia\DoctrineEventDistributorBundle\Event\AbstractEntityEvent;

#[PrePersistEvent]
abstract class ItemEvent extends AbstractEntityEvent
{
    public static function getEntityClass(): ?string
    {
        return Item::class;
    }
}

该扩展包将自动为适当的事件生成代理类。

每个代理类的命名空间开头可见于 此处PROXY_NS 常量值下。

以下类名将始终包含父事件的完整命名空间。此命名空间由扩展包中的自动加载器加载,不应以其他方式(除订阅者和一般使用外)与之交互。

子事件

假设以下场景:您希望在 Item 的状态从 pending 变更为 complete 时触发事件,在这种情况下,您需要在您的 ItemEvent(上面)中添加以下属性。

子事件可以是应用于变量先前和当前状态(或其中之一)的检查,或者仅应用于一个(从 OR 到)。

重要

由于 Doctrine 的传递方式,遗憾的是目前尚不知道集合的变化。

从和到

以下将生成一个 ItemPendingToCompleteEvent 类(在默认代理命名空间下)。

use \DualMedia\DoctrineEventConverterBundle\Attributes\SubEvent;
use \DualMedia\DoctrineEventConverterBundle\Model\Change;

#[SubEvent("PendingToComplete", changes: [new Change('status', ItemStatusEnum::Pending, ItemStatusEnum::Complete)])]

当然,假设存在可以传递给 Change 模型的枚举或其他值。

一次可能需要多个更改,或者根据 SubEvent::$allMode 是任何更改。

以下将生成一个 ItemFromPendingEvent

#[SubEvent("FromPending", changes: [new Change('status', ItemStatusEnum::Pending)])]

以下将生成一个 ItemCompleteEvent

#[SubEvent("Complete", changes: [new Change('status', to: ItemStatusEnum::Complete)])]

PHPStan 和 Psalm 问题忽略

以下提供了一些现成的模板,以使您的工作更加容易。

将来可能提供插件,但尚未确定。

PHPStan

注意:将来将提供 phpstan.neon 文件以忽略这些问题,目前只需将以下行添加到您的文件中。

parameters:
  ignoreErrors:
    - '#Class DualMedia\\DoctrineEventConverterProxy\\[a-zA-Z0-9\\_]+ not found#'
    - '#Parameter \$[a-zA-Z0-9\\_]+ of method [a-zA-Z0-9\\_]+::[a-zA-Z0-9\\_]+\(\) has invalid type DualMedia\\DoctrineEventConverterProxy\\[a-zA-Z0-9\\_]+#'
    - '#Instantiated class DualMedia\\DoctrineEventConverterProxy\\[a-zA-Z0-9\\_]+ not found.#'
    - '#Call to method [a-zA-Z0-9\\_]+\(\) on an unknown class DualMedia\\DoctrineEventConverterProxy\\[a-zA-Z0-9\\_]+.#'

我还建议在您的配置中禁用 reportUnmatchedIgnoredErrors,但这不是强制性的。

Psalm

需要将此配置复制过来,因为 Psalm 不允许包含文件。

<issueHandlers>
  <UndefinedClass>
    <errorLevel type="suppress">
      <referencedClass name="DualMedia\DoctrineEventConverterProxy\*"/>
    </errorLevel>
  </UndefinedClass>

  <UndefinedDocblockClass>
    <errorLevel type="suppress">
      <referencedClass name="DualMedia\DoctrineEventConverterProxy\*"/>
    </errorLevel>
  </UndefinedDocblockClass>
</issueHandlers>