precision-soft / symfony-doctrine-audit
doctrine audit library
v1.0.0
2024-09-17 18:40 UTC
Requires
- php: >=8.2
- doctrine/dbal: 3.*
- doctrine/orm: 3.*
- doctrine/persistence: 3.*
- precision-soft/doctrine-type: 1.*
- precision-soft/symfony-console: 1.*
- 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.