Afișează endpoint-ul pentru un tip de postare personalizat în REST API doar dacă utilizatorul are capabilitatea necesară
Am creat un tip de postare personalizat pentru WordPress, care ar trebui să fie accesibil doar pentru utilizatorii care au o capabilitate personalizată read_cpt
. În cadrul șabloanelor și pre_get_posts
pot efectua verificări pentru a include sau exclude CPT folosind current_user_can()
.
Nu doresc ca acest CPT, nici măcar endpoint-ul, să apară în REST API, pentru a-l menține secret, atâta timp cât un utilizator nu are capabilitatea personalizată.
Singura metodă pe care am găsit-o pentru a ascunde endpoint-urile în API este rularea acestui cod.
Înregistrează tipul de postare pentru WordPress "clasic":
function add_post_type() {
$args = array(
[...]
'public' => false,
'has_archive' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'show_in_rest' => false,
);
register_post_type( 'cpt', $args );
}
add_action( 'init', 'add_post_type', 0 );
și adaugă-l separat în REST API:
add_action( 'init', 'cpt_rest_support', 25 );
function cpt_rest_support() {
global $wp_post_types;
if ( current_user_can( 'read_addresses' ) ) {
//asigură-te că setezi acest lucru la numele tipului tău de postare!
$post_type_name = 'address';
if( isset( $wp_post_types[ 'cpt' ] ) ) {
$wp_post_types[ 'cpt' ]->show_in_rest = true;
}
}
}
Prin crearea unei clase personalizate WP_REST_Posts_Controller
nu am reușit să găsesc o metodă de a ascunde endpoint-ul modificând oricare dintre verificările *_permissions_check
.
Există vreun argument de genul "show_in_rest_permition_check" pentru register_post_type()
sau este metoda descrisă singura variantă disponibilă?

API-ul REST nu are parametri sau opțiuni pentru a rezolva această problemă - în opinia mea. Cu toate acestea, ar trebui să înregistrați doar dacă utilizatorii au capabilitățile necesare în rolul lor, ca în exemplul următor.
add_action( 'rest_api_init', function() {
// Ieșim dacă utilizatorul logat nu are suficiente drepturi.
if ( ! current_user_can( 'edit_posts' ) ) {
return;
}
// Înregistrăm metadatele.
register_meta( 'post', 'foo', array(
'show_in_rest' => true,
));
});
Aceasta va expune datele personalizate în API-ul REST doar dacă utilizatorul are suficiente drepturi și capabilități în rolul său. Funcția mea register_meta()
este doar un exemplu, care ar trebui să funcționeze și cu parametrul tău suplimentar pentru register_post_type
, cum ar fi $wp_post_types[ 'cpt' ]->show_in_rest = true;
.

Întrebare veche, dar această soluție a funcționat pentru mine, respectând cerințele lui @Drivingralle. Puteți utiliza current_user_can()
ca un comutator boolean pentru a modifica comportamentul parametrului show_in_rest
:
function add_post_type() {
$show_in_rest = current_user_can( 'read_cpt' ); //va returna true sau false
$args = array(
[...]
'public' => false,
'has_archive' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'show_in_rest' => $show_in_rest, //comutator boolean din current_user_can()
);
register_post_type( 'cpt', $args );
}
add_action( 'init', 'add_post_type' );
În acest fel, tipul de postare personalizat este afișat în REST doar pentru utilizatorii cu capabilitatea necesară.

Nu te baza doar pe ascunderea acestuia.
În schimb, returnează o eroare în handler:
if (!current_user_can('read_addresses')) {
return new WP_REST_Response('restricted', 403);
}
Pentru a-l ascunde și tu, filtrează conținutul hook-urilor rest_index
și rest_namespace_index
.

Folosește funcția register_rest_route().
if( current_user_can( 'read_addresses' ) ) {
register_rest_route( 'namespace/v1', 'cpt', array(
'methods' => array( 'GET' ),
'callback' => 'callback_function',
'permission_callback' => 'permission_callback_function'
) );
}
Funcția ta callback_function
va gestiona cererea și va returna răspunsul. Funcția permissions_callback_function
va verifica permisiunile utilizatorului și va returna o eroare dacă utilizatorul nu are capabilitățile specificate. În acest caz, verificarea permisiunilor probabil nu este necesară, dar nu strică să o ai implementată pentru orice eventualitate.
