Главная Новости

Pre_user_query в WordPress


Опубликовано: 01.09.2018

Прежде всего нужно понять один важный момент. Когда я только увидел в коде экшн pre_user_query, я подумал: «А, наверное это что-то наподобие pre_get_posts , но только для пользователей».

Ничего подобного. На самом деле существуют два основных фильтра, связанных с полечением пользователей:

pre_get_users (как раз он и является аналогом pre_get_posts для постов) выполняется до того, как спарсится SQL запрос и позволяет поменять какие-то параметры WP_User_Query , например количество выводимых пользователей, их сортировка и т.д. pre_user_query вступает в действие уже после того, как спарсится SQL запрос, непосредственно перед его выполнением. Ему и посвятим этот пост.

Если вы пришли сюда не за готовым примером, а для того, чтобы во всём разобраться, то предлагаю начать с того, чтобы вставить код ниже в functions.php вашей текущей темы и перейти на любую страницу сайта, где присутствует вывод пользователей, например в список пользователей в админке.

add_action ( 'pre_user_query' , 'true_funkciya' ) ; function true_funkciya ( $zapros ) { print_r ( $zapros ) ; }

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

И ещё кое-что, если ваша версия WordPress ниже, чем 3.1, то pre_user_query у вас работать не будет (попробуйте использовать вместо неё pre_user_search, а ещё лучше — обновитесь).

Окей, а теперь давайте на примерах посмотрим, что с этим можно сделать.

1. Скрытый пользователь.

Итак, как полностью скрыть какого-либо пользователя из сайта и админки, но при этом сам он себя будет видеть. Конечно при помощи pre_user_query.

add_action ( 'pre_user_query' ,'true_skrivaem_polzovatelya' ) ; function true_skrivaem_polzovatelya ( $zapros ) { // так как сам себя пользователь видеть должен, поэтому нам понадобится следующее условия $tekuchij_polzovatel = wp_get_current_user ( ); if ( $tekuchij_polzovatel -> ID != 2 ) { // я взял пользователя с ID = 2, вы можете использовать любого другого global $wpdb ; // используем обычную str_replace() для того, чтобы исключить пользователя из SQL запроса $zapros -> query_where = str_replace ( 'WHERE 1=1' , "WHERE 1=1 AND {$wpdb->users} .ID<>2" , $zapros -> query_where ) ; // если будете менять ID, то не забудьте поменять и тут } }

Что можно понять из этого примера?

То, что я извращаюсь с транслитом (надеюсь, это не слишком мешает, просто у меня есть ещё и англоязычный блог, на который я переношу многие из статей — не хочу получить дубликаты кода). Условие на проверку текущего пользователя вы кстати можете вынести за пределы функции и поставить под условие add_action(), в принципе получится вот так:
$tekuchij_polzovatel = wp_get_current_user ( ); if ( $tekuchij_polzovatel -> ID != 2 ) add_action ( 'pre_user_query' ,'true_skrivaem_polzovatelya' ) ;
Хоть пользователь и пропадёт из сайта, для того, чтобы полностью всех обмануть, вам также придётся поработать со счетчиками количества пользователей, для того, чтобы вам было понятно, о чём я говорю, вот скриншот:

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

Как видите, мы просто заменили WHERE-часть запроса, те, кто хорошо знаком с базами данных, увидит здесь гораздо большую свободу действий.

2. Если пользователь не администратор, то скрываем всех администраторов

По сути всё основывается на том же принципе, что и в предыдущем примере, только SQL-запрос станет намного интереснее. Пример будет также основываться на ролях пользователей, про которые можно почитать здесь .

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 add_action ( 'pre_user_query' ,'true_skrivaem_administratorov' ) ; function true_skrivaem_administratorov ( $zapros ) { // так же, как и в предыдущем примере получаем текущего пользователя и убеждаемся, что он не администратор // разумеется тут можно использовать любую свою проверку $tekuchij_polzovatel = wp_get_current_user ( ); if ( $tekuchij_polzovatel -> roles [ 0 ] != 'administrator' ) { global $wpdb ; $zapros -> query_where = str_replace ( 'WHERE 1=1' , "WHERE 1=1 AND {$wpdb->users} .ID IN ( SELECT {$wpdb->usermeta} .user_id FROM $wpdb->usermeta WHERE {$wpdb->usermeta} .meta_key = ' {$wpdb->prefix} capabilities' AND {$wpdb->usermeta} .meta_value NOT LIKE '%administrator%')" , $zapros -> query_where ) ; } }

Если вам всё ещё многое непонятно, могу порекомендовать почитать статью про базы данных в WordPress, про $wpdb тут .

Теперь же краткое описание того, что сделали — как известно, название роли пользователя хранится в таблице базы данных wp_usermeta (заменить wp_ на используемый у вас префикс) под ключом wp_capabilities. И в примере мы получили только тех пользователей, у которых в значении wp_capabilities в базе данных отсутствует administrator.

3. Расширенный поиск пользователей

По умолчанию WordPress позволяет производить поиск пользователей по уже определенным полям, например по логину user_login, емайлу user_email, URL user_url, отображаемому имени display_name, айди ID и по нику user_nicename. Всё, что нам разрешается, это исключить какие-либо из колонок из поиска при помощи фильтра user_search_columns.

Однако и тут pre_user_query открывает перед нами новые возможности — мы можем можем включить в поиск как любые метаданные пользователя, так и заголовки постов!

add_action ( 'pre_user_query' ,'true_poisk_po_meta' ) ; function true_poisk_po_meta ( $zapros ) { // прежде всего делаем несколько проверок, для того, чтобы код применялся только при поиске пользователей if ( $zapros -> query_vars [ 'search' ] ) { $poisk = trim ( $zapros -> query_vars [ 'search' ] , '*' ) ; if ( $_REQUEST [ 's' ] == $poisk ) { global $wpdb ; // добавляем Имя first_name пользователя в поиск $zapros -> query_from .= " JOIN {$wpdb->usermeta} fn ON fn.user_id = {$wpdb->users} .ID AND fn.meta_key = 'first_name'" ; // добавляем любые метаданные пользователя // $zapros->query_from .= " JOIN {$wpdb->usermeta} cstm ON cstm.user_id = {$wpdb->users}.ID AND cstm.meta_key = 'ВАШ ПРОИЗВОЛЬНЫЙ meta_key'"; // ну и пример с заголовками постов (я включил все посты, любого статуса и типа, но вы можете это доработать) $zapros -> query_from .= " JOIN {$wpdb->posts} psts ON psts.post_author = {$wpdb->users} .ID" ; // решаем, по каким полям в итоге производить поиск $posik_po = array ( 'user_login' , 'user_email' , 'fn.meta_value' , 'psts.post_title' ) ; // применяем к запросу $zapros -> query_where = 'WHERE 1=1' . $zapros -> get_search_sql ( $poisk , $posik_po , 'both' ) ; } } }

По теме

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