【问题标题】:Show Out of stock products at the end in Woocommerce在 Woocommerce 中最后显示缺货产品
【发布时间】:2014-09-26 15:01:11
【问题描述】:

是否可以在 wordpress 中的类别或页面末尾显示缺货产品?

所以客户首先看到的是有货的产品,然后是缺货的产品。

【问题讨论】:

    标签: php wordpress woocommerce


    【解决方案1】:

    作为一种替代的简单解决方案,如果您的产品列表位于 flexbox 中,您也可以使用 CSS 来执行以下规则:

    ul.products li.product.outofstock {order:1}
    

    【讨论】:

      【解决方案2】:

      @dacrosby 的答案确实应该是这里的最佳答案。我在与某些插件的兼容性方面遇到了一些问题,但在大多数用例中,它似乎完全没有问题。

      这里说的是一些警告

      • 以编程方式创建产品的插件有时无法添加库存状态元键,如果此键不存在,此解决方案会将它们完全从结果中过滤掉。
      • 在某些用例中,此解决方案可能会与现有排序发生冲突,因为我们是根据 stockstatus 值按字母顺序排序的。如果使用了多种库存状态类型,则由于这种排序,它们会被人为地分组在结果中。

      基于相同实现构建的此版本应提供更广泛的兼容性,而不会牺牲所需的结果。

      
      /**
       * Sorts the Woocommerce Archive product query to push out of stock products to the end 
       */
      function _nok_order_by_stock_status( $posts_clauses, $query ) {
      
          // only change query on WooCommerce loops
          if ( $query->is_main_query() && ( is_product_category() || is_product_tag() || is_product_taxonomy() || is_shop() ) ) {
              global $wpdb;
      
              $posts_clauses['join'] .= 
              " LEFT JOIN ( 
                  SELECT post_id, meta_id, meta_value FROM $wpdb->postmeta 
                  WHERE meta_key = '_stock_status' AND meta_value <> '' 
              ) istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
      
              $posts_clauses['orderby'] = 
              " CASE istockstatus.meta_value WHEN 
                  'outofstock' THEN 1 
                  ELSE 0 
              END ASC, " . $posts_clauses['orderby'];
          }
      
          return $posts_clauses;
      }
      add_filter( 'posts_clauses', '_nok_order_by_stock_status', 2000, 2 );
      
      

      【讨论】:

        【解决方案3】:

        我尝试了上述所有解决方案,它们都有效,但导致网站上出现其他问题(可能是由于主题冲突),我确信它们在不同的情况/主题下都很好。下面的代码终于对我有用(提到的来源)

        来源:https://www.businessbloomer.com/woocommerce-show-in-stock-products-first-shop/

        /**
         * @snippet       Sort Products By Stock Status - WooCommerce Shop
         * @how-to        Get CustomizeWoo.com FREE
         * @author        Rodolfo Melogli
         * @compatible    WooCommerce 3.9
         * @donate $9     https://businessbloomer.com/bloomer-armada/
         */
         
        add_filter( 'woocommerce_get_catalog_ordering_args', 'bbloomer_first_sort_by_stock_amount', 9999 );
         
        function bbloomer_first_sort_by_stock_amount( $args ) {
           $args['orderby'] = 'meta_value';
           $args['order'] = 'ASC';
           $args['meta_key'] = '_stock_status';
           return $args;
        }
        

        【讨论】:

        • 我使用这个过滤器,我认为它是更好的解决方案。谢谢。
        • 我不能说它对我有用。它会扰乱现有的订单,而不是让现有的订单保持原样,只是将缺货的商品移到最后。
        【解决方案4】:

        编辑了上面的一个答案:

        /**
         * @snippet     Order product collections by stock status, instock products first.
         * @author      Rkoms
         */
        
        class iWC_Orderby_Stock_Status {
        
            public function __construct() {
                if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
                    add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000, 2);
                }
            }
        
            public function order_by_stock_status($posts_clauses, $query) {
                global $wpdb;   
                if ( $query->is_main_query() && is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
                    $posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
                    $posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
                    $posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
                }
                return $posts_clauses;
            }
        
        }
        new iWC_Orderby_Stock_Status;
        

        【讨论】:

          【解决方案5】:

          这段代码对我有用:

          add_action( 'pre_get_posts', function( $query ) {
              if ( $query->is_main_query() && is_woocommerce() && ( is_shop() || is_product_category() || is_product_tag() ) ) {
                  if( $query->get( 'orderby' ) == 'menu_order title' ) {  // only change default sorting
                      $query->set( 'orderby', 'meta_value' );
                      $query->set( 'order', 'ASC' );
                      $query->set( 'meta_key', '_stock_status' );
                  }
              }
          });
          

          【讨论】:

            【解决方案6】:

            这是最好的解决方案:

            add_action( 'pre_get_posts', function ( $q ) {
                if (   !is_admin()                 // Target only front end 
                     && $q->is_main_query()        // Only target the main query
                     && $q->is_post_type_archive() // Change to suite your needs
                ) {
                    $q->set( 'meta_key', '_stock_status' );
                    $q->set( 'orderby',  'meta_value'    );
                    $q->set( 'order',    'ASC'           );
                }
            }, PHP_INT_MAX );
            

            【讨论】:

            • 为什么要使用最大优先级?
            【解决方案7】:

            这与 Viktor & Bogdan 的答案相同,但没有额外的 Class 代码。

            它使用post_clause 过滤器来修改产品查询。我们将JOIN wp_postmeta 表添加到查询中,并将orderby _stock_status 子句添加到现有查询中。这样,任何其他 orderby 子句也会保留在查询中。

            add_filter('posts_clauses', 'order_by_stock_status');
            function order_by_stock_status($posts_clauses) {
                global $wpdb;
                // only change query on WooCommerce loops
                if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag() || is_product_taxonomy())) {
                    $posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
                    $posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
                    $posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
                }
                return $posts_clauses;
            }
            

            如果您出于某种原因首先需要缺货商品,可以将 istockstatus.meta_value ASC 更改为 istockstatus.meta_value DESC

            在 WP 上测试:4.8; WC 3.0.8

            【讨论】:

            • 有可能让它在视觉作曲家“最近的产品”和“产品循环”组件中工作吗?我使用自定义页面来展示我的产品,您的代码仅适用于 Woocomerce 中选择为商店的页面(效果很好,谢谢!)。
            • 提到它应该在查询构建序列的最后添加add_filter('posts_clauses', 'order_by_stock_status', 999); 如果没有 999 优先级,它对我没有任何影响。
            • 您还可以在条件中添加is_tax(),用于产品品牌等自定义分类。
            • Getting PHP Notice: Trying to get property 'post_type' of non-object in [path]\wp-includes\class-wp-query.php on line 4103 WooCommerce 版本:3.9.1 WordPress 版本: 5.3.2
            • 我们如何处理可变产品? @DACrosby
            【解决方案8】:

            试试这个代码(放入你的主题的functions.php):

            class iWC_Orderby_Stock_Status {
            public function __construct() {
                if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
                    add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000);
                }
            }
            public function order_by_stock_status($posts_clauses) {
                global $wpdb;   
                if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
                    $posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
                    $posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
                    $posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
                }
                return $posts_clauses;
                }
            }
            new iWC_Orderby_Stock_Status;
            

            拍摄here

            对于 WooCommerce 的最新版本,请参阅下面的答案:https://stackoverflow.com/a/44597448/3925099

            【讨论】:

              【解决方案9】:

              这是重新排列产品的sn-p(有货优先):

              <?php
              
              /**
               * Order product collections by stock status, instock products first.
               */
              class iWC_Orderby_Stock_Status
              {
              
                  public function __construct()
                  {
                      // Check if WooCommerce is active
                      if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
                          add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000);
                      }
                  }
              
                  public function order_by_stock_status($posts_clauses)
                  {
                      global $wpdb;
                      // only change query on WooCommerce loops
                      if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
                          $posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
                          $posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
                          $posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
                      }
                      return $posts_clauses;
                  }
              }
              
              new iWC_Orderby_Stock_Status;
              
              ?>
              

              https://www.snip2code.com/Snippet/114858/WooCommerce-Products-Order-by-Stock-Stat

              【讨论】:

              • 请同时发布链接中的一些内容
              • 谢谢,但这不适用于最新的 Woocoommerce 版本?它将Outofstock 产品下移,但也克隆了许多instock 产品。出了什么问题?
              • 这可以工作,但是在更改产品页面并加载ajax后,不工作!
              【解决方案10】:

              访问 WooCommerce 中库存管理的全局配置选项,查看您的 WordPress 管理员左侧并点击 WooCommerce,然后点击设置,然后点击库存选项卡。

              你会发现这个“缺货可见性”

              缺货可见性 - 此复选框可让您确定是否要在 WooCommerce 目录中隐藏库存商品。

              http://www.inmotionhosting.com/support/website/woocommerce/managing-inventory-in-woocommerce

              为了使它们出现在类别的末尾,您可以使用 pre_get_posts 根据库存进行排序,但您将失去其他排序。

              【讨论】:

              • 谢谢。我们如何在这里使用 pre_get_posts?
              • 在显示中进行缺货更改是否会导致隐藏的页面被重定向到某个地方?还是在 Google 分析中显示为 404 错误页面?我们试图在隐藏缺货商品时避免谷歌分析中的 404 错误,所以我想知道它们是否会自动重定向到主商店页面,或者这是否需要通过 301 重定向 htaccess 文件或 php 配置手动完成。感谢您的帮助。
              • 我没有看到“库存”标签 - 他们是在 UI 更新中重命名它还是什么?
              • 这个答案实际上并没有回答问题,即如何最后显示缺货。
              猜你喜欢
              • 2021-08-22
              • 1970-01-01
              • 2015-03-14
              • 1970-01-01
              • 1970-01-01
              • 2014-08-29
              • 1970-01-01
              • 2014-08-20
              • 2015-04-30
              相关资源
              最近更新 更多