【问题标题】:Woocommerce Vendors Set Selling Locations and Manipulate Product Query LoopWoocommerce 供应商设置销售地点并操纵产品查询循环
【发布时间】:2017-10-27 16:20:04
【问题描述】:

我只想列出可以根据帐单/送货地址中设置的位置运送给客户的产品。 (我的所有用户都已登录)

我的每个供应商只能向某些国家/地区发货,因此我不想向无法向他们发货的用户展示产品。

为了解决这个问题,我在编辑供应商页面中添加了一个额外的字段,它将他们可以运送到的国家/地区(通过多选框)保存为单独的术语元。

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,但我觉得我会搞砸很多其他事情,过滤是最好的方法。

我希望有人的功夫比我强!有人能解决这个问题吗?

希望有人能提供帮助。

更新:

我已经设法在 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 添加为可以运送到的国家/地区的产品。

请注意,元值存储为序列化数组,因此最简单的匹配方法是执行 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 而不是 wp_termmeta 添加 SQL。

干杯

【问题讨论】:

    标签: woocommerce vendors


    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-08
      相关资源
      最近更新 更多