WooCommerce通过id从循环中删除产品

时间:2017-06-08 12:08:20

标签: php wordpress woocommerce

如果任何变种缺货,我试图隐藏woocommerce产品。

到目前为止我尝试了什么

1:获取当前登录用户“区域” 2:获取所有产品变体的列表,这些变体是要针对用户区域进行检查的区域。 3:运行检查,如果匹配则隐藏产品 4:从循环中排除产品

任何煽动都会非常感激。

Deferred

更新2:

我更新了上面的内容并使其工作,但woocommerce_product_is_visible过滤器仅适用于类别存档页面,Noting过滤搜索页面或在自定义页面上使用WP_Query时真的很遗憾。也是他们为什么$ is_visible for woocommerce不能使用pre_get_posts的原因

function tm_remove_product_stock_region($query) {

    $product_variable = new WC_Product_Variable();
    $product_variations = $product_variable->get_available_variations();

/** Get users region. */
    $user_region = tm_get_user_region();

    $post__in = array();

    foreach ( $product_variations as $variation ) {

        /** Get products regions. */
        $product_region = $variation['attributes']['attribute_pa_regions'];

        if ($user_region === $product_region && !$variation->is_in_stock()) {


          $post__in[] = $variation['product_id'];

          add_filter('woocommerce_product_is_visible', function($is_visible, $id) {
                $is_visible = false;
                return $is_visible;
            }, 10,2);


        } else if ($user_region === $product_region && $variation->is_in_stock()) {

          $post__in[] = $variation['product_id'];


            add_filter('woocommerce_product_is_visible', function($is_visible, $id) {
                $is_visible = true;
                return $is_visible;
            }, 10,2);


        }

    }

    if(is_array($post__in) && $post__in != null){
        $query->set('post__in', $post__in);
    }

    return $query;

 }

 add_action('pre_get_posts', 'tm_remove_product_stock_region', 10, 2);

更新3:

经过多个小时的讨论,我注意到两个函数中的Function tm_remove_product_stock_region($is_visible, $id) { $product = wc_get_product(get_the_ID()); $product_variable = new WC_Product_Variable(get_the_ID()); $product_variations = $product_variable->get_available_variations(); /** Get users region. */ $user_region = tm_get_user_region(); foreach ($product_variations as $variation) { /** Get products regions. */ $product_region = $variation['attributes']['attribute_pa_regions']; if (!$product->is_in_stock() && $user_region === $product_region) { $is_visible = false; return $is_visible; } else if ($product->is_in_stock() && $user_region === $product_region) { $is_visible = true; return $is_visible; } } } add_filter('woocommerce_product_is_visible', 'tm_remove_product_stock_region', 10,2); 返回一组不同的结果,即“woocommerce_product_is_visible”产品父ID被返回,但是“pre_get_posts”则是变体ID。

所以我没有得到我想要的结果和pre_get_posts失败,这是我实际需要工作的,我仍然没有解决这个问题。

3 个答案:

答案 0 :(得分:0)

您需要在循环之前设置meta_query,

function tm_remove_product_stock_region($query) {
    $query->set( 'meta_query', array(array(
        'key'       => '_stock_status',
        'value'     => 'outofstock',
        'compare'   => 'NOT IN'
    )));
return $query;

    }
add_action('pre_get_posts', 'tm_remove_product_stock_region');

答案 1 :(得分:0)

也许这就是你要找的东西:

$has_items_in_stock = false;
foreach ($product_variations as $variation) {

    /** Get products regions. */
    $product_region = $variation['attributes']['attribute_pa_regions'];

    if ( $user_region === $product_region && $variation['is_in_stock'] ) {
        $has_items_in_stock = true;
        break;
    }
}

if($has_items_in_stock ) {
    //show product
    //show variations
    //..
}

答案 2 :(得分:0)

经过反复试验,我设法让它正常工作,如果有人有类似的需要,请参阅下面的答案。

add_action('pre_get_posts','remove_products');

function remove_products($query) {
   if(!is_admin() && $query->is_main_query()){

      $user_region = tm_get_user_region();
      $current_category = get_queried_object();

      $args = array(
         'post_type'                => 'product',
         'post_status'              => 'publish',
         'posts_per_page'           => 36,
         'orderBy'                  => 'title',
         'tax_query'                => array(
            array(
               'taxonomy'           => 'product_cat',
               'field'              => 'term_id',
               'terms'              => $current_category->term_id,
            )
         )
      );

      $loop = get_posts($args);
      $post__in = array();

      foreach ($loop as $post) {

         //Product object
         $product = wc_get_product($post->ID);

         //Get product info i.e variations > meta keys
         $product_variations = $product->get_children();

         foreach ($product_variations as $variation) {

            // Store only the meta keys needed
            $product_region = get_post_meta($variation, 'attribute_pa_regions'); // 'region name'
            $stock_status = get_post_meta($variation, '_stock_status'); // 'outofstock'

            // Regional and stock check
            if(in_array($user_region, $product_region) && in_array('outofstock', $stock_status)) { // === wont work here
               $post__in[] = $post->ID;
            }
         }

      }

      //Exclude the product
      if(is_array($post__in) && $post__in != null) {
         $query->set('post__not_in', $post__in);
      }

   }

}

请注意 $product->get_available_variations()会返回大量信息,这会大大减慢您的网页加载速度,最好只使用get_post_meta(the_id, 'meta_key_name');来获取所需的数据。