maize-tech / laravel-badges
Laravel Badges
Installs: 2 240
Dependents: 0
Suggesters: 0
Security: 0
Stars: 33
Watchers: 5
Forks: 3
Open Issues: 1
Requires
- php: ^8.2
- illuminate/console: ^10.0|^11.0
- illuminate/database: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- spatie/laravel-package-tools: ^1.14.1
Requires (Dev)
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.8|^8.1
- nunomaduro/larastan: ^2.0.1
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^2.20
- pestphp/pest-plugin-arch: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
This package is auto-updated.
Last update: 2024-10-08 03:14:35 UTC
README
Laravel Badges
This package lets you easily add badge mechanics to your application.
Installation
You can install the package via composer:
composer require maize-tech/laravel-badges
You can publish the config and migration files and run the migrations with:
php artisan badges:install
This is the contents of the published config file:
return [ /* |-------------------------------------------------------------------------- | Badge model |-------------------------------------------------------------------------- | | Here you may specify the fully qualified class name of the badge model. | */ 'model' => Maize\Badges\Models\BadgeModel::class, /* |-------------------------------------------------------------------------- | Badges |-------------------------------------------------------------------------- | | Here you may specify the list of fully qualified class name of badges. | */ 'badges' => [ // App\Badges\FirstLogin::class, ], ];
Usage
Basic
To use the package, firstly you should implement the Maize\Badges\HasBadges
interface and apply the Maize\Badges\InteractsWithBadges
trait to all models who can have badges:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Maize\Badges\HasBadges; use Maize\Badges\InteractsWithBadges; class User extends Authenticatable implements HasBadges { use InteractsWithBadges; }
Once done, all you have to do is define a class for each badge, extend the Maize\Badges\Badge
class and implement the isAwarded
abstract method:
<?php namespace App\Badges; use Illuminate\Database\Eloquent\Model; use Maize\Badges\Badge; class FirstLogin extends Badge { public static function isAwarded(Model $model): bool { return $model->logins()->exists(); } }
Once done, don't forget to list the newly created badge within the badges
list under config/badges.php
:
'badges' => [ App\Badges\FirstLogin::class, ],
Progressable badges
If your badge can have progress, you should extend the Maize\Badges\ProgressableBadge
class and implement both the getTotal
and getCurrent
abstract methods:
<?php namespace App\Badges; use Illuminate\Database\Eloquent\Model; use Maize\Badges\ProgressableBadge; class FiveLogins extends ProgressableBadge { public static function getTotal(): int { return 5; } public static function getCurrent(Model $model): bool { return $model->logins()->count(); } }
Under the hoods, the isAwarded
method checks if getCurrent
is equals or greater than getTotal
.
Badge metadata
What is a badge without a name or description?
To accomplish this, you can override the metadata
method within all badge classes.
Here is an example implementation using Laravel built-in translation method and the badge slug:
<?php namespace App\Badges; use Illuminate\Database\Eloquent\Model; use Maize\Badges\Badge; class FirstLogin extends Badge { public static function isAwarded(Model $model): bool { return $model->logins()->exists(); } public static function metadata(): array { $slug = static::slug(); return [ 'name' => __("badges.{$slug}.name"), 'description' => __("badges.{$slug}.name"), ]; } }
Once done, you can retrieve the metadata using both the badge class and the BadgeModel
entities:
use App\Badges\FirstLogin; use Maize\Badges\Models\BadgeModel; $user->giveBadge(FirstLogin::class); $user->badges()->first()->metadata; // returns the list of metadata attributes $user->badges()->first()->getMetadata('description'); // returns the attribute with key 'description' FirstLogin::metadata(); // returns the list of metadata attributes FirstLogin::getMetadata('description'); // returns the metadata attribute with key 'description'
Custom badge slug
All badges have a default slug used when storing a badge awarded event into the database.
The default slug is the badge's fully qualified class name.
For example, FirstLogin
badge's slug would be App\Badges\FirstLogin
.
You can however customize the default behaviour overriding the slug
method.
Here is an example using the badge's class basename in kebab case:
<?php namespace App\Badges; use Illuminate\Database\Eloquent\Model; use Maize\Badges\Badge; class FirstLogin extends Badge { public static function slug(): string { return str(static::class) ->classBasename() ->kebab() ->toString(); // returns 'first-login' } public static function isAwarded(Model $model): bool { return $model->logins()->exists(); } }
Beware that all badge classes should have a unique slug to prevent inconsistencies.
Giving a badge
You can give a badge to any entity implementing the HasBadges
interface using one of the following methods:
use App\Badges\FirstLogin; $user->giveBadge(FirstLogin::class); FirstLogin::giveTo($user);
When giving a badge, the isAwarded
method will be evaluated to make sure the entity meets the conditions.
Every time a badge is given, a BadgeAwarded
event will also be fired.
Check if a badge is awarded
To check if an entity has a badge, you can use the hasBadge
method:
use App\Badges\FirstLogin; $user->hasBadge(FirstLogin::class)
Retrieve awarded badges
To retrieve all badges awarded by an entity, you can use the badges
relationship which returns a list of BadgeModel
entities.
use Maize\Badges\Models\BadgeModel; $user->badges->map->badge; // returns the list of awarded badges slug
Sync badges
To sync all badges for a given entity, you can use the syncBadges
method, which retrieves all badges within the badges
list under config/badges.php
and checks whether it can be awarded or not.
$user->syncBadges();
Scheduling badges cleanup
The package also comes with the badges:clear
command, which automatically deletes all stored badges which are not anymore listed within the badges
list under config/badges.php
:
You may schedule the command using the schedule
method of the console kernel (usually located under the App\Console
directory):
use Maize\Badges\Commands\ClearBadgesCommand; $schedule->command(ClearBadgesCommand::class)->daily();
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.