Develop WooCommerce

The official WooCommerce development blog

Extending WC-Admin Reports — February 20, 2020

Extending WC-Admin Reports

This post serves as a guide to extending WC-Admin Reports with a basic UI dropdown, added query parameters, and modification of SQL queries and resulting report data. This example will create a currency selector for viewing the Orders Report based on a specific currency.

Code from this guide can be viewed in the wc-admin code repository.

Getting Started

We’ll be using a local installation of WordPress with WooCommerce and the development version of WC-Admin to take advantage of create-wc-extension as a way to easily scaffold a modern WordPress JavaScript environment for plugins.

In your local install, clone and start WC-Admin if you haven’t already.

cd wp-content/plugins 
git clone
cd woocommerce-admin
npm run build

Once thats working, we can setup the extension folder ready for JavaScript development.

npm run create-wc-extension

After choosing a name, move into that folder and start webpack to watch and build files.

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

Don’t forget to head over to /wp-admin/plugins.php and activate your plugin.

Populating Test Data

Next, set up some orders to have sample data. Using WooCommerce > Settings > Currency, I added three test orders in Mexican Peso, US Dollar, and New Zealand Dollar.

After doing so, check out WC-Admin to make sure the orders are showing up by going to /wp-admin/admin.php?page=wc-admin&period=today&path=%2Fanalytics%2Forders&compare=previous_year. Note that without any modification currency figures show according to what I have currently in WooCommerce settings, which is New Zealand Dollar in this case.

We can confirm each order’s currency by running the following query on the wp_posts table and joining wp_postmeta to gather currency meta values. Results show an order in NZD, USD, and MXN. This query is similar to the one we’ll implement later in the guide to gather and display currency values.

    currency_postmeta.meta_value AS currency
FROM `wp_posts` 
JOIN wp_postmeta currency_postmeta ON wp_posts.ID = currency_postmeta.post_id
WHERE currency_postmeta.meta_key = '_order_currency'
ORDER BY wp_posts.post_date DESC

Add a UI Dropdown

In order to view reports in differing currencies, a filter or dropdown will be needed. We can add a basic filter to reports by adding a configuration object similar to this one from the Orders Report. Feel free to remove default CSS and JavaScript from your new extension.

**There is a known bug in the extension creator scripts such that CSS does not update on changes. The issue to track the fix is here. In the meantime, feel free to dequeue styles by commenting out this line the main PHP file, wp_enqueue_style( 'dev-blog' );.

First, we need to populate the client with data to render the dropdown. The best way to do this is to add data to the wcSettings global. This global can be useful for transferring static configuration data from PHP to the client. In the main PHP file, add currency settings to the Data Registry to populate window.wcSettings.multiCurrency.

function add_currency_settings() {
	$currencies = array(
			'label' => __( 'United States Dollar', 'dev-blog-example' ),
			'value' => 'USD',
			'label' => __( 'New Zealand Dollar', 'dev-blog-example' ),
			'value' => 'NZD',
			'label' => __( 'Mexican Peso', 'dev-blog-example' ),
			'value' => 'MXN',

	$data_registry = Automattic\WooCommerce\Blocks\Package::container()->get(

	$data_registry->add( 'multiCurrency', $currencies );

add_action( 'init', 'add_currency_settings' );

In the console, you can confirm the data has safely made its way to the client.

In index.js create the custom currency filter and add it the Orders Report.

import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';

const addCurrencyFilters = ( filters ) => {
	return [
			label: __( 'Currency', 'dev-blog-example' ),
			staticParams: [],
			param: 'currency',
			showFilters: () => true,
			defaultValue: 'USD',
			filters: [ ...( wcSettings.multiCurrency || [] ) ],


If we check out the Orders Report, we can see our new dropdown. Play around with it and you’ll notice the currency query parameter gets added to the url. If you check out the Network tab, you’ll also see this value included in requests for data used to populate the report. For example, see the requests to orders stats endpoint, /wp-json/wc-analytics/reports/orders/stats. Next we’ll use that query parameter to adjust report results.

Handle Currency Parameters on the Server

Now that our dropdown adds a currency query parameter to requests for data, the first thing we’ll need to do is add the parameter as a query argument to the Orders Data Store and Orders Stats Data Store. Those data stores use query arguments for caching purposes, so by adding our parameter we can be sure a new database query will be performed when the parameter changes. Add the query argument in your main PHP file.

function apply_currency_arg( $args ) {
	$currency = 'USD';

	if ( isset( $_GET['currency'] ) ) {
		$currency = sanitize_text_field( wp_unslash( $_GET['currency'] ) );

	$args['currency'] = $currency;

	return $args;

add_filter( 'woocommerce_analytics_orders_query_args', 'apply_currency_arg' );
add_filter( 'woocommerce_analytics_orders_stats_query_args', 'apply_currency_arg' );

Now that we’re sure a new database query is performed on mutations of the currency query parameter, we can start adding SQL statements to the queries that gather data.

Lets start by adding a JOIN for the orders table, orders stats, and orders chart.

function add_join_subquery( $clauses ) {
	global $wpdb;

	$clauses[] = "JOIN {$wpdb->postmeta} currency_postmeta ON {$wpdb->prefix}wc_order_stats.order_id = currency_postmeta.post_id";

	return $clauses;

add_filter( 'woocommerce_analytics_clauses_join_orders_subquery', 'add_join_subquery' );
add_filter( 'woocommerce_analytics_clauses_join_orders_stats_total', 'add_join_subquery' );
add_filter( 'woocommerce_analytics_clauses_join_orders_stats_interval', 'add_join_subquery' );

Next, add a WHERE clause

function add_where_subquery( $clauses ) {
	$currency = 'USD';

	if ( isset( $_GET['currency'] ) ) {
		$currency = sanitize_text_field( wp_unslash( $_GET['currency'] ) );

	$clauses[] = "AND currency_postmeta.meta_key = '_order_currency' AND currency_postmeta.meta_value = '{$currency}'";

	return $clauses;

add_filter( 'woocommerce_analytics_clauses_where_orders_subquery', 'add_where_subquery' );
add_filter( 'woocommerce_analytics_clauses_where_orders_stats_total', 'add_where_subquery' );
add_filter( 'woocommerce_analytics_clauses_where_orders_stats_interval', 'add_where_subquery' );

And finally, a SELECT clause.

function add_select_subquery( $clauses ) {
	$clauses[] = ', currency_postmeta.meta_value AS currency';

	return $clauses;

add_filter( 'woocommerce_analytics_clauses_select_orders_subquery', 'add_select_subquery' );
add_filter( 'woocommerce_analytics_clauses_select_orders_stats_total', 'add_select_subquery' );
add_filter( 'woocommerce_analytics_clauses_select_orders_stats_interval', 'add_select_subquery' );

Lets head back to the Orders Report and see if it works. You can manipulate the dropdown and see the relevant order reflected in the table.

Finishing Touches

The orders table could use some customisation to reflect the selected currency. We can add a column to display the currency in index.js. The reportTableData argument is an object of headers, rows, and items, which are arrays of data. We’ll need to add a new header and append the currency to each row’s data array.

const addTableColumn = reportTableData => {
	if ( 'orders' !== reportTableData.endpoint ) {
		return reportTableData;

	const newHeaders = [
			label: 'Currency',
			key: 'currency',
	const newRows = ( row, index ) => {
		const item =[ index ];
		const newRow = [
				display: item.currency,
				value: item.currency,
		return newRow;
	} );

	reportTableData.headers = newHeaders;
	reportTableData.rows = newRows;

	return reportTableData;

addFilter( 'woocommerce_admin_report_table', 'dev-blog-example', addTableColumn );

While adding a column is certainly helpful, currency figures in the table and chart only reflect the store currency.

**There currently is no way to alter the currency formats within the chart, summary numbers, and table. This issue proposes adding a filter to allow this customization. I will update this post when that feature becomes available.


In this guide, we added a UI element to manipulate query parameters sent to the server and used those values to modify SQL statements which gather report data. In doing so, we established a way to highly customise WC-Admin reports. Hopefully this example illustrates how the platform can be tailored by extensions to bring a powerful experience to users.

Community Chat #6 Notes —

Community Chat #6 Notes

It’s been a while since we had our January Community Chat. WooCommerce teams have been hard at work preparing the 4.0-beta.1 release, and here comes the summary of our chat #6. We were happy to see 17 people attended the chat and also excited to invite our new Community wrangler Jonathan Wold.

If case you missed this chat, you still can read the full backscroll of the dev chat here or read further for a quick summary.

Continue reading
Storefront 2.5.4 release notes — February 19, 2020

Storefront 2.5.4 release notes

Storefront 2.5.4 has been tagged for release and uploaded to

Here’s what’s changed (pulled directly from the changelog):

* Feature - Add support for new wp_body_open hook.
* Fix - Customizer: Move "Product Page" settings into WooCommerce tab.
* Fix - Blocks: Ensure product grid blocks don't wrap unnecessarily.
* Fix - Editor: Fix layout issue with image block placeholder buttons.
* Fix - Improve "Sale!" badge legibility by using white background (was transparent).
* Fix - Improve accessibility of screen reader skip links.
* Fix - Prevent search engine indexing of add-to-cart link.
* Fix - Ensure password visibility button is not hidden on login form.
* Fix - Allow translation of "or" in admin notice for activating WooCommerce plugin.
* Fix - Remove underline from @wordpress/components button links.
* Fix - Use noreferrer on footer credit link.
* Dev - Update npm dev dependencies.
* Dev - Automatically exclude storefront folder & zip when preparing release.

Download the latest release of Storefront here or venture over to Dashboard → Updates to update your theme from WordPress.

As usual, if you spot any other issues, please log them in detail on Github.


WooCommerce 3.9.2 Security Release — February 13, 2020

WooCommerce 3.9.2 Security Release

WooCommerce 3.9.2 is now available. This minor release includes two security fixes. Additionally — by popular demand! — it restores the default behavior of the “Shipping destination” option.

Since this release contains fixes to improve security, we encourage you to update your sites as soon as possible.

Here’s the full list of fixes:

* Security - Show a notice when a logged-in customer pays for a guest order.
* Security - Disallow links in coupon error messages.
* Fix - Restored the default behavior of the "Shipping destination" option. #25571

Download the latest release of WooCommerce here or visit Dashboard → Updates to update the plugin from your WordPress admin screen.
As usual, if you spot any other issues in WooCommerce core, please log them in detail on GitHub. Discover security issue? Please submit a report via HackerOne.

WooCommerce 4.0 Beta 1 — February 10, 2020

WooCommerce 4.0 Beta 1

Hello everyone! We are excited to announce that WooCommerce 4.0 is now available for beta testing!

As we’ve announced last week, 4.0 will be a release that brings some breaking changes, but there’s only a small number of those. We don’t expect the update to cause a lot of problems, as the only truly breaking change is including Action Scheduler 3.0 which already runs on more than 10,000 sites with WooCommerce Subscriptions.

Even though the changes are not large, we’re going to test the pre-release versions as much as possible on a broad spectrum of configurations and hosting platforms. To help us out and test the beta release of 4.0, you can download it directly from, or install our WooCommerce Beta Tester Plugin which allows you to easily test out this beta and all future beta and release candidates.

What is new in 4.0?

4.0 is the first major release of 2020 and we’re excited to include the new version of WooCommerce Admin in this release. WooCommerce Admin is the first step towards a more modern JavaScript-driven experience of WooCommerce core.

Read further for more details!

Continue reading