2017-05-26 59 views
0

我想只列出可以根據客戶在付費/送貨地址中設置的位置發送給客戶的產品。 (我的所有用戶都已登錄)Woocommerce供應商設置銷售地點和操縱產品查詢循環

我的每個供應商都可能僅向某些國家/地區出貨,因此我不想將產品展示給無法發貨給他們的用戶。

爲了解決這個問題,我在編輯供應商頁面添加了一個額外的字段,它可以保存國家(通過多選框),他們可以將它們作爲單獨的術語元。

update_term_meta($term_id, 'vendor_data_shipping_countries', $selected_shipping_countries);

等等

所有這些數據保存很好,當我打電話get_term_meta($term->term_id, 'vendor_data_shipping_countries')[0]如下輸出。

Array 
(
    [0] => FR 
    [1] => GB 
) 

我有現在的過濾產品循環查詢只顯示可運到與行動「woocommerce_product_query」用戶的產品什麼麻煩。

function ac_vendor_show_deliverable_products($query) 
{ 
    // magical query filter here... 
    // if users location matches any of the vendor products ship to countries then output the product to the user 
    // $query->set(); ... something... 
} 
add_action('woocommerce_product_query','ac_vendor_show_deliverable_products'); 

這是我的技能水平失敗的地方。我對WC相當陌生,不擅長操作查詢。在編寫完整的SQL時更好,但是覺得我會搞亂其他許多事情,過濾是最好的方式。

我希望有人的坤夫比我的強!任何人都可以解釋這一點?

希望有人能幫忙。

UPDATE:

我設法準確地寫什麼,我想在SQL

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts 

LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
LEFT JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id) 
LEFT JOIN wp_termmeta ON (wp_termmeta.term_id = wp_term_taxonomy.term_id) 

WHERE wp_termmeta.meta_key = 'vendor_data_shipping_countries' 
AND wp_termmeta.meta_value LIKE '%"GB"%' 

AND wp_posts.post_type = 'product' 
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.menu_order ASC, wp_posts.post_title ASC LIMIT 0, 12 

已加入GB作爲一個國家,他們可以運送到這僅列出了產品的出現。

請注意meta_value存儲爲序列化數組,因此匹配的最簡單方法是執行LIKE,因爲值存儲爲a:2:{i:0;s:2:"FR";i:1;s:2:"GB";}

如果任何人都可以弄清楚如何將該SQL放入woocommerce_product_query掛鉤,那麼這將是驚人的。但我不能爲我的生活弄清楚這是如何可能的...

https://codex.wordpress.org/Class_Reference/WP_Query上的所有內容都只是爲我所能看到的wp_postmeta添加了SQL而不是wp_termmeta。

乾杯

回答

1

我設法通過使用posts_join和posts_where過濾器來代替它。

我希望這可以幫助其他人。

/* 
* Add the needed term tables 
*/ 
function ac_vendor_sql_join_term_meta($join) 
{ 
    global $wp_query, $wpdb; 

    //only do this is WC product query 
    if(isset($wp_query->query_vars['wc_query']) && $wp_query->query_vars['wc_query'] == 'product_query') 
    { 
     $join .= ' LEFT JOIN '. $wpdb->term_relationships .' tr1 ON (tr1.object_id = '. $wpdb->posts .'.ID)'; 
     $join .= ' LEFT JOIN '. $wpdb->term_taxonomy .' tt1 ON (tt1.term_taxonomy_id = tr1.term_taxonomy_id)'; 
     $join .= ' LEFT JOIN '. $wpdb->termmeta .' tm1 ON (tm1.term_id = tt1.term_id)'; 
    } 

    return $join; 
} 
add_filter('posts_join', 'ac_vendor_sql_join_term_meta'); 

/* 
* Add the needed where statements 
*/ 
function ac_vendor_sql_filter_shipping_where($where, $wp_query) 
{ 
    //only do this is WC product query 
    if(isset($wp_query->query_vars['wc_query']) && $wp_query->query_vars['wc_query'] == 'product_query') 
    { 
     //get the users billing country code. 
     if(is_user_logged_in()) 
     {  
      $billing_country = get_user_meta(get_current_user_id(), 'billing_country', TRUE); 
     } 
     else //default to IP location 
     { 
      $geo_locate   = WC_Geolocation::geolocate_ip($_SERVER['REMOTE_ADDR']); 
      $billing_country = $geo_locate['country']; 
     } 

     $where .= " AND tm1.meta_key = 'vendor_data_shipping_countries'"; 
     $where .= " AND tm1.meta_value LIKE '%\"". $billing_country ."\"%'"; 
    } 

    return $where; 
} 
add_filter('posts_where', 'ac_vendor_sql_filter_shipping_where', 10, 2);