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

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

Мне наконец-то удалось обновить старый сайт WP 3.3.1 до WP 4.1 с небольшими проблемами, но одно неожиданное изменение, похоже, произошло в отношении загрузки файлов.

В версии WP 3.3.1 плагина я включил загрузку для пользовательской роли через ‘read’ и ‘upload_files’.

ПРИМЕЧАНИЕ: Это касается контента, который НЕ основывается на записях. Это просто редактор, который я хочу использовать для каких-то пользовательских таблиц БД. Вызов wp_editor имеет контент, явно установленный в ”. Я использую метод буферизации, чтобы переместить редактор, о чем подробно написано здесь: https://wordpress.stackexchange.com/a/66345

// захватываем редактор для последующего использования...
// ХИТРОСТЬ: https://wordpress.stackexchange.com/a/66345
ob_start();

wp_editor(
    '',
    'xyz-note-editor',
    array(
        'textarea_rows' => '10',
    )
);

$editor = ob_get_clean();

// ...

$edit_form_template = str_replace('{{NotesEditor}}', $editor, $edit_form_template);

После обновления до WP 4.1 все работает для Редакторов и Администраторов.

Это не работает для Авторов, Участников и моей пользовательской роли, с ошибкой: “У вас нет разрешения прикреплять файлы к этой записи.”

(“Запись” кажется независимым экземпляром пользовательского типа записи, к которому загружаемые медиафайлы присваиваются, когда успешно загружаются как Редактор или Администратор.)

Не зная, как все это решить, или не найдя какой-то плагин (например, Members от Джастина Тадлока, рекомендованный в другом месте на StackExchange), я застрял.

Почему Редакторы могут обойти ограничения на загрузку в этом случае?

Я пытался назначить разрешения редактирования/публикации/чтения для Редакторов (и ниже) для пользовательской роли без успеха – основываясь на http://codex.wordpress.org/Roles_and_Capabilities.

add_role(
    XxYyConfig::USER_ROLE(), 
    'Управляющий пользовательскими данными', 
    array(
        'read' => true,

        // ДОБАВЛЕНО: чтобы исправить изменения в том, как работает "Добавить медиа" в WordPress - касательно ошибки "У вас нет разрешения прикреплять файлы к этой записи."
        // ПРИМЕЧАНИЕ: Управляющие пользовательскими данными, Участники и Авторы НЕ МОГУТ добавлять медиафайлы -- НО Редакторы/Администраторы могут. Пытается добавить к записи {custom_post_type} (по неизвестным причинам). Контент для редактора установлен в ''...
        'edit_files' => true,
        'edit_others_pages' => true,
        'edit_others_posts' => true,
        'edit_pages' => true,
        'edit_posts' => true,
        'edit_private_pages' => true,
        'edit_private_posts' => true,
        'edit_published_pages' => true,
        'edit_published_posts' => true,
        'publish_pages' => true,
        'publish_posts' => true,
        'read_private_pages' => true,
        'read_private_posts' => true,
        // ДОБАВЛЕНО: КОНЕЦ

        'upload_files' => true,
    )
);

Я знаю, что в этом вопросе немного запутался, но это кажется несовместимым (даже если что-то из давно прошедшего времени было “исправлено”).

map_meta_cap похоже, может применяться здесь, но отсутствие пользовательского типа записи заставляет меня думать, что это неправильное решение.

В идеале, я хотел бы знать, почему пользовательский тип записи помечается в этом процессе, но я держусь за то, что необходимо настроить для обработки разрешений/возможностей, чтобы разрешить загрузку через WYSIWYG редактор?

ПРАВКА: Поскольку моя роль устанавливается во время активации плагина, я убедился в том, чтобы отключить и снова активировать плагин, чтобы убедиться, что там не происходит ничего необычного.

Нашел основную проблему! Хотя контекст другой, чем тот, который вы описали, коренная причина, вероятно, та же самая. Я пытался позволить пользователям настроить персональную страницу и загрузить изображение для отображения там. Я продолжал получать досадное сообщение “У вас нет разрешения прикреплять файлы к этой записи”.

Сообщение само по себе приходит из wp_ajax_upload_attachment() в /wp-admin/includes/ajax-actions.php, даже если пользователь работает на главной странице, а не на панели управления, потому что плагин, который я использую (Advanced Custom Fields — рекомендую!) использует библиотечные функции WordPress (к счастью, он ограничивает доступ к библиотеке). Ошибка возникает, если current_user_can() не дает разрешение.
(Вы можете подтвердить, что сообщение находится в этой функции, изменив сообщение на что-то другое.)

В свою очередь, current_user_can() вызывает $current_user->has_cap(), чтобы получить текущие возможности.

has_cap() предлагает хороший фильтр, который мы можем использовать, но он все равно продолжал давать сбой. Причина заключалась в том, что он сначала вызывает map_meta_cap(), которая формирует большой массив возможных возможностей для этого экземпляра. Если хотя бы одна из этих возможных возможностей оставлена ‘пустой’, тогда has_cap возвращает false.

Это означает, что любой пользовательский фильтр, который определен для предоставления разрешения, должен пройти по массиву и установить все на true.
Мне кажется, что лучшее постоянное решение заключалось бы в том, чтобы WordPress игнорировал любые возможности, которые не были явно установлены для разрешения или запрета.

На данный момент вот пример функции фильтра, которая работает для меня:

// разрешить пользователям добавлять изображения на свою домашнюю страницу
function allow_own_attachments( $user_caps, $req_caps, $args, $UserObj ) {
   if ( empty($args[2]) ) {
      return $user_caps;  // нечего проверять
   }
   $post = get_post( $args[2] );  // post_id был передан здесь
   if ( $post->post_author == $UserObj->ID ) {  // это моя запись
      foreach ( (array) $req_caps as $cap ) {
         if ( empty( $user_caps[ $cap ] ) )
            $user_caps[ $cap ] = true;
      }
   }
   $user_caps['edit_post'] = true; // протестировано wp_ajax_upload_attachment()
   return $user_caps;
}
add_filter( 'user_has_cap', 'allow_own_attachments', 10, 4 );

Код из предыдущего ответа сработал для меня, но я получал это уведомление в режиме отладки: “Попытка получить свойство ‘post_author’ у ненастоящего объекта”. Я добавил проверку, чтобы убедиться, что $post возвращает объект (if (is_object($post))). Это устраняет уведомление.

function allow_own_attachments( $user_caps, $req_caps, $args, $UserObj ) {
if ( empty($args[2]) ) {
   return $user_caps;  // нечего проверять
}
$post = get_post( $args[2] );  // post_id был передан здесь

if (is_object($post)){  //проверка, является ли $post объектом. Если это не так, код выдает это уведомление: Попытка получить свойство 'post_author' у ненастоящего объекта 
    if ( $post->post_author == $UserObj->ID ) {  // это моя запись
        foreach ( (array) $req_caps as $cap ) {
            if ( empty( $user_caps[ $cap ] ) )
                $user_caps[ $cap ] = true;
        }
    }
}
$user_caps['edit_post'] = true; // протестировано wp_ajax_upload_attachment()
return $user_caps;
}

add_filter( 'user_has_cap', 'allow_own_attachments', 10, 4 );

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

Добавление возможностей загрузки медиа для настраиваемой роли вне постов в WordPress

Обновление сайта на WordPress с версии 3.3.1 до 4.1 может сопрягаться с рядом особенностей, касающихся управления правами доступа и разрешениями для загрузки медиафайлов различным ролям пользователей. Ваша ситуация характеризуется проблемой доступа с не настраиваемыми ролями (например, Автор, Участник и ваша настраиваемая роль), которые получают сообщение об ошибке: "У вас нет разрешения на прикрепление файлов к этому сообщению". Давайте подробнее рассмотрим, как исправить это и добавить необходимые возможности загрузки.

Анализ проблемы

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

Причина ограничения

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

Шаги для решения проблемы

1. Определение необходимых прав

Чтобы разрешить вашей настраиваемой роли загружать медиафайлы, вам необходимо добавить соответствующие возможности через фильтры, как указано ниже:

function custom_role_permissions() {
    $role = get_role('custom_role'); // Замените 'custom_role' на ваше название роли

    if ($role) {
        $role->add_cap('upload_files'); // Позволяет загружать файлы
        $role->add_cap('edit_posts'); // Позволяет редактировать посты
        $role->add_cap('edit_others_posts'); // Позволяет редактировать посты других пользователей
        $role->add_cap('edit_private_posts'); // Позволяет редактировать приватные посты
    }
}
add_action('admin_init', 'custom_role_permissions');

2. Использование фильтра user_has_cap

Для более тонкой настройки доступов, вы можете использовать фильтр user_has_cap. Это позволит вам контролировать и разрешать загрузку медиафайлов на основе определенных условий:

function allow_own_attachments($user_caps, $req_caps, $args, $user_obj) {
    if (empty($args[2])) {
        return $user_caps; // Нечего проверять
    }

    $post = get_post($args[2]); // Получаем пост по ID
    if (is_object($post) && $post->post_author == $user_obj->ID) {
        foreach ((array) $req_caps as $cap) {
            // Обеспечиваем доступ к необходимым возможностям, если они не были установлены
            if (empty($user_caps[$cap])) {
                $user_caps[$cap] = true;
            }
        }
    }
    return $user_caps;
}
add_filter('user_has_cap', 'allow_own_attachments', 10, 4);

Заключение

С помощью указанных выше шагов вы можете эффективно разрешить вашей настраиваемой роли загружать медиафайлы в WordPress 4.1 и выше. Обратите внимание, что при использовании среды, где настраиваемые роли и возможности могут изменяться на лету, важно тщательно тестировать все изменения в безопасности и производительности.

Также стоит отметить, что в WordPress политика безопасности может меняться с выходом новых обновлений, поэтому рекомендую всегда следить за официальной документацией и актуальными изменениями в API.

Эти изменения не только обеспечат функциональность, необходимую для вашего сценария, но и проложат основу для более гибкого подхода к управлению правами в будущем.

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

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