Install Dependencies
composer require simplethings/entity-audit-bundle
composer require braune-digital/activity-bundle "~1.3" # For STEA >= 1.0.6
Enable bundles in config/bundles.php:
return [
// ...
SimpleThings\EntityAudit\SimpleThingsEntityAuditBundle::class,
BrauneDigital\ActivityBundle\BrauneDigitalActivityBundle::class,
];
Basic Configuration
Add to config/packages/braune_digital_activity.yaml:
braune_digital_activity:
doctrine_subscribing: true
observed_classes:
'App\Entity\YourEntity': ~ # Track all CRUD + field changes
First Use Case Trigger an audit event (e.g., via SonataAdmin or direct entity update):
$entity = new YourEntity();
$entity->setTitle('Test');
$em->persist($entity);
$em->flush(); // Activity is auto-created if `doctrine_subscribing: true`
Field-Level Tracking
Configure granular field monitoring in observed_classes:
observed_classes:
'App\Entity\Task':
fields:
status: ~
priority: ~
status/priority generate activities.SonataAdmin Integration
SonataAdminBundle is installed.BrauneDigital\ActivityBundle\Admin\ActivityAdmin.Manual Activity Creation Bypass Doctrine events for one-off activities:
use BrauneDigital\ActivityBundle\Model\Activity;
$activity = new Activity();
$activity->setEntity($entity)
->setAction('UPDATE')
->setField('title')
->setOldValue('Old')
->setNewValue('New');
$activityManager = $this->container->get('braune_digital_activity.activity_manager');
$activityManager->save($activity);
Event Subscribers Extend functionality via Doctrine lifecycle events:
// src/EventSubscriber/CustomActivitySubscriber.php
namespace App\EventSubscriber;
use BrauneDigital\ActivityBundle\Event\ActivityEvent;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
class CustomActivitySubscriber implements EventSubscriber
{
public function postPersist(ActivityEvent $event)
{
if ($event->getEntity() instanceof YourEntity) {
$event->setCustomData(['source' => 'api']);
}
}
}
Register in services.yaml:
services:
App\EventSubscriber\CustomActivitySubscriber:
tags:
- { name: kernel.event_subscriber }
Doctrine Subscribing Overhead
doctrine_subscribing: true adds a listener to every entity operation. Disable for high-traffic endpoints:
braune_digital_activity:
doctrine_subscribing: false # Manual activities only
Field-Specific Config Conflicts
fields are defined and the class is listed alone (~), the fields config is ignored. Explicitly list all fields:
observed_classes:
'App\Entity\Task':
fields:
title: ~
# ... (no bare `~` at root level)
SonataAdmin Visibility
SonataAdminBundle is installed and enabled.ActivityAdmin class is registered in your admin configuration.Performance with Large Audits
activity table. For high-volume systems:
entity_id, action, and timestamp.Check Event Firing Enable Doctrine debug logging to verify events:
# config/packages/dev/doctrine.yaml
doctrine:
dbal:
logging: true
profiling: true
Look for ActivityListener logs in var/log/dev.log.
Activity Not Showing?
observed_classes.Custom Data Not Persisting
Ensure your subscriber implements ActivityEvent methods correctly:
$event->setCustomData(['key' => 'value']); // Must be serializable
Custom Activity Actions
Extend the action field in Activity entity (e.g., IMPORT, EXPORT):
// src/Entity/Activity.php (override)
use Doctrine\ORM\Mapping as ORM;
#[ORM\Column(type: 'string', length: 255)]
private string $action;
Activity Filters Add custom query filters for SonataAdmin:
// src/Admin/ActivityAdmin.php
protected function configureDatagridFilters(DatagridMapper $filter)
{
$filter->add('entityClass', null, [
'field_type' => 'string',
'label' => 'Entity Class',
]);
}
Activity Notifications Integrate with Symfony Messenger to send alerts:
// src/EventSubscriber/ActivityNotifier.php
use BrauneDigital\ActivityBundle\Event\ActivityEvent;
class ActivityNotifier
{
public function __invoke(ActivityEvent $event)
{
if ($event->getAction() === 'DELETE') {
$this->messageBus->dispatch(new NotifyAdminMessage($event->getEntity()));
}
}
}
How can I help you explore Laravel packages today?