atournayre / historique-bundle
This bundle add History management for entities.
Installs: 1 187
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 1
Type:symfony-bundle
pkg:composer/atournayre/historique-bundle
Requires
- php: >=8.1.4
- doctrine/common: ^3.1
- doctrine/orm: ^2.9
- symfony/config: 5.4.*
- symfony/dependency-injection: 5.4.*
- symfony/security-bundle: 5.4.*
- symfony/serializer: 5.4.*
- symfony/yaml: ^5.4
README
This bundle add History management for entities.
Requirements
Symfony ^5.4
PHP ^8.1
Install
Composer
composer require atournayre/historique-bundle
Register bundle
// app/AppKernel.php // ... class AppKernel extends Kernel { // ... public function registerBundles() { $bundles = array( // ... new \Atournayre\Bundle\HistoriqueBundle\HistoriqueBundle(), // ... ); } // ... }
Configuration
Replace App\Model\History by your History entity.
Replace App\Model\User by your User entity.
# 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
Add History entity to your application.
<?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! }
Usage
- Create/Update entity
- Create a factory for the entity you want to log
- Map your entity to the factory
Create/Update entity
You can add History to existing entities or add it to new ones.
To add history to an entity, it needs to implements HistorycableInterface.
Then use HistorycableTrait to add a relation between YourEntity and History.
<?php use Atournayre\Bundle\HistoriqueBundle\Traits\HistorycableInterface; use Atournayre\Bundle\HistoriqueBundle\Traits\HistorycableTrait; class YourEntity implements HistorycableInterface { //... use HistorycableTrait; //... }
Create a factory for the entity you want to log
Factories are where magic happens.
You have to create a Factory that implements how you want to store the history.
<?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() )); } }
Map your entity to the factory
Once you factory is created, you need to add a mapping to the config file, so the listener can automatically get the right factory for the right entity.
# config.packages/atournayre_historique.yaml atournayre_historique: mappings: 'App\Entity\YourEntity': App\Factory\YourEntityFactory
With this, you can locate entities and factories anywhere in your project.
How to get values ?
use Doctrine\Common\Collections\Criteria; $yourEntity = ... // Get all the history (the most recent first) $allPreviousValues = $yourEntity->getEntityChangeSet(); $allPreviousValues = $yourEntity->getEntityChangeSetAsArray();
Contributing
Of course, open source is fueled by everyone's ability to give just a little bit of their time for the greater good. If you'd like to see a feature or add some of your own happy words, awesome! Tou can request it - but creating a pull request is an even better way to get things done.
Either way, please feel comfortable submitting issues or pull requests: all contributions and questions are warmly appreciated :).