从车间循环中排除库存低于低库存门槛的产品

时间:2019-09-20 作者:Saxt0n

在我们的店铺页面上,我们有各种徽章(如“系列1”),单击这些徽章可以链接到各自的产品标签页面。然而,我们也想要一个“低库存”徽章。问题是,我们需要动态地判断某样东西的库存是否很低。我们不能只是贴标签。

我正在与Woocommerce建立低库存徽章链接到自己的页面[products] shortcode,但现在我只需要显示股票在该范围内的股票。到目前为止,我找到的解决方案都提到通过进行分类查询来删除产品,但我不能这样做,因为我无法手动将这些产品分配给低库存标签/类别。

作为参考,以下是我一直使用的分类查询:

function custom_pre_get_posts_query( $q ) {
    if( is_shop() ) {
        $tag_query = (array) $q->get( \'tax_query\' );

        $tag_query[] = array(
               \'taxonomy\' => \'product_tag\',
               \'field\' => \'slug\',
               \'terms\' => array( \'retired\' ), // Don\'t display products with the tag "retired"
               \'operator\' => \'NOT IN\'
        );

        $q->set( \'tax_query\', $tag_query );
    }
}
add_action( \'woocommerce_product_query\', \'custom_pre_get_posts_query\' );

1 个回复
SO网友:Tim Elsass

如果我理解您的问题、示例和用例,我认为您需要解决两件事:

  1. Create a low stock status for products to use

    遵循这些步骤有助于用户设置其产品的低库存状态,并为这些类型的产品提供一种符合逻辑的查询和方式。在创建低库存状态时,我们需要确保考虑两种基本情况:

    User manually sets the stock status on a product

    在此场景中,用户已取消选中“库存管理”下的“库存管理”选项。由于是这种情况,用户可以在此处设置库存状态,以指定产品是否缺货、有库存、缺货等。我们希望在此处添加低库存选项,以便根据需要手动设置每个产品。为此,我们将使用woocommerce_product_stock_status_options 过滤器:

    /**
     * Add low stock to WooCommerce stock status options.
     */
    function add_low_stock_option( $options ) {
        $options[\'lowstock\'] = __( \'Low Stock\', \'textdomain\' );
        return $options;
    }
    
    add_filter( \'woocommerce_product_stock_status_options\', \'add_low_stock_option\' );
    
    b。User has stock management enabled for a product

    现在,我们需要通过在产品上选择“库存管理库存”选项来说明用户管理其库存的情况。选择此选项后,他们可以设置库存物品的数量以及低库存阈值。我将使用此字段作为要设置的低库存状态的阈值,因此用户可以根据需要对每个产品进行更改。我们希望确保在处理产品元时更新低库存状态,因此我们将连接到WooCommerce的woocommerce_process_product_meta 钩子以确保添加了自定义状态:

    /**
     * Save the low stock status.
     */
    function save_low_stock_status( $product_id ) {
        $product = wc_get_product( $product_id );
    
        // Stock managed for product individually and between "Out of Stock" and "Low Stock Amount".
        if ( $product->get_manage_stock() &&
            ( $product->get_stock_quantity() <= $product->get_low_stock_amount() )
        ) {
            // Update to our low stock status.
            update_post_meta( $product_id, \'_stock_status\', \'lowstock\' );
        }
    }
    
    add_action( \'woocommerce_process_product_meta\', \'save_low_stock_status\', 20 );
    
  2. Use the low stock status on the site

    您提到希望基于此自定义状态创建徽章,并给出了过滤查询的代码示例。根据你的最终目标,有很多方法可以实现这些事情。

    下面是一些基于上述内容的代码示例,在实现自定义状态时可能会很有用:

    示例1:更新产品页面上的可用性消息(即显示“低库存”而不是“1件可用”[或任何阈值]):

    /**
     * Get availablity status.
     */
    function get_custom_availability( $data, $product ) {
        $stock_status = get_post_meta( $product->id , \'_stock_status\' , true );
        if ( \'lowstock\' === $stock_status ) {
            $data = [
                \'availability\' => __( \'Low stock\', \'textdomain\' ),
                \'class\' => \'low-stock\'
            ];
        }
    
        return $data;
    }
    
    add_action( \'woocommerce_get_availability\', \'get_custom_availability\', 20, 2 );
    
    示例2:在您的店铺页面上为产品添加低库存徽章

    /**
     * Add a low stock badge on shop pages.
     */
    function add_low_stock_badge() {
        global $product;
    
        $stock_status = $product->get_stock_status();
    
        if ( \'lowstock\' === $stock_status ) {
            echo \'<span class="low-stock-badge">\' . __( \'Low stock\', \'textdomain\' ) . \'</span>\';
        }
    }
    
    add_action( \'woocommerce_before_shop_loop_item\', \'add_low_stock_badge\' );
    
    示例3:仅显示低库存状态的产品

    在您的代码示例中,查询被分类术语过滤并从结果中删除,如果这是您需要的行为,那么这是可行的。对于我们创建的低库存状态,我们并不需要确切的信息,但您的基础是正确的。我们仍然想加入woocommerce_product_query 就像您的示例一样,但要根据附加到产品的元数据过滤结果。这是在中完成的meta_query, 因此,此代码匹配任何具有lowstock 作为_stock_status 产品元数据:

    /**
     * Show only lowstock stock status products in queries.
     */
    function show_low_stock_products( $q ) {
        $meta_query = $q->get( \'meta_query\' );
    
        $meta_query[] = [
            \'key\' => \'_stock_status\',
            \'value\' => \'lowstock\',
            \'compare\' => \'=\',
        ];
    
        $q->set( \'meta_query\', $meta_query );
    }
    
    add_action( \'woocommerce_product_query\', \'show_low_stock_products\' );
    
    示例4:隐藏低库存状态的产品

    当然,这个问题的标题是问如何在商店循环中隐藏库存低于阈值的产品。使用上面c节中的代码,您可以简单地反转compare 在查询中隐藏lowstock状态产品并显示所有其他产品。我还建议将函数名更新为hide_low_stock_products 为了更好的易读性:

    /**
     * Hide the lowstock stock status products in queries.
     */
    function hide_low_stock_products( $q ) {
        $meta_query = $q->get( \'meta_query\' );
    
        $meta_query[] = [
            \'key\' => \'_stock_status\',
            \'value\' => \'lowstock\',
            \'compare\' => \'!=\',
        ];
    
        $q->set( \'meta_query\', $meta_query );
    }
    
    add_action( \'woocommerce_product_query\', \'hide_low_stock_products\' );
    
我也已经着手创建了this gist 包括隐藏查询中的项目、徽章内容和可用性消息示例,以便于您复制和操作。

编辑:

Updating Existing Products

对于freshsite和我们现有的产品,最有效的解决方案可能因不同的因素而有所不同。基本上,在上述方法中save_low_stock_status, 我们加入woocommerce_process_product_meta. 这是在处理和保存产品元数据时运行的,因此现有产品不会使用新的状态信息进行更新。

这对于新站点非常有用,但在大多数情况下,您需要运行某种迁移脚本。为了保持相关性,我将不包括升级挂钩信息和涉及的步骤,因为听起来这只是为了一个站点的运行,让您朝着正确的方向前进。我们将要更新_stock_status 基于任何产品的标准在数据库中输入元数据键_stock 数量达到或低于您决定的阈值,但没有完全脱销。我们可以通过SQL查询来实现这一点。代码使用$wpdb 如下所示:

/**
 * Update all product stock statuses that meet the criteria.
 */
function update_lowstock_products_stock_status(){
    global $wpdb;

    // Low Quantity threshold.
    $threshold = \'2\';

    // SQL statement to update _stock_status to lowstock on all products where _stock >= 1 AND _stock <= $threshold set for lowstock status.
    $sql .= "UPDATE $wpdb->postmeta stock, (SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = \'_stock\' AND meta_value BETWEEN 1 AND $threshold ) id SET stock.meta_value = \'lowstock\' WHERE stock.post_id = id.post_id AND stock.meta_key = \'_stock_status\';";

    // Execute query.
    $wpdb->query( $sql );
}
这将更新符合您标准的每个产品。您可能需要重写查询以满足您的特定站点和需求。例如:如果您的产品确实具有由某人手动管理库存的选项,那么您可能需要查看_low_stock_amount 元值,以获取这些产品的低库存量,而不是为自动处理其余产品而设置的硬阈值。

请记住,我们只需要运行此更新一次,因此如果它是单个站点,您可以在主题的functions.php 文件:

// Only needs to update once, so just add to theme\'s functions.php or if in a plugin you can have migration happen in update hook.
update_lowstock_products_stock_status();

相关推荐