Có thể để một người đóng góp thay đổi tác giả của bài viết của mình? Tôi nhận ra điều này sẽ khóa chúng một cách hiệu quả, đó là điều tôi muốn. Tôi muốn họ có thể thay đổi tác giả sau khi chỉnh sửa xong.
Có thể để một người đóng góp thay đổi tác giả của bài viết của mình? Tôi nhận ra điều này sẽ khóa chúng một cách hiệu quả, đó là điều tôi muốn. Tôi muốn họ có thể thay đổi tác giả sau khi chỉnh sửa xong.
Câu trả lời:
Tôi đang thêm câu trả lời thứ hai vì cách tiếp cận đầu tiên của tôi đã bỏ phiếu và cách này không được quan tâm đúng mức.
Ý tưởng là tạo hộp meta tùy chỉnh liệt kê tất cả người dùng và thay đổi tác giả trong save_post
hook. Bằng cách này, bạn không gây rối với khả năng của người dùng và thay đổi tác giả xảy ra khi bài đăng đã được lưu. Ngoài ra lợi nhuận bổ sung là bạn có thể kiểm soát danh sách người dùng có sẵn trong danh sách tác giả. Các bước để làm theo:
Đăng ký hộp meta:
function wpse313020_add_custom_box() {
// Bail out for users other than contributors
if ( ! user_can( get_current_user_id(), 'contributor' ) ) {
return;
}
// Register custom meta box
add_meta_box(
'wpse313020_author_override',
'Change Author', // metabox title
'wpse313020_author_ovveride_box_html', // callbac function
'post' // a post type you want to show the metabox on
);
}
add_action('add_meta_boxes', 'wpse313020_add_custom_box');
Xây dựng đánh dấu cho hộp meta của bạn:
/**
* HTML for custom meta box
*/
function wpse313020_author_ovveride_box_html() {
// you can modify the list of users by passing additional args to get_users()
$users = get_users();
?>
<label for="wpse313020_author_override_id">Select post author</label><br />
<select name="wpse313020_author_override_id" id="wpse313020_author_override_id" class="postbox">
<option value="">Select user...</option>
<?php
// get post ID on admin edit screen and retrieve saved post meta
$post_id = is_admin() && isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : '';
$saved_value = ! empty( $post_id ) ? get_post_meta( $post_id, 'wpse313020_author_override', true ) : '';
foreach ( $users as $user ) {
echo sprintf( '<option value="%1$d" %2$s>%3$s</option>', absint( $user->ID ), selected( $saved_value, absint($user->ID, false ) ), esc_html( $user->display_name ) );
}
?>
</select>
<?php
}
Móc vào save_post
để lưu dữ liệu và ghi đè lên tác giả:
/**
* Save custom post meta and override the post author
*/
function wpse313020_save_postdata( $post_id ) {
if ( array_key_exists('wpse313020_author_override_id', $_POST ) ) {
// save post meta with author ID
update_post_meta( $post_id, 'wpse313020_author_override', absint( $_POST['wpse313020_author_override_id'] ) );
// now modify the post author, we need to unhook the current function to prevent infinite loop
// you could add additional check here to see if the current author is not the same as chosen author
remove_action( 'save_post', 'wpse313020_save_postdata' );
$updated_data = [
'ID' => $post_id,
'post_author' => absint( $_POST['wpse313020_author_override_id'] ),
];
wp_update_post( $updated_data );
add_action( 'save_post', 'wpse313020_save_postdata' );
}
}
add_action('save_post', 'wpse313020_save_postdata');
LƯU Ý
Hãy nhớ thêm trường nonce và kiểm tra nó trên lưu bài. Ngoài ra, bạn có thể cân nhắc sử dụng các hook khác thay vì save_post
, pre_post_update
hoặc wp_insert_post_data
, để xử lý dữ liệu khi lưu bài đăng ban đầu.
Mong rằng sẽ giúp!
Mặc dù có thể cho phép một tác giả (hoặc cộng tác viên) chỉ định một tác giả khác cho bài đăng của mình bằng cách sử dụng user_has_cap
móc lọc và một số CODE có liên quan, tuy nhiên, cách tiếp cận này về cơ bản là thiếu sót . Vì vậy, ngay cả khi bạn thực hiện tất cả các biện pháp bảo mật cần thiết, nó vẫn là một lỗ hổng vì nó phá vỡ kiến trúc khả năng cùng nhau.
Để tôi cho bạn một kịch bản ví dụ: giả sử một người dùng có vai trò tác giả ít hơn ý định danh dự và spam một tác giả khác có nhiều bài đăng (có thể sử dụng tập lệnh). Lần tới khi tác giả đích đăng nhập, họ sẽ thấy tất cả những bài đăng đó trong tên của mình! Điều này sẽ tiếp tục vì các tác giả khác không có cách nào để ngăn chặn nó! Vì vậy, chúng ta phải tìm một cách tiếp cận khác mà không có lỗ hổng này.
Nếu thay đổi tác giả là một tính năng cần thiết, thì cách tiếp cận tốt hơn là liên quan đến tác giả khác (hoặc người dùng có quyền lực cao hơn như các biên tập viên hoặc quản trị viên khác) trong quá trình thay đổi tác giả, để tác giả khởi xướng có thể không thể spam tác giả đích.
Để đạt được điều đó, chúng tôi sẽ cho phép tác giả khởi xướng chọn tác giả đích từ biên tập viên, nhưng chúng tôi sẽ không thay đổi tác giả bài viết theo cách thẳng. Thay vào đó, tại thời điểm tác giả thay đổi, chúng tôi sẽ lưu meta bài đăng tùy chỉnh sẽ lưu id tác giả đích. Sau đó, trong bảng quản trị, chúng tôi sẽ có một menu phụ bài đăng, nơi tất cả các bài đăng có yêu cầu thay đổi tác giả sẽ xuất hiện. Chỉ tác giả đích và người dùng có edit_others_post
khả năng (như biên tập viên, quản trị viên, v.v.) mới có quyền truy cập vào giao diện người dùng yêu cầu thay đổi tác giả này. Từ UI, người dùng có quyền truy cập phù hợp sẽ phê duyệt thay đổi và chỉ sau đó thay đổi tác giả cuối cùng mới xảy ra.
Việc triển khai CODE có thể thay đổi tùy theo yêu cầu, tuy nhiên, không có bất kỳ triển khai CODE nào khác, các tác giả khởi xướng sẽ có thể sửa đổi bài đăng hoặc thậm chí hoàn nguyên yêu cầu thay đổi tác giả trong cửa sổ của quy trình phê duyệt. Họ sẽ bị khóa khỏi bài viết ngay sau khi yêu cầu thay đổi tác giả được chấp thuận.
Hộp thả xuống của tác giả sẽ chỉ hiển thị khi người dùng có edit_others_posts
khả năng. Tuy nhiên, theo mặc định, bạn không muốn cung cấp khả năng này cho các tác giả. Giải pháp là chỉ cung cấp khả năng này trong các trường hợp cụ thể, cụ thể là khi anh ta đang chỉnh sửa một trong những bài đăng của riêng mình. Vì khả năng được ghi vào cơ sở dữ liệu, bạn cũng phải đảm bảo xóa nó trên bất kỳ trang nào khác.
Đây là một vấn đề thời gian chính xác. Bạn muốn thay đổi khả năng sau khi WP đã quyết định người đóng góp có quyền chỉnh sửa bài đăng, nhưng trước khi hình thức của trang chỉnh sửa ( post.php
) được tạo. Một cái móc phù hợp là admin_init
.
Như thế này:
add_action ('admin_init', 'wpse313020_change_author');
function wpse313020_change_author () {
global $pagenow;
$current_user = wp_get_current_user();
// only do this if current user is contributor
if ('contributor' == $current_user->roles[0]) {
// add capability when we're editing a post, remove it when we're not
if ('post.php' == $pagenow)
$current_user->add_cap('edit_others_posts')
else
$current_user->remove_cap('edit_others_posts');
}
}
Tôi chưa kiểm tra mã, vì vậy nó có thể có lỗi, nhưng bạn hiểu ý.
Tôi đã cố gắng để đạt được những gì bạn cần bằng cách lọc các khả năng meta của người đóng góp và nó có vẻ hoạt động tốt. Tất cả những gì tôi làm ở đây là thêm edit_others_posts
khả năng cho những người đóng góp khi WordPress yêu cầu.
Tuy nhiên, tôi muốn nói rằng đó là một giải pháp hack cho tôi và tôi không chắc nó có an toàn không. Từ những gì tôi đã kiểm tra sau khi đưa bộ lọc của mình lên functions.php
WordPress không cho phép những người đóng góp chỉnh sửa các bài đăng của người dùng khác trong các bối cảnh khác sau đó là bộ lọc bạn đã yêu cầu. Có vẻ ổn, nhưng chúng tôi thực sự không thể kiểm tra rõ ràng nếu người dùng hiện tại là tác giả của bài đăng hiện đang được chỉnh sửa (bạn sẽ không thể lưu bài đăng dưới dạng người dùng khác nếu kiểm tra có điều kiện đó sẽ được thêm vào chức năng) - đó tôi lo lắng.
/**
* author_cap_filter()
*
* Filter on the current_user_can() function.
* This function is used to explicitly allow contributors to change post authors
*
* @param array $allcaps All the capabilities of the user
* @param array $cap [0] Required capability
* @param array $args [0] Requested capability
* [1] User ID
*/
function author_cap_filter( $allcaps, $cap, $args ) {
// Bail out if we're not dealing with right capability:
if ( ! in_array( $args[0], [ 'edit_others_posts' ] ) ) {
return $allcaps;
}
// Bail out for users who are not contributors
if ( ! user_can( $args[1], 'contributor' ) ) {
return $allcaps;
}
// Bail out for users who can already edit others posts:
if ( isset( $allcaps['edit_others_posts'] ) && $allcaps['edit_others_posts'] ) {
return $allcaps;
}
// overwrite 'edit_others_posts' capability
$allcaps[ $args[0] ] = true;
return $allcaps;
}
add_filter( 'user_has_cap', 'author_cap_filter', 100, 3 );
edit_others_posts
khả năng cho tác giả về cơ bản sẽ cho phép họ chỉnh sửa các bài đăng của người khác. Chúng ta cũng có thể làm cho tác giả thành một biên tập viên, điều đó có lẽ tốt hơn là cung cấp cho họ một khả năng cao hơn. Giải pháp thứ hai là một khả năng, nhưng cần thêm một số công việc, IMHO.
edit_others_posts
luôn cho phép chỉnh sửa các bài đăng của người dùng khác. Vui lòng kiểm tra mã từ câu trả lời của tôi - ngay cả khi có bộ lọc, kiểm tra khả năng if ( ! current_user_can( 'edit_post', $post_id ) )
trong github.com/WordPress/WordPress/blob/ Lỗi vẫn trả về sai. Một lần nữa, tôi đồng ý rằng đó không phải là giải pháp an toàn như được đề cập trong câu trả lời của tôi, nhưng tôi nghĩ rằng nó đáng được đề cập vì nó thực sự hoạt động. (xin lỗi vì hai bình luận liên tiếp, tôi không phù hợp với giới hạn của người đánh xe)
Trước hết, cài đặt plugin Trình biên tập vai trò người dùng ( https://wordpress.org/plugins/user-role-editor/ ).
Thứ hai, bằng cách sử dụng plugin tạo một vai trò mới gọi là Post Manager, ví dụ:
Sau khi tạo vai trò mới, bạn sẽ có thể chỉnh sửa các khả năng của nó. Bây giờ, là thời điểm bạn giải quyết vấn đề của mình, nhưng bạn phải quyết định giữa hai lựa chọn:
(đừng lo lắng về vai trò của người đóng góp)
Đầu tiên:
edit_others_posts
và publish_posts
.Thứ hai:
edit_others_posts
.Sau khi quyết định bấm vào "Cập nhật". Vai trò mới của bạn bây giờ sẽ có read
khả năng cộng với (các) bạn đã chọn.
Bây giờ, hãy truy cập trang hồ sơ người dùng cộng tác viên của bạn và ở cuối trang cung cấp cho họ các vai trò bổ sung (tính năng Trình soạn thảo vai trò người dùng):
Giờ đây, mọi người dùng là Cộng tác viên và Trình quản lý bài đăng sẽ có thể thay đổi tác giả bài đăng của các bài đăng không được công bố. Và tùy thuộc vào lựa chọn trước đó của bạn, người dùng cũng có thể xuất bản bài đăng và nếu họ không thể chỉnh sửa bài đăng đó nữa.
QUAN TRỌNG!!!
Tôi đã chỉ cho bạn một giải pháp tạo ra vai trò mới để duy trì các khả năng mặc định của Người đóng góp. Nếu bạn muốn (không khôn ngoan), bạn có thể bỏ qua việc tạo Trình quản lý bài và sử dụng Trình chỉnh sửa vai trò người dùng, bạn sẽ chỉ cần chỉnh sửa trực tiếp các khả năng của Người đóng góp .
Và chỉ để ghi lại, mặc định WordPress chỉ cho phép edit_others_posts
khả năng thay đổi tác giả bài đăng. Xem https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/group-wp-posts-list-table.php dòng 1483.