Installation:
composer require qirolab/laravel-bannable
(Auto-discovery handles Laravel 5.5+; manually register Qirolab\Laravel\Bannable\BannableServiceProvider for older versions.)
Publish Config (Optional):
php artisan vendor:publish --provider="Qirolab\Laravel\Bannable\BannableServiceProvider"
(Default config is minimal; customize if needed.)
Make a Model Bannable:
Use the Bannable trait in your Eloquent model:
use Qirolab\Laravel\Bannable\Traits\Bannable;
class User extends Model
{
use Bannable;
}
First Use Case: Ban a model instance:
$user = User::find(1);
$user->ban(); // Adds `banned_at` timestamp and sets `is_banned` to true
Banning/Unbanning:
// Ban with optional reason
$model->ban('Spam behavior detected');
// Unban
$model->unban();
Query Scoping:
// Active (non-banned) models
User::active()->get();
// Banned models
User::banned()->get();
Soft-Deletes Integration:
If using SoftDeletes, banned models are not automatically soft-deleted. Use:
$model->ban()->forceDelete(); // Explicitly delete
Customizing Ban Logic:
Override isBanned() in your model to add custom logic:
public function isBanned()
{
return parent::isBanned() || $this->suspiciousActivity > 5;
}
banned/unbanned events:
event(new Banned($model, 'Reason'));
return User::active()->get()->map(fn ($user) => $user->only(['id', 'name']));
banned_at and ban_reason in admin interfaces for visibility.Database Schema:
is_banned (boolean) and banned_at (timestamp) columns automatically on first ban.Schema::table('users', function (Blueprint $table) {
$table->boolean('is_banned')->default(false);
$table->timestamp('banned_at')->nullable();
$table->string('ban_reason')->nullable();
});
Caching:
isBanned() checks are not cached by default. For high-traffic apps, cache the result:
public function isBanned()
{
return Cache::remember("user_{$this->id}_is_banned", now()->addHours(1), function () {
return parent::isBanned();
});
}
Mass Actions:
ban() in bulk operations (e.g., User::all()->ban()). Use query builder:
User::where('role', 'spammer')->update(['is_banned' => true, 'banned_at' => now()]);
ban() doesn’t trigger, check for:
use Bannable trait.DB::transaction() if needed).$model->ban('Violated ToS'); // Logs to `ban_reason`
Custom Ban Fields:
Override getBanAttributes() to add custom fields (e.g., banned_by):
protected function getBanAttributes()
{
return array_merge(parent::getBanAttributes(), ['banned_by' => auth()->id()]);
}
Ban Expiry:
Add unban_at and auto-unban logic:
public function ban($reason = null)
{
parent::ban($reason);
$this->unban_at = now()->addDays(30);
}
Policy Integration:
Use the isBanned() check in policies:
public function viewAny(User $user)
{
return !$user->isBanned();
}
config/bannable.php:
'default_reason' => 'Account banned by administrator',
'auto_unban' => true, // Unbans when `unban_at` is reached
How can I help you explore Laravel packages today?