最近我们一直在写关于WordPress中创建简单的CRM的系列教程。上一篇中我们写到了在WP_List_Table中添加列。
今天这篇教程我们将介绍如何扩展搜索功能使得搜索功能包含我们自定义字段中储存的数据。
搜索功能
每一种文章类型都有一个嵌有搜索框的管理界面:
默认情况下用户在管理界面搜索文章,WordPress将会访问wp_posts然后找到与下述字段相匹配的任意内容:
- 标题
- 目录
- 摘要
现在你试着查找一下电话号码,你会发现没有查找结果:
对于我们的Contact 自定义文章类型,如果我们想通过电话号码或邮箱地址来查找contact,那么默认条件下是不能实现的。
Advanced Custom Fields将数据存放在wp_postmeta表单中,我们需要通过运用WordPress中提供的两个filters来让WordPress的查找功能也可以去查找Advanced Custom Fields 的数据。
那两个filters将会执行下面两项操作,分别是:
1、执行WordPress Post Meta表单和Posts表单之间的SQL JOIN。
2、追加一个SQL WHERE子句到WordPress的文章查询来搜索我们的WordPress文章元表。
执行一个SQL JOIN
首先在我们插件类的构造函数中添加一个posts_join的filter:
/**
* Constructor. Called when plugin is initialised
*/
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我们想要添加到Posts 表单中的表单,代码如下:
/**
* 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;
}
附加到SQL WHERE子句
SQL JOIN执行完后,我们现在需要告诉WordPress去搜索Post Mate表单。
回到插件的构造函数,然后添加一个新函数到posts_where 的filter,代码如下:
/**
* Constructor. Called when plugin is initialised
*/
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 Mate表单。代码如下:
/**
* 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 " . $wpdb->posts . ".id";
// Return revised WHERE clause
return $where;
}
编辑完成后保存文件,然后检查我们的JOIN和WHERE子句的工作情况。重新加载Contacts
表单,然后尝试着通过电话号码的一部分查找一个你的contacts:
如果工作正常,你可以查找到在你的CRM系统中满足条件的任意 Advanced Custom Fields 。