I'm working on a WordPress project where I'm using Advanced Custom Fields (ACF) to handle custom post metadata. I have a function hooked to WordPress's save_post action that calculates a "commission" based on a "vehicle price" (example) and some other settings. The calculation appears to be working, but I'm unable to save the result back to an ACF field in the vehicles custom post.
Here's my function:
<?php
declare(strict_types=1);
// Set up vehicle_commission calculation and add to vehicle post;
// Use a priority greater than 10
add_action('save_post_vehicles', 'calculate_vehicle_commission', 20, 3);
function calculate_vehicle_commission($post_id, $post, $update) {
// Debugging
error_log("---- Starting Debug ----");
error_log("Hook Fired for Post ID: " . $post_id);
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
error_log("Skipping due to autosave");
return;
}
// Use get_post_type instead of accessing $post->post_type directly
if (get_post_type($post_id) === 'acf') {
error_log("Skipping due to ACF save");
return;
}
if (wp_is_post_revision($post_id)) {
error_log("Skipping due to post revision");
return;
}
if ($update === false) {
error_log("Skipping due to new post creation");
return;
}
// Use is_wp_error to check for errors
$vehicle_price = get_field('field_60c7ac8043c4b', $post_id);
if (is_wp_error($vehicle_price)) {
error_log("Error getting vehicle price: " . $vehicle_price->get_error_message());
return;
}
error_log("Vehicle Price: {$vehicle_price}");
// Use is_wp_error to check for errors
$commission_settings = get_field('commission', 'option');
if (is_wp_error($commission_settings)) {
error_log("Error getting commission settings: " . $commission_settings->get_error_message());
return;
}
// Use wp_parse_args to merge with default settings
$default_settings = [
'initial_rate' => 0,
'reduced_rate' => 0,
'price_point' => 0,
];
$commission_settings = wp_parse_args($commission_settings, $default_settings);
// Extract settings from array
extract($commission_settings);
error_log("Initial Rate: {$initial_rate}");
error_log("Reduced Rate: {$reduced_rate}");
error_log("Price Point: {$price_point}");
if (!is_numeric($vehicle_price) || !is_numeric($initial_rate) || !is_numeric($reduced_rate) || !is_numeric($price_point)) {
error_log("Validation failed. Data dump: " . print_r([
'vehicle_price' => $vehicle_price,
'initial_rate' => $initial_rate,
'reduced_rate' => $reduced_rate,
'price_point' => $price_point,
], true));
return;
}
$commission = 0;
if ($vehicle_price < $price_point) {
$commission = ($vehicle_price * $initial_rate) / 100;
} else {
$commission = ($vehicle_price * $reduced_rate) / 100;
}
// Use number_format_i18n instead of number_format
$commission = number_format_i18n((float)$commission, 2);
error_log("Calculated Commission: " . $commission);
// Using the field key instead of the field name vehicle_commission
$result = update_field('field_64f0d346807d5', $commission, $post_id);
error_log("Meta Updated: " . ($result ? "1" : "0"));
error_log("---- Ending Debug ----");
}
Things I've tried:
Using update_post_meta() to update the field. Checked WordPress and PHP error logs. Used error_log() to output debug information. Debugging shows that the hook is fired and the calculation is made, but update_post_meta() doesn't seem to update the ACF field.
Any idea what I might be missing? Thanks in advance for your help!
It seems that your calculation is executed before the wp save post. You can use acf/save_post
to interact with the saving process.
add_action('acf/save_post', 'calculate_vehicle_commission', 5);
function calculate_vehicle_commission($post_id) {
// add a condition to target the right process
if (!array_key_exists('action', $_POST) and ! array_key_exists('post_type', $_POST)) {
return;
}
if ($_POST['post_type'] != "my_post_type") {
return;
}
...
$commision_rate = $initial_rate;
if ($vehicle_price > $price_point) {
$commision_rate = $reduced_rate;
}
$commission = ($vehicle_price * $commision_rate) / 100;
// Use number_format_i18n instead of number_format
$commission = number_format_i18n((float)$commission, 2);
// Using the field key instead of the field name vehicle_commission
$_POST['acf']['field_64f0d346807d5'] = $commission;
}