web-dev-qa-db-ja.com

Rest V2(WP4.7)では、特定のRESTFUL動詞をどのように制限しますか?

カスタム投稿タイプごとに特定のRESTUL動詞を制限することを目指しています。たとえば、語彙のカスタム投稿タイプがあるとします。

許可マトリックス

+-------+---+----------+
|index  | X | GET      |
|show   | O | GET      |
|create | X | POST     |
|update | X | PATCH/PUT|
|delete | X | DELETE   |
+-------+---+----------+

V2はそのレベルの制御を提供していないようです。私はソースを調べてきました、そして私が見ることができるものから、パーミッションの変更を利用するためのフック/フィルターはありません。

私の現在の解決策は以下の通りです。許可されたアクションに対してカスタム投稿タイプのマトリックスを読み込むことができるクラスが危険にさらされています。これはrest_prepare_vocabularyフィルタで呼び出され、パーミッションが揃っていない場合はレスポンスを破棄します。

問題

これが合理的な解決策であるとは思わない。これは、パーミッションが2つの場所(1つはコアで、まだ適用されているため)と私のフィルタで解決されていることを意味します。

理想的には、それは構成レベル、すなわちカスタム投稿タイプが定義されている場所にあります。

言い換えれば、私はpost query "snip"を実行するよりも(exclude_from_searchpublicly_queryableなどの行に沿って)ルールを渡すほうが好きです。

現在の解決策(うまくいくが望ましくない)

Access.php

class Access
{
    function __construct($permissions) {
        $this->permissions = $permissions;
    }

    protected function hasId($request) {
        return ! is_null($request->get_param('id'));
    }

    protected function resolveType($request) {
        $method = strtoupper($request->get_method());

        if($method === 'GET' && $this->hasId($request)) {
            return 'show';
        } else if($method === 'GET') {
            return 'index';
        } else if($method === 'DELETE') {
            return 'delete';
        } else if($method === 'POST') {
            return 'create';
        } else if($method === 'PATCH') {
            return 'update';
        }
    }

    function validate($type, $request) {
        return in_array($this->resolveType($request), $this->permissions[$type]);
    }
}

functions.php

// bootstrap the permissions for this particular 
// application
// 
$access = new Access([
    'vocabulary' => ['show'],
]);

add_filter('rest_prepare_vocabulary', 'validate_permissions', 30, 3);
function validate_permissions($response, $post, $request) {
    global $access;

    // Give access->validate the type + request data 
    // and it will figure out if this is allowed
    //
    if( ! $access->validate($post->post_type, $request)) {
        $response->set_data([]);
        $response->set_status(403);
    }

    return $response;
};
20
Chris

私はソースを調べてきました、そして私が見ることができるものから、パーミッションの変更を利用するためのフック/フィルターはありません。

私の理解では、これは意図的な設計上の決定であるということです。

REST AP​​Iは拡張可能なように構築されていますが、あなたが求めている方法でコアエンドポイントを変更することはお勧めできません。

REST AP​​Iハンドブックのこのセクション には限られた情報しかありませんが、その要点は、APIが古くなるにつれて、より多くのコード(コアかサードパーティかを問わず)になることです。具体的な行動が利用可能であり、標準的な対応を提供していることに依存し始めます。

代わりに、カスタムコントローラを作成する必要があります。

rest_controller_class引数register_post_type() にクラス名を指定することで、カスタム投稿タイプにカスタムコントローラを指定できます。

カスタムコントローラがどのように動作するかの概要は REST AP​​Iハンドブック にあります。

改訂をサポートする投稿タイプの抽象WP_REST_Controllerクラスを拡張するカスタムコントローラを作成すると、いくつかの投稿タイプ固有の改訂エンドポイントが自動的に作成されます。

WP_REST_Controllerクラスを拡張しない場合、register_routes()メソッドは呼び出されないので、手動でカスタムルートを登録する必要があります。

1
ssnepenthe