在 Woocommerce 中最后显示缺货产品 [关闭]

问题描述 投票:0回答:11

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

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

php wordpress woocommerce product
11个回答
46
投票

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

它使用

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;厕所 3.0.8


11
投票

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

来源: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;
}

5
投票

这里是重新排列产品的片段(有货在先):

<?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


4
投票

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


2
投票

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

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

缺货可见性 - 此复选框将允许您确定是否要隐藏 WooCommerce 目录中的库存项目。

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

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


2
投票

试试这段代码(放入主题的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;

拍摄这里.

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


2
投票

这是最好的解决方案:

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

2
投票

这段代码对我有用:

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

2
投票

编辑上面的一个答案:

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

2
投票

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

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

0
投票

我认为这个查询可以更好,因为如果一个网站通过预购销售其产品,它将显示在列表的末尾。 此查询是您可以使用的优化版本。 此外,预购产品将保持原样:

function custom_product_query( $clauses, $query ) {
    global $wpdb;
    $clauses['join'] .= "
        LEFT JOIN {$wpdb->prefix}postmeta out_of_stock_meta
        ON ({$wpdb->prefix}posts.ID = out_of_stock_meta.post_id
            AND out_of_stock_meta.meta_key = '_stock_status'
            AND out_of_stock_meta.meta_value = 'outofstock')
    ";
    $clauses['orderby'] = "out_of_stock_meta.meta_value ASC, {$clauses['orderby']}";
    return $clauses;
}
add_filter( 'posts_clauses', 'custom_product_query', 10, 2 );

这段代码在postmeta表中添加了一个left join来获取_stock_status元值,并首先根据产品是否缺货对结果进行排序,然后根据原始orderby值对结果进行排序。此过滤器仅适用于产品类别查询,不会影响其他查询。

这种方法应该是相对有效的,因为它不需要额外的查询,而是通过一个小的额外的连接和排序来修改现有的查询。

© www.soinside.com 2019 - 2024. All rights reserved.