定制 doefom/restrict 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

doefom/restrict

Composer 安装命令:

composer require doefom/restrict

包简介

A Statamic addon that applies your EntryPolicy's `view` method to entry listings in the control panel.

README 文档

README

A Statamic addon that applies your EntryPolicy's view method to entry listings in the control panel.

  • ✅ Statamic v4
  • ✅ Statamic v5
  • ✅ Multisite
  • ❌ Eloquent Driver

Note: Statamic Pro is required.

Features

Prevent entries from showing up in the control panel based on the EntryPolicy you define.

Upgrade Guide

From 0.4.x to 0.5.x

In versions v0.4.x you had to set a restriction closure in the AppServiceProvider to restrict entries. This will no longer work. Instead, you can now set the restriction by extending the Statamic\Policies\EntryPolicy class and adjust the view method to your needs, since this policy method will now be respected when querying entries in the control panel.

Before, you've set your restrictions like this:

// 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());
        });
    }
}

Now you have to set your restrictions as explained in the Getting Started section.

From 0.3.x to 0.4.x

In versions up to 0.3.x there were hard coded permissions to view other authors' entries on a per-collection basis. Those permissions are now removed and will no longer have any effect by default.

Getting Started

Installation

You can search for this addon in the Tools > Addons section of the Statamic control panel and click install, or run the following command from your project root:

composer require doefom/restrict

Create a Custom Entry Policy

To properly use this addon it's best to create a custom entry policy. Make sure it extends the default Statamic\Policies\EntryPolicy and overrides its view method. This method will be called to determine if an entry is listed in the control panel or not.

Tip: You can create a custom policy by running:

php artisan make:policy MyEntryPolicy

Here is what MyEntryPolicy could look like:

<?php

namespace App\Policies;

use Statamic\Policies\EntryPolicy;

class MyEntryPolicy extends EntryPolicy
{

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

}

Register Your Custom Entry Policy

Make sure to register your custom entry policy in your 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
    {
        // ...
    }
}

And that's it! From now on, the view method of your custom entry policy will be called to determine if an entry should be listed in the control panel or not. Your changes will also have an effect on the detail view of an entry and return a 403 if the user is not allowed to view the entry.

Usage Examples

Basic Usage

By default, Statamic ships with the ability to restrict users from editing other authors' entries. Maybe you want your users to not just not edit other authors' entries but rather not have them listed in the control panel at all. To achieve this, you could adjust the view method of your custom entry policy like so:

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;
    }

}

Using Permissions

You can check for anything in the view method of your policy. For example, you could define custom permissions in your Statamic application and check for those.

Let's say you run an application where each user belongs to a company and each company has many entries. By default, a user should only see entries of their own company. However, you might want to allow certain users to view entries of other companies as well. For that you could add a permission to Statamic in your AppServiceProvider and check for this permission in your custom entry policy.

Adding a Permission

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');
        });
    }
    
}

Checking for the Permission

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');
    }

}

Using Permissions on a Per-Collection Basis

Regarding the example above, you might also add a permission to each collection in your AppServiceProvider so that you can prevent entries from being listed in the control panel if the current user belongs to another company. But this time on a per-collection basis.

Adding the Permissions

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")
            );
        });
    }
    
}

Checking for the Permissions

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');
    }

}

Caveats

Works with Control Panel Routes Only

The addon only restricts entries from being listed in the control panel and therefore does not restrict entries from being displayed on the front-end of your site or fetched from your API, that's entirely up to you. To know if the user is currently on a control panel route we check if the route has the statamic.cp.authenticated middleware applied.

App Running in Console

If you run your app in the console, the addon will not have any effect.

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

        // ...
    }
}

Eloquent Driver

This addon does not work with the Eloquent driver. It only works with the default flat file driver. However, it is planned to support the Eloquent driver in the future.

Class Bindings

Restrict works by rebinding Statamic's EntryQueryBuilder and EntryPolicy (this one is done by you). If you were to use custom bindings or another addon which also rebinds one of those classes, you might run into issues. That's just something to keep in mind when using this addon.

// ----------------------------------------------------------------
// 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'));
});

doefom/restrict 适用场景与选型建议

doefom/restrict 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2.42k 次下载、GitHub Stars 达 3, 最近一次更新时间为 2023 年 03 月 08 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 doefom/restrict 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 doefom/restrict 我们能提供哪些服务?
定制开发 / 二次开发

基于 doefom/restrict 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 2.42k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 3
  • 点击次数: 13
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 3
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-03-08