Не работает remove_cap
-
Столкнулся с неожиданной траблой. Не могу урезать конкретного юзера в правах.
$cur_user_id = get_current_user_id(); // id текущего юзера $user = new WP_User( $cur_user_id ); // создаем экземпляр касса юзера $user->remove_cap( 'publish_posts' ); // и урезаем права if(current_user_can('publish_posts') ){ echo "У юзера есть право publish_posts!"; }
Код возвращает мне «У юзера есть право publish_posts!» хотя оно ж блин строкой ранее было удалено по идее… В чем может быть трабла?
-
if(current_user_can('publish_posts') )
убрать
заменитьif ($user->has_cap('publish_posts'))
а так?
Та же трабла((
Я не знаю, важно это или нет. Но юзер у меня принадлежит произвольному типу ролей. Может там особенности какие при работе с подобными ролями и правами/* Создаем новую роль пользователя reel */ $new_role = add_role ( 'reel', // название роли __( 'Моя роль', 'r7'), // отображаемое название роли array( // массив возможностей 'read' => true, // просмотр сайта 'delete_posts' => true, // удаление собственных записей 'edit_posts'=> true, // редактирование собственных записей 'delete_published_posts' => true, // удаление собственных опубликованных записей 'publish_posts'=> true, // публикация постов 'upload_files'=> true, // загрузка файлов 'edit_published_posts'=> true // редактирование собственных опубликованных записей )); if ( null !== $new_role ) { trigger_error("роль успешно создана"); /* смотрим результат - роль успешно создана */ } else { /* если null, то значит роль уже существует */ }
Создание роли повешено на
register_activation_hook(__FILE__, ‘r7i_set_options’);PS урезание прав повешено на
add_action(‘publish_post’, ‘r7_control_package’, 0);
(т.е. суть в чем. Я делаю лимитатор. Что каждый юзер можент опубликовать лишь по одному посту.)урезание прав повешено на
add_action(‘publish_post’, ‘r7_control_package’, 0);Я бы сделал через фильтр
map_meta_cap
:function disallow_publish_posts( $caps, $cap, $current_user_id, $args ) { if ( 'publish_posts' === $cap ) { if ( count_user_posts( $current_user_id ) > 0 ) { $caps[] = 'do_not_allow'; } } return $caps; } add_filter( 'map_meta_cap', 'disallow_publish_posts', 10, 4 );
Спасибо за наводку. А можете чуточку пояснить код. В кодексе чет крайне мало нашел про map_meta_cap http://codex.wordpress.org/Function_Reference/map_meta_cap
и не совсем уловил принцип его работы
хотяб кратко подскажите что значат переменные
$caps, $cap, $current_user_id, $args
я так понимаю, что $caps — это массив?
а еще что лежит у нас в $args ?я пока только вот что понял
в $cap у нас то право, которе хотим урезать.
$current_user_id — id того, кого урезаем.$caps у нас что? Все права которые есть у юзера или как? а в $args?
И в какой момент map_meta_cap срабатывает? Т.е. к примеру я урезаю только юзеров из группы reel, админов и прочих не урезаю….
вообще мой первичный код висел на add_action(‘publish_post’ и выглядел так.
$cur_user_id = get_current_user_id(); // id текущего юзера $user = new WP_User( $cur_user_id ); // создаем экземпляр касса юзера $n_postov = get_the_author_meta('limit_postov', $cur_user_id); // получаем число оставшихся у юзера постов if (($n_postov == '')||$n_postov == '0') { $user->remove_cap( 'publish_posts' ); // и урезаем права if(current_user_can('publish_posts') ){ echo "У юзера есть право publish_posts!"; } else {/*Отнимаетм от счетчика единичку*/} }
Если сильно не углубляться, то в WordPress есть два типа возможностей:
- «Примитивные», которые действуют для всех объектов. Пример:
edit_posts
,edit_published_posts
,edit_others_posts
,edit_private_posts
и др. - «Мета-возможности», которые действуют для конкретного объекта в зависимости от контекста. Пример:
edit_post
,publish_post
.
Проверкой контекста как раз занимается функция
map_meta_cap()
, а фильтр позволяет дополнить этот механизм своими правилами, например:- Запретить редактирование конкретной записи.
- Запретить конкретному пользователю определённое действие.
- Разрешить пользователю действие в зависимости от условий.
Если углубляться — возможно, будут полезны материалы:
- What is the use of map_meta_cap filter?
- Andrew Nacin: Current User Can Watch This Talk
- Erick Hitter: The Power of WordPress Roles and Capabilities – Understanding map_meta_cap (отдельно доступны слайды к презентации)
- WordPress Capabilities Magic with map_meta_cap
$cap у нас то право, которе хотим урезать.
$current_user_id — id того, кого урезаем.Верно.
$caps у нас что? Все права которые есть у юзера или как?
Это массив возможностей, которыми пользователь должен обладать, чтобы совершить текущее действие
$cap
.Например, для редактирования чужой опубликованной записи у пользователя должны быть возможности
edit_others_posts
иedit_published_posts
.Если в массив добавить строку
do_not_allow
, то действие будет запрещено.а в $args?
Аргументы, переданные в вызывающую функцию
current_user_can()
.Например, если проверять права на редактирование конкретной записи —
current_user_can( 'edit_post', $post_id )
— в$args
будет ID записи.В нашем случае не используется, привёл просто для примера 🙂
И в какой момент map_meta_cap срабатывает?
В момент проверки
current_user_can( 'publish_posts' )
.Т.е. к примеру я урезаю только юзеров из группы reel, админов и прочих не урезаю….
Можно добавить проверку роли:
function disallow_publish_posts( $caps, $cap, $current_user_id, $args ) { if ( 'publish_posts' === $cap ) { $user = get_userdata( $current_user_id ); $role = ( $user ) ? current( $user->roles ) : ''; if ( 'reel' === $role && count_user_posts( $current_user_id ) > 0 ) { $caps[] = 'do_not_allow'; } } return $caps; } add_filter( 'map_meta_cap', 'disallow_publish_posts', 10, 4 );
Сергей, спасибо ОГРОМНОЕ! Работает!
Может кому понадобиться, ниже код с комментариями (как я это понял своими словами)function disallow_publish_posts( $caps, $cap, $current_user_id, $args ) { /* Этот фильтр срабатывает всякий раз, когда проверяются права на совершение того или иного действия. Срабатывает всегда при проверке current_user_can. В нашем случае в момент проверки current_user_can( 'publish_posts' ). $cap - право, которое проверяем (в нашем случае его надо урезать) $caps - массив со списком прав, которые необходимы для совершения определенного действия. Если к этим правам добавить $caps[] = 'do_not_allow'; - мы запретим данное действие в данный момент времени */ if ( 'publish_posts' === $cap ) { // проверяется возможность публиковать запись $user = get_userdata( $current_user_id ); // получаем данные юзера $role = ( $user ) ? current( $user->roles ) : ''; // вытаскиваем его роль $n_postov = get_the_author_meta('limit_postov', $current_user_id); // получаем число оставшихся у юзера постов if (($n_postov == '')||$n_postov == '0') { // если счетчик постов на нуле if ( 'reel' === $role) { // и при этом юзер в группе reel $caps[] = 'do_not_allow'; // блокируем возможность прямой публикации поста (вместо этого WP подставит конпку "Отправить на утвеждение") }} else {$n_postov = $n_postov - 1; update_usermeta( $current_user_id, 'limit_postov', $n_postov );} } return $caps;} add_filter( 'map_meta_cap', 'disallow_publish_posts', 10, 4 );
PS в моем случае для юеров в профиле создавался отдельный блок с «лимитом постов» (limit_postov)
Последний вопрос. Как посоветуете активировать вверху сообщение, что мол «ваш лимит постов исчерпан». Чтобы выводилось на каждой страничке выше заголовков.Оповещения сделал через хук add_action(‘admin_notices’)! Спасибо. Тема решена!
- «Примитивные», которые действуют для всех объектов. Пример:
- Тема «Не работает remove_cap» закрыта для новых ответов.