Your question should be specific to WordPress. Generic PHP/JS/SQL/HTML/CSS questions might be better asked at Stack Overflow or another appropriate Stack Exchange network site. Third-party plugins and themes are off-topic for this site; they are better asked about at their developers' support routes.
Closed 6 years ago.
Improve this questionI'm trying to make a plugin that merges two carts into one.
I am doing the following:
$old_order = wc_get_order($old_order_id);
duplicate_line_items($new_order, $old_order);
//re-fetch order to make sure changes aren't lost.
$new_order = $wc_get_order($new_order->get_id());
$new_order->calculate_totals();
$new_order->save_meta_data();
$new_order->save();
My duplicate_line_items()
function looks like this:
function duplicate_line_items($source_order, $new_order){
foreach ($source_order->get_items() as $item){
$new_order->add_item($item);
}
$new_order->apply_changes();
$new_order->save();
}
When I run this code, the items do not display in the admin view of the "new" order (the destination order), nor do they show up in the database.
I do see that per the WC_Order::add_item()
docs, "The order item will not persist until save.", but I am saving the order, several times.
Am I missing a step here or something?
Thanks!
Closed. This question is off-topic. It is not currently accepting answers.Your question should be specific to WordPress. Generic PHP/JS/SQL/HTML/CSS questions might be better asked at Stack Overflow or another appropriate Stack Exchange network site. Third-party plugins and themes are off-topic for this site; they are better asked about at their developers' support routes.
Closed 6 years ago.
Improve this questionI'm trying to make a plugin that merges two carts into one.
I am doing the following:
$old_order = wc_get_order($old_order_id);
duplicate_line_items($new_order, $old_order);
//re-fetch order to make sure changes aren't lost.
$new_order = $wc_get_order($new_order->get_id());
$new_order->calculate_totals();
$new_order->save_meta_data();
$new_order->save();
My duplicate_line_items()
function looks like this:
function duplicate_line_items($source_order, $new_order){
foreach ($source_order->get_items() as $item){
$new_order->add_item($item);
}
$new_order->apply_changes();
$new_order->save();
}
When I run this code, the items do not display in the admin view of the "new" order (the destination order), nor do they show up in the database.
I do see that per the WC_Order::add_item()
docs, "The order item will not persist until save.", but I am saving the order, several times.
Am I missing a step here or something?
Thanks!
You have your duplicate_line_items()
function written so that the items from the first parameter, $source_order
are added to the second parameter, $new_order
, but in your first block of code you're passing the old order as the 2nd parameter:
duplicate_line_items($new_order, $old_order);
So all the items from $new_order
are being added to $old_order
, not the other way round.
Make sure you're using the variables consistently:
duplicate_line_items( $old_order, $new_order );
Maybe name your variables in duplicate_line_items()
a bit more clearly too:
function duplicate_line_items( $source_order, $target_order ) {
foreach ( $source_order->get_items() as $item ) {
$target_order->add_item( $item );
}
$target_order->save();
}
So with those two changes you're properly setting $old_order
as the $source_order
and $new_order
as the $target_order
.
I've solved my issue, I misunderstood the functionality of wc_add_order_item()
's item_array
parameter, and assumed that was for the item data.
The working function:
/**
*
* Copy all line items from
*
* @param $source_order \WC_Order
* @param $destination_order \WC_Order
*/
private function duplicate_line_items($source_order, $destination_order){
//get all item types.
foreach ($source_order->get_items(['line_item', 'shipping', 'tax']) as $item_id => $item){
$data = $item->get_data();
$data['order_id'] = $destination_order->get_id();
$new_item_id = wc_add_order_item($destination_order->get_id(), ['order_item_name' => $item->get_name(), 'order_item_type' => $item->get_type()]);
$meta = wc_get_order_item_meta($item_id);
foreach ($meta as $meta_key => $meta_value){
//needed incase there are multiple values for the same key: eg, ingredients.
foreach ($meta_value as $number => $raw_value){
wc_add_order_item_meta($new_item_id, $meta_key, $raw_value);
}
}
}
}
Hopefully this helps someone else later :)