It’s possible you’ve followed this tutorial from Woo on how to add columns to admin reports, such as the Orders report. And it’s possible you’ve found that it just doesn’t really work as advertised and is incredibly convoluted. Specifically, the Javascript filter callback you register (addFilter
) is just…never called.
Me too. Here’s something that actually works. I’ll be adding the customer email, a much more useful piece of information than the customer name in many cases, to the Orders report.
Working Code
Here’s some Javascript that will get the job done:
const { addFilter } = wp.hooks;
const addCustomerEmailToOrdersReport = reportTableData => {
const { endpoint, items } = reportTableData;
if ("orders" !== endpoint) {
return reportTableData;
}
reportTableData.headers = [
...reportTableData.headers,
{
label: "Customer email",
key: "customer_email",
},
];
reportTableData.rows = reportTableData.rows.map((row, index) => {
const item = items.data[index];
const newRow = [
...row,
{
display: item.extended_info.customer.email,
value: item.extended_info.customer.email,
},
];
return newRow;
});
return reportTableData;
}
addFilter(
"woocommerce_admin_report_table",
"dev-blog-example",
addCustomerEmailToOrdersReport
);
Code language: JavaScript (javascript)
A couple important notes about this, including how it differs from the Woo/Automattic example:
- On line 1, you’ll notice that I had no interest in setting up a webpack project like the Woo docs imply you should, to say nothing of the fact that once you do, their sample code still doesn’t work (in my experience). Thanks to this hero on Stack Overflow for noting that you don’t need all that, and the
wp-hooks
library is available in the browser. - Lines 3-5 show how you can short-circuit this depending on the report
- Lines 20-23 actually demonstrate a shortcoming with this solution. I was never able to figure out how to add data to the items the WooCommerce REST API returns to the report generator. Fortunately, there’s actually a bunch of information bundled in the response already that the report interface simply doesn’t use. Hopefully what you want can be found there, like the customer email was. If you add a quick
console.table(item)
in thatmap
callback, you can inspect all the included information in theextended_info
property.
Server-Side Reports and the Rest of Woo’s Tutorial
The Woo tutorial actually also includes a bunch of PHP code. To get the above to work, at a minimum, you simply need to enqueue your Javascript file:
add_action('admin_enqueue_scripts', function()
{
wp_enqueue_script('your-handle', plugins_url('/assets/index.js', __FILE__), ['wp-hooks'] );
});
Code language: PHP (php)
Fiddle with the asset path as necessary. I also added wc-csv
as a dependency to try and limit the admin pages where this script is loaded, but there’s probably a better way of doing that. You could also just inline your script.
So what’s all that other PHP code in their tutorial if it doesn’t alter the REST response?
Under most circumstances, the CSV generation for your report seems to happen client-side, in the browser, based on the table you’re viewing. Which is kind of nifty!
But it’s implied that there are circumstances, probably with larger reports, where the report is generated server-side instead. When that’s the case, all that other PHP code is required to generate your columns, including extra ones, and populate their data. No one at Automattic has ever claimed to be very DRY.
If you’re familiar with customizing your way around WooCommerce, the PHP portions of their code probably look pretty familiar, and I’m just trusting it works as advertised.
Leave a Reply