Installation:
composer require panoscape/history
For Laravel 5.6.x, use composer require "panoscape/history:^1.0".
Publish Config & Migrations:
php artisan vendor:publish --provider="Panoscape\History\HistoryServiceProvider" --tag=migrations
php artisan vendor:publish --provider="Panoscape\History\HistoryServiceProvider" --tag=config
Run migrations:
php artisan migrate
Enable History for a Model:
Use the HasHistory trait in your Eloquent model:
use Panoscape\History\Traits\HasHistory;
class User extends Model
{
use HasHistory;
}
First Use Case: Track changes to a model:
$user = User::find(1);
$user->name = 'Updated Name';
$user->save(); // Automatically records history
Tracking Changes:
HasHistory trait.save(), update(), and create() operations are automatically tracked.$post = Post::find(1);
$post->title = 'New Title';
$post->save(); // History recorded in `history_entries` table
Querying History:
history() method:
$history = $post->history()->latest()->get();
$history = $post->history()->whereField('title')->get();
Customizing History:
getHistoryAttributes() to specify fields to track:
protected function getHistoryAttributes()
{
return ['title', 'content', 'published_at'];
}
protected function getHistoryExcludedAttributes()
{
return ['password', 'api_token'];
}
Manual History Recording:
$user->recordHistory(); // Manually record changes
Soft Deletes:
use Panoscape\History\Traits\HasSoftDeletes;
class HistoryEntry extends Model
{
use HasSoftDeletes;
}
history.created events for custom logic:
History::created(function ($history) {
// Custom logic (e.g., notifications)
});
Route::get('/posts/{post}/history', function (Post $post) {
return $post->history()->latest()->get();
});
Performance:
visits).getHistoryAttributes() to limit tracked fields.Database Bloat:
HistoryEntry::where('created_at', '<', now()->subYears(1))->delete();
Soft Deletes:
history_entries table has deleted_at column:
Schema::table('history_entries', function (Blueprint $table) {
$table->softDeletes();
});
Mass Updates:
User::update(['active' => false])) may not trigger history. Use individual updates or manual recording:
User::chunk(100, function ($users) {
foreach ($users as $user) {
$user->active = false;
$user->save(); // Triggers history
}
});
Model Events:
saving() or saved() may interfere with history tracking. Use getHistoryAttributes() instead.Missing History:
HasHistory trait is applied.history_entries table exists and has correct columns (model_type, model_id, changes, etc.).History::setDebug(true); // Logs history operations
Incorrect Changes:
getHistoryAttributes() includes the modified fields.dd($history->changes) to inspect recorded changes.Custom History Table:
'table' => 'custom_history_entries',
php artisan vendor:publish --provider="Panoscape\History\HistoryServiceProvider" --tag=migrations
Custom History Model:
HistoryEntry model:
class CustomHistoryEntry extends Panoscape\History\Models\HistoryEntry
{
protected $table = 'custom_history';
}
HistoryServiceProvider:
$this->app->bind(
Panoscape\History\Models\HistoryEntry::class,
CustomHistoryEntry::class
);
Custom Change Format:
getChanges() in HasHistory trait to format changes differently:
protected function getChanges(array $old, array $new)
{
return ['custom_format' => $old, 'custom_new' => $new];
}
Middleware for History:
public function handle($request, Closure $next)
{
History::disable();
$response = $next($request);
History::enable();
return $response;
}
How can I help you explore Laravel packages today?