Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Auditor Doctrine Provider Laravel Package

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.

View on GitHub
Deep Wiki
Context7
## Getting Started

### **Minimal Setup**
1. **Installation**
   Add the package via Composer (updated for 1.2.0):
   ```bash
   composer require damienharper/auditor-doctrine-provider:^1.2.0

Ensure audit is installed (this package extends its functionality):

composer require ocramius/audit
  1. Register the Provider In config/audit.php, add the Doctrine provider:

    'providers' => [
        \DamienHarper\AuditorDoctrineProvider\DoctrineProvider::class,
    ],
    
  2. Configure Doctrine Ensure your EntityManager is properly configured. The provider auto-detects it, but verify lifecycle callbacks are enabled in your entities:

    use Doctrine\ORM\Mapping as ORM;
    
    /** @ORM\Entity @ORM\HasLifecycleCallbacks */
    class User { ... }
    
  3. First Audit Use the Auditor facade to log changes (now correctly handles inverse-side OneToMany associations):

    use Audit;
    
    $user = User::find(1);
    $user->name = 'Updated Name';
    
    Audit::log($user); // Automatically captures changes, including inverse-side associations
    

Where to Look First

  • Doctrine Events: The package hooks into preUpdate, prePersist, and preRemove events. New in 1.2.0: Fixed inverse-side OneToMany association auditing.
  • Audit Configuration: Check config/audit.php for provider-specific settings (e.g., ignored attributes, metadata).
  • Entity Metadata: Ensure your entities are properly annotated with @ORM\HasLifecycleCallbacks and @ORM\Entity.
  • Release Notes: 1.2.0 highlights the fix for inverse-side associations.

First Use Case: Track User Updates with OneToMany

// Example: User has OneToMany relationship with Posts
use Doctrine\ORM\Event\LifecycleEventArgs;
use Audit;

class User {
    /** @ORM\OneToMany(targetEntity="Post", mappedBy="user") */
    private $posts;

    public function preUpdate(LifecycleEventArgs $args) {
        $auditor = new \Audit();
        $auditor->log($this); // Now correctly logs inverse-side (Post) changes
    }
}

Implementation Patterns

1. Event-Driven Auditing (Updated for 1.2.0)

Leverage Doctrine’s lifecycle events for seamless integration. The fix in 1.2.0 ensures inverse-side associations are audited:

// In a Doctrine subscriber or entity listener
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Audit;

class AuditSubscriber implements EventSubscriber {
    public function getSubscribedEvents() {
        return ['preUpdate', 'prePersist', 'preRemove'];
    }

    public function preUpdate(PreUpdateEventArgs $args) {
        $entity = $args->getEntity();
        Audit::log($entity); // Now includes inverse-side OneToMany changes
    }
}

2. Custom Metadata

Override default behavior via config/audit.php:

'audit' => [
    'providers' => [
        \DamienHarper\AuditorDoctrineProvider\DoctrineProvider::class => [
            'ignored_attributes' => ['password', 'temp_token'],
            'metadata' => [
                'User' => [
                    'audit_table' => 'user_audit_logs',
                    'audit_columns' => ['id', 'name', 'email'],
                ],
                'Post' => [ // Explicitly define for inverse-side associations
                    'audit_table' => 'post_audit_logs',
                ],
            ],
        ],
    ],
],

3. Bulk Operations with Inverse-Side Fix

For mass updates (e.g., via QueryBuilder), manually log changes. Note: The 1.2.0 fix ensures inverse-side associations are captured even in bulk operations:

$userIds = [1, 2, 3];
$users = User::whereIn('id', $userIds)->get();

foreach ($users as $user) {
    $user->status = 'active';
    Audit::log($user); // Logs changes, including inverse-side (Post) updates
}

4. Integration with Laravel

If using Laravel + Doctrine (e.g., via laravel-doctrine), bind the EntityManager:

// In a service provider
$this->app->bind(\Doctrine\ORM\EntityManagerInterface::class, function ($app) {
    return Doctrine::entityManager();
});

5. Querying Audit Logs

Use the Audit facade to fetch logs for entities and their inverse-side associations:

$logs = Audit::find(User::class, 1); // Get audit logs for User#1 (and related Posts)
$logs = Audit::all(); // All logs (provider-dependent)

Gotchas and Tips

Pitfalls

  1. Missing Lifecycle Callbacks

    • If entities lack @ORM\HasLifecycleCallbacks, events may not trigger.
    • Fix: Add @HasLifecycleCallbacks to entities or use a global subscriber.
  2. Inverse-Side OneToMany Associations (Fixed in 1.2.0)

    • Old Behavior: Only some inverse-side associations were logged when multiple entities were flushed together.
    • New Behavior: All inverse-side associations are now logged correctly.
    • Fix: Update to ^1.2.0 and ensure your entities have proper @ORM\OneToMany/@ORM\ManyToOne mappings.
  3. Circular Dependencies

    • Doctrine events + Audit may cause loops if not careful.
    • Fix: Avoid logging inside postUpdate/postPersist if using pre* events.
  4. Performance Overhead

    • Logging every change can slow bulk operations.
    • Fix: Batch logs or skip non-critical updates (e.g., ignored_attributes).
  5. Doctrine Version Mismatch

    • The package may not support all Doctrine versions.
    • Fix: Check composer.json for supported versions.

Debugging Tips

  1. Enable Doctrine Logging

    $entityManager->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
    

    Verify events fire during updates, especially for inverse-side associations.

  2. Check Audit Configuration Ensure the provider is listed in config/audit.php and Doctrine is autowired.

  3. Inspect Entity Metadata Use Doctrine’s metadata tools:

    php bin/console doctrine:metadata:info Your\Entity
    
  4. Log Provider Output Temporarily enable debug mode in config/audit.php:

    'debug' => true,
    
  5. Verify Inverse-Side Associations After updating to 1.2.0, test bulk operations to confirm inverse-side associations are logged:

    $user1 = new User(); $user1->posts = [new Post(), new Post()];
    $user2 = new User(); $user2->posts = [new Post()];
    $entityManager->persist($user1);
    $entityManager->persist($user2);
    $entityManager->flush(); // All Post entities should now be audited
    

Extension Points

  1. Custom Audit Tables Extend the provider to support multiple schemas/tables:

    class CustomDoctrineProvider extends \DamienHarper\AuditorDoctrineProvider\DoctrineProvider {
        protected function getAuditTable($entityName) {
            return "audit_{$entityName}_logs";
        }
    }
    
  2. Pre/Post-Processing Hook into Audit::log() to modify payloads:

    Audit::extend(function ($auditor, $entity) {
        $auditor->setMetadata('custom_field', 'value');
    });
    
  3. Conditional Logging Skip audits for specific actions:

    if (!$this->shouldAudit()) {
        return;
    }
    Audit::log($entity);
    
  4. Testing Inverse-Side Associations Add tests for bulk operations with inverse-side relationships:

    public function testBulkInverseSideAudit() {
        $user1 = new User(); $user1->posts = [new Post(), new Post()];
        $user2 = new User(); $user2->posts = [new Post()];
        $entityManager->persist($user1);
        $entityManager->persist($user2);
        $entityManager->flush();
    
        $this->assertCount(3, Audit::find(Post::class)); // All Posts audited
    }
    

Config Quirks

  • Case Sensitivity: Entity names in `metadata
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle