Change the sort order of WooCommerce Grouped Products

WooCommerce has a small army of filters and hooks that you could customize almost every aspect of the plugin. If you have a grouped product the default display method is by menu_order. But recently, someone wanted to display the grouped items by the date they were published.

This is very easily accomplished by filtering the $args being passed through the woocommerce_grouped_children_args filter. WooCommerce queries for the child products in the grouped product via WP_Query so you can essentially use any parameter supported by WP_Query. In this case, we only need to change the orderby parameter to date and since we’d like the most recent items first, we swap the order parameter to descending.

If you need help understanding filters, I wrote what I think is a pretty good tutorial on how to use filters. It took me a while to understand them, but once you do they are very powerful and let you make a lot of customizations.

If you aren’t seeing any changes, chances are that the grouped product’s children have already been stored in a transient. You will need to delete this transient to see changes right away. You can clear all WooCommerce product transients via the Admin. Navigate to WooCommerce>System Status>Tools and click on the button to clear transients.

Hustling for Handball

When I am not coding WooCommerce-related things, my other career as an international athlete. From a purely logical standpoint it has been a terrible career choice because it tends to pay negatively and has put a lot of wear and tear on my body. There have been times when I’ve seriously considered buying a cane because my feet hurt so badly. There was also that time I dislocated my sterno-clavicular joint and couldn’t raise my arm over my head. My clavicles are permanently uneven now. But at the same time, I’ve represented my country in international sports for 10 years, which is something very few people get to do. WooCommerce definitely pays the bills, but as one of my teammates put it, handball is my side hustle.

Four defenders in frame? Someone must be open, but I'm so desperate for action shots that I will post one where I almost assuredly should have passed.
Four defenders in frame? Someone must be open, but I’m so desperate for action shots that I will post one where I almost assuredly should have passed.

I play handball on the USA national team and recently, we placed third at the North American and Caribbean Championships in Puerto Rico, which qualified us to participate in the Pan-American Championships this month in Cuba. Unfortunately, getting to Cuba is not cheap and Handball is still almost completely unknown in the USA so we’re not bringing in the big sponsors. We’ve been training for these games for 2 years. Many of my teammates moved to Auburn, AL to train full-time together and I’ve been playing semi-professionally in France. There are 12 countries going to Cuba and 5 get to leave with a ticket to the World Championships!

We won bronze at the North American and Caribbean Championships! Check out my black eye!
We won bronze at the North American and Caribbean Championships! Check out the black eye I got from a flying headbutt!

So What’s the Deal

In honor of my “side hustle”, for the next TEN DAYS (ending 15 May) I am going to be putting my main hustle in service of handball. I will answer any WooCommerce question, or complete any small WooCommerce-related project in exchange for a donation to the USA Women’s Quest to Cuba. I’m not officially billing you, so what you donate is up to you, but please don’t expect me to write a huge 3rd-party integration for a $5 donation. We’ve only got 10 days, so things I can turn around for you in 1-3 hours is perfect.

Any question that you can’t figure out on your own, I will answer (or tell you I can’t). Any place you’re stuck trying to code your own solution, I will help you solve. Any tweak to your web store that you haven’t gotten around to finding a developer for, I’m here.

You get a little WooCommerce help and the satisfaction of knowing that you are supporting the group of really dedicated and hard-working ladies on Team USA.

Support Team USA!

or get in touch:

Modifying the WooCommerce Product Query

I recently answered a few questions on Stack Overflow and they all seemed to related to how to change what products show up in the shop loop… or any other of the shop archives. I figured I would compile them altogether for reference and inspiration.

WooCommerce builds a custom query for products in its WC_Query class by hooking into the classic pre_get_posts hook and changing WordPress’s query parameters to get the desired products. WooCommerce then removes itself from the query afterwards. I’m not 100% sure of why, but I presume there is a good reason. It might be running in WooCommerce, but it is still a regular WordPress query and so the regular WP_Query Parameters apply.

Like most WooCommerce code there is a convenient action hook right in the middle of the product_query() method which will allow us to hook in and make whatever changes we might like to the product query. Note that $q is the query and $this is the WC_Query class instance.

Example 1: Display Only On-Sale products in Shop

WooCommerce has a shortcode for displaying the most recent on-sale products. So I took a look at how it sets up it’s query args for get_posts(). Turns out WC has a built-in function that returns the IDs of any on-sale products: wc_get_product_ids_on_sale(). So we get grab those ids and then query for those specific posts using the post__in parameter of WP_Query.

As is typical in dealing with WordPress query objects we can use get() and set() methods to retrieve info about the query or set new parameters.

Example 2: Hide Products that are Part of a Grouped Product

The person who asked this question has a lot of products that part of other grouped products and didn’t want to display the items individually and in their grouped versions. Turns out that items that are part of a group have the grouped product as their post_parent. Any grouped product (or other top-level, non-grouped product) will have 0 as a post parent. Therefore, we can set the query argument to require a post parent of 0 and effectively eliminate any grouped items.

Example 3: Hide Specific Out of Stock Items

WooCommerce has a setting that allows you to hide all out of stock items from your store. But what if you don’t want a nuclear option and want to have a little finer control over which items are going to be hidden.

We can’t skip straight to the query, because WooCommerce doesn’t have this data. So we need to add some meta. You could use a custom field, but that isn’t as friendly as adding a little checkbox to the product data metabox. I thought it would be appropriate if we placed it near the stock status inputs. WooCommerce already has functions for creating most of the standard input types so we’ll use that to our advantage.

Then we need to save this data. Normally, I’d save a checkbox as ‘yes’ versus ‘no’ like WooCommerce does. However, getting the product query correct (as you’ll see a little later on), required that the meta exist when you wanted to hide the item and not exist at all otherwise… hence the if/else update_post_meta() versus delete_post_meta()

And now we can get to the query. Because WooCommerce already has a few keys in its default meta query and the default meta query operator is AND (meaning my conditions had to be met in addition to what WooCommerce was already looking for), I couldn’t figure out a way to query for posts that had meta equal to a specific key. But because WordPress supports EXISTS and NOT EXISTS comparisons, we can look for posts that way. What I’ve done is in the case where you aren’t mass hiding all out of stock items via the plugin option, this code will modify the meta query so that any item that does not have the meta key _hide_if_out_of_stock will be shown. That is a counter-intuitive way of saying that any product where the box “hide when out of stock” is checked will be hidden.

Those are the three uses of modifying WooCommerce’s product query that I have encountered in the past few days. Anybody else doing anything interesting to the product query?

WooCommerce Customize Checkout Fields

I was digging around in WooCommerce while trying to come up with a quote for a client. Part of the scope had me wondering if you could remove some fields from the checkout process. If you aren’t selling physical products a billing address can be too much information and could even be off-putting to potential customers.

I eventually tracked the fields down from the checkout template, to the checkout class to the get_address_fields() method in the WC_Countries class.

Removing Billing Address

Like a lot of things in WooCommerce you can modify values via filter. To remove all the physical address fields from the billing address here is the code I used:

Yes this could go in functions.php but that kind of locks you into a specific theme. If this is a permanent change then you probably want to create a site-specific plugin and put it in the wp-content/mu-plugins/ folder.

Add a Custom Checkout Field

While I was fooling around I figured I would see if I could add a custom checkout field. Turns out this is a bit more complex, but ultimately do-able. The following code will add the field to the checkout page, save the data to order meta and display the order meta in the orders admin.

Update: After receiving multiple contacts about adding more than one field I have modified the sample code to add 2 fields.

Note: there is no foreach() in the rest of the function so we must save and display each field individually

Save the extra data on checkout

Display the extra data to users

Display extra data in admin

Alternatively, display extra data as editable data (and save)

This should function like the shipping and billing address data and reveal inputs when the little pencil icon is clicked. Make sure to delete the previous function as two functions with the same name will cause a PHP error.

Add the field to order emails

The easiest way to add data to the emails is to add our meta to the list of meta that WooCommerce will print out automatically. For WooCommerce 2.3 and after, you will do it the following way:

If you’d rather customize the output in the emails you can add some text to any of the hooks available in the email templates.

Hope that helps you. I think there are a few plugins out there now if this was too intimidating, so I would suggest using one of those.

Note: This was tested with WooCommerce 2.2. Any prior or later versions, I can’t promise will be exactly the same.