WooCommerce:将 3 个自定义简码合二为一
WooCommerce: Merge 3 custom shortcodes in one
我有三个独立的 woocommerce 片段,每个片段都有一个功能。
我试图将它们组合在一个脚本中,但似乎 return 不能超过一个值。
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' );
我尝试组合所有脚本并将函数一个接一个地放置,并尝试 return 将这 3 个值放在 3 个函数的末尾。但只有第一个是 returned.
或 return 每个函数末尾的值,运气不好。
我的目标是拥有类似于:
Proposals: Taken(x) | New(x) | Left(x)
将 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"]
虽然接受的答案是完全有效的,但这里有一个更高效和可扩展的代码。
您的代码存在的问题是,对于每次页面加载,您都在获取和计算相同的不变数据。
这是一种开销,不会影响几千名访问者的网站,但当产品、订单或并发流量上升时,上述代码将开始成为瓶颈。
在这段代码中,我广泛使用了 Transient API(缓存),而不是在每个页面加载时更新计数,而是使用缓存的计数。最好的部分是,当每个计数中使用的任何数据发生变化时,它会自动更新缓存的计数。
例如,一旦订购了产品(或取消了订单),代码就会更新 Taken 和 Left。
此代码已完全测试
主要简码
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"]
您可以在 CSS.
中使用 .proposal-stats
class 设置输出样式
我有三个独立的 woocommerce 片段,每个片段都有一个功能。 我试图将它们组合在一个脚本中,但似乎 return 不能超过一个值。
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' );
我尝试组合所有脚本并将函数一个接一个地放置,并尝试 return 将这 3 个值放在 3 个函数的末尾。但只有第一个是 returned.
或 return 每个函数末尾的值,运气不好。
我的目标是拥有类似于:
Proposals: Taken(x) | New(x) | Left(x)
将 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"]
虽然接受的答案是完全有效的,但这里有一个更高效和可扩展的代码。
您的代码存在的问题是,对于每次页面加载,您都在获取和计算相同的不变数据。
这是一种开销,不会影响几千名访问者的网站,但当产品、订单或并发流量上升时,上述代码将开始成为瓶颈。
在这段代码中,我广泛使用了 Transient API(缓存),而不是在每个页面加载时更新计数,而是使用缓存的计数。最好的部分是,当每个计数中使用的任何数据发生变化时,它会自动更新缓存的计数。
例如,一旦订购了产品(或取消了订单),代码就会更新 Taken 和 Left。
此代码已完全测试
主要简码
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"]
您可以在 CSS.
中使用.proposal-stats
class 设置输出样式