morningcore/laravel-gamify

在 Laravel 应用中添加游戏化功能,支持声誉积分和徽章

2.0.0 2023-11-30 07:00 UTC

This package is auto-updated.

Last update: 2024-08-30 01:12:02 UTC


README

Latest Version on Packagist Software License Build Status Total Downloads

使用 qcod/laravel-gamify 快速在 Laravel 应用中添加声誉积分和徽章。

安装

1 - 您可以通过 composer 安装此包

$ composer require qcod/laravel-gamify

2 - 如果您正在安装 Laravel 5.4 或更低版本,您需要手动注册 Service Provider,将其添加到 config/app.php 的 providers 数组中。

'providers' => [
    //...
    QCod\Gamify\GamifyServiceProvider::class
]

在 Laravel 5.5 及更高版本中,服务提供者将自动注册。

3 - 现在发布 gamify 表的迁移

php artisan vendor:publish --provider="QCod\Gamify\GamifyServiceProvider" --tag="migrations"

注意: 它将生成 reputationsbadgesuser_badges 表的迁移,以及为 users 表添加声誉字段的迁移以存储积分。为了支持删除和添加列,您需要运行 composer require doctrine/dbal

php artisan migrate

您可以发布配置文件

php artisan vendor:publish --provider="QCod\Gamify\GamifyServiceProvider" --tag="config"

如果您的收款人(获得积分的模型)模型是 App\User,则不需要在 config/gamify.php 中进行任何更改。

入门指南

1. 在包安装后,现在将 Gamify 特性添加到 App\User 模型或任何充当 用户 的模型。

use QCod\Gamify\Gamify;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable, Gamify;

⭐️ 👑 声誉积分

2 下一步是创建一个积分。

php artisan gamify:point PostCreated

它将在 app/Gamify/Points/ 文件夹下创建一个名为 PostCreated 的 PointType 类。

<?php

namespace App\Gamify\Points;

use QCod\Gamify\PointType;

class PostCreated extends PointType
{
    /**
     * Number of points
     *
     * @var int
     */
    public $points = 20;

    /**
     * Point constructor
     *
     * @param $subject
     */
    public function __construct($subject)
    {
        $this->subject = $subject;
    }

    /**
     * User who will be receive points
     *
     * @return mixed
     */
    public function payee()
    {
        return $this->getSubject()->user;
    }
}

给用户积分

现在,在您创建帖子的控制器中,您可以这样给予积分

$user = $request->user();
$post = $user->posts()->create($request->only(['title', 'body']));

// you can use helper function
givePoint(new PostCreated($post));

// or via HasReputation trait method
$user->givePoint(new PostCreated($post));

撤销已给予的积分

在某些情况下,您可能想撤销已给予的积分,例如,用户删除了他的帖子。

// via helper function
undoPoint(new PostCreated($post));
$post->delete();

// or via HasReputation trait method
$user->undoPoint(new PostCreated($post));
$post->delete();

您也可以在辅助函数 givePoint(new PostCreated($post, $user)) 中传递第二个参数 $user,默认是 auth()->user()。

技巧 您还可以挂钩到 Eloquent 模型事件,在 created 事件上给予积分。同样,可以使用 deleted 事件来撤销积分。

获取总声誉

要获取用户的总声誉,您可以使用 $user->getPoints($formatted = false) 方法。可选地,您可以传递 $formatted = true 以获取声誉如 1K+、2K+ 等。

// get integer point
$user->getPoints(); // 20

// formatted result
$user->getPoints(true); // if point is more than 1000 1K+

获取声誉历史

由于该包存储了所有声誉事件日志,因此您可以通过以下关系获取声誉历史

foreach($user->reputations as $reputation) {
    // name of the point type 
    $reputation->name
    
    // payee user
    $reputation->payee
    
    // how many points
    $reputation->point
    
    // model on which point was given 
    $reputation->subject
}

如果您想获取对 subject 模型给予的所有积分。您应该在模型中定义一个 morphMany 关系。例如,在帖子模型中。

    /**
     * Get all the post's reputation.
     */
    public function reputations()
    {
        return $this->morphMany('QCod\Gamify\Reputation', 'subject');
    }

现在您可以使用 $post->reputations 获取对 Post 给予的所有声誉。

配置积分类型

积分收款人

在大多数情况下,您传递到积分 new PostCreated($post) 中的主题模型将与用户通过某种关系相关。

class PostCreated extends PointType
{
    public $points = 20;
    
    protected $payee = 'user';
    
    // dont need this, payee property will return subject realtion 
    // public function payee()
    // {
    //    return $this->getSubject()->user;
    // }
}

动态积分

如果积分是基于某些逻辑计算的,则应该添加 getPoints() 方法来进行计算,并始终返回一个整数。

class PostCreated extends PointType
{
    protected $payee = 'user';
    
    public function getPoints()
    {
        return $this->getSubject()->user->getPoint() * 10;
    }
}

积分限定符

这是一个可选方法,它返回布尔值。如果是 true,则此积分将被给予,否则将被忽略。如果您想动态确定积分的资格,这将非常有用。

防止重复声誉

默认情况下,您可以多次对同一模型主题给予积分。但您可以通过在类中添加以下属性来防止它

class PostCreated extends PointType
{
    // prevent duplicate point
    public $allowDuplicates = false;

    protected $payee = 'user';
}

声誉变更事件

每次用户积分更改时,都会触发 \QCod\Gamify\Events\ReputationChanged 事件,该事件具有以下负载

class ReputationChanged implements ShouldBroadcast {
    
    ...
    public function __construct(Model $user, int $point, bool $increment)
    {
        $this->user = $user;
        $this->point = $point;
        $this->increment = $increment;
    }
}

此事件也将广播到配置的频道名称,您可以通过前端通过socket实时更新声誉点来收听它。

🏆 🏅 成就徽章

与积分类型类似,您还有徽章。可以根据排名或其他任何标准将徽章授予用户。您应该在 config/gamify.php 中定义徽章级别。

// All the levels for badge
'badge_levels' => [
    'beginner' => 1,
    'intermediate' => 2,
    'advanced' => 3,
],

// Default level
'badge_default_level' => 1

徽章级别以 tinyint 存储为整数,以便在需要时更快地进行排序。

创建徽章

要生成徽章,您可以运行以下提供的命令

php artisan gamify:badge FirstContribution

它将在 app/Gamify/Badges/ 文件夹下创建一个名为 FirstContributionBadgeType 类。

<?php

namespace App\Gamify\Badges;

use QCod\Gamify\BadgeType;

class FirstContribution extends BadgeType
{
    /**
     * Description for badge
     *
     * @var string
     */
    protected $description = '';

    /**
     * Check is user qualifies for badge
     *
     * @param $user
     * @return bool
     */
    public function qualifier($user)
    {
        return $user->getPoints() >= 1000;
    }
}

如您所见,此徽章有一个 $description 字段和一个 qualifier($user) 方法。Gamify 包将监听声誉点的任何变化,并将用户与所有可用的徽章进行比较,并授予所有符合资格的徽章。

更改徽章名称

默认情况下,徽章名称将是徽章类名称的漂亮版本。在上面的例子中,它将是 First Contribution。您可以在类中添加 $name 属性来更改它,或者如果您想动态命名,可以覆盖 getName() 方法。

更改徽章图标

与名称类似,您可以通过 $icon 属性或通过 getIcon() 方法来更改它。当您在类中定义图标时,需要指定包含扩展名的完整路径。《config/gamify.php》文件夹中的 badge_icon_folderbadge_icon_extension 不会被使用。

更改徽章级别

您可以使用相同的 $level 属性或通过 getLevel() 方法来更改它。它的像徽章的类别,所有徽章都在 config/gamify.php 中定义为 badge_levels。如果没有指定,则将从配置中使用 badge_default_level

警告 ⚠️ 不要忘记在运行 php artisan cache:forget gamify.badges.all 以添加或删除徽章时清除缓存。⚠️

获取用户的徽章

您可以通过调用 $user->badges 来获取用户的徽章,这将返回一个包含用户徽章的集合。

不使用徽章

如果您的应用程序不需要 徽章,则应仅使用 HasReputations 特性而不是 Gamify

不使用声誉历史记录

如果您不需要维护用户获得的积分的历史记录,而只想增加和减少声誉,则应使用以下方法

// to add point
$user->addPoint($point = 1);

// to reduce point
$user->reducePoint($point = 1);

// to reset point back to zero
$user->resetPoint();

您不需要为此生成积分类。

配置 Gamify

<?php

return [
    // Model which will be having points, generally it will be User
    'payee_model' => '\App\User',

    // Reputation model
    'reputation_model' => '\QCod\Gamify\Reputation',

    // Allow duplicate reputation points
    'allow_reputation_duplicate' => true,

    // Broadcast on private channel
    'broadcast_on_private_channel' => true,

    // Channel name prefix, user id will be suffixed
    'channel_name' => 'user.reputation.',

    // Badge model
    'badge_model' => '\QCod\Gamify\Badge',

    // Where all badges icon stored
    'badge_icon_folder' => 'images/badges/',

    // Extention of badge icons
    'badge_icon_extension' => '.svg',

    // All the levels for badge
    'badge_levels' => [
        'beginner' => 1,
        'intermediate' => 2,
        'advanced' => 3,
    ],

    // Default level
    'badge_default_level' => 1
];

更改日志

有关最近更改的更多信息,请参阅 CHANGELOG

测试

该包包含一些集成/烟雾测试,使用 Orchestra 设置。可以通过 phpunit 运行测试。

$ composer test

贡献

有关详细信息,请参阅 CONTRIBUTING

安全

如果您发现任何与安全相关的问题,请通过电子邮件 saquibweb@gmail.com 而不是使用问题跟踪器。

鸣谢

关于 QCode.in

QCode.in (https://www.qcode.in) 是由 Saqueib 撰写的博客,涵盖关于全栈 Web 开发的所有内容。

许可

MIT 许可证(MIT)。有关更多信息,请参阅 许可文件