Skip to content

Commit

Permalink
Add support for PSR clock (#536)
Browse files Browse the repository at this point in the history
  • Loading branch information
X-Coder264 authored Feb 13, 2023
1 parent 28b46c6 commit 29eb4e6
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 8 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"doctrine/event-manager": "^1.1",
"doctrine/orm": "^2.10",
"doctrine/persistence": "^2.2 || ^3.0",
"psr/clock": "^1.0",
"symfony/config": "^4.4 || ^5.4 || ^6.0",
"symfony/dependency-injection": "^4.4 || ^5.4 || ^6.0",
"symfony/http-kernel": "^4.4 || ^5.4 || ^6.0",
Expand Down
8 changes: 6 additions & 2 deletions src/AuditManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Doctrine\Common\EventManager;
use Doctrine\ORM\EntityManager;
use Psr\Clock\ClockInterface;
use SimpleThings\EntityAudit\EventListener\CreateSchemaListener;
use SimpleThings\EntityAudit\EventListener\LogRevisionsListener;
use SimpleThings\EntityAudit\Metadata\MetadataFactory;
Expand All @@ -29,10 +30,13 @@ class AuditManager

private MetadataFactory $metadataFactory;

public function __construct(AuditConfiguration $config)
private ?ClockInterface $clock;

public function __construct(AuditConfiguration $config, ?ClockInterface $clock = null)
{
$this->config = $config;
$this->metadataFactory = $config->createMetadataFactory();
$this->clock = $clock;
}

/**
Expand Down Expand Up @@ -64,6 +68,6 @@ public function createAuditReader(EntityManager $em)
public function registerEvents(EventManager $evm): void
{
$evm->addEventSubscriber(new CreateSchemaListener($this));
$evm->addEventSubscriber(new LogRevisionsListener($this));
$evm->addEventSubscriber(new LogRevisionsListener($this, $this->clock));
}
}
12 changes: 9 additions & 3 deletions src/EventListener/LogRevisionsListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use Doctrine\ORM\Persisters\Entity\EntityPersister;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Persistence\Mapping\MappingException;
use Psr\Clock\ClockInterface;
use SimpleThings\EntityAudit\AuditConfiguration;
use SimpleThings\EntityAudit\AuditManager;
use SimpleThings\EntityAudit\Metadata\MetadataFactory;
Expand All @@ -37,6 +38,8 @@ class LogRevisionsListener implements EventSubscriber

private MetadataFactory $metadataFactory;

private ?ClockInterface $clock;

/**
* @var string[]
*
Expand All @@ -63,10 +66,11 @@ class LogRevisionsListener implements EventSubscriber
*/
private array $extraUpdates = [];

public function __construct(AuditManager $auditManager)
public function __construct(AuditManager $auditManager, ?ClockInterface $clock = null)
{
$this->config = $auditManager->getConfiguration();
$this->metadataFactory = $auditManager->getMetadataFactory();
$this->clock = $clock;
}

/**
Expand Down Expand Up @@ -323,15 +327,17 @@ private function getManyToManyRelations(EntityManagerInterface $em, object $enti
*/
private function getRevisionId(Connection $conn)
{
$now = $this->clock instanceof ClockInterface ? $this->clock->now() : new \DateTimeImmutable();

if (null === $this->revisionId) {
$conn->insert(
$this->config->getRevisionTableName(),
[
'timestamp' => date_create('now'),
'timestamp' => $now,
'username' => $this->config->getCurrentUsername(),
],
[
Types::DATETIME_MUTABLE,
Types::DATETIME_IMMUTABLE,
Types::STRING,
]
);
Expand Down
11 changes: 9 additions & 2 deletions src/Resources/config/auditable.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Doctrine\ORM\EntityManager;
use Psr\Clock\ClockInterface;
use SimpleThings\EntityAudit\AuditConfiguration;
use SimpleThings\EntityAudit\AuditManager;
use SimpleThings\EntityAudit\AuditReader;
Expand All @@ -40,7 +41,10 @@
$containerConfigurator->services()
->set('simplethings_entityaudit.manager', AuditManager::class)
->public()
->args([new ReferenceConfigurator('simplethings_entityaudit.config')])
->args([
new ReferenceConfigurator('simplethings_entityaudit.config'),
(new ReferenceConfigurator(ClockInterface::class))->nullOnInvalid(),
])
->alias(AuditManager::class, 'simplethings_entityaudit.manager')
->public()

Expand All @@ -56,7 +60,10 @@

->set('simplethings_entityaudit.log_revisions_listener', LogRevisionsListener::class)
->tag('doctrine.event_subscriber', ['connection' => '%simplethings.entityaudit.connection%'])
->args([new ReferenceConfigurator('simplethings_entityaudit.manager')])
->args([
new ReferenceConfigurator('simplethings_entityaudit.manager'),
(new ReferenceConfigurator(ClockInterface::class))->nullOnInvalid(),
])

->set('simplethings_entityaudit.create_schema_listener', CreateSchemaListener::class)
->tag('doctrine.event_subscriber', ['connection' => '%simplethings.entityaudit.connection%'])
Expand Down
8 changes: 7 additions & 1 deletion tests/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Doctrine\ORM\Tools\SchemaTool;
use Gedmo\DoctrineExtensions;
use PHPUnit\Framework\TestCase;
use Psr\Clock\ClockInterface;
use SimpleThings\EntityAudit\AuditConfiguration;
use SimpleThings\EntityAudit\AuditManager;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
Expand Down Expand Up @@ -171,12 +172,17 @@ protected function getAuditManager(): AuditManager
$auditConfig->setGlobalIgnoreColumns(['ignoreme']);
$auditConfig->setUsernameCallable(static fn (): string => 'beberlei');

$auditManager = new AuditManager($auditConfig);
$auditManager = new AuditManager($auditConfig, $this->getClock());
$auditManager->registerEvents($this->_getConnection()->getEventManager());

return $this->auditManager = $auditManager;
}

protected function getClock(): ?ClockInterface
{
return null;
}

protected function setUpEntitySchema(): void
{
$em = $this->getEntityManager();
Expand Down
69 changes: 69 additions & 0 deletions tests/ClockTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\EntityAuditBundle\Tests;

use Psr\Clock\ClockInterface;
use Sonata\EntityAuditBundle\Tests\Fixtures\Issue\Issue318User;

final class ClockTest extends BaseTest
{
protected $schemaEntities = [
Issue318User::class,
];

protected $auditedEntities = [
Issue318User::class,
];

public function testFixedClockIsUsed(): void
{
$user = new Issue318User();
$user->setAlias('alias');
$this->em->persist($user);
$this->em->flush();

$userId = $user->getId();

\assert(\is_int($userId));

$reader = $this->auditManager->createAuditReader($this->em);

$revisions = $reader->findRevisions(Issue318User::class, $userId);

static::assertCount(1, $revisions);
static::assertSame($this->getFixedTime()->format('Y-m-d H:i:s'), $revisions[0]->getTimestamp()->format('Y-m-d H:i:s'));
}

protected function getClock(): ?ClockInterface
{
return new class($this->getFixedTime()) implements ClockInterface {
private \DateTimeImmutable $now;

public function __construct(\DateTimeImmutable $now)
{
$this->now = $now;
}

public function now(): \DateTimeImmutable
{
return $this->now;
}
};
}

private function getFixedTime(): \DateTimeImmutable
{
return new \DateTimeImmutable('2022-10-25 15:00:00');
}
}

0 comments on commit 29eb4e6

Please sign in to comment.