PHPackages                             denismitr/laravel-event-recorder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. denismitr/laravel-event-recorder

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

denismitr/laravel-event-recorder
================================

Laravel Event Recorder

v2.0(7y ago)490MITPHPPHP &gt;=7.0

Since Aug 8Pushed 7y ago2 watchersCompare

[ Source](https://github.com/denismitr/laravel-event-recorder)[ Packagist](https://packagist.org/packages/denismitr/laravel-event-recorder)[ RSS](/packages/denismitr-laravel-event-recorder/feed)WikiDiscussions master Synced yesterday

READMEChangelog (3)Dependencies (8)Versions (10)Used By (0)

Laravel Event Recorder
----------------------

[](#laravel-event-recorder)

[![Build Status](https://camo.githubusercontent.com/a5fb1b354517d0d2cc4bd6ff14c9694b50233266f93755ad81ed3c66a8f48b16/68747470733a2f2f7472617669732d63692e6f72672f64656e69736d6974722f6c61726176656c2d6576656e742d7265636f726465722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/denismitr/laravel-event-recorder)

Author
------

[](#author)

Denis Mitrofanov

### Requirements

[](#requirements)

PHP 7.0 or higher MYSQL 5.7 or higher or POSTGRES probably any 9.\* version or higher will do Laravel &gt;=5.5

### Version 2.x

[](#version-2x)

### Overview

[](#overview)

Any class that should be recorded to DB must implement the `Denismitr\EventRecorder\Contracts\ShouldBeRecorded` interface or extend `Denismitr\EventRecorder\ConditionallyRecordable` abstract class that gives ability to record events only under certain conditions. Both ways enforce the concrete implementation of two methods `getProperties(): array`and `getDescription(): string` methods, plus a method `public function shouldBeSkipped(): bool`, in case of extending the abstract class, can be overridden when you wish to skip the recording of event under certain conditions. Properties returned by the `getProperties()` are an arbitrary array of important **key-value** pairs for the given event that you wish to log/persist. (see example below). `getDescription(): string` is just a human readable form of the event that occurred. The properties are stored in **json** format and description is a **VARCHAR** 512 (configurable) string field.

### Installation

[](#installation)

Via composer `composer require denismitr/laravel-event-recorder`

In Laravel 5.5 the service provider will automatically get registered. But you can register it manually too in the `config/app.php` file:

```
'providers' => [
    // ...
    Denismitr\EventRecorder\EventRecorderServiceProvider::class,
];

```

You can publish the migration with:

```
php artisan vendor:publish --provider="Denismitr\EventRecorder\EventRecorderServiceProvider" --tag="migrations"
```

You can publish the config file with:

```
php artisan vendor:publish --provider="Denismitr\EventRecorder\EventRecorderServiceProvider" --tag="config"
```

After the migration has been published and you are happy with configuration, run the mirations: `php artisan migrate`

### Usage

[](#usage)

Let's imagine we have a `MoneyAddedToWallet` event:

```
class MoneyAddedToWallet implements ShouldBeRecorded
{
    /**
     * @var Wallet
     */
    public $wallet;

    /**
     * @var int
     */
    public $amount;

    /**
     * MoneyAddedToWallet constructor.
     * @param Wallet $wallet
     * @param int $amount
     */
    public function __construct(Wallet $wallet, int $amount)
    {
        $this->wallet = $wallet;
        $this->amount = $amount;
    }

    public function getProperties(): array
    {
        return [
            'wallet_id' => $this->wallet->id,
            'amount' => $this->amount,
            'user_id' => $this->wallet->user_id,
            'operation' => 'credit',
        ];
    }

    public function getDescription(): string
    {
        return vsprintf("User with ID %s added %d to the wallet with ID %s", [
            $this->wallet->user_id,
            $this->amount,
            $this->wallet->id,
        ]);
    }
}
```

Or another option with inheritance:

```
class MoneyAddedToWallet extends ConditionallyRecordable
{
    use TriggeredByUser;

    /**
     * @var Wallet
     */
    public $wallet;

    /**
     * @var int
     */
    public $amount;

    /**
     * @var bool
     */
    public $byAdmin;

    /**
     * MoneyAddedToWallet constructor.
     * @param Wallet $wallet
     * @param int $amount
     * @param bool $byAdmin
     */
    public function __construct(Wallet $wallet, int $amount, $byAdmin = false)
    {
        $this->wallet = $wallet;
        $this->amount = $amount;
        $this->byAdmin = $byAdmin;
    }

    public function getProperties(): array
    {
        return [
            'wallet_id' => $this->wallet->id,
            'amount' => $this->amount,
            'user_id' => $this->getTriggeredById(),
            'operation' => 'credit',
        ];
    }

    public function getDescription(): string
    {
        return vsprintf("User with ID %s added $%d to the wallet with ID %s", [
            $this->getTriggeredById(),
            $this->amount,
            $this->wallet->id,
        ]);
    }

    // This method overrides default implementation
    // that always return false
    public function shouldBeSkipped(): bool
    {
        // skip events generated by admin action
        return !! $this->byAdmin;
    }
}
```

After it is fired. A record in the `recorded_events` table will be created. The following extract from test file hopefully explains what is going on.

```
event(new MoneyAddedToWallet($this->wallet, 1234));

$recordedEvent = RecordedEvent::first();

$this->assertEquals(MoneyAddedToWallet::class, $recordedEvent->class);
// json properties
$this->assertEquals(1234, $recordedEvent->properties->get('amount'));
$this->assertEquals($this->wallet->id, $recordedEvent->properties->get('wallet_id'));
$this->assertEquals($this->user->id, $recordedEvent->properties->get('user_id'));
$this->assertEquals('credit', $recordedEvent->properties->get('operation'));

$this->assertDatabaseHas('recorded_events', [
    'name' => 'money_added_to_wallet',
    'class' => 'Denismitr\EventRecorder\Tests\Stubs\Events\MoneyAddedToWallet',
    'description' => "User with ID {$this->user->id} added 1234 to the wallet with ID {$this->wallet->id}"
]);
```

Two important things to notice:

- first - this package uses a dependency [denismitr/laravel-json-attributes](https://github.com/denismitr/laravel-json-attributes)to handle json properties in an elegant way. See the [docs](https://github.com/denismitr/laravel-json-attributes) for more information.
- second - there is a column **name** in `recorded_events` it is being generated from the full event class in the form of **snake cased class name** (without the namespace).

### Triggered By

[](#triggered-by)

As of version 1.0 package supports recording an ID of a user who triggered an event and as of version 2.0 also you can store arbitrary attributes of the user. If you use a trait `Denismitr\EventRecorder\TriggeredByUser` in the event class you wish to record, when event occurs the user who is currently logged in ID will be saved along with other data for this event. The DB column in `recorded_events` used for this is called `triggered_by_id`. There is a Laravel `belongsTo` relationship defined in `RecordedEvents` model. This way you can retrieve an instance of a user whose actions have triggered the event.

As of version 2.0 there is a **nullable** `triggered_by_properties` column added to the schema. And a new trait `Denismitr\EventRecorder\Traits\CanTriggerEvents` that is responsible for picking, filtering the user data for stroing into that column. Use of this trait is **optional**. By default it will persist all attributes that the given **User** model has, except for those included in the standard **Laravel** User model `$hidden` array. You can further control what attributes should not be persisted by adding `public $eventAttributeBlacklist = [];` to your User model and filling it with attributes you wish to exclude.

Since this trait is responsible only for storing user data as json, not using it will not prevent the storing of user id as `triggered_by_id` that is fully the responsibility of the `Denismitr\EventRecorder\TriggeredByUser` and the event class where it is being used.

### Configuration

[](#configuration)

The contents of configuration file is as follows:

```
return [
    'triggered_by_id_type' => 'unsignedInteger',

    'triggered_by_class' => 'App\User',

    'max_length' => [
        'event_name' => 100,
        'event_description' => 512,
    ]
];
```

If you need to change some of these properties, be sure to do that before you actually run the `php artisan migrate`, otherwise you will have to do either `php artisan migrate:fresh`or if it is already impossible, you would have to manually create the logic for changing your DB schema.

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

9

Last Release

2828d ago

Major Versions

v0.5 → v1.0.x-dev2018-08-12

v1.0 → v2.0.x-dev2018-08-15

PHP version history (3 changes)v0.1PHP ^7.1

v0.3PHP &gt;=7.1

v0.5PHP &gt;=7.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/6d68ae5d5ca94f49a69f961a7825865d92247b09e276a25fcc6ad485d4c8c964?d=identicon)[denismitr](/maintainers/denismitr)

---

Top Contributors

[![denismitr](https://avatars.githubusercontent.com/u/16356446?v=4)](https://github.com/denismitr "denismitr (31 commits)")

---

Tags

eventslaravellaraveleventsevent sourcingdenismitrevent-recording

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/denismitr-laravel-event-recorder/health.svg)

```
[![Health](https://phpackages.com/badges/denismitr-laravel-event-recorder/health.svg)](https://phpackages.com/packages/denismitr-laravel-event-recorder)
```

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M687](/packages/barryvdh-laravel-ide-helper)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[spatie/laravel-enum

Laravel Enum support

3655.4M31](/packages/spatie-laravel-enum)[psalm/plugin-laravel

Psalm plugin for Laravel

3274.9M308](/packages/psalm-plugin-laravel)[chelout/laravel-relationship-events

Missing relationship events for Laravel

5252.3M17](/packages/chelout-laravel-relationship-events)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
