我想更改某些类别产品的折扣(销售价格),但无论我try 什么代码:

  1. 仅在父类别中运行良好
  2. 不幸的是,相同类别的翻译为完全不同的产品设置了折扣
  3. 折算折扣乘以汇率(例如,汇率为4:1时,价值为100的产品从10%的折扣变为40%的折扣)

如何让它在WPML/WCML翻译之间更换相同的产品并保持相同的价格?谢谢你的建议

///automatic randomized discounts 
// Define a custom 1-minute interval
function custom_1_minute_interval($schedules) {
    $schedules['1minute'] = array(
        'interval' => 60, // 1 minute in seconds
        'display'  => __('Every 1 Minute'),
    );
    return $schedules;
}
add_filter('cron_schedules', 'custom_1_minute_interval');

// Schedule the event to run the custom function every 1 minute
add_action('init', 'schedule_custom_function');

function schedule_custom_function() {
    if (!wp_next_scheduled('every_1_minute_custom_function')) {
        wp_schedule_event(time(), '1minute', 'every_1_minute_custom_function');
    }
}

add_action('every_1_minute_custom_function', 'custom_function_to_manage_discounts');

function custom_function_to_manage_discounts() {
    // Define the log file
    $log_file = WP_CONTENT_DIR . '/promo.log';

    // Open the log file for writing (creates a new file if it doesn't exist)
    $log_handle = fopen($log_file, 'a');

    // Check if the log file was successfully opened
    if ($log_handle) {
        // Log a timestamp indicating the start of the custom function
        fwrite($log_handle, date('[d-M-Y H:i:s]') . " Custom function started." . PHP_EOL);

        // Get all products in category ID 29 for the original language version
        $category_id = 29;
        $args = array(
            'post_type' => 'product',
            'posts_per_page' => -1,
            'tax_query' => array(
                array(
                    'taxonomy' => 'product_cat',
                    'field'    => 'id',
                    'terms'    => $category_id,
                    'include_children' => true,
                ),
            ),
        );

        $products = get_posts($args);

        if ($products) {
            // Log the product IDs retrieved from the category
            $product_ids_list = array();
            foreach ($products as $product) {
                $product_ids_list[] = $product->ID;
            }
            fwrite($log_handle, date('[d-M-Y H:i:s]') . " Product IDs Retrieved from Category ID {$category_id}: " . implode(', ', $product_ids_list) . PHP_EOL);

            // Calculate the number of products to apply discounts to (25% of total)
            $discount_count = ceil(0.25 * count($products));

            // Shuffle the products array randomly
            shuffle($products);

            // Iterate through products to clear discounts for all
            foreach ($products as $product) {
                // Get the product object
                $product_obj = wc_get_product($product->ID);

                // Clear discount price (sale price)
                $product_obj->set_sale_price('');
                $product_obj->set_date_on_sale_from('');
                $product_obj->set_date_on_sale_to('');

                // Log the action in the log file
                fwrite($log_handle, date('[d-M-Y H:i:s]') . " Cleared discount for Product ID: {$product->ID}" . PHP_EOL);

                // Save the product to trigger WooCommerce cache refresh
                $product_obj->save();
            }

            // Apply discounts to a random 25% of products
            for ($i = 0; $i < $discount_count; $i++) {
                $product = $products[$i];

                // Get the regular price
                $regular_price = get_post_meta($product->ID, '_regular_price', true);

                // Calculate the new discount price (90% of the regular price)
                $new_discount_price = $regular_price * 0.9;

                // Get the product object
                $product_obj = wc_get_product($product->ID);

                // Set the new discount price (sale price)
                $product_obj->set_sale_price($new_discount_price);
                $product_obj->set_date_on_sale_from(time());

                // Calculate the new price as a separate variable
                $new_price = $regular_price * 0.9;

                // Log the action in the log file with the new price
                fwrite($log_handle, date('[d-M-Y H:i:s]') . " Applied discount for Product ID: {$product->ID}, New Price: {$new_price}" . PHP_EOL);

                // Save the product to trigger WooCommerce cache refresh
                $product_obj->save();
            }
        }

        // Log a timestamp indicating the completion of the custom function
        fwrite($log_handle, date('[d-M-Y H:i:s]') . " Custom function completed." . PHP_EOL);

        // Close the log file
        fclose($log_handle);
    }
}

Update: Code which works on my staging but not production:

// Define a custom 1-minute interval
function custom_1_minute_interval($schedules) {
    $schedules['1minute'] = array(
        'interval' => 60, // 1 minute in seconds
        'display'  => __('Every 1 Minute'),
    );
    return $schedules;
}
add_filter('cron_schedules', 'custom_1_minute_interval');

// Schedule the event to run the custom function every 1 minute
add_action('init', 'schedule_custom_function');

function schedule_custom_function() {
    if (!wp_next_scheduled('every_1_minute_custom_function')) {
        wp_schedule_event(time(), '1minute', 'every_1_minute_custom_function');
    }
}

add_action('every_1_minute_custom_function', 'custom_function_to_manage_discounts');

function custom_function_to_manage_discounts() {
    // Define the log file
    $log_file = WP_CONTENT_DIR . '/promo.log';

    // Open the log file for writing (creates a new file if it doesn't exist)
    $log_handle = fopen($log_file, 'a');

    // Check if the log file was successfully opened
    if ($log_handle) {
        // Log a timestamp indicating the start of the custom function
        fwrite($log_handle, date('[d-M-Y H:i:s]') . " Custom function started." . PHP_EOL);

        // Get all products in category ID 29 for the original language version
        $category_id = array(2465); // <== Changed variable as an array

        $posts_ids = get_posts( array(
            'post_type'      => 'product',
            'post_status'    => 'publish', // <== Added (published products only)
            'posts_per_page' => -1,
            'fields'         => 'ids', // <== Get an array of product IDs
            'orderby'        => 'rand', // <== Random order (replace shuffle)
            'tax_query'      => array(
                array(
                    'taxonomy' => 'product_cat',
                    'field'    => 'term_id', // <== Mistake corrected (not 'id')
                    'terms'    => $category_id,
                    'include_children' => true,
                ),
            ),
        ) );

        if ( count($posts_ids) > 0 ) {
            fwrite($log_handle, date('[d-M-Y H:i:s]') . " Product IDs Retrieved from Category ID {$category_id}: " . implode(', ', $posts_ids) . PHP_EOL);

            // Calculate the number of products to apply discounts to (25% of total)
            $discount_count = ceil(0.25 * count($posts_ids));

            // Loop through product Ids
            foreach ($posts_ids as $post_id) {
                $product = wc_get_product($post_id); // Get the product object

                // Reset sale price from discounted products only
                if ( $product->get_sale_price() > 0 ) {
                    $reg_price = $product->get_regular_price(); // get regular price
                    $product->set_price($reg_price); // Set back the regular price
                    // Clear sale price
                    $product->set_sale_price('');
                    $product->set_date_on_sale_from('');
                    $product->set_date_on_sale_to('');

                    $product->save(); // Save the product to trigger WooCommerce cache refresh

                    do_action( 'wpml_sync_custom_field', $post_id, '_price' ); // refresh price for translations
                    do_action( 'wpml_sync_custom_field', $post_id, '_sale_price' ); // refresh sale price for translations
                    do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_from' ); // refresh field for translations
                    do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_to' ); // refresh field for translations

                    // Log the action in the log file
                    fwrite($log_handle, date('[d-M-Y H:i:s]') . " Cleared discount for Product ID: {$post_id}" . PHP_EOL);
                }
            }

            // Apply discounts to a random 25% of products
            for ($i = 0; $i < $discount_count; $i++) {
                $post_id    = $posts_ids[$i];
                $product    = wc_get_product($posts_ids[$i]); // Get the product object
                $reg_price  = $product->get_regular_price(); // get regular price
                $sale_price = $reg_price * 0.9; // Calculate 10% discount

                // Set the new discount price (sale price)
                $product->set_price($sale_price);
                $product->set_sale_price($sale_price);
                $product->set_date_on_sale_from(time());

                $product->save(); // Save the product to trigger WooCommerce cache refresh

                do_action( 'wpml_sync_custom_field', $post_id, '_price' ); // refresh price for translations
                do_action( 'wpml_sync_custom_field', $post_id, '_sale_price' ); // refresh sale price for translations
                do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_from' ); // refresh field for translations
                do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_to' ); // refresh field for translations

                // Log the action in the log file with the new price
                fwrite($log_handle, date('[d-M-Y H:i:s]') . " Applied discount for Product ID: {$post_id}, New Price: {$sale_price}" . PHP_EOL);
            }
        }
        // Log a timestamp indicating the completion of the custom function
        fwrite($log_handle, date('[d-M-Y H:i:s]') . " Custom function completed." . PHP_EOL);
        fclose($log_handle); // Close the log file
    }
}

推荐答案

您的代码中有一些错误.

我首先开始在WPML网站上搜索,我遇到了多个支持线程相关的产品(或帖子)同步翻译:

要使用的操作钩子是wpml_sync_all_custom_fields,用于刷新/同步帖子(或产品)翻译的所有元数据.

然后再搜索,我找到了wpml_sync_custom_field hook个允许"Sync custom field value across all translations of a given post"的.

以下是您的主函数的重新访问的代码版本,它应该也会更新/刷新产品翻译:

add_action('every_1_minute_custom_function', 'custom_function_to_manage_discounts');
function custom_function_to_manage_discounts() {
    // Define the log file
    $log_file = WP_CONTENT_DIR . '/promo.log';

    // Open the log file for writing (creates a new file if it doesn't exist)
    $log_handle = fopen($log_file, 'a');

    // Check if the log file was successfully opened
    if ($log_handle) {
        // Log a timestamp indicating the start of the custom function
        fwrite($log_handle, date('[d-M-Y H:i:s]') . " Custom function started." . PHP_EOL);

        // Get all products in category ID 29 for the original language version
        $category_id = array(29); // <== Changed variable as an array

        $posts_ids = get_posts( array(
            'post_type'      => 'product',
            'post_status'    => 'publish', // <== Added (published products only)
            'posts_per_page' => -1,
            'fields'         => 'ids', // <== Get an array of product IDs
            'orderby'        => 'rand', // <== Random order (replace shuffle)
            'tax_query'      => array(
                array(
                    'taxonomy' => 'product_cat',
                    'field'    => 'term_id', // <== Mistake corrected (not 'id')
                    'terms'    => $category_id,
                    'include_children' => true,
                ),
            ),
        ) );

        if ( count($posts_ids) > 0 ) {
            fwrite($log_handle, date('[d-M-Y H:i:s]') . " Product IDs Retrieved from Category ID {$category_id}: " . implode(', ', $posts_ids) . PHP_EOL);

            // Calculate the number of products to apply discounts to (25% of total)
            $discount_count = ceil(0.25 * count($posts_ids));

            // Loop through product Ids
            foreach ($posts_ids as $post_id) {
                $product = wc_get_product($post_id); // Get the product object

                // Reset sale price from discounted products only
                if ( $product->get_sale_price() > 0 ) {
                    $reg_price = $product->get_regular_price(); // get regular price
                    $product->set_price($reg_price); // Set back the regular price
                    // Clear sale price
                    $product->set_sale_price('');
                    $product->set_date_on_sale_from('');
                    $product->set_date_on_sale_to('');

                    $product->save(); // Save the product to trigger WooCommerce cache refresh

                    do_action( 'wpml_sync_custom_field', $post_id, '_price' ); // refresh price for translations
                    do_action( 'wpml_sync_custom_field', $post_id, '_sale_price' ); // refresh sale price for translations
                    do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_from' ); // refresh field for translations
                    do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_to' ); // refresh field for translations

                    // Log the action in the log file
                    fwrite($log_handle, date('[d-M-Y H:i:s]') . " Cleared discount for Product ID: {$post_id}" . PHP_EOL);
                }
            }

            // Apply discounts to a random 25% of products
            for ($i = 0; $i < $discount_count; $i++) {
                $post_id    = $posts_ids[$i];
                $product    = wc_get_product($posts_ids[$i]); // Get the product object
                $reg_price  = $product->get_regular_price(); // get regular price
                $sale_price = $reg_price * 0.9; // Calculate 10% discount

                // Set the new discount price (sale price)
                $product->set_price($sale_price);
                $product->set_sale_price($sale_price);
                $product->set_date_on_sale_from(time());

                $product->save(); // Save the product to trigger WooCommerce cache refresh

                do_action( 'wpml_sync_custom_field', $post_id, '_price' ); // refresh price for translations
                do_action( 'wpml_sync_custom_field', $post_id, '_sale_price' ); // refresh sale price for translations
                do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_from' ); // refresh field for translations
                do_action( 'wpml_sync_custom_field', $post_id, '_sale_price_dates_to' ); // refresh field for translations

                // Log the action in the log file with the new price
                fwrite($log_handle, date('[d-M-Y H:i:s]') . " Applied discount for Product ID: {$post_id}, New Price: {$sale_price}" . PHP_EOL);
            }
        }
        // Log a timestamp indicating the completion of the custom function
        fwrite($log_handle, date('[d-M-Y H:i:s]') . " Custom function completed." . PHP_EOL);
        fclose($log_handle); // Close the log file
    }
}

代码位于您的子主题的unctions.php文件中(或在插件中).这可能会奏效.


Addition-WPML:从帖子ID获取翻译的帖子ID

使用"get all other languages for a post"中的代码,您可以从父ID获得转换后的产品ID.我已经将代码嵌入到一个单独的可重用函数中:

function get_wpml_translated_post_ids( $post_id ) {
    $type = apply_filters( 'wpml_element_type', get_post_type( $post_id ) );
    $trid = apply_filters( 'wpml_element_trid', false, $post_id, $type );
    $product_ids  = [];  
    $translations = apply_filters( 'wpml_get_element_translations', array(), $trid, $type );
    foreach ( $translations as $lang => $data ) {
        $product_ids[] = $data->element_id;
    }
    return $product_ids;
}

代码位于您的子主题的unctions.php文件中(或在插件中).

Php相关问答推荐

如果再次调用SESSION_START(),会话.gc-max是否会重新启动?或者它是从第一次创建会话开始计算的?

具有重叠捕获组的PHP正则表达式

PHP-带POST验证的for循环

在WooCommerce管理中 for each 运输方法设置添加自定义字段

PHP -将字符串拆分为两个相等的部分,但第二个字符串中的单词更多

未收到Strava WebHook事件数据

无额外字段的Laravel同步

如何使用PHP从TXM(XML)标记中读取特定属性

按类别层次 struct 过滤 Laravel 集合

如何从 URL 核心 PHP 中的 API 获取 JSON?

PHP 中使用 JSON 的自定义会话处理程序会因错误而 destruct 会话

为什么 debug_backtrace() 不返回任何内容?

为WooCommerce中的Guest用户保存唯一的客户代码到订单中

Xdebug 不会在断点处停止

适当的时区处理 Laravel / Carbon

如何限制for循环php中的条目数

hasOne/belongsToMany 或多对多

Laravel - 关联与设置观察者事件的 ID

路由未定义的 laravel 导出

如何简化 php API 中的格式化数组列表数据以提供 React Native 部分列表