Статьи

Создание простой CRM в WordPress: расширение поиска в WordPress

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

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

Каждый тип сообщения с интерфейсом администрирования поставляется с окном поиска:

Поле поиска WordPress

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

  • заглавие
  • содержание
  • выдержка

Если мы попытаемся найти неполный номер телефона, мы увидим, что результаты не отображаются:

Поиск в наших расширенных пользовательских полях данных не работает

Для нашего Контактного Пользовательского Типа Поста это не очень полезно, если мы хотим найти контакт по номеру телефона или адресу электронной почты!

Расширенные пользовательские поля хранят свои данные в таблице wp_postmeta , которую WordPress не ищет по умолчанию. Нам нужно использовать два из предоставленных WordPress фильтров, чтобы позволить поисковой функции WordPress также выполнять поиск в данных расширенных пользовательских полей. Эти фильтры будут:

  1. выполнить SQL-соединение между таблицей метаданных WordPress Post и таблицей постов WordPress
  2. добавьте SQL-предложение WHERE в пост-запрос WordPress для поиска в нашей мета-таблице постов WordPress

Давайте начнем с добавления фильтра 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 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.