用于在结果中添加自定义字段的自定义搜索SQL查询

时间:2015-06-02 作者:Jonathan Lafleur

我必须编写自己的MySQL查询,因为我还没有找到在wordpress功能中实现它的好方法。

我希望搜索查询通过post\\u title/post\\u content&;搜索;第页中的meta\\u密钥描述(&U);CPT transit\\u路由它还需要以特定语言获取这些结果(从WPML复制过滤器),然后最终按posts\\u类型和posts\\u日期排序结果。下面是我的函数:

function search_query_with_trips( ) {
    global $wpdb;
    $search_string = esc_sql($_GET[\'s\']);
    $sql = "SELECT SQL_CALC_FOUND_ROWS {$wpdb->base_prefix}posts.ID FROM {$wpdb->base_prefix}posts
            LEFT JOIN {$wpdb->base_prefix}icl_translations t ON {$wpdb->base_prefix}posts.ID = t.element_id AND t.element_type LIKE \'post\\_%\'
            LEFT JOIN {$wpdb->base_prefix}postmeta m ON m.post_id={$wpdb->base_prefix}posts.ID
            LEFT JOIN {$wpdb->base_prefix}icl_languages l ON t.language_code=l.code AND l.active=1 WHERE 1=1
            AND ( ( {$wpdb->base_prefix}posts.post_title LIKE \'%".$search_string."%\') OR ({$wpdb->base_prefix}posts.post_content LIKE \'%".$search_string."%\') OR ((m.meta_key = \'description\') AND (m.meta_value LIKE \'%".$search_string."%\')) )
            AND {$wpdb->base_prefix}posts.post_type IN (\'page\',\'transit_routes\')
            AND ({$wpdb->base_prefix}posts.post_status = \'publish\')
            AND (t.language_code=\'".ICL_LANGUAGE_CODE."\' OR t.language_code IS NULL )
            ORDER BY {$wpdb->base_prefix}posts.post_type DESC, {$wpdb->base_prefix}posts.post_date DESC";

    $query=$wpdb->get_results($sql);
    return $query;
}
第一部分工作得很好,因为我已经对它进行了测试,它会返回符合我标准的帖子ID。问题是我在搜索中尝试的循环何时出现。在my while之前添加的php(have\\u posts()){…}

$search_result = search_query_with_trips();
/*
$search_result =
    array (
        0 => 
            stdClass::__set_state(array(
                \'ID\' => \'2224\',
        )),
        1 => 
            stdClass::__set_state(array(
            \'ID\' => \'2224\',
        )),
        2 => 
            stdClass::__set_state(array(
            \'ID\' => \'2224\',
        )),
        3 => 
            stdClass::__set_state(array(
            \'ID\' => \'2224\',
        )),
        4 => 
            stdClass::__set_state(array(
            \'ID\' => \'2224\',
        )),
        5 => 
            stdClass::__set_state(array(
            \'ID\' => \'2224\',
        )),
        6 => 
            stdClass::__set_state(array(
            \'ID\' => \'2224\',
        )),
        7 => 
           stdClass::__set_state(array(
           \'ID\' => \'2224\',
        )),
        8 => 
           stdClass::__set_state(array(
           \'ID\' => \'2224\',
        )),
        9 => 
           stdClass::__set_state(array(
           \'ID\' => \'2224\',
        )),
        ...
        26 => 
            stdClass::__set_state(array(
            \'ID\' => \'2223\',
        )),
        27 => 
            stdClass::__set_state(array(
            \'ID\' => \'217\',
        )),
        28 => 
            stdClass::__set_state(array(
            \'ID\' => \'217\',
        )),
        29 => 
            stdClass::__set_state(array(
            \'ID\' => \'217\',
        )),
    ) 
*/
setup_postdata($search_result);
但我看不出它是这样工作的,但我不知道怎么做。。。

2 个回复
SO网友:Jonathan Lafleur

我明白了!这是我为那些将搜索类似问题的人编写的最终代码:)

在函数中。php:

function se190254_custom_sql_for_search( ) {
    global $wpdb;
    //For security escape the search parameter 
    $search_string = esc_sql($_GET[\'s\']);

    //Build the SQL request with $wpdb->base_prefix for "portability" 
    $sql = "SELECT SQL_CALC_FOUND_ROWS {$wpdb->base_prefix}posts.ID FROM {$wpdb->base_prefix}posts
                LEFT JOIN {$wpdb->base_prefix}icl_translations t ON {$wpdb->base_prefix}posts.ID = t.element_id AND t.element_type LIKE \'post\\_%\'
                LEFT JOIN {$wpdb->base_prefix}postmeta m ON m.post_id={$wpdb->base_prefix}posts.ID
                LEFT JOIN {$wpdb->base_prefix}icl_languages l ON t.language_code=l.code AND l.active=1 WHERE 1=1
                AND ( ( {$wpdb->base_prefix}posts.post_title LIKE \'%".$search_string."%\') OR ({$wpdb->base_prefix}posts.post_content LIKE \'%".$search_string."%\') OR ((m.meta_key = \'description\') AND (m.meta_value LIKE \'%".$search_string."%\')) )
                AND {$wpdb->base_prefix}posts.post_type IN (\'page\',\'transit_routes\')
                AND ({$wpdb->base_prefix}posts.post_status = \'publish\')
                AND (t.language_code=\'".ICL_LANGUAGE_CODE."\' OR t.language_code IS NULL )
                ORDER BY {$wpdb->base_prefix}posts.post_type DESC, {$wpdb->base_prefix}posts.post_date DESC";

    //Get results of the SQL request (save in object by default, array_a or array_n is not needed here)
    $query=$wpdb->get_results($sql);

    //Loop trough each result and create a array with unique value and change it from array of object too simple array
    foreach ($query as $post) {
        $result[$post->ID] = $post->ID;
    }

    return $result;
}
在模板文件中:

        $search_result = se190254_custom_sql_for_search();
        if ( count($search_result) > 0 ) { ?>
            <header class="page-header">
                <h1 class="page-title"><?php printf(__(\'Search Results for: %s\', \'se190254\'), \'<span>\' . get_search_query() . \'</span>\'); ?></h1>
            </header><!-- .page-header -->
            <ul><?php
            foreach( $search_result as $post ) {
               $post = get_post($post->ID);
               setup_postdata($post); ?>
               <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li><?php
           } ?>
           </ul><?php
       } else { ?>
           <p>Sorry nothing match your search query</p><?php
        } ?>
希望它能帮助别人!

SO网友:shanebp

我认为您需要为每个帖子设置帖子数据。尝试:

$search_result = search_query_with_trips();

foreach( $search_result as $post ) :
  setup_postdata($post); ?>
    <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; 
您可能需要global $post 在foreach循环之前。

https://codex.wordpress.org/Function_Reference/setup_postdata

结束