precision-soft / symfony-doctrine-audit
doctrine audit library
Package info
github.com/precision-soft/symfony-doctrine-audit
Type:symfony-bundle
pkg:composer/precision-soft/symfony-doctrine-audit
v2.1.0
2025-01-06 08:00 UTC
Requires
- php: >=8.2
- doctrine/dbal: 3.*||4.*
- doctrine/orm: 3.*
- doctrine/persistence: 3.*
- precision-soft/doctrine-type: 2.*
- precision-soft/symfony-console: 1.*||2.*
- symfony/config: 7.*
- symfony/console: 7.*
- symfony/dependency-injection: 7.*
- symfony/filesystem: 7.*
- symfony/http-kernel: 7.*
- symfony/serializer: 7.*
Requires (Dev)
README
You may fork and modify it as you wish.
Any suggestions are welcomed.
This is a work in progress.
Usage
Sample config and storage
precision_soft_doctrine_audit: storages: doctrine_one: type: doctrine entity_manager: audit_em_one config: # \PrecisionSoft\Doctrine\Audit\Storage\Doctrine\Configuration transaction_table_name: 'audit_transaction' file: type: file file: '%kernel.project_dir%/var/audit.log' doctrine_two: type: doctrine entity_manager: audit_em_two config: # \PrecisionSoft\Doctrine\Audit\Storage\Doctrine\Configuration transaction_table_name: 'audit_transaction' rabbit: type: custom service: Acme\Shared\Service\AuditStorageService auditors: doctrine: entity_manager: source_em_one storages: - doctrine transaction_provider: Acme\Shared\Service\AuditTransactionProviderService logger: monolog.logger ignored_fields: - created - modified file: entity_manager: source_em_two storages: - file transaction_provider: Acme\Shared\Service\AuditTransactionProviderService async: entity_manager: source_em_three storages: - doctrine_two - rabbit synchronous_storages: - rabbit # the rabbit storage will publish the storage dto and a consumer will be required to save to the doctrine storage transaction_provider: Acme\Shared\Service\AuditTransactionProviderService
# services.yaml services: Acme\Shared\Service\AuditStorageService: arguments: $storage: '@precision_soft_doctrine_audit.storage.doctrine_two'
<?php declare(strict_types=1); namespace Acme\Shared\Service; use PrecisionSoft\Doctrine\Audit\Contract\TransactionProviderInterface; use PrecisionSoft\Doctrine\Audit\Dto\Storage\TransactionDto; final class AuditTransactionProviderService implements TransactionProviderInterface { public function getTransaction(): TransactionDto { $username = '~'; /* @todo implement application specific logic */ return new TransactionDto($username); } }
<?php declare(strict_types=1); namespace Acme\Shared\Service; use PrecisionSoft\Doctrine\Audit\Contract\StorageInterface; use PrecisionSoft\Doctrine\Audit\Dto\Storage\StorageDto; use PrecisionSoft\Doctrine\Audit\Storage\Doctrine\Storage; use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface; use PhpAmqpLib\Message\AMQPMessage; use Psr\Log\LoggerInterface; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\SerializerInterface; use Throwable; class AuditStorageService implements StorageInterface { private SerializerInterface $serializer; private Storage $storage; private ProducerInterface $producer; private LoggerInterface $logger; private ThrowableHandlerService $throwableHandlerService; public function __construct( SerializerInterface $serializer, Storage $storage, ProducerInterface $auditProducer, LoggerInterface $logger, ThrowableHandlerService $throwableHandlerService ) { $this->serializer = $serializer; $this->storage = $storage; $this->producer = $auditProducer; $this->logger = $logger; $this->throwableHandlerService = $throwableHandlerService; } public function save(StorageDto $storageDto): void { try { $message = $this->serializer->serialize($storageDto, JsonEncoder::FORMAT); $this->producer->publish($message); } catch (Throwable $t) { $context = $this->throwableHandlerService->getContext($t); /* @todo serialize by hand */ $context['dto'] = $message ?? 'could not serialize'; $this->logger->error($t->getMessage(), $context); } } public function consume(AMQPMessage $message): void { /** @var StorageDto $storageDto */ $storageDto = $this->serializer->deserialize($message->getBody(), StorageDto::class, JsonEncoder::FORMAT); $this->storage->save($storageDto); } }
Doctrine storage
This library will register two commands for each auditor with a doctrine type storage:
precision-soft:doctrine:audit:schema:create:<em-name>- will create the audit database schema for auditor default.precision-soft:doctrine:audit:schema:update:<em-name>- will update the audit database schema for auditor default.
Dev
git clone git@gitlab.com:precision-soft-open-source/symfony/doctrine-audit.git cd doctrine-audit ./dc build && ./dc up -d
Todo
- Unit tests.
- Retain old values in case the values are changed directly from database.