Mam na celu ograniczenie niektórych czasowników RESTUL dla niestandardowego typu postu. Na przykład, biorąc pod uwagę niestandardowy typ słownika, chciałbym powiedzieć:
Macierz uprawnień
+-------+---+----------+
|index | X | GET |
|show | O | GET |
|create | X | POST |
|update | X | PATCH/PUT|
|delete | X | DELETE |
+-------+---+----------+
Wydaje się, że V2 nie zapewnia takiego poziomu kontroli. Przeszedłem przez źródło i z tego, co widzę, nie ma żadnych haków / filtrów, które można by wykorzystać do zmiany uprawnień.
Moje obecne rozwiązanie jest następujące. Jest to kompromis klasy, w której można załadować macierz niestandardowych typów postów przeciwko dozwolonym działaniom. Można to następnie wywołać w rest_prepare_vocabulary
filtrze, niszcząc odpowiedź, jeśli uprawnienia się nie zgadzają.
Problem
Nie wydaje mi się, żeby to rozsądne rozwiązanie. Oznacza to, że uprawnienia są rozwiązywane w dwóch punktach (jeden, w rdzeniu, ponieważ są one nadal stosowane) i w moich filtrach.
Idealnie byłoby na poziomie konfiguracji, czyli tam, gdzie zdefiniowane są niestandardowe typy postów.
Inaczej mówiąc, wolałbym, aby przejść w zasadach (wzdłuż linii exclude_from_search
, publicly_queryable
itp) zamiast wykonywać pocztowy zapytanie „ciach”.
Aktualne rozwiązanie (działa, ale nie jest pożądane)
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
w globalnym zasięgu? Potrzebujesz go gdzie indziej? Jeśli odpowiesz tak , możesz zamiast tego dołączyć filtr.\App
i dostęp jest w rzeczywistości\App\Services\Access
Odpowiedzi:
Rozumiem, że była to celowa decyzja projektowa.
Chociaż interfejs API REST został zbudowany w taki sposób, aby był rozszerzalny, nie zaleca się modyfikowania podstawowych punktów końcowych w sposób, w jaki pytasz.
W tej sekcji podręcznika API REST dostępnych jest kilka ograniczonych informacji , ale ich istotą jest to, że w miarę starzenia się interfejsu API, więcej kodu (niezależnie od tego, czy będzie to rdzeń, czy strona trzecia) zacznie zależeć od dostępności określonych działań i zapewnienia standardowych odpowiedzi
Zamiast tego należy utworzyć niestandardowy kontroler.
Niestandardowym typom postów można nadać niestandardowy kontroler, podając nazwę klasy w
rest_controller_class
argumencie doregister_post_type()
.Przegląd działania kontrolerów niestandardowych można znaleźć w podręczniku interfejsu API REST .
Należy również pamiętać o tym, że jeśli utworzysz niestandardowy kontroler, który rozszerzy
WP_REST_Controller
klasę abstrakcyjną dla typu postu, który obsługuje wersje, automatycznie zostanie utworzonych kilka punktów końcowych wersji specyficznych dla typu postu.Jeśli nie rozszerzy
WP_REST_Controller
klasy,register_routes()
metoda nie zostanie wywołana, więc będziesz musiał ręcznie zarejestrować własne trasy.źródło