2014-06-27 55 views
0

我正在嘗試使用add_filter function在WordPress中編輯wp_query。當我var_dump我的查詢request它按預期輸出SQL。add_filter函數未按預期工作

但是,它運行時會返回一個不同的查詢錯誤!有誰知道爲什麼查詢可能會改變,並且改變很多!

requestvar_dump查詢(如預期):

SELECT SQL_CALC_FOUND_ROWS wp_posts.*, 
    (3959 * acos(
     cos(radians(52.486243)) 
     * cos(radians(lat)) 
     * cos(radians(lng) - radians(-1.890401)) 
     + sin(radians(52.486243)) 
     * sin(radians(lat)) 
     )) 
    AS distance , lat AS latitude , lng AS longitude 
FROM wp_posts 
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) 
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) 
INNER JOIN lat_lng_post ON wp_posts.ID = lat_lng_post.post_id 
WHERE 1=1 
AND (wp_term_relationships.term_taxonomy_id IN (2)) 
AND wp_posts.post_type = 'event' 
AND ((wp_posts.post_status = 'publish')) 
AND ((wp_postmeta.meta_key LIKE 'date_%_start-date' AND CAST(wp_postmeta.meta_value AS SIGNED) <= '20140704') 
AND (mt1.meta_key LIKE 'date_%_end-date' AND CAST(mt1.meta_value AS SIGNED) >= '20140627')) 
AND lat_lng_post.lat = lat 
AND lat_lng_post.lng = lng 
AND substr(wp_postmeta.meta_key, 1, 6) = substr(mt1.meta_key, 1, 6) 
GROUP BY wp_posts.ID 
HAVING distance <= 20 
ORDER BY distance ASC 
LIMIT 0, 10 

這是顯示錯誤[Unknown column 'lat' in 'field list'](不預期)下面的查詢:

SELECT wp_posts.*, 
    (3959 * acos( 
     cos(radians(52.486243)) 
     * cos(radians(lat)) 
     * cos(radians(lng) - radians(-1.890401)) 
     + sin(radians(52.486243)) 
     * sin(radians(lat)) 
    )) AS distance , lat AS latitude , lng AS longitude 
FROM wp_posts 
WHERE 1=1 
AND wp_posts.post_type = 'acf-field' 
AND ((wp_posts.post_status = 'publish')) 
AND wp_posts.post_name = 'field_535e6b9ffe3da' 
AND lat_lng_post.lat = lat 
AND lat_lng_post.lng = lng 
GROUP BY wp_posts.ID 
HAVING distance <= 20 
ORDER BY distance ASC 
LIMIT 0, 1 

注意

我有一個名爲lat_lng_post的自定義表,它有三列,post_id,latlng來存儲每個事件的位置數據(自定義帖子類型)。在查詢中使用

編輯所有功能的add_filter:

function distance_query($distance) { 

    $lat = $_SESSION['search']['lat']; 
    $lng = $_SESSION['search']['long']; 


    $distance .= ", 
    (3959 * acos(
     cos(radians(".$lat.")) 
     * cos(radians(lat)) 
     * cos(radians(lng) - radians(".$lng.")) 
     + sin(radians(".$lat.")) 
     * sin(radians(lat)) 
     )) 
    AS distance , lat AS latitude , lng AS longitude"; 
    return $distance; 
} 
add_filter('posts_fields', 'distance_query'); 



// add lat_lng_post table inner join 
function lat_lng_join($join) { 
    $join = str_replace('(wp_posts.ID = mt1.post_id)', '(wp_posts.ID = mt1.post_id) INNER JOIN lat_lng_post ON wp_posts.ID = lat_lng_post.post_id', $join); 
    return $join; 
} 
add_filter('posts_join', 'lat_lng_join'); 


// set lat lng definition 
function lat_lng_define($define) { 
    $define .= ' AND lat_lng_post.lat = lat AND lat_lng_post.lng = lng'; 
    return $define; 
} 
add_filter('posts_where', 'lat_lng_define'); 


// HAVING distance less than user distance 
function having_distance($having) { 
    $radius = $_SESSION['search']['distance']; 
    $having = 'wp_posts.ID HAVING distance <= '.$radius.''; 
    return $having; 
} 
add_filter('posts_groupby', 'having_distance'); 

// if sorting by distance 
function sort_distance($sortdistance) { 
    $sortdistance = 'distance ASC'; 
    return $sortdistance; 
} 
if($_SESSION['search']['sort-by'] == 'distance') : 
    add_filter('posts_orderby', 'sort_distance'); 
endif; 


function add_additional_where_condition($where) { 
    $where .= " AND substr(wp_postmeta.meta_key, 1, 6) = substr(mt1.meta_key, 1, 6) "; 
    return $where; 
} 

// fix for setting the date to search field 
function date_to($to) { 
    $to = str_replace("mt1.meta_key = 'date_%_end-date'", "mt1.meta_key LIKE 'date_%_end-date'", $to); 
    return $to; 
} 

// fix for setting the date from search field 
function date_from($from) { 
    $from = str_replace("meta_key = 'date_%_start-date'", "meta_key LIKE 'date_%_start-date'", $from); 
    return $from; 
} 

// fix for ordering by date 
function order_date($like) { 
    $like = str_replace("mt2.meta_key = 'date_%_end-date'", "mt2.meta_key LIKE 'date_%_end-date'", $like); 
    return $like; 
} 

// fix for searching by LIKE post title, requires all characters to match 
function title_filter($where, &$wp_query) { 
    global $wpdb; 
    if ($search_term = $wp_query->get('title_like')) { 
     $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql(like_escape($search_term)) . '%\''; 
    } 
    return $where; 
} 

而且,這是wp_query本身,這些功能被添加到:

// add query for title 
    add_filter('posts_where', 'title_filter', 10, 2); 

// dates to and from logic 
    add_filter('posts_where', 'date_from'); 
    add_filter('posts_where', 'date_to'); 
    add_filter('posts_where', 'order_date'); 
    add_filter('posts_where', 'add_additional_where_condition'); 


// get date inputs from search 
    $date1 = str_replace('/', '-', $_SESSION['search']['from']); 
    $when = date("Ymd", strtotime($date1)); 

    $date2 = str_replace('/', '-', $_SESSION['search']['to']); 
    $when2 = date("Ymd", strtotime($date2)); 

    $year = date('Y'); 




// Declare the query arguments 
    if (get_query_var('paged')) { 
     $paged = get_query_var('paged'); 
    } else if (get_query_var('page')) { 
     $paged = get_query_var('page'); 
    } else { 
     $paged = 1; 
    } 

// make keywords an array 
    $keywordString = $_SESSION['search']['keyword']; 
    $keywords = explode(', ', $keywordString); 

    $taxQuery = array(
     'relation' => 'AND', 
     array (
      'taxonomy' => 'main-cat', 
      'field' => 'slug', 
      'terms' => $_SESSION['search']['cat'] 
     ) 
    ); 

    if($_SESSION['search']['keyword'] != '') { 
     $taxQuery[] = array(
      'taxonomy' => 'sub-cat', 
      'field' => 'name', 
      'terms' => $keywords 
     ); 
    } 

    $args = array(
     // general 
     'post_type' => 'event', 
     'post_status' => 'publish', 
     'posts_per_page' => 10, 
     'paged' => $paged, 
     'cache_results' => false, 
     'update_post_meta_cache' => false, 
     'update_post_term_cache' => false, 

     'meta_key' => $_SESSION['search']['sort-key'], 
     'orderby' => $_SESSION['search']['sort-by'], 
     'order' => 'ASC', 

     // category filter 
     'tax_query' => $taxQuery, 

     // date filter 

     'meta_query' => array(
      'relation' => 'AND', 
      array(
       'key' => 'date_%_start-date', 
       'value' => $when2, 
       'compare' => '<=', 
       'type' => 'NUMERIC' 
      ), 
      array (
       'key' => 'date_%_end-date', 
       'value' => $when, 
       'compare' => '>=', 
       'type' => 'NUMERIC' 
      ) 

     ) 
    ); 


    $temp = $wp_query; 
    $wp_query = null; 
    $wp_query = new WP_Query($args); 
+0

我想你試圖修改多個單一查詢的SQL。你能分享過濾器代碼嗎?它是主要查詢還是輔助查詢,您正在嘗試修改? – birgire

+0

嗨,這是唯一一個在頁面上運行的查詢,它基本上是一個搜索頁面,帶有永久鏈接'/ event-search /',將使用所有'add_filter'函數編輯我的問題。 – lukeseager

+0

這些過濾器會影響所有'WP_Query'查詢,除了'get_posts()'包裝器,其中的過濾器被抑制。 – birgire

回答

4

它看起來像你想設置posts_*篩選器爲輔助查詢,但您忘記以後刪除篩選器,因此它們影響其他查詢器後來運行。

i)您可以使用remove_filter()函數刪除過濾器。這裏有一個例子:

// Add some filter: 
add_filter('some_filter', 'some_filter_callback', $priority); 

// Run a secondary query: 
$wp_query = new WP_Query($args); 

// Remove the previous filter: 
remove_filter('some_filter', 'some_filter_callback', $priority); 

其中濾波器優先必須匹配。

ii)另一種方法是在some_filter_callback()函數中使用添加remove_filter()。例如:

add_filter('some_filter', 'some_filter_callback'); 
$wp_query = new WP_Query($args); 

其中

some_filter_callback($string) 
{ 
    // Remove the current filter: 
    remove_filter(current_filter(), __FUNCTION__); 

    // Some modifications to the input: 
    // ... 

    // Output: 
    return $string; 
} 

這將確保您的過濾器將只運行一次。如果您使用的pre_get_posts

if(! is_admin() && is_main_query()) 
{ 
    // ... 
} 

if(! is_admin() && $query->is_main_query()) 
{ 
    // ... 
} 

,:

III)如果你想修改主查詢,你可以限制與過濾器其中$query是輸入參數。

IV)另一種選擇是創建一個擴展WP_Query幷包含你希望所有的過濾器的新類:

class My_Search_Query extends WP_Query 
{ 
    // ... 
} 

在您使用

$query = new My_Search_Query($args); 

運行查詢。

+0

太棒了!這擺脫了SQL錯誤,奇怪它破壞了頁面的分頁,但奇怪! – lukeseager

+0

太好了。在SQL查詢中分頁不變嗎? – birgire

+1

嗯,通過將首頁更改爲設置中的靜態頁面對其進行排序:) – lukeseager