imanghafoori/laravel-temp-tag

Laravel Temporary Tag 简化了 Eloquent 模型的标签功能。

v1.2.17 2023-02-15 14:02 UTC

README

在任何 Eloquent 模型上自动过期标签,并附加额外的有效负载数据。





image


用爱为每位聪明的 Laravel 开发者打造

Scrutinizer Code Quality StyleCI Software License Check Imports



安装

composer require imanghafoori/laravel-temp-tag

然后您可以通过发布和迁移创建所需的标签表

php artisan vendor:publish
php artisan migrate

laravel 8 的示例应用

https://github.com/imanghafoori1/laravel-tasks

在此每日任务应用中,您可以标记任务为 完成失败忽略 等,但在一天结束时它们会回滚到默认状态,因此您可以重新标记它们以供明天使用。

使用案例

  • 您想禁止一个用户,但只禁用一周。

  • 您想给某人 VIP 访问权限,但只限一个月。

  • 管理员批准评论。

  • 您想将产品放入滑块中,直到周末。

  • 存储每个用户的偏好,可以通过附加 'settings' 标签和偏好作为有效负载来完成。

  • 存储用户对任何模型的好恶。

  • 计划模型在未来发布。

  • 在特定时间段内对特定产品的优惠券代码。

然后您可以为它们添加临时标签并检查模型是否有该标签。

标签有效负载

您还可以存储一些额外的 JSON 数据,例如用户被禁止的原因,或禁止用户的人,或缩略语或标题的翻译。

这是通过将第三个参数作为数组传递给 ->tagIt(...) 方法来完成的

要点

  • 标签也可以是永久的。

  • 我们在迁移中不接触您现有的表。

  • 您可以在具有 getKeygetTable 方法的任何 Eloquent 模型或任何其他对象上放置标签。

示例

1- 给用户标记到明天

  $user = User::find(1);
  $tomorrow = Carbon::now()->addDay();
  $note = ['reason' => 'You were nasty!']; // You can optionally store additional data in a json column.

  tempTags($user)->tagIt('banned', $tomorrow, $note);

  tempTags($user)->tagIt('banned');  // will never expire

2- 一小时后标签仍然有效,因此

  $user = User::find(1);
 
  $tagObj = tempTags($user)->getActiveTag('banned');  // <--- Uses cache behind the scenes
  
  if (! is_null($tagObj)) {
    $tagObj->isActive();         // true
    $tagObj->isPermanent();      // false
    $tagObj->title === 'banned'; // true
    $tagObj->payload;            // ['reason' => 'You were nasty!']
    $tagObj->expiresAt();        // Carbon instance
  }

3- 一周后,标签过期,因此

  $user = User::find(1);
  $tagObj = tempTags($user)->getTag('banned');  // <--- fetches the tag regardless of its expire date.
  
  if (! is_null($tagObj)) {
    $tagObj->isActive();         // false
    $tagObj->isPermanent();      // false
    $tagObj->title === 'banned'; // true
    $tagObj->expiresAt();        // Carbon instance
  }

获取有效负载数据

有两种方式可以获取有效负载数据

您可以使用 getPayload 方法

  $tagObj->getPayload('reason');       //  'You were nasty!'      
  $tagObj->getPayload();               //  ['reason' => 'You were nasty!'] 
  $tagObj->getPayload('missing_key');  //  null

或者您可以将它们表现得像 eloquent 属性一样

  $tagObj->reason;       //  'You were nasty!'      
  $tagObj->payload;      //  ['reason' => 'You were nasty!'] 
  $tagObj->missing_key;  //  null

删除标签

  $user = User::find(1);
  
  tempTags($user)->unTag('banned');           // single string

  tempTags($user)->unTag('bann*');            // using a wildcard 

  tempTags($user)->unTag(['banned', 'man']);  // an array of tags to delete

  tempTags($user)->deleteExpiredTags();       // all the expired tags, bye bye.

注意:您还可以使用 * 通配符匹配 0 或多个字符(就像 SQL 中的 % 一样)

注意:这些会为每个标签触发 "删除" 和 "已删除" eloquent 事件。

立即使标题为 "banned" 的标签过期

 tempTags($user)->expireNow('banned');  // updates the value of expire_at to now() and deletes from cache

这些方法只是做它们所说的

  $actives = tempTags($user)->getAllActiveTags();  // A collect of "TempTag" model objects.

  $expired = tempTags($user)->getAllExpiredTags();

  $all = tempTags($user)->getAllTags();

仅获取标记的模型

假设您有一个用于 Product 模型的滑块,并且您只想显示带有 'slider' 标签的记录。

首先,您必须将 Imanghafoori\Tags\Traits\hasTempTags 特性放在 Product 模型上。

class Product extends Model 
{
  use hasTempTags;
  
  ...
}

现在您可以执行以下查询

Product::hasActiveTags('slider')->where(...)->get();

// Only if the tag of model is expired and it has the specified title.
Product::hasExpiredTags('slider')->where(...)->get();

// To fetch regardless of expiration date of tags, only the title matters.
Product::hasTags('slider')->where(...)->get();

注意:如果您传递一个标签数组,它就像 whereIn() 一样操作,因此如果行有一个标签,它将被选中。

如果您想找到明天还将活跃的产品,您可以使用 hasActiveTagsAthasNotActiveTagsAt,如下所示

Product::hasActiveTagsAt('slider', now()->addDay())->where(...)->get();

Product::hasNotActiveTagsAt('slider', now()->addDay())->where(...)->get();

示例

当您想向用户发送通知,通知他们在他们的 VIP 账户结束前还有 24 小时,这样他们就可以充电了。

User::hasActiveTag('VIP')
    ->hasNotActiveTagsAt('VIP', now()->addDay())
    ->get();

标签不存在

Product::hasNotActiveTags('slider')->where(...)->get();

Product::hasNotExpiredTags('slider')->where(...)->get();

Product::hasNotTags('slider')->where(...)->get();

示例

当您想将文章发布在未来时,您可以给文章添加一个自定义标签标题,如:"hidden",然后按此方式检索它们

$articles = Article::hasNotActiveTags('hidden')->where(...)->get();

因此,只要 'hidden' 标签有效,文章就不会显示在列表中,当标签过期时,文章就会上线。

基于有效载荷的过滤

$product1 = Product::find(1);
$product2 = Product::find(1);

tempTags($product1)->tagIt('status', $tomorrow, ['value' => 'sold_out']);
tempTags($product2)->tagIt('status', $tomorrow, ['value' => 'sold_out']);

// now we have tagged these two rows we can fetch them later on with the below query

...

Product::hasActiveTags('status', ['value' => 'sold_out'])->where(...)->get();

上面的示例向您展示了具有活动状态标签的产品,这些产品还具有指定键和值的有效载荷数据。

注意:您还可以使用 * 通配符匹配 0 或多个字符(就像 SQL 中的 % 一样)

Product::hasActiveTags('stat*', ['value' => 'sold_out'])->where(...)->get();

高级用法

每个 has...Tag 方法都有一个对应的 orHas...Tag,因此您可以在查询中放置多个条件。

请记住,它们都应该位于 ->where(function ($q) { 的相邻位置。

Post::where('user_id', 12)->where(function ($q) {
    $q->hasActiveTags('status', ['value' => 'active'])
    ->orHasActiveTags('status', ['value' => 'promoted']);
})->get();

自动删除过期的标签

为了节省磁盘空间和加快数据库查询速度,您可能希望删除过期的标签。

在完成基本安装后,您可以使用 tag:delete-expired 命令。在大多数情况下,您可能想安排此命令,以便不必每次需要删除过期标签时都手动运行它。

// app/Console/Kernel.php

protected function schedule(Schedule $schedule)
{
    // Will run:  php artisan  tag:delete-expired
    $schedule->command( 'tag:delete-expired' )->everyDay();
}

🙋 贡献

如果您发现了一个问题或有一个更好的方法来完成某事,请随时提出问题或发送拉取请求。

⭐ 您的星标让我们做得更多 ⭐

一如既往,如果您发现这个包很有用,并且您希望鼓励我们维护并改进它,只需按下星标按钮即可表达您的意愿。

作者的其他作品

Laravel Microscope

💎 它会自动在您的 Laravel 应用中找到错误

Laravel HeyMan

💎 它允许您编写表达式的代码来授权、验证和身份验证。


此包最初受到 cybercog/laravel-ban 包的启发。



It's not that I'm so smart, it's just that I stay with problems longer.


"Albert Einstein"