Hello ihor!
I struggled with the hook to affect the vendor’s rating. So I took a different approach to the problem and tried to replicate the same POST call from the current review form on the listing page and apparently it is working, these are the steps I have taken so far:
- In functions.php add a hook to create a listing with a custom meta field:
// Hook to create a public listing for each vendor with a custom meta field
add_action('hivepress/v1/models/vendor/update', function($vendor_id) {
// Ensure the hook only runs for the vendor currently being updated
if (get_transient('creating_vendor_listing_' . $vendor_id)) {
return;
}
set_transient('creating_vendor_listing_' . $vendor_id, true, 10);
error_log("Running hook to create public listing for vendor ID: " . $vendor_id);
// Verify that $vendor_id is valid
if (!$vendor_id || !is_numeric($vendor_id)) {
error_log("Vendor ID is invalid or missing.");
delete_transient('creating_vendor_listing_' . $vendor_id);
return;
}
// Check if a public listing with the custom meta field already exists for this specific vendor
$linked_listing = get_posts([
'post_type' => 'hp_listing',
'meta_query' => [
[
'key' => '_linked_vendor_id',
'value' => intval($vendor_id),
'compare' => '='
],
[
'key' => '_is_hidden_review_listing',
'value' => '1',
'compare' => '='
]
],
'post_status' => 'publish',
'numberposts' => 1
]);
// Create the public listing if it doesn't already exist
if (empty($linked_listing)) {
$listing_id = wp_insert_post([
'post_type' => 'hp_listing',
'post_title' => 'Review for Vendor ' . $vendor_id,
'post_status' => 'publish' // Set the status to 'publish' to make it public
]);
if ($listing_id) {
// Add the linked vendor ID
add_post_meta($listing_id, '_linked_vendor_id', $vendor_id, true);
// Add the custom meta field to identify the listing
add_post_meta($listing_id, '_is_hidden_review_listing', '1', true);
error_log("Public listing created with ID: " . $listing_id . " for vendor ID: " . $vendor_id);
} else {
error_log("Error creating listing for vendor ID: " . $vendor_id);
}
} else {
error_log("Public listing already exists for vendor ID: " . $vendor_id);
}
// Remove the transient to allow future executions if necessary
delete_transient('creating_vendor_listing_' . $vendor_id);
});
- Added this code to functions.php to create a form on the woocommerce order page that is only visible when the order has been completed.
add_action('woocommerce_order_details_after_order_table', function($order) {
// Verify the order status
$order_status = $order->get_status();
// Display the form only if the status is "completed" (delivered)
if ($order_status !== 'completed') {
error_log("Order status is '$order_status'. Review form is not displayed.");
return;
}
// Get the vendor ID from the order
$vendor_id = $order->get_meta('hp_vendor');
// Get the public linked listing with the custom meta field
$linked_listing = get_posts([
'post_type' => 'hp_listing',
'meta_query' => [
[
'key' => '_linked_vendor_id',
'value' => intval($vendor_id),
'compare' => '='
],
[
'key' => '_is_hidden_review_listing',
'value' => '1',
'compare' => '='
]
],
'post_status' => 'publish',
'numberposts' => 1
]);
// Display the form only if the linked listing exists
if (!empty($linked_listing)) {
$listing_id = $linked_listing[0]->ID;
echo '<h3>Please rate your satisfaction with the service you received</h3>';
echo '<form id="review-form" method="post" action="#" data-action="' . esc_url(site_url('/wp-json/hivepress/v1/reviews/')) . '">';
echo '<label for="review_content">Your message:</label>';
echo '<textarea id="review_content" name="text"></textarea>';
echo '<label for="review_rating">Satisfaction</label>';
echo '<select id="review_rating" name="rating" required>';
echo '<option value="5">5 - Very satisfied</option>';
echo '<option value="4">4 - Somewhat satisfied</option>';
echo '<option value="3">3 - Neither satisfied nor dissatisfied</option>';
echo '<option value="2">2 - Somewhat dissatisfied</option>';
echo '<option value="1">1 - Not satisfied at all</option>';
echo '</select>';
echo '<input type="hidden" name="listing" value="' . esc_attr($listing_id) . '">';
echo '<button type="submit" name="submit_review">Submit review</button>';
echo '</form>';
} else {
error_log("No linked listing found for vendor ID: $vendor_id.");
}
});
- When said form is submitted, I call a .js file (custom-review-form.js) I saved in wp-content/themes/experthive/js that handles the call from the form.
document.getElementById('review-form').addEventListener('submit', async (event) => {
event.preventDefault(); // Prevent the default form submission behavior
const form = event.target;
const actionUrl = form.getAttribute('data-action'); // Retrieve the action URL from the form's data attribute
const payload = {
listing: form.querySelector('input[name="listing"]').value, // Get the listing ID from the hidden input field
rating: form.querySelector('select[name="rating"]').value, // Get the selected rating value
text: form.querySelector('textarea[name="text"]').value // Get the review text from the textarea
};
try {
const response = await fetch(actionUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json', // Indicate that the payload is JSON
'X-WP-Nonce': wpApiSettings.nonce, // Use the nonce defined in wpApiSettings for authentication
},
body: JSON.stringify(payload) // Convert the payload to a JSON string
});
const result = await response.json();
if (response.ok) {
alert('Review submitted successfully!'); // Notify the user of a successful review submission
window.location.reload(); // Reload the page to reflect the changes
} else {
console.error('Error submitting review:', result); // Log any errors returned by the server
alert('Error submitting review. Please try again.'); // Notify the user of an error
}
} catch (error) {
console.error('Unexpected error:', error); // Log any unexpected errors
alert('Unexpected error. Please try again.'); // Notify the user of an unexpected error
}
});
- Add this little code to functions.php in order to configure that custom js file for WordPress:
function enqueue_custom_scripts() {
wp_enqueue_script('custom-script-js', get_template_directory_uri() . '/js/custom-review-form.js', ['jquery'], '1.0', true);
wp_localize_script('custom-script-js', 'wpApiSettings', [
'root' => esc_url_raw(rest_url()),
'nonce' => wp_create_nonce('wp_rest'),
]);
}
add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');
This has allowed us to review the vendor from the order that was created through a request. The listing that was created in step 1 to store this reviews is still shown as any other listing in the platform… I have still a task to hide it on the listings page, but we are good with having it on the vendors page for people to check out the vendors review.
There are of course lots of things to improve yet, so any feedback or warning with this approach is much appreciated.
Thanks for your patience!