Я пытаюсь запретить некоторым пользователям доступ к определенным сообщениям, страницам, категориям и вложениям как в интерфейсе администратора («бэкэнд»), так и на реальном сайте («интерфейс»).
Я решил внешний интерфейс, используя действие template_redirect
, проверяя, разрешено ли wp_get_current_user()
просматривать global $post
, а если нет, просто вызвать 404.
Я также решил большинство списков сообщений, используя фильтр pre_get_posts
. Даже списки внутри админа (хотя не все списки, к сожалению).
Однако внутри администратора пользователь все еще может редактировать любое сообщение, вложение, категорию или страницу, к которым он фактически не должен иметь доступ, просто введя правильный URL-адрес, например /wp-admin/post.php?post=SOME_ID&action=edit
.
Я пытался исправить это с помощью фильтра map_meta_cap
, и, хотя он, кажется, работает для постов и страниц (и вложений при просмотре обычного экрана редактирования), я не могу заставить его работать для всплывающих окон вложений "(когда вы щелкаете вложение в списке и получаете всплывающее окно с URL-адресом такого типа: /wp-admin/upload.php?item=SOME_ID
) или категориями (/wp-admin/term.php?taxonomy=category&tag_ID=SOME_ID&post_type=post
).
Прежде всего, я даже не уверен, какую возможность я должен фильтровать для вложений и категорий, но я пробовал использовать upload_files
и manage_categories
, но нет никакого способа узнать, какой пост / термин редактируется. :
add_filter('map_meta_cap', function ($caps, $cap, $user_id, $args) {
# NOTE: $args[0] contains the post->ID
if (in_array($cap, ['edit_post', 'delete_post', 'edit_page', 'delete_page']) and !can_current_user_access_post($args[0])) {
return ['do_not_allow'];
}
elseif (in_array($cap, ['upload_files'])) {
# NOTE: $args is false, not sure how to check if user can access current attachment
}
elseif (in_array($cap, ['manage_categories'])) {
# NOTE: $args is false, not sure how to check if user can access current term
}
return $caps;
}, 10, 4);
Мне также любопытно, почему я не могу просто добавить read_post
и read_page
к заглавным буквам, которые я проверяю, чтобы предотвратить доступ для чтения? (Что позволило бы мне удалить мой код template_redirect
).
Кроме того, если бы я мог заставить этот map_meta_cap
код работать хорошо везде (даже для read
), я мог бы удалить мой pre_get_posts
фильтр, что было бы неплохо.
Я никогда раньше не использовал map_meta_cap
и, честно говоря, я немного растерялся относительно того, как именно это работает.
Редактировать: теперь я решил экран редактирования категории, используя возможность edit_term
.