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

Вопрос или проблема

В моей установке 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/

Другим временным решением является выбор отсутствия страницы конфиденциальности в настройках конфиденциальности.

Редактирование страницы политики конфиденциальности ограничено 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;
}

Спасибо @Sven за хорошее временное решение, оно работает отлично, но у меня была проблема, когда пользователь еще не вошел в систему, действие map_meta_cap срабатывало в любом случае, что приводило к ошибке “502 bad getaway”. Я добавил проверку is_user_logged_in() как показано ниже:

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

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

Предоставленный ответ помог. Однако, эта строка:

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;
}

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

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

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

wp cap add editor manage_privacy_options

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

wp user add-cap USER_ID manage_privacy_options

Ответ или решение

Вопрос о том, как предоставить права редактору редактировать только страницу или настройки конфиденциальности в WordPress (версии 4.9.8), требует тщательного подхода, чтобы избежать предоставления излишних привилегий. Насколько я понимаю, вы хотите, чтобы редактор мог редактировать страницу конфиденциальности, но при этом не имел прав на управление всеми административными настройками.

Теория: В WordPress права доступа регулируются посредством ролей и способностей (capabilities). Рекомендуется добавлять только необходимые права, чтобы минимизировать риски безопасности. В данном случае, проблема состоит в том, что стандартная мера — добавление способности manage_privacy_options — также требует возможности управлять всеми настройками (manage_options), что предоставляет редактору слишком много прав.

Пример: Рассмотрим код, который позволяет предоставить редактору доступ только к редактированию настройки страницы конфиденциальности:

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');
    $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;
}

Этот код добавляется в файл functions.php вашей темы и использует фильтр map_meta_cap, чтобы модифицировать способности пользователя. Код проверяет, является ли текущий пользователь редактором, и если да, то удаляет задания управления всеми настройками, оставляя только возможность редактировать страницу конфиденциальности.

Применение: Чтобы применить этот подход на практике, внесите указанный код в ваш файл functions.php. После этого ваши редакторы смогут редактировать страницу конфиденциальности, не имея доступа к управлению всеми настройками сайта.

Важно учитывать также текущие баги в системе, такие как обозначенные проблемы на WordPress Trac. Кроме того, перед внесением изменений настоятельно рекомендую протестировать их на тестовой установке WordPress, чтобы избежать непредвиденных последствий на рабочем сайте.

Таким образом, вы сможете предоставить редакторам необходимые права с минимальными изменениями в ролях пользователя, сохраняя при этом безопасность и целостность административных настроек сайта.

Оцените материал
Добавить комментарий

Капча загружается...