Tôi muốn cho phép một số người dùng nhất định chỉ chỉnh sửa một trang và đó là các trang con. Làm thế nào điều này sẽ có thể? Tôi đã thử vai trò Scoper cũ, nhưng nó dường như có rất nhiều vấn đề và lỗi.
Tôi muốn cho phép một số người dùng nhất định chỉ chỉnh sửa một trang và đó là các trang con. Làm thế nào điều này sẽ có thể? Tôi đã thử vai trò Scoper cũ, nhưng nó dường như có rất nhiều vấn đề và lỗi.
Câu trả lời:
Điều đầu tiên cần làm để thực hiện nhiệm vụ đó là có thể nhận ra trang nào người dùng có thể chỉnh sửa.
Có nhiều cách khác nhau để làm điều đó. Nó có thể là một meta người dùng, một số giá trị cấu hình ... Vì lợi ích của câu trả lời này, tôi sẽ giả sử rằng một hàm tồn tại:
function wpse_user_can_edit( $user_id, $page_id ) {
$page = get_post( $page_id );
// let's find the topmost page in the hierarchy
while( $page && (int) $page->parent ) {
$page = get_post( $page->parent );
}
if ( ! $page ) {
return false;
}
// now $page is the top page in the hierarchy
// how to know if an user can edit it, it's up to you...
}
Bây giờ chúng tôi có một cách để xác định xem người dùng có thể chỉnh sửa trang hay không, chúng tôi chỉ cần yêu cầu WordPress sử dụng chức năng này để kiểm tra khả năng của người dùng để chỉnh sửa trang.
Điều đó có thể được thực hiện thông qua 'map_meta_cap'
bộ lọc.
Cái gì đó như:
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 value
if ( ! in_array( $cap, $to_filter, true ) ) {
return $caps;
}
// First item in $args array should be page ID
if ( ! $args || empty( $args[0] ) || ! wpse_user_can_edit( $user_id, $args[0] ) ) {
// User is not allowed, let's tell that to WP
return [ 'do_not_allow' ];
}
// Otherwise just return current value
return $caps;
}, 10, 4 );
Tại thời điểm này, chúng tôi chỉ cần một cách để kết nối người dùng với một hoặc nhiều trang.
Có thể có các giải pháp khác nhau tùy thuộc vào trường hợp sử dụng.
Một giải pháp linh hoạt có thể là thêm một trang "gốc" thả xuống (xem wp_dropdown_pages
) vào màn hình quản trị người dùng chỉnh sửa và lưu (các) trang đã chọn làm meta người dùng.
Chúng tôi có thể tận dụng 'edit_user_profile'
để thêm trường thả xuống trang và 'edit_user_profile_update'
lưu trữ giá trị được chọn làm meta người dùng.
Tôi chắc chắn rằng trong trang web này có đủ hướng dẫn về cách chi tiết.
Khi (các) trang được lưu trữ dưới dạng meta người dùng, wpse_user_can_edit()
chức năng từ phía trên có thể được kết thúc bằng cách kiểm tra xem id trang có phải là một phần của giá trị meta người dùng hay không.
Xóa khả năng chỉnh sửa trang, WordPress sẽ thực hiện phần còn lại: sẽ xóa mọi liên kết chỉnh sửa khỏi phụ trợ và giao diện, sẽ ngăn truy cập trực tiếp ... v.v.
Phải mất một lượng nhỏ mã để thực hiện tính năng này, ngay cả khi bạn sử dụng lớp PHP để tránh các biến toàn cục. Tôi cũng không muốn ẩn các trang bị cấm đối với người dùng trong Bảng điều khiển. Điều gì nếu họ thêm nội dung đã có trên trang web?
$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();
public function __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.
*/
private function is_user_limited() {
$current_user = wp_get_current_user();
return ( $current_user->ID == $this->user_id );
}
private function is_page_allowed( $post_id ) {
return in_array( $post_id, $this->allowed );
}
/**
* Removes the edit link from the front-end as needed.
*/
public function 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
*/
public function 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
*/
public function 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;
}
}
Những gì đoạn mã trên làm là ngăn những thứ sau hoạt động hoặc xuất hiện khi cần thiết:
get_edit_post_link
Edit Page
liên kết trên Thanh quản trị WP xuất hiện cho TrangEdit
, Quick Edit
và Trash
các liên kết nhanh xuất hiện bên dưới Trang trong/wp-admin/edit.php?post_type=page
Điều này làm việc trên cài đặt WordPress 4.7 cục bộ của tôi. Giả sử rằng các trang trên trang web sẽ không thay đổi thường xuyên, có thể tốt hơn là mã hóa ID của trang và các trang phụ của nó và xóa phương thức WP_Query
bên trong __construct
. Điều này sẽ tiết kiệm rất nhiều cho các cuộc gọi cơ sở dữ liệu.
Nếu bạn muốn tránh xa các plugin, bạn có thể biến thể mã bên dưới trong tệp tin.php. Hoặc một plugin tùy chỉnh.
Có 2 phần riêng biệt cho mã này, Bạn sẽ chỉ cần sử dụng 1 trong số đó, nhưng phần nào phụ thuộc vào độ phức tạp của các yêu cầu.
Phần 1 là chỉ định một người dùng và giới hạn họ vào một bài đăng cụ thể.
Phần 2 cho phép bạn tạo bản đồ người dùng và đăng ID và cho phép nhiều bài đăng
Mã dưới đây chỉ dành cho một trang, nhưng nếu bạn muốn thay đổi nó thành một bài đăng, hoặc một loại bài đăng tùy chỉnh, bạn sẽ cần phải thay đổi chuỗi $screen->id == 'page'
thành một thứ khác.
Bạn có thể tìm thấy một tham chiếu đến ID màn hình xung quanh wp-admin tại đây
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 user
if( $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 123
11 => [ 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' );
Tôi đã sử dụng User Role Editor
một vài lần và là khá tốt. Có lẽ nó cũng có thể giúp bạn. Đây là liên kết Trình chỉnh sửa vai trò người dùng