damienharper/auditor-doctrine-provider
Doctrine ORM provider for DamienHarper/auditor. Automatically records audit logs for Doctrine entities (create/update/delete) with DBAL/ORM integration and configurable auditing, making change tracking and accountability easy in PHP applications.
fix: audit all inverse-side OneToMany associations when multiple entities are flushed together by @DamienHarper in #2
Doctrine's UoW does not reliably schedule inverse-side (OneToMany/mappedBy) collections for update when the FK is changed through the owning-side ManyToOne field. When multiple entities sharing the same target are flushed together, only some ASSOCIATE entries were emitted on the inverse side's audit table.
Note: This bug also affects the deprecated
DoctrineProviderembedded inauditor(≤ 4.x). It will not be backported there — users are encouraged to migrate toauditor-doctrine-provider.
Full Changelog: https://github.com/DamienHarper/auditor-doctrine-provider/compare/1.1.0...1.2.0
When using auditor inside Symfony Messenger workers, only the first message was audited
correctly. Subsequent messages silently failed because the DoctrineSubscriber held a stale
EntityManager reference after reset, and DoctrineProvider reused cached PreparedStatement
objects bound to a closed connection.
DoctrineProvider now implements Symfony\Contracts\Service\ResetInterface. Its reset()
method clears the prepared statement cache and resets all subscriber transaction caches,
ensuring clean state between messages.
DoctrineSubscriber now retrieves the EntityManager directly from event arguments
(OnFlushEventArgs, LifecycleEventArgs) instead of relying on a constructor-injected
reference that could become stale.
kernel.reset in SymfonyTag DoctrineProvider with kernel.reset so that Symfony's services_resetter calls
reset() automatically between messages:
# config/services.yaml
services:
DH\Auditor\Provider\Doctrine\DoctrineProvider:
tags:
- { name: kernel.reset, method: reset }
If your service definition uses autoconfigure: true, Symfony detects ResetInterface
and registers the tag automatically — no additional config needed.
ResetInterface and kernel.reset for Messenger workersworkflow_dispatch trigger to sync-docs workflowFull Changelog: https://github.com/DamienHarper/auditor-doctrine-provider/compare/1.0.0...1.1.0
The standalone Doctrine ORM provider for
auditor. This is the first release ofauditor-doctrine-provider— previously shipped as the built-inDoctrineProviderinsidedamienharper/auditor, it is now a dedicated, independently versioned package.
auditor-doctrine-provider implements the auditor provider interface for Doctrine ORM.
It tracks all entity lifecycle changes and persists them as structured audit entries:
Supported databases: MySQL, MariaDB, PostgreSQL, SQLite — and any other RDBMS supported by Doctrine DBAL.
Note: bulk operations via DQL (
$em->createQuery('UPDATE ...')) or raw DBAL queries bypass Doctrine's UnitOfWork and are not tracked.
All features from damienharper/auditor 4.x are available in this release.
Audit entries carry arbitrary supplementary data through a nullable JSON extra_data column.
Wire up a LifecycleEvent listener to populate whatever context matters — HTTP request,
user roles, business workflow step, anything.
#[AsEventListener]
public function onAudit(LifecycleEvent $event): void
{
$event->getPayload()['extra_data'] = [
'ip' => $this->requestStack->getCurrentRequest()?->getClientIp(),
'role' => $this->security->getUser()?->getRoles(),
];
}
A extra_data_provider callable on Configuration attaches context to every audit entry
automatically, without a per-entity listener.
$configuration->setExtraDataProvider(function (): ?array {
return ['ip' => $this->requestStack->getCurrentRequest()?->getClientIp()];
});
$filter = new JsonFilter('extra_data', 'role', '=', 'ROLE_ADMIN');
Native JSON indexing on MySQL, MariaDB, PostgreSQL, and SQLite.
$filter = new NullFilter('blame_id'); // blame_id IS NULL
$filter = new NullFilter('blame_id', true); // blame_id IS NOT NULL
Configure a storage_mapper callable to route audit rows to the correct storage EM when
using multiple Entity Managers. See docs/providers/doctrine/multi-database.md.
| auditor-doctrine-provider 1.x | |
|---|---|
| PHP | ≥ 8.4 |
| Doctrine DBAL | ≥ 4.0 |
| Doctrine ORM | ≥ 3.2 |
| auditor | ≥ 4.0 |
composer require damienharper/auditor-doctrine-provider
See docs/getting-started/installation.md for the full setup guide.
If you were using DoctrineProvider directly from damienharper/auditor (without
auditor-bundle), migration is straightforward:
composer require damienharper/auditor-doctrine-provider
Update your import statements:
// Before (auditor 4.x, deprecated)
use DH\Auditor\Provider\Doctrine\DoctrineProvider;
// After
use DH\AuditorDoctrineProvider\DoctrineProvider;
The deprecated classes in damienharper/auditor still exist as aliases through 4.x
and will be removed in v5.0.
Users of
auditor-bundledo not need to do anything — the bundle pulls in this package automatically since 8.0.
docs/ and are versioned alongside the code.Full Changelog: https://github.com/DamienHarper/auditor-doctrine-provider/commits/1.0.0
How can I help you explore Laravel packages today?