f9webltd/laravel-deletable

优雅地限制 Laravel Eloquent 模型的删除

2.0.3 2024-03-10 12:27 UTC

This package is auto-updated.

Last update: 2024-09-10 13:45:37 UTC


README

Packagist Version run-tests-laravel-8 StyleCI Status Packagist License PHP ^8.2

Laravel Deletable

优雅地处理您Eloquent 模型的删除限制,如 Laravel News 中所述

要求

  • PHP ^8.2
  • Laravel ^10.0 / ^11.0

对于旧版本的 PHP / Laravel,请使用版本 1.0.6

安装

composer require f9webltd/laravel-deletable

此包将自动注册自己。

可选:通过运行 php artisan vendor:publish 并选择适当的包来发布配置文件。

文档

用法

在 Eloquent 模型中使用 RestrictsDeletion 特性

namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   use RestrictsDeletion;
}

特性覆盖了 Eloquent 的 delete() 方法调用。

在相关的模型中实现 isDeletable() 方法。

此方法应返回 true 以允许删除,并返回 false 以拒绝删除

namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
  use RestrictsDeletion;
  
  public function isDeletable() : bool
  {
    return $this->orders()->doesntExist();
  }  
}

上述示例拒绝删除有订单的用户。

isDeletable() 方法返回 false 时,不可删除的模型会抛出异常

namespace App\Controllers;

use F9Web\LaravelDeletable\Exceptions\NoneDeletableModel;
use App\User;

class UsersController
{
  public function destroy(User $user) : bool
  {
    try {
      $user->delete();
    } catch (NoneDeletableModel $e) {
      // dd($ex->getMessage());
    }
  }  
}

Eloquent 基础模型

默认情况下,isDeletable() 方法返回 true,因此可以定义一个基础 Eloquent 模型,所有模型都从该模型扩展。然后每个模型可以按需实现 isDeletable() 方法。

自定义消息

默认异常消息在配置 f9web-laravel-deletable.messages.default 中定义,并简单地是 模型无法删除

f9web-laravel-deletable.messages.default 设置为 null,将自动生成更详细的消息,例如 受限删除:App\User - 1 无法删除

可以在 isDeletable() 方法中设置自定义消息

namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class User extends Model
{
  use RestrictsDeletion;
  
  public function isDeletable() : bool
  {
    if (Str::endsWith($this->email, 'f9web.co.uk')) {
        return $this->denyDeletionReason('Users with f9web.co.uk company email addresses cannot be deleted');
    }

    return true;
  }  
}

可以使用 denyDeletionReason() 方法指定异常消息。

在上面的示例中,异常消息是 具有 f9web.co.uk 公司电子邮件地址的用户无法删除

多次检查

如果需要,可以在 isDeletable() 中执行多次检查,每个检查都返回不同的异常消息

namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class User extends Model
{
  use RestrictsDeletion;
  
  public function isDeletable() : bool
  {
    if (Str::endsWith($this->email, 'f9web.co.uk')) {
       return $this->denyDeletionReason('Users with f9web.co.uk company email addresses cannot be deleted');
    }
    
    if ($this->orders->isNotEmpty()) {
       return false;
    }
    
    if ($this->purchaseOrders->isNotEmpty()) {
       return $this->denyDeletionReason('This user has active purchase orders and cannot be deleted');
    }
    
    if ($this->overdueInvoices->isNotEmpty()) {
       return $this->denyDeletionReason('Users with overdue invoices cannot be deleted');
    }

    return true;
  }  
}

贡献

欢迎任何想法。请随时提交任何问题或拉取请求。

测试

composer test

安全性

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

鸣谢

许可

MIT 许可证 (MIT)。请参阅 许可文件 以获取更多信息。