Git Product home page Git Product logo

laravel-badges's Introduction

Social Card of Laravel Badges

Laravel Badges

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

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.

laravel-badges's People

Contributors

dependabot[bot] avatar enricodelazzari avatar github-actions[bot] avatar riccardodallavia avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.