Zezwalanie użytkownikowi na edycję tylko niektórych stron
16
Chciałbym zezwolić niektórym użytkownikom na edycję tylko jednej strony i jej podstron. Jak to by było możliwe? Próbowałem starego Role Scopera, ale wydaje się, że ma wiele problemów i błędów.
Usunąłem twoją prośbę o rekomendację wtyczki, ponieważ to sprawiło, że pytanie stało się nie na temat. Tak, powinno to być możliwe dzięki wtyczce, ale kiedy widzę próby robienia rzeczy wymagających tego rodzaju włamania się do podstawowych funkcji, nie mogę nie myśleć, że podejrzewasz niewłaściwe podejście. Czy możesz wyjaśnić projekt bardziej szczegółowo?
s_ha_dum
Odpowiedzi:
14
Pierwszą rzeczą do zrobienia w celu realizacji takiego zadania jest rozpoznanie, którą stronę użytkownik może edytować.
Można to zrobić na różne sposoby. Może to być meta użytkownika, pewna wartość konfiguracyjna ... Ze względu na tę odpowiedź założę, że istnieje funkcja lile:
function wpse_user_can_edit( $user_id, $page_id ){
$page = get_post( $page_id );// let's find the topmost page in the hierarchywhile( $page &&(int) $page->parent ){
$page = get_post( $page->parent );}if(! $page ){returnfalse;}// now $page is the top page in the hierarchy// how to know if an user can edit it, it's up to you...}
Teraz, gdy mamy sposób na ustalenie, czy użytkownik może edytować stronę, musimy po prostu powiedzieć WordPressowi, aby użył tej funkcji do sprawdzenia możliwości użytkownika do edycji strony.
add_filter('map_meta_cap',function( $caps, $cap, $user_id, $args ){
$to_filter =['edit_post','delete_post','edit_page','delete_page'];// If the capability being filtered isn't of our interest, just return current valueif(! in_array( $cap, $to_filter,true)){return $caps;}// First item in $args array should be page IDif(! $args || empty( $args[0])||! wpse_user_can_edit( $user_id, $args[0])){// User is not allowed, let's tell that to WPreturn['do_not_allow'];}// Otherwise just return current valuereturn $caps;},10,4);
W tym momencie potrzebujemy tylko sposobu, aby połączyć użytkownika z jedną lub kilkoma stronami.
Mogą istnieć różne rozwiązania w zależności od przypadku użycia.
Elastycznym rozwiązaniem może być dodanie listy rozwijanej stron „root” (patrz wp_dropdown_pages ) do ekranu administratora edycji użytkownika i zapisanie wybranych stron jako meta użytkownika.
Jestem pewien, że na tej stronie jest wystarczająco dużo wskazówek, jak to szczegółowo.
Gdy strony są przechowywane jako meta użytkownika, wpse_user_can_edit()powyższą funkcję można zakończyć, sprawdzając, czy identyfikator strony jest częścią meta wartości użytkownika.
Usuwając możliwość edycji strony, WordPress zrobi resztę: usunie dowolny link edycyjny z backendu i frontendu, uniemożliwi bezpośredni dostęp ... i tak dalej.
To o wiele lepsze niż moja odpowiedź. Po co ograniczać linki edycyjne, skoro można po prostu zmodyfikować możliwości użytkownika i pozwolić WordPress zająć się resztą?
ricotheque
powinieneś użyć „a” przed słowem „użytkownik”, a nie „an”, ponieważ długie „u” brzmi jak „yu”, który zaczyna się spółgłoską.
Philip
7
Zaimplementowanie tej funkcji wymaga niewielkiej ilości kodu, nawet jeśli używasz klasy PHP, aby uniknąć zmiennych globalnych. Nie chciałem też ukrywać zabronionych stron dla użytkownika w Panelu. Co jeśli dodadzą treści, które były już na stronie?
$user_edit_limit =new NS_User_Edit_Limit(15,// User ID we want to limit[2,17]// Array of parent page IDs user is allowed to edit(also accepts sub-page IDs));class NS_User_Edit_Limit {/**
* Store the ID of the user we want to control, and the
* posts we will let the user edit.
*/private $user_id =0;private $allowed = array();publicfunction __construct( $user_id, $allowed ){// Save the ID of the user we want to limit.
$this->user_id = $user_id;// Expand the list of allowed pages to include sub pages
$all_pages =new WP_Query( array('post_type'=>'page','posts_per_page'=>-1,));foreach( $allowed as $page ){
$this->allowed[]= $page;
$sub_pages = get_page_children( $page, $all_pages );foreach( $sub_pages as $sub_page ){
$this->allowed[]= $sub_page->ID;}}// For the prohibited user...// Remove the edit link from the front-end as needed
add_filter('get_edit_post_link', array( $this,'remove_edit_link'),10,3);
add_action('admin_bar_menu', array( $this,'remove_wp_admin_edit_link'),10,1);// Remove the edit link from wp-admin as needed
add_action('page_row_actions', array( $this,'remove_page_list_edit_link'),10,2);}/**
* Helper functions that check if the current user is the one
* we want to limit, and check if a specific post is in our
* list of posts that we allow the user to edit.
*/privatefunction is_user_limited(){
$current_user = wp_get_current_user();return( $current_user->ID == $this->user_id );}privatefunction is_page_allowed( $post_id ){return in_array( $post_id, $this->allowed );}/**
* Removes the edit link from the front-end as needed.
*/publicfunction remove_edit_link( $link, $post_id, $test ){/**
* If...
* - The limited user is logged in
* - The page the edit link is being created for is not in the allowed list
* ...return an empty $link. This also causes edit_post_link() to show nothing.
*
* Otherwise, return link as normal.
*/if( $this->is_user_limited()&&!$this->is_page_allowed( $post_id )){return'';}return $link;}/**
* Removes the edit link from WP Admin Bar
*/publicfunction remove_wp_admin_edit_link( $wp_admin_bar ){/**
* If:
* - We're on a single page
* - The limited user is logged in
* - The page is not in the allowed list
* ...Remove the edit link from the WP Admin Bar
*/if(
is_page()&&
$this->is_user_limited()&&!$this->is_page_allowed( get_post()->ID )){
$wp_admin_bar->remove_node('edit');}}/**
* Removes the edit link from WP Admin's edit.php
*/publicfunction remove_page_list_edit_link( $actions, $post ){/**
* If:
* -The limited user is logged in
* -The page is not in the allowed list
* ...Remove the "Edit", "Quick Edit", and "Trash" quick links.
*/if(
$this->is_user_limited()&&!$this->is_page_allowed( $post->ID )){
unset( $actions['edit']);
unset( $actions['inline hide-if-no-js']);
unset( $actions['trash']);}return $actions;}}
Powyższy kod uniemożliwia działanie lub pojawianie się w razie potrzeby:
get_edit_post_link
Edit Page link na pasku administracyjnym WP, który pojawia się dla stron
Edit, Quick Editoraz Trashszybkie linki, które pojawiają się pod stronami w/wp-admin/edit.php?post_type=page
To działało na mojej lokalnej instalacji WordPress 4.7. Zakładając, że strony w witrynie często się nie zmieniają, może być lepiej zakodować identyfikatory strony i jej podstron oraz usunąć WP_Querywnętrze __constructmetody. Zaoszczędzi to wiele na połączeniach z bazą danych.
+1 za bardziej kompletną odpowiedź niż @ Ben, ale właściwym sposobem obsługi linków jest manipulowanie możliwościami
Mark Kaplun,
Tak, kiedy zobaczyłem odpowiedź gmazzap, pomyślałem: „A dlaczego nie pomyślałem o tym?”
ricotheque
5
Jeśli chcesz trzymać się z daleka od wtyczek, możesz odmiany kodu poniżej w pliku functions.php lub wtyczce niestandardowej.
W tym kodzie znajdują się 2 oddzielne części. Wystarczy użyć 1 z nich, ale zależy to od złożoności wymagań.
Część 1 określa pojedynczego użytkownika i ogranicza go do określonego postu.
Część 2 pozwala na stworzenie mapy użytkowników i identyfikatorów postów oraz pozwala na wiele postów
Poniższy kod dotyczy tylko strony, ale jeśli chcesz zmienić go na post lub niestandardowy typ postu, musisz zmienić ciąg $screen->id == 'page'na coś innego.
Odwołanie do identyfikatorów ekranowych wokół wp-admin znajduje się tutaj
function my_pre_get_posts( $query ){
$screen = get_current_screen();
$current_user = wp_get_current_user();/**
* Specify a single user and restrict to a single page
*/
$restricted_user_id =10;//User ID of the restricted user
$allowed_post_id =1234;//Post ID of the allowed post
$current_post_id = isset( $_GET['post'])?(int)$_GET['post']:false;//Only affecting a specific userif( $current_user->ID !== $restricted_user_id ){return;}//Only Affecting EDIT page.if(! $current_post_id ){return;}if( $screen->id =='page'&& $current_post_id !== $allowed_post_id ){
wp_redirect( admin_url());exit;}/**
* Specify a map of user_id => $allowed_posts
*/
$restrictions_map =[10=>[123],//Allow user ID to edit Page ID 12311=>[152,186]//Allow user ID to edit Page ID 123 and 186];if( array_key_exists( $current_user->ID, $restrictions_map )){
$allowed_posts = $restrictions_map[$current_user->ID];if( $screen->id =='page'&&! in_array( $current_user->ID, $allowed_posts )){
wp_redirect( admin_url());exit;}}}
add_action('pre_get_posts','my_pre_get_posts');
+1, ponieważ może działać, aby wykonać podstawową funkcjonalność, ale nadal pozostawia to linki do edycji wyświetlanych stron, nawet użytkownikom, którzy nie mogą ich edytować, co czyni zły interfejs użytkownika
Mark Kaplun
-4
Użyłem User Role Editorkilka razy i jest całkiem niezły. Może to też może ci pomóc. Oto link Edytor ról użytkownika
Wygląda na solidną wtyczkę, ale nie mogę znaleźć sposobu na ograniczenie użytkownika do edycji określonych stron.
naf
Ustaw użytkowników, których chcesz ograniczyć, w ten sposób użytkowników na poziomie autora. Dodaj opcję „edit_pages” do poziomu użytkownika autora (używając Edytora ról użytkownika). Ustaw autora strony użytkownikowi, któremu chcesz nadać uprawnienia do edycji. Użytkownik na poziomie autora, który ma możliwość edit_pages, może zobaczyć listę stron na pulpicie nawigacyjnym, ale nie ma możliwości edycji, z wyjątkiem stron, których jest autorem.
user2319361
4
Dzięki, to działa do pewnego stopnia. W pewnym momencie może być konieczne ograniczenie liczby użytkowników do modyfikowania określonej strony, więc musiałby istnieć sposób na ustawienie wielu autorów na stronie.
chociaż ta konkretna wtyczka jest teraz solidną rzeczą, prawdopodobnie łatwiej jest napisać kod, aby to zrobić, niż brnąć we wszystkich opcjach, które oferuje wtyczka. (jeśli pozwoli ci nawet zrobić to, o co prosi OP)
Odpowiedzi:
Pierwszą rzeczą do zrobienia w celu realizacji takiego zadania jest rozpoznanie, którą stronę użytkownik może edytować.
Można to zrobić na różne sposoby. Może to być meta użytkownika, pewna wartość konfiguracyjna ... Ze względu na tę odpowiedź założę, że istnieje funkcja lile:
Teraz, gdy mamy sposób na ustalenie, czy użytkownik może edytować stronę, musimy po prostu powiedzieć WordPressowi, aby użył tej funkcji do sprawdzenia możliwości użytkownika do edycji strony.
Można to zrobić przez
'map_meta_cap'
filtr.Coś jak:
W tym momencie potrzebujemy tylko sposobu, aby połączyć użytkownika z jedną lub kilkoma stronami.
Mogą istnieć różne rozwiązania w zależności od przypadku użycia.
Elastycznym rozwiązaniem może być dodanie listy rozwijanej stron „root” (patrz
wp_dropdown_pages
) do ekranu administratora edycji użytkownika i zapisanie wybranych stron jako meta użytkownika.Możemy użyć dźwigni,
'edit_user_profile'
aby dodać pole rozwijane stron i'edit_user_profile_update'
zapisać wybraną wartość jako meta użytkownika.Jestem pewien, że na tej stronie jest wystarczająco dużo wskazówek, jak to szczegółowo.
Gdy strony są przechowywane jako meta użytkownika,
wpse_user_can_edit()
powyższą funkcję można zakończyć, sprawdzając, czy identyfikator strony jest częścią meta wartości użytkownika.Usuwając możliwość edycji strony, WordPress zrobi resztę: usunie dowolny link edycyjny z backendu i frontendu, uniemożliwi bezpośredni dostęp ... i tak dalej.
źródło
Zaimplementowanie tej funkcji wymaga niewielkiej ilości kodu, nawet jeśli używasz klasy PHP, aby uniknąć zmiennych globalnych. Nie chciałem też ukrywać zabronionych stron dla użytkownika w Panelu. Co jeśli dodadzą treści, które były już na stronie?
Powyższy kod uniemożliwia działanie lub pojawianie się w razie potrzeby:
get_edit_post_link
Edit Page
link na pasku administracyjnym WP, który pojawia się dla stronEdit
,Quick Edit
orazTrash
szybkie linki, które pojawiają się pod stronami w/wp-admin/edit.php?post_type=page
To działało na mojej lokalnej instalacji WordPress 4.7. Zakładając, że strony w witrynie często się nie zmieniają, może być lepiej zakodować identyfikatory strony i jej podstron oraz usunąć
WP_Query
wnętrze__construct
metody. Zaoszczędzi to wiele na połączeniach z bazą danych.źródło
Jeśli chcesz trzymać się z daleka od wtyczek, możesz odmiany kodu poniżej w pliku functions.php lub wtyczce niestandardowej.
W tym kodzie znajdują się 2 oddzielne części. Wystarczy użyć 1 z nich, ale zależy to od złożoności wymagań.
Część 1 określa pojedynczego użytkownika i ogranicza go do określonego postu.
Część 2 pozwala na stworzenie mapy użytkowników i identyfikatorów postów oraz pozwala na wiele postów
Poniższy kod dotyczy tylko strony, ale jeśli chcesz zmienić go na post lub niestandardowy typ postu, musisz zmienić ciąg
$screen->id == 'page'
na coś innego.Odwołanie do identyfikatorów ekranowych wokół wp-admin znajduje się tutaj
źródło
Użyłem
User Role Editor
kilka razy i jest całkiem niezły. Może to też może ci pomóc. Oto link Edytor ról użytkownikaźródło