Reopening ticket https://toolset.com/forums/topic/cred_commerce_after_payment_completed-data-finds-legacy-data-to-cause-error/
(tried to add comment to that, but it's closed...).
Hi Waqar,
I have finally had it happen again! Here's the debug report from the code you provided me in the last ticket.
[21-Apr-2022 14:52:14 UTC] Array
(
[user_id] => 487
[transaction_id] => 76729
[extra_data] => Array
(
[0] => Array
(
[cred_product_id] => 925
[cred_form_id] => 928
[cred_post_id] => 75482
)
)
)
So, to explain.
I am User ID 1. Post ID 75482 is one that I have been using to do some tests on the site, owned by user id 1. Its wpcf-xxx-ad-status was set to 'Paused'.
At exactly the timestamp shown above, User ID 487 submitted a Woocommerce order through the website which has NO relation to Toolset (i.e. no cred commerce product, or anything). No other orders have been processed today.
As the log above shows, function xxx_advert_update has fired, based on the user who submitted the unrelated order, and my post ID.
To be absolutely clear, I have NOT submitted form 928 for this post today.
The outcome of this was that 75482 had its wpcf-xxx-ad-status changed to 'live' and its wpcf-xxx-ad-end-date changed, by someone else submitting a Woocommerce order completely unconnected to the post.
This suggests to me that the two extracts from the $data array contain some legacy values, perhaps from the last time someone submitted a cred form.
$form_id = $data['extra_data'][0]['cred_form_id'];
$post_id = $data['extra_data'][0]['cred_post_id'];
So... That being the case, I need an extra condition on my code to ensure that this doesn't happen. Do you have any suggestions?
Thanks.
Hi,
Thank you for contacting us and I'd be happy to assist.
Based on the tests I performed on my website earlier, what you're reporting from your website, seems unusual.
Would it be possible for your to share a clone/snapshot of the website so that I can investigate it on a different server?
( ref: https://toolset.com/faq/provide-supporters-copy-site/ )
I'll be in a better position to guide you with the next steps, accordingly.
Note: I've set your next reply as private.
regards,
Waqar
Thanks for writing back.
Our standard Privacy Policy and GDPR Compliance terms are available at:
https://toolset.com/privacy-policy-and-gdpr-compliance/
The terms for the Privacy and Security while interacting with the support are available here:
https://toolset.com/toolset-support-policy/privacy-security-providing-debug-information-support/
In summary, we don't extract, re-use, or re-distribute any information from client websites and the clone/snapshot of a client website is only requested when it is absolutely required to troubleshoot and investigate any particular case. That clone/snapshot is deleted once this troubleshooting has been completed.
And it doesn't have to be a clone/snapshot from the production website. If you can reproduce the issue in hand on a new test/staging website, you can share the clone/snapshot from that too. We just need to fully understand the setup and the issue to suggest a fix or workaround.
I hope this makes it more clear and I'm setting your next reply as private again.
I understand and respect your decision. We definitely don't want to put you in a position where you have to share something against your legal or contractual obligations.
Since your results/observations are different from the test results that I performed on my website and it shouldn't be happening in the first place. And without access to the website, it wouldn't be possible for us to investigate this abnormality/exception specifically.
Thinking through the requirement, I can suggest a slightly different workflow, which can take care of this distinction between orders placed through Toolset Forms and without them:
1. When a user submits the first post to create a draft Ad post, you can save the created Ad post's ID in a user field "user-draft-post", using a custom function attached to the "cred_save_data" hook.
https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data
2. Next, you can remove the custom function attached to the hook "cred_commerce_after_payment_completed" and instead use the WooCommerce's order status-completed hook, which fires when an order is completed. In this custom function, you can get the user's ID from the completed order and see if any AD post ID exists in the user's "user-draft-post" field. If it exists, it would mean that this order was put forward through the Toolset form and if not, it would mean that the user placed the order directly using the WooCommerce's checkout process only. If the AD post ID is available in the user's "user-draft-post" field, you can update that Ad post's custom fields values, which were previously getting updated by the function attached to the "cred_commerce_after_payment_completed" hook. Once these custom fields have been updated, you can remove the Ad post's ID from the user field "user-draft-post".
Here are some useful guides on using the WooCommerce's order status-completed hook:
hidden link
hidden link
I hope this helps and please let me know if any step or point is not clear.
For more personalized assistance around custom code, you can consider hiring a professional from our list of recommended contractors:
https://toolset.com/contractors/
Hi Waqar,
I'm not surprised your testing doesn't find it - it only seems to happen when someone is editing a post at the exact same time that an order is put through by someone else. It's a very infrequent occurence on our site.
Thanks for the alternative suggestion - unfortunately a user can have several draft ads before they purchase any one of them, which makes the process you suggest too messy, I think.
I was thinking of something much simpler in the existing function to catch the exception: compare [user_id] and author of [cred_post_id]. Would be sufficient?
Thanks for the update and here is the updated code, that checks not only for the specific form ID but also matches the user ID and the post author ID:
add_action('cred_commerce_after_payment_completed','xxx_advert_update',10,1);
function xxx_advert_update($data)
{
// Extract relevant elements from data
$user_id = $data['user_id'];
$form_id = $data['extra_data'][0]['cred_form_id'];
$post_id = $data['extra_data'][0]['cred_post_id'];
$post_author_id = get_post_field( 'post_author', $post_id );
// if form is the Advert Activation Form and the user_id and post author ID match, set status to 'live' after payment and change end date
if ( ($form_id==928) && ($post_author_id == $user_id) ) {
$ad_listing_status="Live";
$ad_status_field="wpcf-xxx-ad-status";
update_post_meta($post_id, $ad_status_field, $ad_listing_status);
$xxx_end_date = time() + (365 * 24 * 60 * 60);
$ad_end_field = "wpcf-xxx-ad-end-date";
update_post_meta($post_id, $ad_end_field, $xxx_end_date);
}
}
Please include this change and hopefully it should take care of that infrequent occurrence.
Hi Waqar,
Thank you for that suggestion, which I will implement. Please could you ask the devs to investigate how $data is populated, in case other situations like this arise... Thanks.
All the best,
Neil
PS Sorry, had to reopen the ticket to post this message - feel free to close it now.
Please free to test this and start a new ticket, in case you need any further assistance.