Laravel 12
PHP 8.2+
Low commit activity in last 18 months
A long-lived project that still receives updates
Journalism is a Laravel package providing a simple way to log data to your database
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

brainmaestro/composer-git-hooks
^3.0
phpunit/phpunit
^11.0
vimeo/psalm
^6.0

Runtime

 Project Readme

Journalism

Journalism is a Laravel package providing a simple way to log data to your database.

Installation

composer require thtg88/journalism

You can publish the configuration file and views by running:

php artisan vendor:publish --provider="Thtg88\Journalism\JournalismServiceProvider"

Usage

Journalism is particularly useful when tracking changes to models.

You can therefore apply it to either a generic model observer for every model event (create, update, and destroy) or, if you use the repository pattern to all your CRUD methods to track what, when, and by whom certain changes have occurred.

Make sure you register the helper as a singleton in your AppServiceProvider:

// app/Providers/AppServiceProvider.php

use Thtg88\Journalism\Helpers\JournalEntryHelper;

public function register(): void
{
    $this->app->singleton(JournalEntryHelper::class, static function ($app) {
        return $app->make(JournalEntryHelper::class);
    });
}

Or you can simply use it in whichever class you prefer:

use Thtg88\Journalism\Helpers\JournalEntryHelper;

(new JournalEntryHelper())->createJournalEntry('create', $model, ['foo' => 'bar']);

Using Model Observers

For more documentation on model observer, see the Laravel docs

First, create a base model observer:

<?php

// app/Observers/Observer.php

namespace App\Observers;

use Illuminate\Database\Eloquent\Model;
use Thtg88\Journalism\Helpers\JournalEntryHelper;
use Thtg88\Journalism\Models\JournalEntry;

abstract class Observer
{
    /**
     * Handle the Model "created" event.
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     * @return void
     */
    public function created(Model $model): void
    {
        if (config('journalism.enabled') === false) {
            return;
        }

        // Create journal entry only if not creating journal entry i.e. infinite recursion
        if ($model instanceof JournalEntry) {
            return;
        }

        app(JournalEntryHelper::class)->createJournalEntry(
            'create',
            $model,
            $model->toArray(),
        );
    }

    /**
     * Handle the Model "updated" event.
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     * @return void
     */
    public function updated(Model $model): void
    {
        if (config('journalism.enabled') === false) {
            return;
        }

        // Create journal entry only if not creating journal entry i.e. infinite recursion
        if ($model instanceof JournalEntry) {
            return;
        }

        app(JournalEntryHelper::class)->createJournalEntry(
            'update',
            $model,
            $model->toArray(),
        );
    }

    /**
     * Handle the Model "deleted" event.
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     * @return void
     */
    public function deleted(Model $model): void
    {
        if (config('journalism.enabled') === false) {
            return;
        }

        // Create journal entry only if not creating journal entry i.e. infinite recursion
        if ($model instanceof JournalEntry) {
            return;
        }

        app(JournalEntryHelper::class)->createJournalEntry('delete', $model);
    }

    /**
     * Handle the Model "forceDeleted" event.
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     * @return void
     */
    public function forceDeleted(Model $model): void
    {
        if (config('journalism.enabled') === false) {
            return;
        }

        // Create journal entry only if not creating journal entry i.e. infinite recursion
        if ($model instanceof JournalEntry) {
            return;
        }

        app(JournalEntryHelper::class)->createJournalEntry('delete', $model);
    }
}

Then, create an actual model observer, extending your base one:

<?php

// app/Observers/UserObserver.php

namespace App\Observers;

class UserObserver extends Observer
{
}

Register it in EventServiceProvider:

use App\Models\User;
use App\Observers\UserObserver;

public function boot()
{
    User::observe(UserObserver::class);
}

Now you can perform a database operation using the user model. A database row should appear in the journal_entries table!

Using the Repository Pattern

Coming soon!

License

Journalism is open-sourced software licensed under the MIT license.

Security Vulnerabilities

If you discover a security vulnerability within Journalism, please send an e-mail to Marco Marassi at security@marco-marassi.com. All security vulnerabilities will be promptly addressed.