skip to Main Content

I am trying to add a column to the table provided by WooCommerce Analytics -> Orders, and the item name (not product name) of this order is displayed on it.

sample

I added a hook and tried to extract all names of the item in the order (this hook is what I used before, and it’s useful at the WooCommerce -> Orders table)

/**
 * Adds 'Item Name' column header to 'Orders' page immediately after 'Customer Type' column.
 *
 * @param string[] $columns
 * @return string[] $new_columns
 */
function sv_wc_reps_add_order_item_name_column_header( $columns ) {

    $new_columns = array();

    foreach ( $columns as $column_name => $column_info ) {

        $new_columns[ $column_name ] = $column_info;

        if ( 'customer_type' === $column_name ) {
            $new_columns['order_item_name'] = __( 'Item Name', 'my-textdomain' );
        }
    }

    return $new_columns;
}
add_filter( 'woocommerce_report_orders_export_columns', 'sv_wc_reps_add_order_item_name_column_header', 20 );


/**
 * Adds 'Item Name' value into each column
 */
add_action( 'woocommerce_report_orders_prepare_export_item' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id ) {
    global $the_order, $post;

    if ( 'order_item_name' === $column ) {
        $products_names = []; // Initializing

        // Loop through order items
        foreach ( $the_order->get_items() as $item ) {
            $product = $item->get_product(); // Get the WC_Product object
            $products_names[]  = $item->get_name(); // Store in an array
        }
        // Display
        echo '<ul style="list-style: none;"><li>' . implode('</li><li>', $products_names) . '</li></ul>';
    }
}

But after I saved my code and refreshed the page, the order report table did not add a new column, and when I clicked to download report, the csv file did not display the new column. I think my code is missing some important parts.

2

Answers


  1. While you have correctly added filter for creating new column name, the second part of preparing the value for that column is where you went wrong.

    woocommerce_report_orders_prepare_export_item is a filter hook and not an action hook. In your code you are using it as action hook. Filter hook helps you to modify the output. You may use it as follows:

    add_filter('woocommerce_report_orders_prepare_export_item', 'custom_orders_list_column_content', 10, 2)
    
    function custom_orders_list_column_content( $export_item, $item ){ 
        global $post, $the_order;
    
    $items = $the_order->get_items();
    foreach ( $items as $item ) {
        $product_name[] = $item->get_name();
    }
    
    $export_item['order_item_name'] = $item[$product_name];
    
        return $export_item
    } 
    
    Login or Signup to reply.
  2. I had to do something similar today, here is the documentation and the example I used, and here is how I did it.

    First, clone and start woocommerce-admin:

    cd wp-content/plugins 
    git clone [email protected]:woocommerce/woocommerce-admin.git
    cd woocommerce-admin
    npm run build
    

    Run this command that will set up your extenison:

    npm run create-wc-extension
    

    After you are done with that, run these commands:

    cd ../<your-plugin-name>
    npm install
    npm start
    

    If you managed to get this far, go to the admin panel and activate your plugin. Your file structure should look like this:

    enter image description here

    In the plugins main php file you will have a function by default that includes the js file, after which add your filter like this:

    /**
     * Show the phone number of the customer in the order analytics table
     * @param $results
     * @param $args
     * @return mixed
     */
    add_filter('woocommerce_analytics_orders_select_query', function ($results, $args) {
    
        if ($results && isset($results->data) && !empty($results->data)) {
            foreach ($results->data as $key => $result) {
                $order = wc_get_order($result['order_id']);
                
                //get the order item data here
                // ...........................
                
                //here is how i did it for the customers phone number
                $results->data[$key]['customer_phone'] = $order->get_billing_phone();
            }
        }
    
        return $results;
    }, 10, 2);
    

    Display your newly added column in the CSV

    /**
     * Add the phone number column to the CSV file
     * @param $export_columns
     * @return mixed
     */
    add_filter('woocommerce_report_orders_export_columns', function ($export_columns){
        $export_columns['customer_phone'] = 'Customer phone';
        return $export_columns;
    });
    
    /**
     * Add the phone number data to the CSV file
     * @param $export_item
     * @param $item
     * @return mixed
     */
    add_filter('woocommerce_report_orders_prepare_export_item', function ($export_item, $item){
        $export_item['customer_phone'] = $item['customer_phone'];
        return $export_item;
    }, 10, 2);
    

    Next, you will have to modify the javascript file. Here is how I used it to display the phone number:

    // Import SCSS entry file so that webpack picks up changes
    import './index.scss';
    import {addFilter} from '@wordpress/hooks';
    import {__} from '@wordpress/i18n';
    
    const addTableColumn = reportTableData => {
        if ('orders' !== reportTableData.endpoint) {
            return reportTableData;
        }
    
        const newHeaders = [
            ...reportTableData.headers,
            {
                label: 'Customer phone',
                key: 'customer_phone',
                required: false,
            },
        ];
    
        const newRows = reportTableData.rows.map((row, index) => {
            const item = reportTableData.items.data[index];
            const newRow = [
                ...row,
                {
                    display: item.customer_phone,
                    value: item.customer_phone,
                },
            ];
            return newRow;
        });
    
        reportTableData.headers = newHeaders;
        reportTableData.rows = newRows;
    
        return reportTableData;
    };
    
    addFilter('woocommerce_admin_report_table', 'wg-woocommerce-addon', addTableColumn);
    

    I’d suggest that you process your data server side, and use the javascript to display it, but it’s up to you.
    The new column will be automatically included in the exported csv. You can find a few more examples here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search