atournayre/historique-bundle

此包为实体添加历史管理功能。

3.3.1 2022-11-15 10:34 UTC

This package is auto-updated.

Last update: 2024-08-31 00:42:39 UTC


README

此包为实体添加历史管理功能。

要求

Symfony ^5.4

PHP ^8.1

安装

Composer

composer require atournayre/historique-bundle

注册包

// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    // ...
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new \Atournayre\Bundle\HistoriqueBundle\HistoriqueBundle(),
            // ...
        );
    }
    // ...
}

配置

App\Model\History 替换为您的历史实体。

App\Model\User 替换为您的用户实体。

# config/packages/doctrine.yaml
doctrine:
  orm:
    resolve_target_entities:
      Atournayre\Bundle\HistoriqueBundle\Interfaces\History: App\Model\History
      Symfony\Component\Security\Core\User\UserInterface: App\Model\User

# config/packages/atournayre_historique.yaml
atournayre_historique:
  history_class: App\Model\History

History 实体添加到您的应用中。

<?php

namespace App\Model;

use Atournayre\Bundle\HistoriqueBundle\Entity\History as BaseHistory;
use Atournayre\Bundle\HistoriqueBundle\EventSubscriber\HistoryEventSubscriber;
use Atournayre\Bundle\HistoriqueBundle\Interfaces\History as HistoryInterface;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\EntityListeners([HistoryEventSubscriber::class])]
class History extends BaseHistory implements HistoryInterface
{
    // It is recommended not to extend this entity!
}

使用

  1. 创建/更新实体
  2. 为要记录的实体创建一个工厂
  3. 将实体映射到工厂

创建/更新实体

您可以将 History 添加到现有实体或新实体中。

要添加历史到实体,实体需要实现 HistorycableInterface

然后使用 HistorycableTraitYourEntityHistory 之间添加关系。

<?php

use Atournayre\Bundle\HistoriqueBundle\Traits\HistorycableInterface;
use Atournayre\Bundle\HistoriqueBundle\Traits\HistorycableTrait;

class YourEntity implements HistorycableInterface
{
    //...
    use HistorycableTrait;
    //...
}

为要记录的实体创建一个工厂

工厂是魔法发生的地方。

您需要创建一个实现如何存储历史的工厂。

<?php

namespace App\Factory;

use App\Entity\Utilisateur;
use Atournayre\Bundle\HistoriqueBundle\DTO\HistoryDTO;
use Atournayre\Bundle\HistoriqueBundle\Exception\HistoriqueException;
use Atournayre\Bundle\HistoriqueBundle\Factory\AbstractFactory;
use Atournayre\Bundle\HistoriqueBundle\Interfaces\History;
use Symfony\Component\Security\Core\User\UserInterface;

class YourEntityHistoryFactory extends AbstractFactory
{
    /**
     * @throws HistoriqueException
     */
    public function create(array $changeSet): ?History
    {
        // Create how many methods you want for each node in your change set.
        $this->user($changeSet);
        // You must call this method (it will convert $changeSet and create the History entity).
        return parent::createHistory();
    }

    // This method implement how information are stored when a user is changed.
    private function user(array $changeSet): void
    {
        /** @var UserInterface[]|null $currentChangeSet */
        $currentChangeSet = $changeSet['user'] ?? null;

        if (is_null($currentChangeSet)) return;

        $this->changeSet->set('user', HistoryDTOFactory::createFromChangeSet(
            'New username',
            $currentChangeSet,
            fn (Utilisateur $utilisateur) => $utilisateur?->getUsername()
        ));
    }
}

将实体映射到工厂

一旦创建工厂,您需要将其映射添加到配置文件中,以便监听器可以自动获取正确实体对应的正确工厂。

# config.packages/atournayre_historique.yaml
atournayre_historique:
  mappings:
    'App\Entity\YourEntity': App\Factory\YourEntityFactory

这样,您可以在项目的任何地方定位实体和工厂。

如何获取值?

use Doctrine\Common\Collections\Criteria;

$yourEntity = ...

// Get all the history (the most recent first) 
$allPreviousValues = $yourEntity->getEntityChangeSet();
$allPreviousValues = $yourEntity->getEntityChangeSetAsArray();

贡献

当然,开源是由每个人贡献一点点时间来推动的。如果您想看到某个功能或添加一些您自己的美好词汇,太棒了!您可以请求它 - 但创建拉取请求是完成任务的更好方式。

无论如何,请放心提交问题或拉取请求:所有贡献和问题都深受欢迎 :)。