代码之家  ›  专栏  ›  技术社区  ›  enkiki

WooCommerce:将3个自定义短代码合并为一个

  •  1
  • enkiki  · 技术社区  · 8 年前

    我有三个单独的woocommerce代码段,其中每个代码段都有一个函数。 我试图将它们组合在一个脚本中,但似乎无法返回多个值。

    function display_woocommerce_order_count2( $atts, $content = null ) {
    $args = shortcode_atts( array(
        'status' => 'completed',
    ), $atts );
    $statuses    = array_map( 'trim', explode( ',', $args['status'] ) );
    $order_count = 0;
    foreach ( $statuses as $status ) {
        // if we didn't get a wc- prefix, add one
        if ( 0 !== strpos( $status, 'wc-' ) ) {
            $status = 'wc-' . $status;
        }
        $order_count += wp_count_posts( 'shop_order' )->$status;
    }
    ob_start();
    return '<span style="color:#fff;text-align:center;font-size:12px">Deals:' . 
    $order_count;
    $user->total;
    return ob_get_clean();
    }
    add_shortcode( 'wc_order_count3', 'display_woocommerce_order_count2' );
    

    function get_instock_products_count(){
    global $wpdb;
    
    // The SQL query
    $result = $wpdb->get_col( "
        SELECT COUNT(p.ID)
        FROM {$wpdb->prefix}posts as p
        INNER JOIN {$wpdb->prefix}postmeta as pm ON p.ID = pm.post_id
        WHERE p.post_type LIKE '%product%'
        AND p.post_status LIKE 'publish'
        AND pm.meta_key LIKE '_stock_status'
        AND pm.meta_value LIKE 'instock'
    " );
    
    return '<span style="color:#fff;text-align:center;font-size:12px">Proposals 
    Left: ' . reset($result);
    }
    add_shortcode('fp7', 'get_instock_products_count');
    

    function new_proposals2(){
    global $wpdb;
    
    // 24 hours ago
    $is_24h_ago = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")." -1day"));
    
    // The SQL query
    $result = $wpdb->get_col( "
        SELECT COUNT(p.ID)
        FROM {$wpdb->prefix}posts as p
        WHERE p.post_type LIKE '%product%'
        AND p.post_status LIKE 'publish'
        AND p.post_date > '$is_24h_ago'
    " );
    
    return '<span style="color:#fff;text-align:center;font-size:12px">New 
    Proposals: ' . reset($result);
    }
    add_shortcode( 'new_proposals', 'new_proposals2' );
    

    我尝试将所有脚本组合在一起,将函数一个接一个地放置,并尝试在3个函数的末尾返回这3个值。但只返回了第一个。

    或者在每个函数的末尾返回值,没有运气。

    我的目标是获得类似于:

    提案:采取(x)|新(x)|左(x)

    2 回复  |  直到 8 年前
        1
  •  2
  •   LoicTheAztec    8 年前

    将这3个短代码合并为一个非常简单,可以通过以下方式完成:

    function order_multi_count( $atts, $content = null ) {
        global $wpdb;
    
        $args = shortcode_atts( array(
            'status' => 'completed',
        ), $atts );
    
        ## ---- ---- ---- ---- ---- ---- TAKEN ---- ---- ---- ---- ---- ---- ---- ##
    
        $statuses    = array_map( 'trim', explode( ',', $args['status'] ) );
        $taken = 0;
    
        foreach ( $statuses as $status ) {
            // if we didn't get a wc- prefix, add one
            if ( 0 !== strpos( $status, 'wc-' ) ) {
                $status = 'wc-' . $status;
            }
            $taken += wp_count_posts( 'shop_order' )->$status;
        }
    
        ## ---- ---- ---- ---- ---- ----  LEFT ---- ---- ---- ---- ---- ---- ---- ##
    
        // The SQL query 
        $result = $wpdb->get_col( "
            SELECT COUNT(p.ID)
            FROM {$wpdb->prefix}posts as p
            INNER JOIN {$wpdb->prefix}postmeta as pm ON p.ID = pm.post_id
            WHERE p.post_type LIKE '%product%'
            AND p.post_status LIKE 'publish'
            AND pm.meta_key LIKE '_stock_status'
            AND pm.meta_value LIKE 'instock'
        " );
    
        $left = reset($result);
    
        ## ---- ---- ---- ---- ---- ----  NEW  ---- ---- ---- ---- ---- ---- ---- ##
    
        // 24 hours ago
        $is_24h_ago = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")." -1day"));
    
        // The SQL query
        $result2 = $wpdb->get_col( "
            SELECT COUNT(p.ID)
            FROM {$wpdb->prefix}posts as p
            WHERE p.post_type LIKE '%product%'
            AND p.post_status LIKE 'publish'
            AND p.post_date > '$is_24h_ago'
        " );
    
        $new = reset($result2);
    
        ## ---- ---- ---- ---- ---- RETURNING VALUE ---- ---- ---- ---- ---- ---- ##
    
        $style = 'style="color:#fff;text-align:center;font-size:12px"';
        return "<span $style><strong>Proposals:</strong> Taken ($taken) | New ($new) | Left ($left)</span>"; 
    }
    add_shortcode( 'order_multi_count', 'order_multi_count' );
    

    这应该行得通


    用法: [order_multi_count] [order_multi_count status="processing"]

        2
  •  0
  •   Dhaval Shah    8 年前

    虽然公认的答案是完全正确的,但这里有一个更高性能和可伸缩性的代码。

    您的代码的问题是,对于您正在获取的每个页面加载(&P);计算相同的不变数据。

    这是一项开销,不会影响数千名访问者的网站,但当产品、订单或并发流量增加时,上述代码将开始成为瓶颈。

    在这段代码中,我广泛使用了瞬态API(缓存),它将使用缓存计数,而不是更新每个页面加载的计数。最好的部分是,当每个计数中使用的任何数据发生更改时,它将自动更新缓存的计数。

    例如,一旦订购了产品(或取消了订单),代码就会更新 左边 .


    此代码经过全面测试

    主短代码

    add_shortcode( 'wp1707_proposal_stats', 'wp1707_proposal_stats_func' );
    /**
     * Shortcode to display In-Stock, New in last 24hours and Ordered products.
     *
     * @param      array   $atts   The atts passed via shortcode
     *
     * @return     string  Outputs Shortcode HTML
     */
    function wp1707_proposal_stats_func( $atts ){
    
        $args = shortcode_atts( array(
            'status' => 'completed',
        ), $atts );
    
        /**
         * Taken
         */
        $requested_statuses = array_map( 'trim', explode( ',', $args['status'] ) );
        $order_count_all_statuses = wp1707_get_count_posts();
        $taken = 0;
    
        foreach ( $requested_statuses as $key => $status ) {
            // if we didn't get a wc- prefix, add one
            if ( 0 !== strpos( $status, 'wc-' ) ) {
                $status = 'wc-' . $status;
            }
            $taken += $order_count_all_statuses->$status;
        }
    
        /**
         * Left
         */
        $left = wp1707_instock_products_count( false );
    
       /**
        * New
        */
       $new = wp1707_new_products_count();
    
       return sprintf("<span style='proposal-stats'>Proposals:Taken (%d)| Left (%d) | New (%d)</span>", $taken, $left, $new );
    }
    

    实用程序功能

    add_action('transition_post_status', 'wp1707_update_transients', 10, 3 );
    /**
     * Updates transients for Orders Count and In-Stock Products Count
     *
     * @param      string   $new_status  New status passed by WordPress Hook
     * @param      string   $old_status  Old status passed by WordPress Hook
     * @param      WP_Post  $post       WP Post instance
     */
    function wp1707_update_transients( $new_status, $old_status, $post ){
        if( 'publish' === $new_status || 'publish' === $old_status ) {
            if ( $post->post_type === 'shop_order' ) {
                wp1707_get_count_posts( true );
            } elseif ( in_array( $post->post_type, array( 'product', 'product_variation' ) ) ) {
                wp1707_new_products_count( true );
            }
        }
    }
    
    /**
     * Gets Shop Order Counts for each of the Statuses available
     *
     * @param      boolean  $update  Force update the transient. Pass true to use
     *                               data in transient api. Default false
     *
     * @return     array    Array containing Status as keys and order counts as values.
     */
    function wp1707_get_count_posts ( $update = false ){
        $shop_order_count = get_transient( 'wp1707_shop_order_count' );
    
        if ( !$shop_order_count || !$update) {
            $shop_order_count = wp_count_posts( 'shop_order' );
            set_transient( 'wp1707_shop_order_count', $shop_order_count, 12 * HOUR_IN_SECONDS );
        }
    
        return reset( $shop_order_count );
    }
    
    /**
     * Counts New Products published in last 24hours
     *
     * @param      boolean  $update  Force update the transient. Pass true to use
     *                               data in transient api. Default false
     *
     * @return     int      Count of new products pubplished in last 24hours
     */
    function wp1707_new_products_count( $update = false ){
    
        $new_products_count = get_transient( 'wp1707_new_products_count' );
    
        if ( !$new_products_count || $update === true ) {
            /**
             * It wasn't there or a product was just published, so regenerate the
             * data and save the transient */
            global $wpdb;
    
            // 24 hours ago
            $is_24h_ago = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")." -1day"));
    
            // The SQL query
            $new_products_count = $wpdb->get_col( "
                                                 SELECT COUNT(p.ID)
                                                 FROM {$wpdb->posts} as p
                                                 WHERE p.post_type LIKE '%product%'
                                                 AND p.post_status LIKE 'publish'
                                                 AND p.post_date > '$is_24h_ago'
                                                 " );
    
           set_transient( 'wp1707_new_products_count', $new_products_count, 24 * HOUR_IN_SECONDS ); // Tweak the time here per your need
       }
    
       return reset( $new_products_count );
    }
    
    
    add_action('woocommerce_product_set_stock', 'wp1707_instock_products_count');
    add_action('woocommerce_variation_set_stock', 'wp1707_instock_products_count');
    /**
     * Counts In-Stock Products
     *
     * @param      boolean  $update  Force update the transient. Pass false to use
     *                               data from transient api. Default true
     *
     * @return     int      Count of instock products
     */
    function wp1707_instock_products_count( $update = true ){
    
        // Get any existing copy of our transient data
        $instock_products_count = get_transient( 'wp1707_instock_products_count' );
    
        if ( !$instock_products_count || $update === true ) {
            /**
             * It wasn't there or stock was updated for some product, so regenerate
             * the data and save the transient */
            global $wpdb;
            // The SQL query
            $instock_products_count = $wpdb->get_col( "
                                    SELECT COUNT(p.ID)
                                    FROM {$wpdb->posts} as p
                                    INNER JOIN {$wpdb->postmeta} as pm ON p.ID = pm.post_id
                                    WHERE p.post_type LIKE '%product%'
                                    AND p.post_status LIKE 'publish'
                                    AND pm.meta_key LIKE '_stock_status'
                                    AND pm.meta_value LIKE 'instock'
                                    " );
    
           set_transient( 'wp1707_instock_products_count', $instock_products_count, 12 * HOUR_IN_SECONDS ); // Tweak the time here per your usual sales traffic
        }
    
       return reset( $instock_products_count );
    }
    

    用法

    [wp1707_proposal_stats] [wp1707_proposal_stats status="processing,on-hold,completed"]

    您可以使用 .proposal-stats 在CSS中初始化。