Мы искали, как создать простую систему CRM в WordPress. В последней части этой серии мы добавили код в наш плагин, который позволял нам отображать наши дополнительные настраиваемые поля в таблице списка WordPress (WP_List_Table) и сортировать наши данные в алфавитном порядке по этим новым полям.
Сегодня мы расскажем, как расширить функциональность поиска, чтобы включить данные, хранящиеся в наших пользовательских полях.
Функциональность поиска
Каждый тип сообщения с интерфейсом администрирования поставляется с окном поиска:
По умолчанию, когда пользователь выполняет поиск сообщений в интерфейсе администрирования WordPress, WordPress будет искать в таблице wp_posts
любые частичные совпадения содержимого в следующих полях:
- заглавие
- содержание
- выдержка
Если мы попытаемся найти неполный номер телефона, мы увидим, что результаты не отображаются:
Для нашего Контактного Пользовательского Типа Поста это не очень полезно, если мы хотим найти контакт по номеру телефона или адресу электронной почты!
Расширенные пользовательские поля хранят свои данные в таблице wp_postmeta
, которую WordPress не ищет по умолчанию. Нам нужно использовать два из предоставленных WordPress фильтров, чтобы позволить поисковой функции WordPress также выполнять поиск в данных расширенных пользовательских полей. Эти фильтры будут:
- выполнить SQL-соединение между таблицей метаданных WordPress Post и таблицей постов WordPress
- добавьте SQL-предложение WHERE в пост-запрос WordPress для поиска в нашей мета-таблице постов WordPress
Выполнение SQL JOIN
Давайте начнем с добавления фильтра posts_join
в конструкцию нашего плагина для присоединения к WordPress:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
/**
* Constructor.
*/
function __construct() {
add_action( ‘init’, array( &$this, ‘register_custom_post_type’ ) );
add_action( ‘plugins_loaded’, array( &$this, ‘acf_fields’ ) );
add_filter( ‘manage_edit-contact_columns’, array( &$this, ‘add_table_columns’ ) );
add_action( ‘manage_contact_posts_custom_column’, array( &$this, ‘output_table_columns_data’ ), 10, 2 );
add_filter( ‘manage_edit-contact_sortable_columns’, array( &$this, ‘define_sortable_table_columns’ ) );
if ( is_admin() ) {
add_filter( ‘request’, array( &$this, ‘orderby_sortable_table_columns’ ) );
add_filter( ‘posts_join’, array ( &$this, ‘search_meta_data_join’ ) );
}
}
|
Нам также нужно определить нашу search_meta_data_join()
, которая сообщает WordPress, к какой таблице мы хотим присоединиться к основной таблице сообщений WordPress:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/**
* Adds a join to the WordPress meta table for license key searches in the WordPress Administration
*
* @param string $join SQL JOIN statement
* @return string SQL JOIN statement
*/
function search_meta_data_join($join) {
global $wpdb;
// Only join the post meta table if we are performing a search
if ( empty ( get_query_var( ‘s’ ) ) ) {
return $join;
}
// Only join the post meta table if we are on the Contacts Custom Post Type
if ( ‘contact’ != get_query_var( ‘post_type’ ) ) {
return $join;
}
// Join the post meta table
$join .= » LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id «;
return $join;
}
|
get_query_var()
— это функция, которая возвращает соответствующую переменную запроса, хранящуюся в классе WP_Query
. WP_Query
— это класс WordPress, который обеспечивает:
… информация, определяющая текущий запрос … с каким типом запроса он (например, архив категорий, архив дат, фид или поиск) и извлекающий запрошенные сообщения. Он сохраняет много информации по запросу, которую можно получить позже.
get_query_var()
— это магия, которая позволяет нам «извлекать» эту информацию. В этом случае мы проверяем переменную запроса 's'
, сообщая нам, какой поисковый запрос (если есть) был запрошен пользователем. Мы также используем эту же функцию для проверки того, какие типы сообщений запрашивает пользователь — мы хотим расширить наш поиск, только если пользователь просматривает контактный пользовательский тип сообщения.
Если эти условия выполняются, мы присоединяем таблицу wp_postmeta
к основной таблице wp_posts
.
$wpdb
также используется $wpdb
, и это определенный класс, который:
… содержит набор функций, используемых для взаимодействия с базой данных. Его основная цель — обеспечить интерфейс с базой данных WordPress, но его можно использовать для связи с любой другой подходящей базой данных.
Короче говоря, $wpdb
позволяет нам получить доступ к базе данных MySQL, получить параметры конфигурации и выполнить запросы SQL.
В этом случае мы используем $wpdb
для получения имен таблиц Post и Post Meta, поскольку они могут быть изменены при каждой установке WordPress. Например, одна установка может установить префикс имени таблицы wp_
(по умолчанию), тогда как другая установка может установить для него my_awesome_site_
. Мы не можем жестко кодировать имена таблиц, так как не можем гарантировать, что они всегда будут wp_posts
и wp_postmeta
, поэтому мы используем $wpdb->posts
и $wpdb->postmeta
, которые содержат фактические имена таблиц, характерные для этой установки WordPress. ,
Добавление к предложению SQL WHERE
После завершения нашего SQL JOIN нам нужно сообщить WordPress, что нужно искать в объединенной мета-таблице Post.
Вернитесь к плагину __construct()
и добавьте новую функцию в фильтр posts_where
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
/**
* Constructor.
*/
function __construct() {
add_action( ‘init’, array( &$this, ‘register_custom_post_type’ ) );
add_action( ‘plugins_loaded’, array( &$this, ‘acf_fields’ ) );
add_filter( ‘manage_edit-contact_columns’, array( &$this, ‘add_table_columns’ ) );
add_action( ‘manage_contact_posts_custom_column’, array( &$this, ‘output_table_columns_data’ ), 10, 2 );
add_filter( ‘manage_edit-contact_sortable_columns’, array( &$this, ‘define_sortable_table_columns’ ) );
if ( is_admin() ) {
add_filter( ‘request’, array( &$this, ‘orderby_sortable_table_columns’ ) );
add_filter( ‘posts_join’, array (&$this, ‘search_meta_data_join’ ) );
add_filter( ‘posts_where’, array( &$this, ‘search_meta_data_where’ ) );
}
}
|
Нам также нужно определить нашу search_meta_data_where()
, которая сообщает WordPress для поиска в наших метаданных Post:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/**
* Adds a where clause to the WordPress meta table for license key searches in the WordPress Administration
*
* @param string $where SQL WHERE clause(s)
* @return string SQL WHERE clauses
*/
function search_meta_data_where($where) {
global $wpdb;
// Only join the post meta table if we are performing a search
if ( empty ( get_query_var( ‘s’ ) ) ) {
return $where;
}
// Only join the post meta table if we are on the Contacts Custom Post Type
if ( ‘contact’ != get_query_var( ‘post_type’ ) ) {
return $where;
}
// Get the start of the query, which is ‘ AND ((‘, and the rest of the query
$startOfQuery = substr( $where, 0, 7 );
$restOfQuery = substr( $where ,7 );
// Inject our WHERE clause in between the start of the query and the rest of the query
$where = $startOfQuery .
«(» . $wpdb->postmeta . «.meta_value LIKE ‘%» . get_query_var( ‘s’ ) . «%’ OR » . $restOfQuery .
«GROUP BY » .
// Return revised WHERE clause
return $where;
}
|
Таким же образом, как мы это делали в search_meta_data_join()
, мы снова проверяем, что запрос WordPress — это поиск по типу пользовательской записи контактов. Если это не так, мы возвращаем предложение $while
без изменений.
Если нам нужно изменить предложение $while
, мы сделаем это следующим образом:
- начало предложения WHERE:
' AND(('
- получение остатка от предложения WHERE
- добавление предложения WHERE для поиска в столбце
meta_value
таблицы Post Meta любого экземпляра нашего поискового запроса - добавив условие OR в конец нашего предложения WHERE, добавив к нему остальную часть запроса
- группировка результатов по идентификатору поста
Нам нужно сгруппировать результаты, потому что обычно в таблице мета-столбов будет несколько записей для данного идентификатора поста. Поскольку мы создали JOIN между постами и их мета-версией Post, если мы не сгруппируем результаты, мы получим тот же пост, повторяющийся в нашей таблице.
Чтобы убедиться, что наши предложения JOIN и WHERE сработали, перезагрузите таблицу контактов и попробуйте найти один из ваших контактов по части их номера телефона:
Если это работает, поздравляю! Теперь вы можете осуществлять поиск по любым дополнительным настраиваемым полям, указанным в вашей системе CRM.
Следующий…
В следующей статье мы собираемся ограничить и скрыть функции администрирования WordPress и пункты меню, которые нам не нужны для нашей CRM.