2016-01-21 50 views
0

我正在爲使用Woocommerce的客戶編寫自定義的Wordpress網站。該平臺適用於所有事情,只有一個問題:客戶的物品具有自定義屬性,他希望能夠在其中進行搜索。Woocommerce - 擴展搜索不會返回多字段搜索,可能的SQL問題。爲什麼?

woocommerce允許屬性問題本身。爲了增強搜索功能,我在functions.php中添加了一段代碼,它爲每篇文章增加了額外元數據,目的是稍後通過元值進行搜索,鬆散地基於this question中給出的元數值。做到這一點的代碼去如下:

function wcproduct_set_attributes($id) { 

    $materials = get_the_terms($id, 'pa_material'); 

    $i = 0; 
    $mat_list = ''; 

    foreach($materials as $material){ 
     if($i == 0) 
      $mat_list = $mat_list . $material->name; 
     else 
      $mat_list = $mat_list . ", " . $material->name; 
     $i++; 
    } 

    $sizeozs = get_the_terms($id, 'pa_sizeoz'); 

    $i = 0; 
    $sizeoz_list = ''; 

    foreach($sizeozs as $sizeoz){ 
     if($i == 0) 
      $sizeoz_list = $sizeoz_list . $sizeoz->name; 
     else 
      $sizeoz_list = $sizeoz_list . ", " . $sizeoz->name; 
     $i++; 
    } 


    // Now update the post with its new attributes 
    update_post_meta($id, '_material', $mat_list); 
    update_post_meta($id, '_sizeoz', $sizeoz_list); 

} 

// After inserting post 
add_action('save_post_product', 'wcproduct_set_attributes', 10); 

後來,我增加了一個功能,我通過網絡(here),其允許woocommerce搜索中自定義元信息搜索找到。定製爲我的需求後,我結束了這一點:

/** 
* Add custom join and where statements to product search query 
* @param mixed $q query object 
* @return void 
*/ 
function jc_woo_search_pre_get_posts($q){ 

    if (is_search()) { 
     add_filter('posts_join', 'jc_search_post_join'); 
     add_filter('posts_where', 'jc_search_post_excerpt'); 
    } 

} 

/** 
* Add Custom Join Code for wp_mostmeta table 
* @param string $join 
* @return string 
*/ 
function jc_search_post_join($join = ''){ 

    global $wp_the_query; 

    // escape if not woocommerce searcg query 
    if (empty($wp_the_query->query_vars['wc_query']) || empty($wp_the_query->query_vars['s'])) 
      return $join; 

    $join .= "INNER JOIN wp_postmeta AS jcmt1 ON (wp_posts.ID = jcmt1.post_id)"; 
    return $join; 
} 

/** 
* Add custom where statement to product search query 
* @param string $where 
* @return string 
*/ 
function jc_search_post_excerpt($where = ''){ 

    global $wp_the_query; 

    // escape if not woocommerce search query 
    if (empty($wp_the_query->query_vars['wc_query']) || empty($wp_the_query->query_vars['s'])) 
      return $where; 


    $where = preg_replace("/post_title LIKE ('%[^%]+%')/", "post_title LIKE $1) 
       OR (jcmt1.meta_key = '_sizeoz' AND CAST(jcmt1.meta_value AS CHAR) LIKE $1) 
       OR (jcmt1.meta_key = '_material' AND CAST(jcmt1.meta_value AS CHAR) LIKE $1", $where); 



    return $where; 
} 

目前,該系統完美的搜索在標題,內容和屬性的參數。當我嘗試同時搜索兩個屬性時出現問題。例如,我有一種名爲Titanite的材料,盎司尺寸設置爲5盎司。如果我搜索泰坦尼克,我會得到兩款產品。如果我搜索5盎司,我會得到一個單一的產品,這也是我搜索泰坦尼克時出現的兩種產品之一。到現在爲止還挺好。

如果我搜索Titanite 5oz,問題來了,因爲在那種情況下,即使有一個材料設置爲Titanite並且其大小設置爲5oz的項目,由於某種原因,我也會得到空的搜索結果。我一直在盯着代碼兩天,我找不到原因。我去了SQL代碼注入到第二功能搜索,肚裏爲:

AND (((wp_posts.post_title LIKE '%titanite%') OR (jcmt1.meta_key = '_sizeoz' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%titanite%') OR (jcmt1.meta_key = '_material' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%titanite%') OR (post_excerpt LIKE '%titanite%') OR (wp_posts.post_content LIKE '%titanite%')) AND ((wp_posts.post_title LIKE '%5oz%') OR (jcmt1.meta_key = '_sizeoz' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%5oz%') OR (jcmt1.meta_key = '_material' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%5oz%') OR (post_excerpt LIKE '%5oz%') OR (wp_posts.post_content LIKE '%5oz%'))) AND ((wp_postmeta.meta_key = '_visibility' AND CAST(wp_postmeta.meta_value AS CHAR) IN ('visible','search'))) AND wp_posts.post_type = 'product' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 

但有沒有運氣無論是。格式化爲方便閱讀後,我結束了:

AND 
(
((wp_posts.post_title LIKE '%titanite%') 
OR (jcmt1.meta_key = '_sizeoz' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%titanite%') 
OR (jcmt1.meta_key = '_material' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%titanite%') 
OR (post_excerpt LIKE '%titanite%') 
OR (wp_posts.post_content LIKE '%titanite%')) 
    AND 
((wp_posts.post_title LIKE '%5oz%') 
OR (jcmt1.meta_key = '_sizeoz' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%5oz%') 
OR (jcmt1.meta_key = '_material' AND CAST(jcmt1.meta_value AS CHAR) LIKE '%5oz%') 
OR (post_excerpt LIKE '%5oz%') 
OR (wp_posts.post_content LIKE '%5oz%')) 

) 
AND 
((wp_postmeta.meta_key = '_visibility' AND CAST(wp_postmeta.meta_value AS CHAR) IN ('visible','search'))) 
AND wp_posts.post_type = 'product' 
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 

...我無法找到所有的犯錯有什麼。據我所知,它的寫法是這樣的,它應該給出Meta包含Titanite和5oz的結果,即使在單獨的實例中,正如使用的OR值所給出的那樣。搜索泰坦尼克和5盎司時返回的任何物品都應該是搜索的一部分,那爲什麼它不在那裏呢?我在這裏錯過了一些非常明顯的東西,或者這個過程是不知何故被竊聽的?

+0

你如何使用您的搜索?你能給一個示例url嗎? – Reigel

+0

我目前沒有在線。我正在使用默認的woocommerce搜索小工具,在右側的工具欄上顯示了二十幾個主題。目前沒有任何關於主題或插件的自定義功能,這些功能超出了我在那裏提供的搜索功能。 – Tizzy

+0

我的意思是你把它作爲'?s = 5oztitanite'或某種類型的網址? – Reigel

回答

0

試試這個在您jc_search_post_excerpt

function jc_search_post_excerpt($where = ''){ 

    global $wp_the_query; 

    // escape if not woocommerce search query 
    if (empty($wp_the_query->query_vars['wc_query']) || empty($wp_the_query->query_vars['s'])) 
      return $where; 


    $where = preg_replace("/post_title LIKE ('%[^%]+%')/", "post_title LIKE $1) 
       OR (jcmt1.meta_key = '_color' AND CAST(jcmt1.meta_value AS CHAR) LIKE $1) 
       OR (jcmt1.meta_key = '_size' AND CAST(jcmt1.meta_value AS CHAR) LIKE $1", $where); 
    $where = str_replace(') AND ((wp_posts.post_title',' OR (wp_posts.post_title',$where); 

    return $where; 
} 
+0

不起作用 - 現在當我尋找「Titanite 5oz」時,它返回包括「titanite」在內的所有實例和包括「5oz」在內的所有實例它應該給我包含兩者的條目,而不是:\ – Tizzy