laravel-policies

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Laravel Policies

Laravel 策略

Policies encapsulate authorization logic and delegate to permission systems.
Related guides:
  • routing-permissions.md - Route-level authorization
  • Enums - Permission enums
策略封装了授权逻辑,并委托给权限系统处理。
相关指南:
  • routing-permissions.md - 路由级授权
  • Enums - 权限枚举

Structure

结构

php
<?php

declare(strict_types=1);

namespace App\Policies;

use App\Enums\Permission;
use App\Models\Order;
use App\Models\User;

class OrderPolicy
{
    public function viewAny(User $user): bool
    {
        return $user->can(Permission::ListOrders);
    }

    public function view(User $user, Order $order): bool
    {
        return $user->can(Permission::ViewOrders)
            && $order->customer_id === $user->customer_id;
    }

    public function create(User $user): bool
    {
        return $user->can(Permission::CreateOrders);
    }

    public function update(User $user, Order $order): bool
    {
        return $user->can(Permission::UpdateOrders)
            && $order->canBeModified()
            && $order->customer_id === $user->customer_id;
    }

    public function delete(User $user, Order $order): bool
    {
        return $user->can(Permission::DeleteOrders)
            && $order->isPending();
    }

    public function cancel(User $user, Order $order): bool
    {
        return $this->update($user, $order)
            && $order->canBeCancelled();
    }
}
php
<?php

declare(strict_types=1);

namespace App\Policies;

use App\Enums\Permission;
use App\Models\Order;
use App\Models\User;

class OrderPolicy
{
    public function viewAny(User $user): bool
    {
        return $user->can(Permission::ListOrders);
    }

    public function view(User $user, Order $order): bool
    {
        return $user->can(Permission::ViewOrders)
            && $order->customer_id === $user->customer_id;
    }

    public function create(User $user): bool
    {
        return $user->can(Permission::CreateOrders);
    }

    public function update(User $user, Order $order): bool
    {
        return $user->can(Permission::UpdateOrders)
            && $order->canBeModified()
            && $order->customer_id === $user->customer_id;
    }

    public function delete(User $user, Order $order): bool
    {
        return $user->can(Permission::DeleteOrders)
            && $order->isPending();
    }

    public function cancel(User $user, Order $order): bool
    {
        return $this->update($user, $order)
            && $order->canBeCancelled();
    }
}

Permission Enum

权限枚举

php
<?php

declare(strict_types=1);

namespace App\Enums;

use Henzeb\Enumhancer\Concerns\Comparison;
use Henzeb\Enumhancer\Concerns\Dropdown;

enum Permission: string
{
    use Comparison, Dropdown;

    case ListOrders = 'list orders';
    case ViewOrders = 'view orders';
    case CreateOrders = 'create orders';
    case UpdateOrders = 'update orders';
    case DeleteOrders = 'delete orders';
    case CancelOrders = 'cancel orders';
}
php
<?php

declare(strict_types=1);

namespace App\Enums;

use Henzeb\Enumhancer\Concerns\Comparison;
use Henzeb\Enumhancer\Concerns\Dropdown;

enum Permission: string
{
    use Comparison, Dropdown;

    case ListOrders = 'list orders';
    case ViewOrders = 'view orders';
    case CreateOrders = 'create orders';
    case UpdateOrders = 'update orders';
    case DeleteOrders = 'delete orders';
    case CancelOrders = 'cancel orders';
}

Standard Policy Methods

标准策略方法

Laravel conventions for policy methods:
  • viewAny()
    - List/index
  • view()
    - Show single resource
  • create()
    - Create new resource
  • update()
    - Update resource
  • delete()
    - Delete resource
  • restore()
    - Restore soft-deleted
  • forceDelete()
    - Permanently delete
Custom methods for non-standard actions:
  • cancel()
  • approve()
  • ship()
  • etc.
Laravel 策略方法的约定:
  • viewAny()
    - 列表/索引页
  • view()
    - 查看单个资源
  • create()
    - 创建新资源
  • update()
    - 更新资源
  • delete()
    - 删除资源
  • restore()
    - 恢复软删除资源
  • forceDelete()
    - 永久删除资源
自定义方法用于非标准操作:
  • cancel()
  • approve()
  • ship()
  • 等等

Key Patterns

核心模式

1. Delegate to Permission System

1. 委托给权限系统

php
return $user->can(Permission::CreateOrders);
php
return $user->can(Permission::CreateOrders);

2. Ownership Checks

2. 归属校验

php
return $user->can(Permission::ViewOrders)
    && $order->customer_id === $user->customer_id;
php
return $user->can(Permission::ViewOrders)
    && $order->customer_id === $user->customer_id;

3. State Checks

3. 状态校验

php
return $user->can(Permission::DeleteOrders)
    && $order->isPending();
php
return $user->can(Permission::DeleteOrders)
    && $order->isPending();

4. Combine Existing Methods

4. 组合已有方法

php
public function cancel(User $user, Order $order): bool
{
    return $this->update($user, $order)
        && $order->canBeCancelled();
}
php
public function cancel(User $user, Order $order): bool
{
    return $this->update($user, $order)
        && $order->canBeCancelled();
}

Usage in Routes

路由中的使用

php
Route::get('/orders', [OrderController::class, 'index'])
    ->can('viewAny', Order::class);

Route::get('/orders/{order}', [OrderController::class, 'show'])
    ->can('view', 'order');

Route::post('/orders', [OrderController::class, 'store'])
    ->can('create', Order::class);
See routing-permissions.md for route authorization.
php
Route::get('/orders', [OrderController::class, 'index'])
    ->can('viewAny', Order::class);

Route::get('/orders/{order}', [OrderController::class, 'show'])
    ->can('view', 'order');

Route::post('/orders', [OrderController::class, 'store'])
    ->can('create', Order::class);
更多路由授权内容请查看 routing-permissions.md

Summary

总结

Policies should:
  • Use permission enums (not strings)
  • Check ownership when needed
  • Check state when needed
  • Delegate to permission system
  • Follow Laravel naming conventions
  • Stay simple and focused
策略应当:
  • 使用权限枚举(而非字符串)
  • 必要时校验资源归属
  • 必要时校验资源状态
  • 委托给权限系统处理
  • 遵循 Laravel 命名约定
  • 保持简洁且聚焦