hostnet/entity-revision-component

监听事件以便进行修订

1.1.6 2022-05-04 09:57 UTC

This package is auto-updated.

Last update: 2024-09-04 15:02:53 UTC


README

文档

实体修订组件是什么?

实体修订组件是一个利用实体追踪组件并允许您挂钩到entityChanged事件的库。

此组件允许您在每次刷新时自动为一系列实体存储修订。

要求

修订组件需要至少php 7.3,并在Doctrine2上运行。有关具体要求,请查看composer.json

安装

安装很简单,此软件包可在packagist上找到。您可以将此软件包锁定到主版本,因为我们遵循语义版本控制2.0.0

示例

    "require" : {
        "hostnet/entity-revision-component" : "1.*"
    }

注意:如果您想获取最新的更改,可以使用dev-master,但这不建议用于生产代码!

文档

它是如何工作的?

它通过在实体上放置@Revision注解和RevisionableInterface并在entityChanged事件上注册监听器来实现,假设您已经配置了实体追踪组件

以下是一个使用示例。

注意:此组件与实体变更组件配合使用非常出色。这种组合非常适合根据修订回溯。

设置

  • 您必须在您的实体上添加@Revision
  • 您必须在您的实体上添加RevisionableInterface。
  • 您需要一个修订实体。

注册事件

以下是一个非常基本的设置示例。如果您使用具有依赖注入容器的框架,设置将会容易得多。

设置可能看起来有些复杂,但它基本上是设置追踪组件。如果您在框架中使用它,建议为该框架创建一个特定配置软件包来自动化此操作。

注意:如果您使用Symfony2,可以查看hostnet/entity-tracker-bundle。此软件包旨在为您配置服务。

use Acme\Bundle\AcmeBundle\AcmeRevisionFactory;
use Hostnet\Component\EntityRevision\Resolver\RevisionResolver;
use Hostnet\Component\EntityTracker\Listener\EntityChangedListener;
use Hostnet\Component\EntityTracker\Provider\EntityAnnotationMetadataProvider;
use Hostnet\Component\EntityTracker\Provider\EntityMutationMetadataProvider;

/* @var $em \Doctrine\ORM\EntityManager */
$event_manager = $em->getEventManager();

// default doctrine annotation reader
$annotation_reader = new AnnotationReader();

// setup required providers
$mutation_metadata_provider   = new EntityMutationMetadataProvider($annotation_reader);
$annotation_metadata_provider = new EntityAnnotationMetadataProvider($annotation_reader);
$logger = ...; // instance of LoggerInterface from the psr/log package, optional argument
 
// pre flush event listener that uses the @Revision annotation
$entity_changed_listener = new EntityChangedListener(
    $mutation_metadata_provider,
    $annotation_metadata_provider,
    $logger
);

// the resolver is used to find the correct annotation
$revision_resolver = new RevisionResolver($annotation_metadata_provider);

// this factory will provide the revision and as author Henk
$revision_factory = new AcmeRevisionFactory('Henk');

// creating the revision listener
$revision_listener = new RevisionListener($revision_resolver, $revision_factory);

$event_manager->addEventListener('preFlush', $entity_changed_listener);
$event_manager->addEventListener('postFlush', $revision_listener);
$event_manager->addEventListener('entityChanged', $revision_listener);

注意:修订监听器必须在onFlush和entityChanged上注册。因为修订是按刷新分组存储的,所以您还必须确保修订监听器在实体变更监听器之前注册。如果没有这样做,您将收到意外的结果。

创建修订实体

修订存储在数据库中,因此需要一个实体。您可以自由决定如何存储它,但您应该在其上实现RevisionInterface。

use Doctrine\ORM\Mapping as ORM;
use Hostnet\Component\EntityRevision\RevisionInterface;

/**
 * @ORM\Entity
 */
class Revision implements RevisionInterface
{
       
    /**
     * @ORM\...
     */
    private $author;
    
    /**
     * @ORM\...
     */
    private $created_at;
    
    public function __construct($author, \DateTime $created_at)
    {
        $this->author     = $author;
        $this->created_at = $created_at;
    }
    
    public function getUser()
    { 
        return $this->author;
    }

    public function getCreatedAt()
    {
        return $this->created_at;
    }
}

配置实体

现在我们只需在我们的实体上放置@Revision注解和RevisionableInterface即可。

use Doctrine\ORM\Mapping as ORM;
use Hostnet\Component\EntityRevision\RevisionableInterface;

/**
 * @ORM\Entity
 * @Revision
 */
class MyEntity implements RevisionableInterface
{
    /**
     * The current revision of the contact person
     *
     * @ORM\ManyToOne(targetEntity="Revision")
     * @ORM\JoinColumn(name="revision_id", referencedColumnName="id")
     * @var Revision
     */
    private $revision;
    
    public function setRevision(RevisionInterface $revision)
    {
        $this->revision = $revision;
    }
    
    public function getRevision()
    {
        return $this->revision;
    }
}

创建AcmeRevisionFactory

工厂负责提供修订实体。您可以自由填写您想要的内容,不需要像以下示例那样使用构造函数。唯一的要求是它能够创建一个修订。

namespace Acme\Bundle\AcmeBundle;

use Hostnet\Component\EntityRevision\Factory\RevisionFactoryInterface;

class AcmeRevisionFactory implements RevisionFactoryInterface
{
    private $author;
    
    public function __construct($author)
    {
        $this->author = $author;
    }

    public function createRevision(\DateTime $created_at)
    {
        return new Revision($this->author, $created_at);
    }
}

下一步是什么?

现在您只需要更改多个带有@Revision的实体,它们将被分组到修订实体中。

// imagine all instances to be Revisionable
$user->setName('Henk');
$address->setNumber('42');
$em->flush();
var_dump($user->getRevision() === $address->getRevision()); // true