skyraptor / laravel-achievements
Laravel的成就系统
Requires
- ramsey/uuid: ^3.7|^4.0
Requires (Dev)
- laravel/laravel: ^6.0|^7.0
- phpunit/phpunit: ^8
README
一个受Laravel通知系统启发的成就系统实现。这是对Gabriel Simonetti的Laravel Achievements软件包的分支和延续。
目录
要求
- Laravel 6或更高版本
- PHP 7.2或更高版本
安装
默认安装通过Composer进行。服务提供程序将自动注册。
composer require skyraptor/laravel-achievements
您可以使用以下命令发布此软件包的配置。
php artisan vendor:publish --provider="SkyRaptor\Achievements\AchievementsServiceProvider" --tag="config"
备份您的数据库并运行迁移以在数据库上设置所需的表。
php artisan migrate
创建成就
类似于Laravel对通知的实现,每个成就都由单个类(通常存储在app\Achievements
目录中)表示。当您运行make:achievement
命令时,此目录将自动为您创建。
php artisan make:achievement UserMadeAPost
此命令将在您的app/Achievements
目录中创建一个新的成就,仅定义了两个属性:name
和description
。您应该将这些属性的默认值更改为更好地说明成就是什么以及如何解锁它。完成后,它应该看起来像这样
<?php namespace App\Achievements; use SkyRaptor\Achievements\Achievement; class UserMadeAPost extends Achievement { /* * The achievement name */ public $name = 'Post Created'; /* * A small description for the achievement */ public $description = 'Congratulations! You have made your first post!'; }
解锁成就
可以使用Achiever
特质来解锁成就。
<?php namespace App; use SkyRaptor\Achievements\Traits\Achiever; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Achiever; }
这个特质包含了一个unlock
方法,可以用来解锁一个成就。该unlock
方法期望一个Achievement
实例
use App\Achievements\UserMadeAPost; $user->unlock(new UserMadeAPost());
记住,您并不限于User
类。您可以将Achiever
特质添加到任何可以解锁成就的实体中。
添加进度
而不是直接解锁一个成就,您可以为它添加一个进度。例如,您可能有一个名为UserMade10Posts
的成就,并希望跟踪用户在解锁此成就上的进度。
为了做到这一点,您必须在您的UserMade10Posts
类中设置一个额外的参数,称为$points
<?php namespace App\Achievements; use SkyRaptor\Achievements\Achievement; class UserMade10Posts extends Achievement { /* * The achievement name */ public $name = '10 Posts Created'; /* * A small description for the achievement */ public $description = 'Wow! You have already created 10 posts!'; /* * The amount of "points" this user need to obtain in order to complete this achievement */ public $points = 10; }
现在您可以通过Achiever
特质上的addProgress
和removeProgress
方法来控制进度。这两个方法都期望一个Achievement
实例和一个要添加或移除的点数
use App\Achievements\UserMade10Posts; $user->addProgress(new UserMade10Posts(), 1); // Adds 1 point of progress to the UserMade10Posts achievement
此外,您可以使用resetProgress
方法将进度重置为0,使用setProgress
方法将其设置为指定的点数
use App\Achievements\FiveConsecutiveSRanks; if($rank != 'S'){ $user->resetProgress(new FiveConsecutiveSRanks()); } else { $user->addProgress(new FiveConsecutiveSRanks(), 1); }
use App\Achievements\Have1000GoldOnTheBag; $user->setProgress(new Have100GoldOnTheBag(), $user->amountOfGoldOnTheBag);
一旦成就达到定义的点数,它将自动解锁。
检索成就
《成就者》特性还为实现它的实体添加了一个便捷的关系:`achievements()`。您可以使用它来检索实体已与之交互的所有成就的进度。由于`achievements()`是一个关系,您可以使用它作为QueryBuilder进一步筛选数据。
$achievements = $user->achievements; $unlocked_today = $user->achievements()->where('unlocked_at', '>=', Carbon::yesterday())->get();
您还可以使用`achievementStatus()`方法搜索特定的成就。
$details = $user->achievementStatus(new UserMade10Posts());
《成就者》特性还包括三个额外的辅助方法:`lockedAchievements()`、`inProgressAchievements()`和`unlockedAchievements()`。
事件监听器
监听所有成就
Laravel成就提供两个可以在其中监听的事件,以提供“成就解锁”消息或类似信息。这两个事件都接收触发它们的事件实例`AchievementProgress`。
`SkyRaptor\Achievements\Event\Progress`事件在成就者有进度但未解锁成就时触发。`SkyRaptor\Achievements\Event\Unlocked`事件在成就者实际解锁成就时触发。
有关如何监听这些事件的详细信息,请参阅Laravel事件文档。
监听特定成就
上述事件监听器适用于所有成就。如果您只想为特定成就添加事件监听器,您可以在《成就》类上实现`whenUnlocked`或`whenProgress`方法。
<?php namespace App\Achievements; use SkyRaptor\Achievements\Achievement; class UserMade50Posts extends Achievement { /* * The achievement name */ public $name = '50 Posts Created'; /* * A small description for the achievement */ public $description = 'Wow! You have already created 50 posts!'; /* * The amount of "points" this user need to obtain in order to complete this achievement */ public $points = 50; /* * Triggers whenever an Achiever makes progress on this achievement */ public function whenProgress($progress) { } /* * Triggers whenever an Achiever unlocks this achievement */ public function whenUnlocked($progress) { } }