doefom /

Statamic 插件,将 EntryPolicy 的 `view` 方法应用于控制面板中的条目列表。

v0.5.4 2024-06-02 07:08 UTC

This package is auto-updated.

Last update: 2024-09-02 07:46:12 UTC


README

Statamic 插件,将你的 EntryPolicy 的 view 方法应用于控制面板中的条目列表。

  • ✅ Statamic v4
  • ✅ Statamic v5
  • ✅ 多站点
  • ❌ Eloquent 驱动

注意:需要 Statamic Pro。

功能

根据你定义的 EntryPolicy 阻止条目在控制面板中显示。

升级指南

从 0.4.x 到 0.5.x

在版本 v0.4.x 中,您必须在 AppServiceProvider 中设置一个限制闭包来限制条目。这现在将不再工作。相反,现在您可以扩展 Statamic\Policies\EntryPolicy 类来设置限制,并调整 view 方法以满足您的需求,因为现在在查询控制面板中的条目时将尊重此策略方法。

之前,您设置限制的方式如下

// v0.4.x:

use Doefom\Restrict\Facades\Restrict;
use Statamic\Contracts\Auth\User;
use Statamic\Contracts\Entries\Entry;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // ...
    }

    public function boot(): void
    {
        Restrict::setRestriction(function (User $user, Entry $entry) {
            // Can view own entries only 
            return $entry->authors()->contains($user->id());
        });
    }
}

现在您需要按照入门部分中所述设置限制。

从 0.3.x 到 0.4.x

在版本 0.3.x 以下,针对每个集合有硬编码的“查看其他作者条目”权限。这些权限现在已被移除,并且默认情况下将不再有任何效果。

入门

安装

您可以在 Statamic 控制面板的 工具 > 插件部分中搜索此插件,然后点击 安装,或者从您的项目根目录运行以下命令

composer require doefom/restrict

创建自定义条目策略

为了正确使用此插件,最好创建一个自定义条目策略。请确保它扩展了默认的 Statamic\Policies\EntryPolicy 并重写了其 view 方法。此方法将被调用来确定条目是否在控制面板中列出。

提示:您可以通过以下命令创建自定义策略

php artisan make:policy MyEntryPolicy

以下是一个可能的 MyEntryPolicy 的样子

<?php

namespace App\Policies;

use Statamic\Policies\EntryPolicy;

class MyEntryPolicy extends EntryPolicy
{

    public function view($user, $entry)
    {
        // ...
    }

}

注册您的自定义条目策略

请确保在您的 AppServiceProvider 中注册您的自定义条目策略

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->bind(
            \Statamic\Policies\EntryPolicy::class,
            \App\Policies\MyEntryPolicy::class
        );
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // ...
    }
}

这样就可以了!从现在起,您的自定义条目策略的 view 方法将被调用来确定条目是否应在控制面板中列出。您的更改还将影响条目的详细视图,如果用户无权查看条目,则返回 403

使用示例

基本使用

默认情况下,Statamic 具有阻止用户编辑其他作者条目的能力。也许您希望用户不仅不能编辑其他作者的条目,而且根本不在控制面板中列出这些条目。为了实现这一点,您可以像这样调整自定义条目策略的 view 方法

use Statamic\Policies\EntryPolicy;

class MyEntryPolicy extends EntryPolicy
{

    public function view($user, $entry)
    {
        $default = parent::view($user, $entry);

        if ($entry->blueprint()->hasField('author')) {
            return $default && $entry->authors()->contains($user->id());
        }

        return $default;
    }

}

使用权限

您可以在策略的 view 方法中检查任何内容。例如,您可以在 Statamic 应用程序中定义自定义权限并在策略中检查这些权限。

假设您运行的应用程序中,每个用户都属于一家公司,并且每个公司都有许多条目。默认情况下,用户应仅查看他们自己公司的条目。但是,您可能希望允许某些用户查看其他公司的条目。为此,您可以在 AppServiceProvider 中添加 Statamic 权限,并在自定义条目策略中检查此权限。

添加权限

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    /**
     * Register any application services.
     */
    public function register(): void
    {
        // ...
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // Add one general permission to Statamic 
        Permission::extend(function () {
            Permission::register('view entries of other companies')
                ->label('View entries of other companies');
        });
    }
    
}

检查权限

use Statamic\Policies\EntryPolicy;

class MyEntryPolicy extends EntryPolicy
{

    public function view($user, $entry)
    {
        $default = parent::view($user, $entry);
        
        if ($user->hasPermission('view entries of other companies')) {
            // Can view all entries
            return $default;
        }

        // Can view entries of the same company only
        return $default && $user->get('company') === $entry->get('company');
    }

}

基于集合的权限使用

关于上面的示例,你还可以在每个集合中添加一个权限到你的 AppServiceProvider 中,这样你就可以阻止当前用户属于另一个公司时,条目出现在控制面板中。但这次是针对每个集合的。

添加权限

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    /**
     * Register any application services.
     */
    public function register(): void
    {
        // ...
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // Add one permission per collection 
        Permission::extend(function () {
            Permission::get('view {collection} entries')->addChild(
                Permission::make("view {collection} entries of other companies")
                    ->label("View entries of other companies")
            );
        });
    }
    
}

检查权限

use Statamic\Policies\EntryPolicy;

class MyEntryPolicy extends EntryPolicy
{

    public function view($user, $entry)
    {
        $default = parent::view($user, $entry);
        
        if ($user->hasPermission("view {$entry->collectionHandle()} entries of other companies")) {
            // Can view all entries in the entry's collection
            return $default;
        }

        // Can view entries of the same company only for this collection
        return $default && $user->get('company') === $entry->get('company');
    }

}

注意事项

仅与控制面板路由兼容

此插件仅限制条目在控制面板中列出,因此它不会限制条目在网站前端显示或从你的API中获取,这完全取决于你。要了解用户当前是否位于控制面板路由,我们检查路由是否应用了 statamic.cp.authenticated 中间件。

在控制台运行应用

如果你在控制台运行你的应用,此插件将没有任何效果。

class ServiceProvider extends AddonServiceProvider
{
    public function bootAddon(): void
    {
        if ($this->app->runningInConsole()) {
            return;
        }

        // ...
    }
}

Eloquent 驱动器

此插件与 Eloquent 驱动器兼容。它仅与默认的平面文件驱动器兼容。然而,计划在未来支持 Eloquent 驱动器。

类绑定

限制 通过重新绑定 Statamic 的 EntryQueryBuilderEntryPolicy(这是由你完成的)来实现。如果你要使用自定义绑定或另一个也重新绑定这些类之一的插件,你可能会遇到问题。这只是在使用此插件时需要注意的一点。

// ----------------------------------------------------------------
// Rebinding the Entry Policy in your AppServiceProvider
// ----------------------------------------------------------------

$this->app->bind(
    \Statamic\Policies\EntryPolicy::class,
    \App\Policies\MyEntryPolicy::class
);

// ----------------------------------------------------------------
// Rebinding the Entry Query Builder as done
// by the Restrict addon in its ServiceProvider.
// ----------------------------------------------------------------

$this->app->bind(\Statamic\Stache\Query\EntryQueryBuilder::class, function ($app) {
    return new \Doefom\Restrict\Stache\Query\EntryQueryBuilder($app['stache']->store('entries'));
});