faustvik / yii2-audit-log
Audit log package for Yii2 with framework-agnostic core
v2.0.0
2026-07-16 16:55 UTC
Requires
- php: >=8.2
- psr/event-dispatcher: ^1.0
- psr/log: ^3.0
- yiisoft/yii2: ^2.0.51
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
- rector/rector: ^2.3
- symfony/console: ^7.4
- yidas/yii2-bower-asset: ^2.0
This package is auto-updated.
Last update: 2026-07-16 16:59:00 UTC
README
Audit logging package for Yii2 applications with framework-agnostic core.
Features
- Automatic logging - INSERT, UPDATE, DELETE operations via Behavior
- Batch logging - Atomic multi-record saves with
logBatch()— all or nothing - Events - Before/After log events for customization (including batch events)
- Query builder - Advanced filtering with AuditLogQuery
- Ready-to-use widgets - Display change history with filters
- Framework-agnostic core - Can be used with any PHP framework
- Yii2 integration - Behavior, Widgets, Migrations out of the box
Requirements
- PHP 8.2+
- Yii2 2.0.51+
Quick Start
1. Install via Composer
composer require faustvik/yii2-audit-log
2. Add Behavior to Model
use FaustVik\AuditLog\Yii2\Integration\AuditLogBehavior; class User extends ActiveRecord { public function behaviors(): array { return [ 'auditLog' => [ 'class' => AuditLogBehavior::class, 'excludeAttributes' => ['hash_password', 'auth_key'], ], ]; } }
3. Display in View
<?= \FaustVik\AuditLog\Yii2\Integration\AuditLogFilterWidget::widget([ 'model' => $user, 'pageSize' => 20, 'title' => 'Change History', ]) ?>
Documentation
Structure
src/
├── Core/ # Framework-agnostic core
│ ├── Contracts/ # Interfaces
│ ├── DTO/ # Data Transfer Objects
│ ├── Enums/ # Enumerations
│ ├── Events/ # BeforeLogEvent, AfterLogEvent, BeforeLogBatchEvent, AfterLogBatchEvent
│ ├── Exceptions/ # Exceptions
│ ├── Query/ # AuditLogQuery
│ └── Services/ # AuditLogger
│
└── Yii2/ # Yii2 integration
├── Adapter/ # Adapters for Yii2
├── Integration/ # Behavior, Widgets
└── Migrations/ # Migration base classes
Example Usage
Logging with Events
// In bootstrap.php Yii::$app->on( \FaustVik\AuditLog\Core\Events\BeforeLogEvent::class, function (\FaustVik\AuditLog\Core\Events\BeforeLogEvent $event) { // Cancel logging for specific operations if ($event->entityClass === User::class && $event->operation->value === 'DELETE') { $event->stopPropagation(); } } );
Batch Logging
Log multiple operations atomically — either all records are saved or none (transaction is rolled back on failure).
/** @var \FaustVik\AuditLog\Core\Contracts\AuditLoggerInterface $logger */ $logger->logBatch([ [ 'entityClass' => User::class, 'entityId' => 1, 'operation' => \FaustVik\AuditLog\Core\Enums\Operation::Update, 'changedAttributes' => [ 'status' => ['old' => 'active', 'new' => 'banned'], ], 'customData' => ['reason' => 'policy violation'], ], [ 'entityClass' => UserProfile::class, 'entityId' => 1, 'operation' => \FaustVik\AuditLog\Core\Enums\Operation::Update, ], ]);
Cancelling a batch via event:
Yii::$app->on( \FaustVik\AuditLog\Core\Events\BeforeLogBatchEvent::class, function (\FaustVik\AuditLog\Core\Events\BeforeLogBatchEvent $event) { // Stop the entire batch $event->stopPropagation(); // Or filter items — remove sensitive entities $event->items = array_values(array_filter( $event->items, fn ($item) => $item['entityClass'] !== SensitiveModel::class, )); } );
Atomicity: logBatch() wraps all inserts in a single database transaction. If any insert fails, the transaction is rolled back and no records are saved. The error is then handled according to the configured AuditErrorMode (Ignore / Log / Throw).
Query Logs
use FaustVik\AuditLog\Core\Query\AuditLogQuery; use FaustVik\AuditLog\Core\Contracts\AuditStorageInterface; $storage = Yii::createObject(AuditStorageInterface::class); // All changes for a specific User record $logs = (new AuditLogQuery($storage)) ->forEntityClass(User::class) ->forEntityId($userId) ->operation(\FaustVik\AuditLog\Core\Enums\Operation::Update) ->dateRange('2025-01-01', '2025-12-31') ->limit(50) ->all(); // All changes across all User records today (no specific ID required) $allUserChangesToday = (new AuditLogQuery($storage)) ->forEntityClass(User::class) ->dateRange(date('Y-m-d'), date('Y-m-d')) ->all();
License
MIT
Authors
- FaustVik