Пошук за користувацькими полями WordPress

Привіт:) У цьому пості покажу як включити у стандартний пошук користувацькі поля (Custom Fields) WordPress.

Користувацькі поля є однією з найпотужніших функцій ВордПрес. Вони особливо корисні при розширенні WordPress за допомогою користувацьких типів записів (Custom Post Types). Останні створюють, наприклад, для товарів, портфоліо чи галереї під час розробки тем та плагінів.

Користувацькі поля зручні, коли потрібно вказувати додаткові відомості, наприклад, про товар: унікальний код, ціна, виробник. WordPress за замовчуванням шукатиме за стандартними типами записів — Записами та Сторінками. Але стандартний пошуковий запит можна налаштувати так, щоб він включав ще і користувацькі поля.

Розгляну поетапно весь процес.

Весь наступний код потрібно додати у файл functions.php.

Left Join

У таблиці postmeta зберігаються всі дані користувацьких полів у базі даних. За замовчуванням функція пошуку WordPress налаштована на пошук лише в таблиці posts. Щоб включити дані користувацьких полів у пошук, спочатку потрібно виконати ліве об’єднання таблиць posts і postmeta в базі даних.

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter( 'posts_join', 'cf_search_join' );

Зміна пошукового запиту

Наступний крок — зміна пошукового запиту WordPress для включення користувацьких полів.

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

Виключення дублювання

На останньому етапі потрібно додати ключове слово DISTINCT до SQL-запиту, щоб запобігти поверненню дублікатів.

/**
 * Prevent duplicates
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

Повний код

Просто додайте PHP-код нижче у свій файл functions.php.

Пошук за користувацькими полями працюватиме не лише для користувача сайту, але й у адмін-частині.

<?php
/**
 * Extend WordPress search to include custom fields
 *
 * https://adambalee.com
 */

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter( 'posts_join', 'cf_search_join' );

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

/**
 * Prevent duplicates
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

Джерело

Михайло Петров
Михайло Петров

Мене звати Михайло. Я — WordPress-розробник. Створюю візитки, корпоративні сайти, блоги на WordPress.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *