qcod/laravel-gamify

在 Laravel 应用中添加声誉积分和徽章支持以实现游戏化

1.0.8 2024-08-24 04:32 UTC

This package is auto-updated.

Last update: 2024-09-24 05:10:50 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 或更低版本,您需要手动在 config/app.php 中的 providers 数组中添加 Service Provider

'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;
    }
}

积分限定符

这是一个可选方法,它返回一个布尔值,如果为真,则分配此积分,否则忽略。如果需要动态确定积分资格,这将很有帮助。

防止重复声誉

默认情况下,您可以多次为同一模型主题分配积分。但您可以添加以下属性到类中防止重复。

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;
    }
}

此事件也会在配置的频道名称中广播,因此您可以通过套接字从前端实时更新声誉积分来收听它。

🏆 🏅 成就徽章

与积分类型类似,您还有徽章。您可以根据排名或其他标准将徽章授予用户。您应该在 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
];

变更日志

请参阅 变更日志 了解最近更改的更多信息。

测试

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

$ composer test

贡献

有关详细信息,请参阅 贡献指南

安全

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

鸣谢

关于 QCode.in

QCode.in (https://www.qcode.in) 是由 Saqueib 创办的博客,涵盖了关于全栈 Web 开发的一切。

许可证

MIT 许可证 (MIT)。请参阅 许可证文件 了解更多信息。