php - 按价格对 Woocommerce 产品变体自定义输出进行排序

标签 php woocommerce shortcode product price

贝娄我有一个基于 this answer code 的自定义简码函数显示简单产品和可变产品的每个变体的产品数据 block 。变体 block 的输出似乎是按变体本身的 ID 排序的。

例如,这是前端输出的屏幕截图:

https://freshysites.d.pr/9gAMgn

您可以看到与变体 ID 的顺序(从最小到最大)匹配的屏幕截图:

https://freshysites.d.pr/wjS9Cj

我想要的是按价格对变化进行排序(而不是按 ID)从最低到最高排序。如有任何帮助,我们将不胜感激。

这是我当前的自定义代码:

add_shortcode("price_variation_table", "fs_custom_available_variations_table");
function fs_custom_available_variations_table( $atts ) {

    global $post;

    // Attributes
    $atts = shortcode_atts(
        array(
            'id'    => $post->ID
        ),
        $atts, 'price_variation_table'
    );

    if( is_admin() ) return; // Only on front end

    $product = wc_get_product($atts['id']); // Get the WC_Product Object

    $output = '<div class="fs-product-data-wrapper">';

    // Variable products
    if( $product->is_type('variable'))
    {
        // Get available variations in the variable product
        $available_variations = $product->get_available_variations();

        if( count($available_variations) > 0 ){
            foreach( $available_variations as $variation )
                $output .= fs_format_product_data_output( $variation['variation_id'] );
        }
    }
    // Simple products
    elseif( $product->is_type('simple'))
    {
        $output .= fs_format_product_data_output( $product->get_id() );
    }
    else return; // Exit

    return $output .= '</div>'; // return always for a shortcode
}

// Utility funtion: getting and formtting product data
function fs_format_product_data_output( $the_id ){
    $empty =  __( '<em>(empty)</em>', 'woocommerce' );

    // Get an instance of the WC_Product_Variation object
    $product = wc_get_product( $the_id );

    // Only wc_get_price_to_display() respect if product is to be displayed with or without including taxes
    $price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );

    $sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
    $sale_price = ! empty( $sale_price ) ? wc_price($sale_price) : $empty;
    // can use this class is there is no sale price set
    if ( ! $product->is_on_sale() ) {
        $no_sale_price = ' no-sale-price';
    }

    $size = $product->get_attribute( 'pa_size' );
    $size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;

    $stock_qty = $product->get_stock_quantity();
    $stock_qty = ! empty( $stock_qty ) ? $stock_qty : '0';
    if ( $stock_qty <= 0 ) {
        $stock_status = 'stock-sold-out';
    }
    else {
        $stock_status = 'stock-available';
    }
    $output = '
    <ul class="'. $stock_status .'">
        <li class="fs-data-price">'.$price.' ea.</li>
        <li class="fs-data-size">Size: '.$size.'</li>
        <li class="fs-data-sale'. $no_sale_price .'">'.$sale_price.' ea. Preferred customer price</li>
        <li class="fs-data-stock">Quantity in Stock: '.$stock_qty.'</li>
        <li class="fs-data-notice">Quantities change quickly!</li>
    </ul>';

    return $output;
}

最佳答案

尝试以下稍微更改的代码,其中每个显示的变体将按常规价格排序(从低到高):

add_shortcode("price_variation_table", "custom_available_variations_table");
function custom_available_variations_table( $atts ) {

    global $post;

    // Attributes
    $atts = shortcode_atts(
        array(
            'id'    => $post->ID
        ),
        $atts, 'price_variation_table'
    );

    if( is_admin() ) return; // Only on front end

    $product = wc_get_product($atts['id']); // Get the WC_Product Object

    $output = '<div class="fs-product-data-wrapper">';

    // Variable products
    if( $product->is_type('variable'))
    {
        // Get available variations in the variable product
        $available_variations = $product->get_available_variations();

        if( count($available_variations) > 0 ){
            $variations_ids = array();

            // First loop - set variations Ids in an array with regular prices
            foreach( $available_variations as $variation ){
               $product = wc_get_product( $variation['variation_id'] );
               $price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );
               $variations_ids[$variation['variation_id']] = $price;
            }
            // Sorting variation Ids using prices from lower to highest
            natsort($variations_ids);

            // 2nd Loop - Display formatted variation data
            foreach( array_keys($variations_ids) as $variations_id ){
               $output .= format_product_data_output( $variations_id );
            }
        }
    }
    // Simple products
    elseif( $product->is_type('simple'))
    {
        $output .= format_product_data_output( $product->get_id() );
    }
    else return; // Exit

    return $output .= '</div>'; // return always for a shortcode
}

// Utility funtion: getting and formatting product data
function format_product_data_output( $the_id ){
    $empty =  __( '<em>(empty)</em>', 'woocommerce' );

    // Get an instance of the WC_Product_Variation object
    $product = wc_get_product( $the_id );

    // Only wc_get_price_to_display() respect if product is to be displayed with or without including taxes
    $price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );
    $sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
    $sale_price = ! empty( $sale_price ) ? wc_price($sale_price) : $empty;

    $size = $product->get_attribute( 'pa_size' );
    $size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;

    $no_sale_price = ! $product->is_on_sale() ? ' no-sale-price' : '';

    $size = $product->get_attribute( 'pa_size' );
    $size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;

    $stock_qty = $product->get_stock_quantity();
    $stock_qty = ! empty( $stock_qty ) ? $stock_qty : '0';
    $stock_status = $stock_qty <= 0 ? 'stock-sold-out' : 'stock-available';

    $output = '
    <ul class="'. $stock_status .'">
        <li class="fs-data-price">'.$price.' ea.</li>
        <li class="fs-data-size">Size: '.$size.'</li>
        <li class="fs-data-sale'. $no_sale_price .'">'.$sale_price.' ea. Preferred customer price</li>
        <li class="fs-data-stock">Quantity in Stock: '.$stock_qty.'</li>
        <li class="fs-data-notice">Quantities change quickly!</li>
    </ul>';

    return $output;
}

代码位于事件子主题(或事件主题)的 function.php 文件中。经过测试并有效。

关于php - 按价格对 Woocommerce 产品变体自定义输出进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49945108/

相关文章:

php - 将 DateInterval 格式化为 ISO8601

php - 获取父行和子行的所有数据

php - 从 woocommerce 中的电子邮件模板中删除订单信息部分

wordpress - 如何在 woocommerce 中的新订单电子邮件中显示高级自定义字段数据

php - 向 WooCommerce 单个产品页面添加多个选项卡

php - 来自自定义插件短代码的 HTML 显示在 WordPress 的编辑页面屏幕上

php - 为什么这个正则表达式匹配是肯定的?

php - Laravel 分页返回 http 而不是 https 的链接

php - 用于创建选项卡的自定义简码

php - 带有查询 SQL 的简码 WordPress