kikwik/doctrine-entity-logger-bundle
A Symfony bundle that automatically logs Doctrine entity changes—creates, updates, and deletes—to give you a reliable audit trail. It hooks into Doctrine events and stores a history of modifications, making it easy to track who changed what and when.
The v0.2.0 release changes logging from implicit/global to opt-in per entity: a model is only logged when it carries the LoggableEntity attribute. That is the first thing to internalize — a model can have the logging trait, be observed, or be listed in config, and still produce no logs unless the attribute is present.
Minimal setup:
composer require <vendor>/<package>) and run any publish/migrate steps if the package provides them.src/Attributes/LoggableEntity.php. Confirm its namespace before annotating models; a wrong import is a silent no-op.use Vendor\Package\Attributes\LoggableEntity;
#[LoggableEntity]
class Order extends Model
{
//
}
Order and confirm a log entry appears. Then create/update a non-annotated model and confirm it does not — that verifies the new gate is active.First real use case: pick one high-value entity (Order, Invoice, Subscription), annotate it, and validate the log output before rolling the attribute out across the domain. Do not bulk-annotate everything on day one; the release intentionally narrows what gets logged.
Attribute-first opt-in. Treat #[LoggableEntity] as the switch, not the trait/config. Audit every model you expect to log and add the attribute explicitly. Keep a short internal list/PR checklist of “loggable entities” so the set is intentional rather than accidental.
Migration from pre-0.2.0 behavior. Anything that logged before may now be silent. Grep your codebase and tests for log assertions, then map each expected log source to a model and confirm the attribute is present. This is the primary upgrade task.
Per-concrete-model annotation. PHP class attributes are not inherited. If you annotate a base model, child models will not automatically be treated as loggable. Add the attribute to each concrete model you want logged.
#[LoggableEntity]
class Order extends Model {}
#[LoggableEntity]
class Invoice extends Model {}
Test both sides of the gate. Add a feature test that asserts a log row is created for an annotated model and one that asserts no log row is created for an unannotated model. That second test is what protects you from future attribute-discovery regressions.
$this->assertDatabaseCount('activity_log', 1);
Order::create([...]);
$this->assertDatabaseCount('activity_log', 1); // unchanged
Draft::create([...]); // no attribute
Runtime conditionality. The attribute is static metadata. If you need “log only in production” or “log only for tenant X,” do that in the package config/channel or around the logging call — do not expect the attribute to accept runtime conditions. If the attribute constructor exposes options, inspect it; otherwise keep the gate simple and layer runtime rules elsewhere.
Queue/worker and Octane awareness. Attribute discovery often happens during boot or is cached. After adding the attribute, clear caches and restart long-running workers so the change is picked up.
$attrs = (new ReflectionClass(Order::class))
->getAttributes(\Vendor\Package\Attributes\LoggableEntity::class);
dump($attrs); // empty array means the gate is closed
use statement matches the package’s attribute class exactly.php artisan optimize:clear (and any package-specific cache command) after adding or removing the attribute.How can I help you explore Laravel packages today?