atournayre / historique-bundle
This bundle add History management for entities.
Installs: 1 183
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 1
Type:symfony-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 :).