Stephen S
Forum Replies Created
-
one last important point:
The absence of my meta data, I have verified, is in
$item_meta->display( true, true, '_', "\n" )Because if I print out:
echo '<pre>'; print_r($item_meta->meta); echo '</pre>';interestingly, my key is there at the correct time. So I believe there is a bug in the $item_meta->display() code in Woo.
Well, it does not matter whether I run it with woocommerce_order_status_completed or woocommerce_order_status_completed_notification, the result is identical: my new meta data is NOT found in the
$item_meta->display( true, true, '_', "\n" )string.FWIW, Here is my final code which WILL force it to work, added to the template for email.-order-items.php
// Variation if ( ! empty( $item_meta->meta ) ) { $thrstring = nl2br( $item_meta->display( true, true, '_', "\n" ) ); echo '<br/><small>' . $thrstring . '</small>'; $pos = strpos($thrstring,'signup_code'); $suc = wc_get_order_item_meta( $item_id, 'signup_code' ); if($pos === false) { //error_log("KEY does NOT exist in item_meta display string"); if ($suc) { echo '<br/><small>signup_code: ' . esc_html( $suc ) . '</small>'; } } else { //error_log("KEY DOES exist and is this: $suc"); } }Thanks for the help anyway, I appreciate it.
I am priority 5, and no, it still does not work. (and it isn’t a new order I am emailing, it is a completed order)
well, I tried both, and the problem is the exact same alas. The meta data doesn’t show up until a second order complete unless I add my code.
What do you suggest? I tried woocommerce_order_status_completed but it runs AFTER woocommerce_order_status_completed_notification. And I need this to run when order completes (I think), because woocommerce_payment_complete (for example) does not fire when putting through a manual order, only as a callback from a gateway. I need to run this action AFTER verifying payment, so woocommerce_order_status_completed_notification seems the only logical place, as it would take place after manually completing the order. Do you suggest another place?
The full code is above in the convo, but here it is again with just the snippet in question:
wc_add_order_item_meta( $item_id, $signupkey, $randomcode, true );and this happens in this hook (BEFORE the woocommerce one runs):
add_action( 'woocommerce_order_status_completed_notification', 'mysite_woocommerce_order_status_completed', 5 );I will use part of that with the escape thanks. But I need to keep the array key check, for the reasons I stated above: Even though the meta key exists in the DB when the mail is sent, for some reason it does not show, so I am forced to check for it, and if it is not there output it. The problem of it being duplicated comes if I put an order that already has that meta key through the complete status again in the admin. My code will not create a second meta key in the DB, but in this case it will be read out TWICE. That is why it is necessary to check first in the array, and IF if it is there, NOT print mine (which is a workaround for the fact that the base code somehow is missing the meta key that IS in the db).
This is the crux of the entire problem: Woocommerce is not pulling the meta data that is in the db at the time of emailing this notification. That is why I had to create this workaround in the first place.
I’m not doing that check, that is in WooCommerce code. Are you saying I should remove it?All I am doing is checking for MY meta key in that array, so that I don’t output it twice (which will happen if I “re-complete” an order).
This is Woo code before my changes:
// Variation if ( ! empty( $item_meta->meta ) ) { echo '<br/><small>' . nl2br( $item_meta->display( true, true, '_', "\n" ) ) . '</small>'; }and this is code AFTER my changes:
// Variation if ( ! empty( $item_meta->meta ) ) { echo '<br/><small>' . nl2br( $item_meta->display( true, true, '_', "\n" ) ) . '</small>'; if (!array_key_exists('signup_code',$item_meta->meta)) { $suc = wc_get_order_item_meta( $item_id, 'signup_code' ); if ($suc) { echo '<br/><small>signup_code: ' . $suc . '</small>'; }} }um…where? And how would that be different than what I am doing above? I am using that in my code already.
it would seem so, yes. Although why that would be loaded before the notification goes out or order is completed is beyond me. Do you have a recommendation for a better solution than what I have cobbled together?
Not sure I understand what you are asking. I posted above in the conversation the function I am using to add meta data (in this case a signup code) to my order, just BEFORE the completed order email notification goes out.
The $item_meta in the code just above is woocommerce code inside the email-order-items.php file, I have just added 5 lines to check for my meta inside and get and output it if it is not there.
Well, this is super ugly and probably not the best way to do this, but I have a solution. Here it is, hope it helps some other poor soul. I copied the email-order-items.php template into my theme and made the following change:
// Variation if ( ! empty( $item_meta->meta ) ) { echo '<br/><small>' . nl2br( $item_meta->display( true, true, '_', "\n" ) ) . '</small>'; if (!array_key_exists('signup_code',$item_meta->meta)) { $suc = wc_get_order_item_meta( $item_id, 'signup_code' ); if ($suc) { echo '<br/><small>signup_code: ' . $suc . '</small>'; }} }it will check for a dupe in the meta array and not output if it already exists. I can’t believe this is all necessary, but I can’t find any other pointers anywhere that can address this.
And stranger…when I go into the file that is spitting out the metadata for emails (woocommerce/templates/emails/email-order-items.php) and add a little of my own code to the foreach loop like so:
// Variation if ( ! empty( $item_meta->meta ) ) { echo '<br/><small>' . nl2br( $item_meta->display( true, true, '_', "\n" ) ) . '</small>'; $suc = wc_get_order_item_meta( $item_id, 'signup_code' ); //MY code if ($suc) { //My code echo '<small>signup_code:' . $suc . '</small>'; //MY code } //MY code }it will output on first email completion, so at this point the data is most definitely in the DB already. The problem is, any subsequent email will now have my signup code showing TWICE. This is so frustrating.
I even just tried adding a specific filter to force the meta to the email, and it did not work:
add_filter('woocommerce_email_order_meta_keys', 'my_woocommerce_email_order_meta_keys'); function my_woocommerce_email_order_meta_keys( $keys ) { $keys['Signup Code'] = 'signup_code'; return $keys; }