Skip to content

Instantly share code, notes, and snippets.

@tamarazuk
Last active August 31, 2018 04:42
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save tamarazuk/46e66064a40c4a611397 to your computer and use it in GitHub Desktop.
Customer/Order CSV Export: Separate item meta into multiple columns in the Default – One Row per Item format
<?php // only copy this line if needed
/**
* The use of this snippet requires at least WooCommerce 3.2
*/
/**
* Alter the column headers for the orders CSV to split item_meta into separate columns
*
* Note that this change is only applied to the Default - One Row per Item format
*
* @param array $column_headers {
* column headers in key => name format
* to modify the column headers, ensure the keys match these and set your own values
* }
* @param WC_Customer_Order_CSV_Export_Generator $csv_generator, generator instance
* @return array column headers in column_key => column_name format
*/
function sv_wc_csv_export_order_headers_split_item_meta( $column_headers, $csv_generator ) {
if ( sv_wc_csv_export_is_one_row( $csv_generator ) ) {
// remove item_meta column
unset( $column_headers['item_meta'] );
$item_meta_headers = array();
// loop over order ids
foreach ( $csv_generator->ids as $order_id ) {
$order = wc_get_order( $order_id );
// get line items
foreach ( $order->get_items() as $item ) {
// get item meta
foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) {
$item_meta_headers[ $meta->key ] = 'item_meta: ' . $meta->key;
}
}
}
$column_headers = sv_wc_array_insert_after( $column_headers, 'item_total', $item_meta_headers );
}
return $column_headers;
}
add_filter( 'wc_customer_order_csv_export_order_headers', 'sv_wc_csv_export_order_headers_split_item_meta', 10, 2 );
/**
* CSV Order Export Row for One Row per Item.
*
* Filter the individual row data for the order export to add data for each item meta key
*
* @param array $order_data {
* order data in key => value format
* to modify the row data, ensure the key matches any of the header keys and set your own value
* }
* @return array the modified order data
*/
function sv_wc_csv_export_order_row_one_row_per_item_split_item_meta( $order_data ) {
$item = new WC_Order_Item_Product( $order_data['item_id'] );
foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) {
$order_data[ $meta->key ] = $meta->value;
}
return $order_data;
}
add_filter( 'wc_customer_order_csv_export_order_row_one_row_per_item', 'sv_wc_csv_export_order_row_one_row_per_item_split_item_meta', 10 );
/** Helper Functions **********************************************************/
if ( ! function_exists( 'sv_wc_array_insert_after' ) ) :
/**
* Insert the given element after the given key in the array
*
* @param array $array array to insert the given element into
* @param string $insert_key key to insert given element after
* @param array $element element to insert into array
* @return array
*/
function sv_wc_array_insert_after( Array $array, $insert_key, Array $element ) {
$new_array = array();
foreach ( $array as $key => $value ) {
$new_array[ $key ] = $value;
if ( $insert_key == $key ) {
foreach ( $element as $k => $v ) {
$new_array[ $k ] = $v;
}
}
}
return $new_array;
}
endif;
if ( ! function_exists( 'sv_wc_csv_export_is_one_row' ) ) :
/**
* Helper function to check the export format
*
* @param \WC_Customer_Order_CSV_Export_Generator $csv_generator the generator instance
* @return bool - true if this is a one row per item format
*/
function sv_wc_csv_export_is_one_row( $csv_generator ) {
$one_row_per_item = false;
if ( version_compare( wc_customer_order_csv_export()->get_version(), '4.0.0', '<' ) ) {
// pre 4.0 compatibility
$one_row_per_item = ( 'default_one_row_per_item' === $csv_generator->order_format || 'legacy_one_row_per_item' === $csv_generator->order_format );
} elseif ( isset( $csv_generator->format_definition ) ) {
// post 4.0 (requires 4.0.3+)
$one_row_per_item = 'item' === $csv_generator->format_definition['row_type'];
}
return $one_row_per_item;
}
endif;
@tonydjukic
Copy link

Where would we place this code in the existing WooCommerce Order/Customer CSV Export extension?

@patrickhills
Copy link

@tonydjukic put it in your child theme's functions.php file and it'll work.

@altruistas
Copy link

Hi, i have question:
I have meta value: Paslėpti 3 vnt. (03) 50.00 €
is it posible to separate in 2 columns somehow to be like:
col1 | col2
Paslėpti 3 vnt. | (03)
and rest "50.00 €" dont show.
Thanks in advance.

@MarkSch521
Copy link

After putting this code in my child theme functions. I get a fatal error. for function sv_wc_csv_export_order_headers_split_item_meta

@zamson
Copy link

zamson commented Apr 19, 2016

( ! ) Notice: get_formatted_legacy is deprecated since version 2.4! Use Item Meta Data is being called with legacy arguments instead.

Any input? Trying to wrap my head around this.

@dcolumbus
Copy link

Since updating WooCommerce, I'm now getting:

Notice: get_formatted_legacy is deprecated since version 2.4! Use Item Meta Data is being called with legacy arguments instead.

I'm thinking that is has to do with the use of WC_Order_Item_Meta within the sv_wc_csv_export_order_row_one_row_per_item_split_item_meta method...

Can someone please advise?

Thanks!

@aislingkelly
Copy link

Hi there,

Love this snippet. So helpful and I've been using it for a while! However since updating WooCommerce and Customer/Order Export to the latest versions it seems to have stopped working. I've copied the latest version of the snippet today into functions.php but when exporting in Default – One Row per Item format I get the error:

"Something unexpected happened while exporting. Your export may or may have not completed. Please check the Export List and your site error log for possible clues as to what may have happened."

Any ideas what might be going wrong?

Thanks!

@dcolumbus
Copy link

@aislingkelly

  1. Make sure in Settings that Order Export Format is set to "Default - One Item per row"
  2. Replace "order_format" with "export_format" ... order_format is deprecated.
  3. Make sure your PHP Memory Limit is increased to something like 128M.

wp-config.php:
define('WP_MEMORY_LIMIT', '128M');

@pennstar
Copy link

@aislingkelly did you get this to work? I've been using this fantastic snippet for ages but now the item_meta field contains all of the product add-on information, instead of separating the item meta. I've tried @dcolumbus' suggestions but they've made no difference. The item_meta will only show in the CSV if the setting is on custom, not Default - one row per item (NB in the column tab it is set to "a row represents a single line item".

I'm sure I've done something wrong! I've tried seemingly every combination. Any help v much appreciated!

@overhaulics
Copy link

@pennstar ever have any luck figuring this out. I am in the same boat as you. Tried @dcolumbus' suggestion and now don't see the item_meta column in the export at all and don't have any of the new info in columns either.

@KamGraphica
Copy link

This solution looks great. I have to abstract order line items to their own columns for mapping into another system. I implemented the provided code on my theme's functions.php file and export. No luck, the line_item data is not split into its own columns.

Please advise.

@alai6039
Copy link

quick stupid question. I am a newbie:

Does this snippet allow me to see each item as a separate order? At checkout, I still want the customer to feel like he is only making one order, but when the customer goes to their "orders" they can see all the item as separate orders. This way the user can easily reach out to customer support based on that one product. When the Admin sees the request and wants to issue a refund, he/she can just focus on that one order/product.

@jpgninja
Copy link

jpgninja commented Aug 6, 2017

This is really slick. Needed to chop up a row of key/value pairs into columns, and stumbled across this gist which was 90% there for what I needed. You rock! 🙌

@Pransh20
Copy link

Pransh20 commented Dec 7, 2017

@dcolumbus
I am facing the same issue you pointed with the function WC_Order_Item_Meta.
It is deprecated now in woocommerce update

Were you able to change this script accordingly?

@bradholmes-studio
Copy link

really need this has anyone got this working

@tamarazuk
Copy link
Author

Sorry everyone, GitHub doesn't notify people about comments on gists. I have updated this to work with the latest Customer/Order/Coupon CSV Export version and WooCommerce 3.2

@frikinelmo
Copy link

THANK YOU THANK YOU THANK YOU!

@davidallenlewis
Copy link

davidallenlewis commented Feb 27, 2018

This only sort of works for me. It does separate the item_meta into separate columns but it creates a whole new set of columns for every order instead of just using one set of item_meta columns for all the orders. This results in so many columns that my spreadsheet software can't even create enough columns to import the CSV (Apple Numbers seems to be limited to 255 columns)

screen shot 2018-02-27 at 9 03 57 am

@davidallenlewis
Copy link

Replying to my post above... Tamara fixed this an updated the GIST. The issue was that the array keys being generated for the injected data were just too specific. Removing the meta_id from lines 37 and 67 fixed it!

@plastisound
Copy link

almost all my fields are empty!!! but I have a lot of attributes!!! any reason?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment