


Блог IT-шника
Блог IT-шника
Привіт:) У цьому пості покажу як включити у стандартний пошук користувацькі поля (Custom Fields) WordPress.
Користувацькі поля є однією з найпотужніших функцій ВордПрес. Вони особливо корисні при розширенні WordPress за допомогою користувацьких типів записів (Custom Post Types). Останні створюють, наприклад, для товарів, портфоліо чи галереї під час розробки тем та плагінів.
Користувацькі поля зручні, коли потрібно вказувати додаткові відомості, наприклад, про товар: унікальний код, ціна, виробник. WordPress за замовчуванням шукатиме за стандартними типами записів — Записами та Сторінками. Але стандартний пошуковий запит можна налаштувати так, щоб він включав ще і користувацькі поля.
Розгляну поетапно весь процес.
У таблиці 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' );