Meu objetivo é restringir certos verbos RESTUL por tipo de postagem personalizada. Por exemplo, dado um tipo de postagem personalizada de vocabulário, gostaria de dizer:
Matriz de permissão
+-------+---+----------+
|index | X | GET |
|show | O | GET |
|create | X | POST |
|update | X | PATCH/PUT|
|delete | X | DELETE |
+-------+---+----------+
O V2 não parece fornecer esse nível de controle. Passei pela fonte e, pelo que posso ver, não há ganchos / filtros para alterar as permissões.
Minha solução atual é a seguinte. Isso compromete uma classe na qual você pode carregar uma matriz de tipos de postagem personalizados em relação às ações permitidas. Isso pode ser chamado no rest_prepare_vocabulary
filtro, destruindo a resposta se as permissões não estiverem alinhadas.
Problema
Não acho que essa seja uma solução razoável. Isso significa que as permissões estão sendo resolvidas em dois pontos (um, no núcleo, como ainda são aplicados) e nos meus filtros.
Idealmente, seria em um nível de configuração, ou seja, onde os tipos de postagem personalizados são definidos.
Em outras palavras, eu preferiria passar em regras (ao longo das linhas exclude_from_search
, publicly_queryable
, etc) em vez de executar uma consulta post "snip".
Solução atual (funciona, mas não é desejável)
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;
};
Access
no escopo global? Você precisa em outro lugar? Caso você responda sim , você pode anexá-lo a um filtro.\App
e o acesso é realmente\App\Services\Access
Respostas:
Meu entendimento é que essa foi uma decisão de design intencional.
Embora a API REST tenha sido construída para ser extensível, não é recomendável modificar os terminais principais da maneira que você está solicitando.
Há algumas informações limitadas disponíveis nesta seção do manual da API REST , mas a essência é que, à medida que a API envelhece, mais código (seja ele principal ou de terceiros) começará a depender de ações específicas disponíveis e fornecer padrões respostas.
Em vez disso, você deve criar um controlador personalizado.
Os tipos de postagem personalizados podem receber um controlador personalizado, especificando um nome de classe no
rest_controller_class
argumento pararegister_post_type()
.Uma visão geral de como os controladores personalizados devem funcionar pode ser encontrada no manual da API REST .
Outra coisa a ter em mente é que, se você criar um controlador personalizado que estenda a
WP_REST_Controller
classe abstrata para um tipo de postagem que suporta revisões, vários pontos de extremidade de revisão específicos do tipo de postagem serão criados automaticamente.Se não estender a
WP_REST_Controller
classe, oregister_routes()
método não será chamado, portanto você terá que registrar manualmente suas rotas personalizadas.fonte