Как разрешить редактору редактировать только страницу конфиденциальности и настройки?

8 нояб. 2018 г., 10:29:29
Просмотры: 15K
Голосов: 19

В моей установке WordPress (4.9.8.) роль редактора не имеет прав на редактирование страницы конфиденциальности.

Это можно исправить, добавив следующий код в functions.php:

$role_object = get_role( 'editor' );
$role_object->add_cap( 'manage_privacy_options', true );
$role_object->add_cap( 'manage_options' ); // это должно быть активно, чтобы предыдущее право работало

Но теперь у редактора появляется значительно больше прав, чем просто редактирование страницы конфиденциальности.

Есть ли другой способ предоставить доступ роли редактора с помощью нескольких строк PHP кода?


В качестве временного решения я использую этот плагин: https://wordpress.org/plugins/manage-privacy-options/

Еще одно временное решение - просто не выбирать страницу конфиденциальности в настройках.

2
Комментарии

может, это поможет? https://wordpress.org/support/topic/4-9-6-new-privacy-capability/

User User
8 нояб. 2018 г. 12:07:49

@George, да, я тоже видел эту страницу. не понимаю, что не так с моим кодом. тестировал на двух разных, довольно чистых установках WP.

André Kelling André Kelling
8 нояб. 2018 г. 12:29:30
Все ответы на вопрос 4
12
26

Редактирование страницы политики конфиденциальности ограничено возможностью manage_privacy_options, как указано в комментарии к файлу ядра WordPress wp-includes/capabilities.php:

/*
 * Установка страницы политики конфиденциальности требует `manage_privacy_options`,
 * поэтому её редактирование тоже должно требовать этого.
 */
if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
  $caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
}

Чтобы разрешить пользователям с ролями editor и administrator, которые могут редактировать страницы (в одиночных и мультисайтовых инсталляциях), редактировать и удалять страницу политики конфиденциальности, необходимо переопределить массив $caps:

add_filter('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
function custom_manage_privacy_options($caps, $cap, $user_id, $args)
{
  if (!is_user_logged_in()) return $caps;

  if ('manage_privacy_options' === $cap) {
    $manage_name = is_multisite() ? 'manage_network' : 'manage_options';
    $caps = array_diff($caps, [ $manage_name ]);
  }
  return $caps;
}

Обновление: Разрешить пользователям с ролью editor или administrator редактировать и удалять страницу политики конфиденциальности (что по умолчанию невозможно в мультисайтовых инсталляциях):

add_filter('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
function custom_manage_privacy_options($caps, $cap, $user_id, $args)
{
  if (!is_user_logged_in()) return $caps;

  $user_meta = get_userdata($user_id);
  if (array_intersect(['editor', 'administrator'], $user_meta->roles)) {
    if ('manage_privacy_options' === $cap) {
      $manage_name = is_multisite() ? 'manage_network' : 'manage_options';
      $caps = array_diff($caps, [ $manage_name ]);
    }
  }
  return $caps;
}
16 янв. 2019 г. 19:00:37
Комментарии

О, выглядит очень умно.. 1. $caps = array_diff($caps, [ $manage_name ]); действительно ограничивает все другие права manage_options? И разрешает только редактирование настроек конфиденциальности? 2. administrator в этом не нуждается, так как это право уже включено, верно?

André Kelling André Kelling
17 янв. 2019 г. 11:00:54

@AndréKelling 1. Хук map_meta_cap работает на основе отдельных записей. Другие записи не имеют ограничения manage_privacy_options, поэтому его можно спокойно удалить. Подробнее здесь. 2. В среде WordPress Multisite только супер-администраторы могут редактировать страницу политики конфиденциальности. Как вы отметили, это не относится к одиночным установкам.

Sven Sven
17 янв. 2019 г. 14:42:36

@AndréKelling У вас есть ещё вопросы по моему ответу? Если нет, пожалуйста, примите ответ, чтобы отметить этот вопрос как решённый :)

Sven Sven
4 мар. 2019 г. 15:01:43

Нет, извини, не нашёл времени проверить это. Сделаю немедленно!

André Kelling André Kelling
4 мар. 2019 г. 16:16:04

Это работает довольно хорошо, но не будет ли лучше дополнительно проверять роль пользователя... ведь это повлияет на данное разрешение для всех пользователей, не так ли?

GDY GDY
12 дек. 2019 г. 09:42:12

@GDY Хорошее замечание. Я предполагал, что только редакторы и администраторы могут редактировать страницы. Добавил проверку роли пользователя в свой ответ.

Sven Sven
12 дек. 2019 г. 12:06:47

Собственно, вопрос касается роли редактора (который в стандартных установках не может редактировать страницу конфиденциальности), поэтому ответ должен охватывать и редакторов, и администраторов.

GDY GDY
12 дек. 2019 г. 16:25:27

Да, я еще раз обновил свой ответ. Спасибо за обратную связь!

Sven Sven
12 дек. 2019 г. 17:26:41

Отличное решение! Спасибо.

Fatih Toprak Fatih Toprak
17 июл. 2020 г. 01:35:28

Большое спасибо за решение. Для тех, кто хочет разрешить WooCommerce Shop Managers редактировать политику конфиденциальности, добавьте "shop_manager" в array_intersect во втором примере.

Andrew Andrew
24 нояб. 2020 г. 01:07:13

Я знаю, что add_action является алиасом для add_filter, но поскольку фильтр map_meta_cap определяется с помощью apply_filters, я думаю, что для краткости следует заменить add_action() на add_filter().

Cornel Raiu Cornel Raiu
2 сент. 2022 г. 03:16:20

Этот код вызывает фатальную ошибку (Fatal error: Uncaught TypeError: array_intersect(): Argument #2 must be of type array, null given ...snip... /wp-admin/user-new.php(195): edit_user()) при создании новой учетной записи пользователя. Похоже, что пользователь может быть null. Я добавил дополнительную проверку после вызова get_userdata(), которая оборачивает его следующим образом: if ($user_meta && isset($user_meta->roles) && is_array($user_meta->roles)) { }

rtpHarry rtpHarry
15 февр. 2024 г. 18:15:08
Показать остальные 7 комментариев
0

Спасибо @Sven за отличное решение, оно работает хорошо, но у меня возникла проблема, когда пользователь еще не вошел в систему, действие map_meta_cap все равно срабатывало, что приводило к ошибке "502 Bad Gateway". Я добавил проверку is_user_logged_in() перед этим, вот так:

if (is_user_logged_in()){
    add_action('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
}

Возможно, это из-за моей конфигурации сервера (nginx), что приводит к этой ошибке, но если у кого-то возникнет такая же проблема, вот решение.

2 мар. 2020 г. 17:15:33
3

Предоставленное решение сработало. Однако эта строка:

if (array_intersect(['editor', 'administrator'], $user_meta->roles)) {

Вызывала следующую ошибку:

array_intersect(): Expected parameter 2 to be an array, null given in

Поэтому я немного изменил код, чтобы убедиться, что оба значения являются валидными массивами (полный код):

add_action('map_meta_cap', 'custom_manage_privacy_options', 1, 4);
function custom_manage_privacy_options($caps, $cap, $user_id, $args) {
    if ( !is_user_logged_in() ) return $caps;

$target_roles = array('editor', 'administrator');
$user_meta = get_userdata($user_id);
$user_roles = ( array ) $user_meta->roles;

if ( array_intersect($target_roles, $user_roles) ) {
    if ('manage_privacy_options' === $cap) {
        $manage_name = is_multisite() ? 'manage_network' : 'manage_options';
        $caps = array_diff($caps, [ $manage_name ]);
    }
}

return $caps;
}
21 апр. 2021 г. 07:35:35
Комментарии

Я не вижу, что ты изменил. Если $user_meta->roles равно null, ты всё равно передаёшь null в array_intersect здесь.

Rup Rup
21 апр. 2021 г. 12:35:08

Раз мы сначала убеждаемся, что пользователь залогинен, $user_meta->roles никогда не может быть null? Я думал, что проблема была из-за использования $user_meta->roles напрямую в array_intersect, поэтому сначала сохранил это в переменную. Я больше не получаю сообщений об ошибках, так что похоже это исправило проблему.

Preguntón Preguntón
21 апр. 2021 г. 13:51:05

Приведение $user_meta->roles к массиву — определённо не лучший способ. Просто проверь, установлен ли $user_meta.

Gavin Gavin
9 июл. 2021 г. 14:12:57
2

⚠ Внимание! Пока эта ошибка не исправлена, этот ответ, хотя концептуально верный, не будет работать! ⚠

На мой взгляд, теперь это лучше выполнять с помощью wp-cli.

Например, расширить роль редактора:

wp cap add editor manage_privacy_options

Или только для одного пользователя:

wp user add-cap USER_ID manage_privacy_options
3 авг. 2024 г. 11:22:42
Комментарии

Ого, похоже, это не работает :-( Если кто-то может прокомментировать, подтвердить... Пахнет багом.

sphakka sphakka
22 авг. 2024 г. 15:00:32

Нашел виновника, довольно старый баг :-/

sphakka sphakka
22 авг. 2024 г. 15:06:54