developer-savyour/laravel-gamify

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

1.0.3 2019-09-05 14:13 UTC

This package is auto-updated.

Last update: 2024-09-25 19:03:41 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数组中。

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

Laravel 5.5及以上版本中服务提供者会自动注册。

3 - 现在发布游戏化表的迁移

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. 在包安装后,现在在App\User模型或任何在您的应用中充当用户的模型上添加Gamify特质。

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)。请参阅 许可文件 了解更多信息。