hostnet / entity-revision-component
监听事件以便进行修订
Requires
- php: ^7.3|^8.0
- doctrine/orm: ^2.4.0
- hostnet/entity-tracker-component: ^1.2.0||^2.0.0
- psr/log: ^1.0.0
Requires (Dev)
- hostnet/phpcs-tool: ^9.1.0
- phpunit/phpunit: ^9.5.6
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