我有一个带有自定义分类的自定义帖子类型,基本上是一个库帖子类型。我想能够在帖子类型中搜索图像。我为帖子类型和附件创建了一个自定义搜索查询,但效果不太好。我得到了一些图像的重复搜索结果。因为图像是CPT条目的一部分,但也存在于媒体库中。是否有办法仅从CPT中搜索附件?
<?php
Class SMGallerySearch {
private $query_instance;
public function __construct(){
add_filter( \'posts_join\', array( &$this, \'terms_join\' ) );
add_filter( \'posts_search\', array( &$this, \'search_where\' ), 10, 2 );
add_filter( \'posts_request\', array( &$this, \'distinct\' ) );
add_filter( \'pre_get_posts\', array( &$this, \'search_query\' ) );
add_filter( \'attachment_link\', array( &$this, \'the_search_attachment_link\' ), 10, 2 );
add_filter( \'the_excerpt\', array( &$this, \'the_search_excerpt\' ) );
}
public function terms_join( $join ) {
global $wpdb;
if ( ! empty( $this->query_instance->query_vars[\'s\'] ) ) {
// searching custom taxonomies
$taxonomies = get_object_taxonomies( array( \'sm_gallery_item\', \'attachment\' ) );
foreach ( $taxonomies as $taxonomy ) {
$on[] = "ttax.taxonomy = \'" . addslashes( $taxonomy )."\'";
}
// build our final string
$on = \' ( \' . implode( \' OR \', $on ) . \' ) \';
$join .= " LEFT JOIN $wpdb->term_relationships AS trel ON ($wpdb->posts.ID = trel.object_id) LEFT JOIN $wpdb->term_taxonomy AS ttax ON ( " . $on . " AND trel.term_taxonomy_id = ttax.term_taxonomy_id) LEFT JOIN $wpdb->terms AS tter ON (ttax.term_id = tter.term_id) ";
}
return $join;
}
/**
* Creates the list of search keywords from the \'s\' parameters
*
* @since 1.8.7
*/
public function get_search_terms() {
global $wpdb;
$s = isset( $this->query_instance->query_vars[\'s\'] ) ? $this->query_instance->query_vars[\'s\'] : \'\';
$sentence = isset( $this->query_instance->query_vars[\'sentence\'] ) ? $this->query_instance->query_vars[\'sentence\'] : false;
$search_terms = array();
if ( !empty( $s ) ) {
// added slashes screw with quote grouping when done early, so done later
$s = stripslashes( $s );
if ( $sentence ) {
$search_terms = array( $s );
} else {
preg_match_all( \'/".*?("|$)|((?<=[\\\\s",+])|^)[^\\\\s",+]+/\', $s, $matches );
$search_terms = array_map( create_function( \'$a\', \'return trim($a, "\\\\"\\\'\\\\n\\\\r ");\' ), $matches[0] );
}
}
return $search_terms;
}
/**
* Add where clause to the search query
*
* @since 1.8.7
*/
public function search_where( $where, $wp_query ) {
$this->query_instance = &$wp_query;
global $wpdb;
$searchQuery = $this->search_default();
$searchQuery .= $this->build_search_categories();
if ( $searchQuery != \'\' ) {
$where = preg_replace( \'#\\(\\(\\(.*?\\)\\)\\)#\', \'((\'.$searchQuery.\'))\', $where );
}
return $where;
}
/**
* Search for terms in default locations like title and content
* replacing the old search terms seems to be the best way to
* avoid issue with multiple terms
*
* @since 1.8.7
*/
public function search_default(){
global $wpdb;
$not_exact = empty( $this->query_instance->query_vars[\'exact\'] );
$search_sql_query = \'\';
$seperator = \'\';
$terms = $this->get_search_terms();
// if it\'s not a sentance add other terms
$search_sql_query .= \'(\';
foreach ( $terms as $term ) {
$search_sql_query .= $seperator;
$esc_term = esc_sql( $term );
if ($not_exact) {
$esc_term = "%$esc_term%";
}
$like_title = "($wpdb->posts.post_title LIKE \'$esc_term\')";
$like_post = "($wpdb->posts.post_content LIKE \'$esc_term\')";
$search_sql_query .= "($like_title OR $like_post)";
$seperator = \' AND \';
}
$search_sql_query .= \')\';
return $search_sql_query;
}
/**
* Create the search categories query
*
* @since 1.8.7
*/
public function build_search_categories() {
global $wpdb;
$vars = $this->query_instance->query_vars;
$s = $vars[\'s\'];
$search_terms = $this->get_search_terms();
$exact = isset( $vars[\'exact\'] ) ? $vars[\'exact\'] : \'\';
$search = \'\';
if ( ! empty( $search_terms ) ) {
// Building search query for categories slug.
$n = ( $exact ) ? \'\' : \'%\';
$searchand = \'\';
$searchSlug = \'\';
foreach ( $search_terms as $term ) {
$term = addslashes_gpc( $term );
$searchSlug .= "{$searchand}(tter.slug LIKE \'{$n}".sanitize_title_with_dashes( $term )."{$n}\')";
$searchand = \' AND \';
}
if ( count( $search_terms ) > 1 && $search_terms[0] != $s ) {
$searchSlug = "($searchSlug) OR (tter.slug LIKE \'{$n}".sanitize_title_with_dashes( $s )."{$n}\')";
}
if ( ! empty( $searchSlug ) )
$search = " OR ({$searchSlug}) ";
// Building search query for categories description.
$searchand = \'\';
$searchDesc = \'\';
foreach ( $search_terms as $term ) {
$term = addslashes_gpc( $term );
$searchDesc .= "{$searchand}(ttax.description LIKE \'{$n}{$term}{$n}\')";
$searchand = \' AND \';
}
$sentence_term = esc_sql( $s );
if ( count( $search_terms ) > 1 && $search_terms[0] != $sentence_term ) {
$searchDesc = "($searchDesc) OR (ttax.description LIKE \'{$n}{$sentence_term}{$n}\')";
}
if ( ! empty( $searchDesc ) )
$search = $search." OR ({$searchDesc}) ";
}
return $search;
}
public function distinct( $query ) {
global $wpdb;
if ( ! empty( $this->query_instance->query_vars[\'s\'] ) ) {
if ( strstr( $query, \'DISTINCT\' ) ) {}
else {
$query = str_replace( \'SELECT\', \'SELECT DISTINCT\', $query );
}
}
return $query;
}
public function search_query( $query ) {
if ( ! $query->is_search )
return $query;
if ( $query->get( \'post_type\' ) && \'sm_gallery_item\' == $query->get( \'post_type\' ) ) {
$post_types = $query->get( \'post_type\' );
if ( $post_types && \'sm_gallery_item\' == $post_types )
$post_types = array( \'sm_gallery_item\', \'attachment\' );
$query->set( \'post_type\', $post_types );
/**
* Add post status "inherit" (for attachments) since WP only searches "publish"
*/
$post_status = $query->get( \'post_status\' );
if ( ! $post_status || \'publish\' == $post_status )
$post_status = array( \'publish\', \'inherit\' );
if ( is_array( $post_status ) )
$post_status[] = \'inherit\';
$query->set( \'post_status\', $post_status );
return $query;
}
}
}
SO网友:Sam Edgecombe
我想我已经破解了。将前14行代码替换为
类SellMediaSearch{
private $query_instance;
/**
* Init
*/
public function __construct(){
add_filter( \'posts_join\', array( &$this, \'terms_join\' ) );
add_filter( \'posts_search\', array( &$this, \'search_where\' ), 10, 2 );
add_filter( \'posts_request\', array( &$this, \'distinct\' ) );
add_filter( \'pre_get_posts\', array( &$this, \'search_query\' ) );
add_filter( \'attachment_link\', array( &$this, \'the_search_attachment_link\' ), 10, 2 );
add_filter( \'the_excerpt\', array( &$this, \'the_search_excerpt\' ) );
add_filter( \'posts_where\' , array( &$this, \'posts_where\' ));
}
public function posts_where( $where ) {
global $wpdb;
if( is_search() ) {
$where .= \' AND ( post_type = \\\'sell_media_item\\\' OR ( post_type = \\\'attachment\\\' AND post_parent != 0 ) ) \';
}
return $where;
}
需要测试,但最初对我有效。有关更多注释,请参阅github。