Ich möchte bestimmte RESTUL-Verben pro benutzerdefiniertem Beitragstyp einschränken. Zum Beispiel möchte ich bei einem benutzerdefinierten Vokabeltyp Folgendes sagen:
Berechtigungsmatrix
+-------+---+----------+
|index | X | GET |
|show | O | GET |
|create | X | POST |
|update | X | PATCH/PUT|
|delete | X | DELETE |
+-------+---+----------+
Die V2 scheint diese Kontrolle nicht zu bieten. Ich habe die Quelle durchgesehen, und soweit ich sehen kann, gibt es keine Hooks / Filter, mit denen sich Berechtigungen ändern lassen.
Meine derzeitige Lösung lautet wie folgt. Kompromisse einer Klasse, in der Sie eine Matrix benutzerdefinierter Beitragstypen gegen zulässige Aktionen laden können. Dies kann dann im rest_prepare_vocabulary
Filter aufgerufen werden, wodurch die Antwort zerstört wird, wenn die Berechtigungen nicht übereinstimmen.
Problem
Ich halte das nicht für eine vernünftige Lösung. Dies bedeutet, dass Berechtigungen an zwei Stellen (eine im Kern, da sie noch angewendet werden) und in meinen Filtern aufgelöst werden.
Idealerweise ist dies eine Konfigurationsebene, in der die benutzerdefinierten Beitragstypen definiert sind.
Mit anderen Worten, ich würde es vorziehen , in Regeln passieren (entlang der Linien exclude_from_search
, publicly_queryable
usw.) , anstatt einen Beitrag Abfrage „schnippeln“ durchgeführt wird .
Aktuelle Lösung (funktioniert aber nicht wünschenswert)
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
im globalen Bereich instanziiert ? Benötigen Sie es woanders? Wenn Sie dies mit Ja beantworten , möchten Sie es möglicherweise stattdessen an einen Filter anhängen.\App
und Zugang ist eigentlich\App\Services\Access
Antworten:
Mein Verständnis ist, dass dies eine beabsichtigte Entwurfsentscheidung war.
Obwohl die REST-API so erstellt wurde, dass sie erweiterbar ist, wird nicht empfohlen, die Kernendpunkte auf die von Ihnen gewünschte Weise zu ändern.
In diesem Abschnitt des REST-API-Handbuchs sind einige Informationen nur in begrenztem Umfang verfügbar. Der Kern des Handbuchs ist jedoch, dass mit zunehmendem Alter der API mehr Code (unabhängig davon, ob es sich um Kern- oder Drittanbieter handelt) von bestimmten verfügbaren Aktionen und Standardfunktionen abhängt Antworten.
Stattdessen sollten Sie einen benutzerdefinierten Controller erstellen.
Benutzerdefinierte Post-Typen können durch Angabe eines Klassennamens im
rest_controller_class
Argument fürregister_post_type()
einen benutzerdefinierten Controller zugewiesen werden .Eine Übersicht über die Funktionsweise benutzerdefinierter Controller finden Sie im REST-API-Handbuch .
Beachten Sie außerdem, dass beim Erstellen eines benutzerdefinierten Controllers, der die abstrakte
WP_REST_Controller
Klasse für einen Beitragstyp erweitert, der Revisionen unterstützt, automatisch eine Reihe von Beitragstyp-spezifischen Revisionsendpunkten erstellt wird.Wenn die
WP_REST_Controller
Klasse nicht erweitert wird , wird dieregister_routes()
Methode nicht aufgerufen, sodass Sie Ihre benutzerdefinierten Routen manuell registrieren müssen.quelle