Today we’re excited to release WooCommerce 3.0 (previously 2.7), dubbed the “Bionic Butterfly”, into the wild! 3.0 has been in beta since December, development since August, and has had over 3000 commits from 115 contributors.
Read on to find out what’s new!
CRUD (Create, Read, Update, Delete) objects and data-stores
The CRUD classes in 3.0 represent a fundamental change in how we work with data objects in core (thats products, orders, coupons, customers etc).
Traditionally in WordPress when working with, for example, posts and post data you’re pretty much able to update/get/create any meta data you want anyway you want, procedurally direct to the database. Our new CRUD approach on the other hand introduces another layer between the database and your code which adds structure, validation and control.
As a simple example, let’s imagine you have a product and this product has a price. With the old way, if you wanted to update the price of this product you’d:
- need to know where that price is stored (meta key)
- need to know in what format that data is stored (string? 2 decimal places?)
- need to know how to update that data (
With CRUD, you instead have a list of product properties, one of which is price, and you can call
->set_regular_price() to set the data, followed by
->save() to make that data persist in the database. Where is gets stored is none of your concern and formatting is handled for you. Example:
$product = wc_get_product( 1 ); $product->set_regular_price( 10.99 ); $product->save();
- We define the structured data for each resource and you can look it up easily.
- We control the flow of data, and any validation needed.
- You don’t need to know the internals of the data you’re working with.
- Internally, the data can be moved elsewhere e.g. custom tables, without affecting existing code.
- It’s reusable (API, CLI, WP Admin) and has more unit test coverage.
We’re excited about this change, and it really paves the way for us to improve performance in the future.
A new product gallery
Back in August we posted about some improvements we wanted to make to our product image galleries and then took a poll to see what users wanted. The results showed that the majority of voters liked the zoom feature, and a significant number of people wanted to keep some form of lightbox.
Based on these findings, we devised a system that included both, with added mobile device support and includes the following benefits:
- Visitors now have access to both magnification and zooming (lightbox)
- Gallery behaviour is more intuitive – clicking a thumbnail updates the main image rather than opening a lightbox
- Dramatic improvements on handheld, in particular; touch gestures – swipe to scroll through the gallery, pinch to zoom, swipe up to close, etc
- Opening the lightbox on mobile now displays the image in it’s true size, larger than the in-page display
To avoid disrupting custom lightboxes in themes, non-default WordPress themes will need to enable the new functionality using
add_theme_support(). It’s easy; you can read how to do this here.
New CLI (Command Line Interface) and Rest API v2
2.6.x had a CLI but it was custom and didn’t share any code with the rest of the codebase. This was wasteful and hard to maintain; we have a fully blown REST API after all. In 3.0.x we’ve made a new CLI which integrates directly with the REST API and supports all of the same functionality.
We’ve also introduced a new version of the API with several benefits over v1. To summarise whats new:
- Support for meta data on most endpoints.
- New variations endpoint for creating and updating variations. In addition, we’ve prevented the (broken) ability to manipulate variations directly on the products endpoints.
- Settings endpoint (update/view shop settings).
- Shipping zones endpoints.
- Payment and shipping methods endpoints, including settings.
- Added support for oAuth1.0a authentication using headers.
- Additional caching and removal of slow queries (last order query from the customers part of the API).
A new logging system
The new logger, which can be used by extensions to log events, errors and warnings, addresses limitations in our old logger. It includes log handlers, it implements the methods described by the PSR-3 logger interface, and it’s much more extensible.
The new logger includes 2 handlers; file and database. The database handler can be enabled with;
define( 'WC_LOG_HANDLER', 'WC_Log_Handler_DB' );
There are several performance improvements in 3.0.x. To summarise the main ones:
- For variable products specifically, we’ve tried to optimise variable product sync. Upper/lower price meta data is no longer stored (it was not used in core), just the main prices, if a child has weight, and if a child has dimensions.
- In our template files, we’ve removed WP_Query from up-sells.php and related.php and replaced with PHP foreach loop (since we already have the product IDs). This means one less large query on product and cart pages.
- We’ve removed the feature where old orders get access to new downloads on product edit. Looping (potentially) thousands of orders to do this update was too much of a performance burden for some stores and this also could lead to unexpected behaviour. After this update we do however update edited downloads, so editing a file will not prevent purchasers from downloading it.
- We’ve removed the ‘order items’ column on the orders page. Whilst this can be useful, loading all items for all orders on the page is not performant. This may return in the future but it will need to be dynamic so it may just be left for a future UI redesign.
- Rather than sending emails in one big request when placing an order on checkout, we’ve implemented a delayed CRON event to send the emails instead. This sends the emails after a small delay in a separate request and in turns speeds up the checkout by about 50% in testing.
Additionally, since joining to the post meta table can cause significant slowdown when you have a large product catalog, we’ve made some optimisations to utilise taxonomies more for frontend product filters.
- Product visibility (which controls if products are visible in the catalog, search, or both) was previously post meta, and was used in all WooCommerce product queries. In 3.0 this is a new product_visibility taxonomy instead. In testing, with ~8k products we saw speed improvements of around 94%.
- Featured products are also using the new product_visibility taxonomy instead of meta which improves queries on those.
- And the same for out of stock products. If you’re hiding out of stock products from your catalog, you’ll see improvements.
Meta to taxonomy conversions are handled by our upgrade script.
- Sorting tax rates was previously a manual process. When you have pages of tax rates this becomes cumbersome. In 3.0.x we sort tax rates automatically, placing more specific rules above more general rules (the way they should be sorted).
- On the frontend, we’ve made the storewide notice dismissible making it less of an issue when it overlaps content on mobile 🙂
- On WordPress networks/multisite, when a user logs into a store with an account, but not an account on the current store, WooCommerce will add existing users to the store rather than throw an error as it did in 2.6.
- Previously, structured data was output inline in our template files (marking up things such as products). In 3.0 we’ve switched to JSON-LD format which keeps our template files tidy and keeps data intact if customisations are made by theme developers.
- When authorising payments with PayPal Standard, funds are now automatically captured when the order is changed to processing or completed. It was a manual process in 2.6.x.
- We merged cart percent and product percent coupon types into one and removed product_cart discounts. The discounts these coupons provide are identical, however, the cart based validation would stop the coupon being applied if any non-eligble item was in the cart, rather than just discounting eligible items like product coupons do. This was not intuitive, caused store owner and confusion, and most important of all, just meant users would have to checkout twice to make use of these coupons (thats not fair nor ideal).
- Variable product prices which contain sale items will no longer contain a strikethrough. Showing a striked out range followed by a non-striked out range, especially if the prices overlap, is too darn confusing and longwinded. Instead we show just a range now. Sale prices will still be shown when selecting a variation.
- Grouped products are linked from the parent rather than the children. Children can be in more than one group.
There are many more smaller tweaks and improvements in 3.0 but this covers the main changes that you may notice.
Upgrading to 3.0
As always, before upgrading ensure that your extensions and theme are compatible with 3.0 and you’ve made backups. If unsure, check with the theme/extension developer.
Store owners, read this helpful guide on preparing for the update and if you see any deprecation notices after updating don’t be alarmed; read here to understand why.
After upgrading, the data upgrader prompt will run updates in the background. If your site is not accessible or password protected there may be a delay for the cron-based fallback to run.
If you’ve not yet made your extensions and themes compatible with 3.0.x (!) here are some notes we’ve been writing during our own testing:
- 2.6.x to 3.0.0 Developer Migration Notes
- Template changes
- Deprecated functions and filters
- Bookings extension compatibility example
- Deposits extension compatibility example
- More extension compatibility examples
How we tested 3.0
In total we had 4 beta versions for “2.7” from December; you can check out the Beta 1, beta 2, and beta 3 posts if interested. We then had a “2.7” release candidate before deciding to move to Semantic Versioning and use
3.0.0 instead. In total our betas have had at least 1,148 downloads according to the stats we have from Github.
Internally we’ve been testing our own plugins and themes, releasing updates where needed, and we’ve had support from our 3rd party developers also. Huge kudos to our 3rd party devs!
On top of the manual testing we’ve all been performing, and the testing by the community, we’ve also been gradually expanding our unit test coverage which is now up to 50%. You can view current test coverage on Scruitinizer.
A huge thanks for our contributors!