在WooCommerce单个产品页面上仅显示“有现货”相关的产品

3

我想在 WooCommerce 单个商品页面上仅展示与“有库存”相关的产品。

我知道可以通过我的主题覆盖 single-product/related.php 模板文件。下面是该模板的相关代码:

<section class="related products">

    <h2><?php _e( 'You May Also Want', 'MyStore' ); ?></h2>

    <?php woocommerce_product_loop_start(); ?>

        <?php foreach ( $related_products as $related_product ) : ?>

            <?php
                $post_object = get_post( $related_product->get_id() );

                setup_postdata( $GLOBALS['post'] =& $post_object );

                wc_get_template_part( 'content', 'product' ); ?>
                
        <?php endforeach; ?>

    <?php woocommerce_product_loop_end(); ?>

</section>

有可能通过对该文件进行一些更改,只在WooCommerce单个产品页面上显示“有库存”的相关商品吗? 谢谢您的帮助。

3个回答

2
这是我一直在使用的方法,对我来说很有效:

add_filter( 'woocommerce_related_products', 'mysite_filter_related_products', 10, 1 );
function mysite_filter_related_products( $related_product_ids )
{

if (!is_admin()) {
    foreach ($related_product_ids as $key => $value) {
        $relatedProduct = wc_get_product($value);
        if (!$relatedProduct->is_in_stock() ) {
            unset($related_product_ids["$key"]);
        }
    }

    return $related_product_ids;
  }
}

1

更新

由于当前显示的4个产品缺货时不会显示任何内容(如果默认显示4个产品),您可以使用以下代码片段而不是覆盖模板文件

function filter_woocommerce_related_products( $related_posts, $product_id, $args ) {    
    foreach( $related_posts as $key => $related_post ) {        
        // Get product
        $related_product = wc_get_product( $related_post );
        
        // Is a WC product 
        if ( is_a( $related_product, 'WC_Product' ) ) {
            // Stock status
            $stock_status = $related_product->get_stock_status();
            
            // NOT instock
            if ( $stock_status != 'instock' ) {
                unset( $related_posts[$key] );
            }
        }
    }
    
    return $related_posts;
}
add_filter( 'woocommerce_related_products', 'filter_woocommerce_related_products', 10, 3 );


覆盖模板文件

总会有多种解决方案,但其中一种可能是通过覆盖模板文件来实现。

https://github.com/woocommerce/woocommerce/blob/02cf0dfaed5923513de0c88add597d1560c2cfd2/templates/single-product/related.php

  • 通过将此模板复制到yourtheme/woocommerce/single-product/related.php,可以覆盖此模板。

替换
<?php foreach ( $related_products as $related_product ) : ?>

        <?php
        $post_object = get_post( $related_product->get_id() );

        setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found

        wc_get_template_part( 'content', 'product' );
        ?>

<?php endforeach; ?>

With

<?php foreach ( $related_products as $related_product ) : ?>

    <?php
    $stock_status = $related_product->get_stock_status();

    if ( $stock_status == 'instock' ) {
        
        $post_object = get_post( $related_product->get_id() );

        setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found

        wc_get_template_part( 'content', 'product' );
    }
    ?>

<?php endforeach; ?>

1

不必编辑模板文件,您可以使用woocommerce_product_related_posts_query专用过滤器钩子来更改查询,将“缺货”的产品从显示的相关产品中排除:

add_filter( 'woocommerce_product_related_posts_query', 'alter_product_related_posts_query', 10, 3 );
function alter_product_related_posts_query( $query, $product_id, $args ){
    global $wpdb;

    $query['join']  .= " INNER JOIN {$wpdb->postmeta} as pm ON p.ID = pm.post_id ";
    $query['where'] .= " AND pm.meta_key = '_stock_status' AND meta_value != 'outofstock' ";

    return $query;
}

代码放在活动子主题(或活动主题)的functions.php文件中。经过测试可以正常工作。

相关:如何使用Woocommerce中的自定义元查询自定义相关产品


1
@MohamedAliSamali 抱歉,但这段代码可以正常工作并仅显示未缺货的相关产品,这是您在问题中提出的要求... 对于您的问题,您可能需要有时进入WooCommerce设置>状态>工具(选项卡)并在“WooCommerce短暂”中单击“清除短暂”。 - LoicTheAztec
add_filter可以工作,但它会隐藏所有内容。我认为它只取前4或5个产品……如果第4或第5个产品缺货,它将不显示任何内容。但在我的情况下,第6、7个产品等都没有缺货。 - Dali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接