简体   繁体   English

在 Woocommerce 的最后显示缺货产品

[英]Show Out of stock products at the end in Woocommerce

Is it possible to show out of stock products at the end of a category or page in wordpress?是否可以在 wordpress 中的类别或页面末尾显示缺货产品?

So the customer first see the products that are available and after that the products that are out of stock.因此,客户首先看到可用的产品,然后看到缺货的产品。

This is the same as Viktor & Bogdan's answer, but without the extra Class code.这与 Viktor & Bogdan 的答案相同,但没有额外的 Class 代码。

It uses the post_clause filter to modify the product query.它使用post_clause过滤器来修改产品查询。 We JOIN the wp_postmeta table to the query and prepend an orderby _stock_status clause to the existing query.我们JOIN的wp_postmeta表来查询和前面加上一个orderby _stock_status子句现有查询。 This way any other orderby clauses remain in the query as well.这样,任何其他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;
}

You could change istockstatus.meta_value ASC to istockstatus.meta_value DESC if you for some reason wanted the Out Of Stock items first.如果您出于某种原因首先想要缺货商品,您可以将istockstatus.meta_value ASC更改为istockstatus.meta_value DESC

Tested on WP: 4.8;在 WP 上测试:4.8; WC 3.0.8厕所 3.0.8

Here is a snippet for rearranging products (in stock come first):这是重新排列产品的片段(有货在先):

<?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 https://www.snip2code.com/Snippet/114858/WooCommerce-Products-Order-by-Stock-Stat

Access the global configuration options for inventory management in WooCommerce, look to the left of your WordPress admin and click on WooCommerce, then on Settings, then click on the Inventory tab.在 WooCommerce 中访问库存管理的全局配置选项,查看 WordPress 管理员的左侧并单击 WooCommerce,然后单击设置,然后单击库存选项卡。

You will find this "Out of Stock Visibility"你会发现这个“缺货可见性”

Out of Stock Visibility - This checkbox will allow you to determine if you want to hide out of inventory items within the WooCommerce catalog.缺货可见性 - 此复选框将允许您确定是否要隐藏 WooCommerce 目录中的库存项目。

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

For making them appear at the end of the category you could use pre_get_posts to order based on the stock, but then you'll lose your other sorting.为了使它们出现在类别的末尾,您可以使用 pre_get_posts 根据库存进行排序,但随后您将丢失其他排序。

Try this code (put in functions.php of your theme):试试这个代码(放在你的主题的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;

Taken here . 在这里拍摄。

For the last versions of WooCommerce see answer below: https://stackoverflow.com/a/44597448/3925099对于 WooCommerce 的最新版本,请参阅以下答案: https ://stackoverflow.com/a/44597448/3925099

This code work for me:这段代码对我有用:

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' );
        }
    }
});

This is the best solution:这是最好的解决方案:

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 );

Edited one answer above:编辑了上面的一个答案:

/**
 * @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;

I tried all the solutions above, they worked but resulted in other issues on the site (probably due to theme conflict), Im sure they are all good in different situations / themes.我尝试了上述所有解决方案,它们有效但导致网站上出现其他问题(可能是由于主题冲突),我确定它们在不同情况/主题下都很好。 The below code finally worked great for me (source mentioned)下面的代码终于对我很有用(提到了来源)

source: https://www.businessbloomer.com/woocommerce-show-in-stock-products-first-shop/来源: 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;
}

@dacrosby answer really should be the best answer here. @dacrosby 的答案真的应该是这里的最佳答案。 I've had a few issues with compatibility with some plugins but in most use cases it seems to work with no issues at all.我在与某些插件的兼容性方面遇到了一些问题,但在大多数用例中,它似乎完全没有问题。

That being said here are a few caveats话虽如此,这里有一些警告

  • Plugins that create products programmatically can sometimes fail to add the stock status meta key and if this key doesn't exist this solution will filter them out of the results entirely.以编程方式创建产品的插件有时无法添加库存状态元键,如果此键不存在,此解决方案会将它们从结果中完全过滤掉。
  • There are also use cases where this solution can conflict with existing ordering because we're ordering alphabetically on the stockstatus value.在某些用例中,此解决方案可能会与现有排序发生冲突,因为我们根据 stockstatus 值按字母顺序排序。 If multiple stock status' types are used they are artificially grouped in the results due to this ordering.如果使用多个库存状态类型,则由于此排序,它们会在结果中人为分组。

This version built on top of the same implementation should provide wider compatibility without sacrificing the desired result.这个建立在相同实现之上的版本应该提供更广泛的兼容性,而不会牺牲所需的结果。


/**
 * 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 );

作为另一种简单的解决方案,如果您的产品列表在 flexbox 中,您也可以使用 CSS 使用以下规则:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM