将 WooCommerce 产品销售价格复制为正常价格并重置销售价格
Copy WooCommerce products Sale prices to regular prices and reset Sale prices
我想用促销价值替换我的 WooCommerce 商店中的所有常规价格,并删除 wp_postmeta
table 下的促销价值.
post_id
列对于每种产品的两种价格都是相同的,要复制的列是 _sale_price
到 _price
并删除 _sale_price
。
我 运行 可以用什么查询来实现?
这是一个自定义函数,可以将促销价复制到正常价格并重置促销 price.Regarding WooCommerce 中的价格有:
- 有效价格:
'_price'
- 正常价格:
'_regular_price'
- 售价:
'_sale_price'
因此您也需要更新正常价格并重置促销价的所有相关数据。还需要刷新价格。
此功能有一个 UI 将出现在商店页面或单个产品页面中 仅供管理员和商店经理使用 。
If you have more than 1000 products, the process will be auto split in multiple steps (by 1000 products) to avoid errors when there is too many products.
SQL 查询只会 select 有促销价的产品 ID,而不是所有产品。对于 update/Reset 价格,我使用 update_post_meta() 函数而不是查询来刷新每个产品缓存...
看起来像:
- 开始更新价格(第一步):
- 继续必要的步骤:
- 价格更新完成(结束画面):
Important: Before starting this kind of process always make a database backup
这是钩子函数代码:
add_action( 'woocommerce_before_main_content', function(){
// Only admins and shop manargers
if( ! current_user_can( 'edit_products' ) ) return;
global $wpdb;
$products_count = get_option( 'product_prices_update_count' );
// Auto enable multistep price updates for more than 1000 products
$limit = $products_count > 2 ? 2 : false;
if( $limit != false )
$offset = get_option( 'product_prices_update_offset' );
if( empty( $offset ) && $limit != false ) {
$offset = 0;
add_option( 'product_prices_update_offset', $offset );
}
$control_process = $limit != false ? "LIMIT $offset, $limit" : "";
if( ! isset( $_POST['prices_updates'] ) ) $control_process = '';
// 1. First query: Get for all product ids the sale price
$results = $wpdb->get_results( "
SELECT postmeta.post_id, postmeta.meta_value as price
FROM {$wpdb->prefix}postmeta as postmeta
INNER JOIN {$wpdb->prefix}posts as posts ON postmeta.post_id = posts.ID
WHERE posts.post_type LIKE '%product%'
AND postmeta.meta_key = '_sale_price'
AND postmeta.meta_value != ''
ORDER BY posts.ID ASC
$control_process
" );
if( empty( $products_count ) ){
update_option( 'product_prices_update_count', count($results) );
$count = count($results);
} else $count = $products_count;
$remaining = ! empty( $products_count ) && $limit != false ? $count-($offset+$limit) : count($results);
$products_updated = 0;
echo '<div style="border: solid 1px grey; padding: 16px; margin-bottom: 12px;)">
<form class="cart" method="post" enctype="multipart/form-data">';
if( isset( $_POST['prices_updates'] ) && ( $remaining > 0 || ! $limit ) ){
foreach($results as $result){
$post_id = $result->post_id;
$price = $result->price;
// 2. Updating Active and Regular prices
update_post_meta( $post_id, '_price', $price );
update_post_meta( $post_id, '_regular_price', $price );
// 3. Reset Sale price
update_post_meta( $post_id, '_sale_price', '' );
update_post_meta( $post_id, '_sale_price_dates_from', '');
update_post_meta( $post_id, '_sale_price_dates_to', '');
// 4. Refresh product cache
wc_delete_product_transients($post_id);
$products_updated++;
// echo "$post_id ($products_updated), ";
}
}
if( ( ! $limit && ! empty( $products_count ) ) || $remaining <= 0 ){
echo "<p><strong>Process is now finished.</strong><br>
<em>You can remove or comment the code, Thanks</em></p>";
if( isset($_POST['prices_updates'] ) ){
delete_option( 'product_prices_update_offset' );
delete_option( 'product_prices_update_count' );
}
} else {
if( isset( $_POST['prices_updates'] ) ){
update_option( 'product_prices_update_offset', $offset+$limit );
echo "<p>$products_updated products have been updated.<br>";
echo "There is still $remaining remaining products to update.</p>";
} else
echo "<p>There is $remaining products to update.</p>";
$value = empty( $products_count ) ? "Start update" : "Continue update";
echo '<input type="submit" class="button" name="prices_updates" value="'.$value.'" />';
}
echo '</form></div>';
}, 2, 0);
代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件。
此代码已经过测试并且有效。
这是您要查找的纯 MySQL 查询:
首先你必须使用自连接来更新_price
和_regular_price
字段
UPDATE `wp_postmeta` AS a,
`wp_postmeta` AS b
SET a.`meta_value` = b.meta_value
WHERE a.post_id = b.post_id
AND a.meta_key IN ('_price', '_regular_price')
AND b.meta_key = '_sale_price'
AND b.meta_value != ''
AND a.`post_id` IN
(SELECT `ID`
FROM `wp_posts`
WHERE `post_type` = 'product'
AND `post_status` = 'publish');
现在要重置促销价和日期,您必须将其设置为空白
UPDATE `wp_postmeta`
SET `meta_value` = ''
WHERE `meta_key` IN ('_sale_price', '_sale_price_dates_from', '_sale_price_dates_to')
AND `post_id` IN
(SELECT `ID`
FROM `wp_posts`
WHERE `post_type` = 'product'
AND `post_status` = 'publish' );
如果你想删除这些字段,那么使用带有 WHERE 子句的 DELETE 语句,它会解决你的目的。
您还必须删除存储在 _transient_timeout_wc_var_prices_{{post_id}}
下的 wp_options
table 中的 WooCommerce 产品价格缓存和_transient_wc_var_prices_{{post_id}}
在 option_name
DELETE
FROM `wp_options`
WHERE (`option_name` LIKE '_transient_wc_var_prices_%'
OR `option_name` LIKE '_transient_timeout_wc_var_prices_%')
特别感谢@LoicTheAztec 指出产品价格缓存
以上查询已经过测试并且对我有效。
在 运行 这个查询之前做一个数据库备份
希望对您有所帮助!
我想用促销价值替换我的 WooCommerce 商店中的所有常规价格,并删除 wp_postmeta
table 下的促销价值.
post_id
列对于每种产品的两种价格都是相同的,要复制的列是 _sale_price
到 _price
并删除 _sale_price
。
我 运行 可以用什么查询来实现?
这是一个自定义函数,可以将促销价复制到正常价格并重置促销 price.Regarding WooCommerce 中的价格有:
- 有效价格:
'_price'
- 正常价格:
'_regular_price'
- 售价:
'_sale_price'
因此您也需要更新正常价格并重置促销价的所有相关数据。还需要刷新价格。
此功能有一个 UI 将出现在商店页面或单个产品页面中 仅供管理员和商店经理使用 。
If you have more than 1000 products, the process will be auto split in multiple steps (by 1000 products) to avoid errors when there is too many products.
SQL 查询只会 select 有促销价的产品 ID,而不是所有产品。对于 update/Reset 价格,我使用 update_post_meta() 函数而不是查询来刷新每个产品缓存...
看起来像:
- 开始更新价格(第一步):
- 继续必要的步骤:
- 价格更新完成(结束画面):
Important: Before starting this kind of process always make a database backup
这是钩子函数代码:
add_action( 'woocommerce_before_main_content', function(){
// Only admins and shop manargers
if( ! current_user_can( 'edit_products' ) ) return;
global $wpdb;
$products_count = get_option( 'product_prices_update_count' );
// Auto enable multistep price updates for more than 1000 products
$limit = $products_count > 2 ? 2 : false;
if( $limit != false )
$offset = get_option( 'product_prices_update_offset' );
if( empty( $offset ) && $limit != false ) {
$offset = 0;
add_option( 'product_prices_update_offset', $offset );
}
$control_process = $limit != false ? "LIMIT $offset, $limit" : "";
if( ! isset( $_POST['prices_updates'] ) ) $control_process = '';
// 1. First query: Get for all product ids the sale price
$results = $wpdb->get_results( "
SELECT postmeta.post_id, postmeta.meta_value as price
FROM {$wpdb->prefix}postmeta as postmeta
INNER JOIN {$wpdb->prefix}posts as posts ON postmeta.post_id = posts.ID
WHERE posts.post_type LIKE '%product%'
AND postmeta.meta_key = '_sale_price'
AND postmeta.meta_value != ''
ORDER BY posts.ID ASC
$control_process
" );
if( empty( $products_count ) ){
update_option( 'product_prices_update_count', count($results) );
$count = count($results);
} else $count = $products_count;
$remaining = ! empty( $products_count ) && $limit != false ? $count-($offset+$limit) : count($results);
$products_updated = 0;
echo '<div style="border: solid 1px grey; padding: 16px; margin-bottom: 12px;)">
<form class="cart" method="post" enctype="multipart/form-data">';
if( isset( $_POST['prices_updates'] ) && ( $remaining > 0 || ! $limit ) ){
foreach($results as $result){
$post_id = $result->post_id;
$price = $result->price;
// 2. Updating Active and Regular prices
update_post_meta( $post_id, '_price', $price );
update_post_meta( $post_id, '_regular_price', $price );
// 3. Reset Sale price
update_post_meta( $post_id, '_sale_price', '' );
update_post_meta( $post_id, '_sale_price_dates_from', '');
update_post_meta( $post_id, '_sale_price_dates_to', '');
// 4. Refresh product cache
wc_delete_product_transients($post_id);
$products_updated++;
// echo "$post_id ($products_updated), ";
}
}
if( ( ! $limit && ! empty( $products_count ) ) || $remaining <= 0 ){
echo "<p><strong>Process is now finished.</strong><br>
<em>You can remove or comment the code, Thanks</em></p>";
if( isset($_POST['prices_updates'] ) ){
delete_option( 'product_prices_update_offset' );
delete_option( 'product_prices_update_count' );
}
} else {
if( isset( $_POST['prices_updates'] ) ){
update_option( 'product_prices_update_offset', $offset+$limit );
echo "<p>$products_updated products have been updated.<br>";
echo "There is still $remaining remaining products to update.</p>";
} else
echo "<p>There is $remaining products to update.</p>";
$value = empty( $products_count ) ? "Start update" : "Continue update";
echo '<input type="submit" class="button" name="prices_updates" value="'.$value.'" />';
}
echo '</form></div>';
}, 2, 0);
代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件。
此代码已经过测试并且有效。
这是您要查找的纯 MySQL 查询:
首先你必须使用自连接来更新_price
和_regular_price
字段
UPDATE `wp_postmeta` AS a,
`wp_postmeta` AS b
SET a.`meta_value` = b.meta_value
WHERE a.post_id = b.post_id
AND a.meta_key IN ('_price', '_regular_price')
AND b.meta_key = '_sale_price'
AND b.meta_value != ''
AND a.`post_id` IN
(SELECT `ID`
FROM `wp_posts`
WHERE `post_type` = 'product'
AND `post_status` = 'publish');
现在要重置促销价和日期,您必须将其设置为空白
UPDATE `wp_postmeta`
SET `meta_value` = ''
WHERE `meta_key` IN ('_sale_price', '_sale_price_dates_from', '_sale_price_dates_to')
AND `post_id` IN
(SELECT `ID`
FROM `wp_posts`
WHERE `post_type` = 'product'
AND `post_status` = 'publish' );
如果你想删除这些字段,那么使用带有 WHERE 子句的 DELETE 语句,它会解决你的目的。
您还必须删除存储在 _transient_timeout_wc_var_prices_{{post_id}}
下的 wp_options
table 中的 WooCommerce 产品价格缓存和_transient_wc_var_prices_{{post_id}}
在 option_name
DELETE
FROM `wp_options`
WHERE (`option_name` LIKE '_transient_wc_var_prices_%'
OR `option_name` LIKE '_transient_timeout_wc_var_prices_%')
特别感谢@LoicTheAztec 指出产品价格缓存
以上查询已经过测试并且对我有效。
在 运行 这个查询之前做一个数据库备份
希望对您有所帮助!