-
Notifications
You must be signed in to change notification settings - Fork 10.8k
2.6.x to 3.0.0 Developer Migration Notes
- Virtual orders do not have shipping addresses
- Accessing
$item['item_meta']
directly get_qty_refunded_for_item
handling- set_payment_method does not update meta values
- Data filters differ when extending classes with a different object type
- Notification email sending
- Order post dates
- Display of variable product and 'free' prices
- Product visibility is taxonomy based instead of meta based
- Removed "items" column in orders panel
- Removed product downloads update for past orders
- Automatic tax rate sorting
- Product schema markup moved to JSON LD format
- Auto-capture of authorised paypal payments
- Cart percent/Product percent coupon types merged
- Array return values being swapped out with objects implementing ArrayAccess
- Variation actions/filters prefixes
- Objects are passed by reference to actions/filters
- Variation IDs
- Select2 Version 4
- Order version property
- Order address indexes
- Template changes
- Deprecated functions
- Deprecated filters
In 2.6.x, orders containing virtual items only would copy the billing address to the shipping address on save.
In 3.0.x, orders containing virtual items will not have shipping addresses because the order is not shippable. Code that requires a shipping address should fall back to the billing address if not available.
To detect this, see if the order has shipping_address_2 or shipping_address_2 set, or use the ->has_shipping_address()
method after 3.0.4.
When accessing this via an item object, $item['item_meta']
will return an array of values under 2.6, but a single meta value under 3.0.7.
We recommend using $item->get_meta()
instead as accessing legacy data is not encouraged.
In 2.6.x this would return a negative count (bug). In 3.0.x this is a positive count representing how many units have been refunded.
In 3.0.0, using $order->set_payment_method()
also requires a call to $order->save()
to persist the data.
Filters in objects take the format:
woocommerce_{your_object_type}_get_{prop}
For example, a width prop in a product object has the filter: woocommerce_product_get_width
If you extending products and used a custom object type in place of product
, your filter name would differ.
See this issue for more details.
In 2.6.x, email notifications were sent in the same request as the order status change.
In 3.0.0, they are instead queued using WP Cron and send in a separate request.
If using actions to stop emails sending, your code will need to handle the new system. https://github.com/woocommerce/woocommerce/issues/13318
As pointed out in https://github.com/woocommerce/woocommerce/issues/13380, orders in 2.6.x would have their post dates updated when moving from pending to some other status.
In 3.0.0, the post date is the date the order was created. This will no longer change unless explicitly set.
Prices have been standardized in 3.0.0.
Variable products which show ranges and are on sale no longer show the striked out prices since these are long and confusing.
Example:
2.6.x:
<del>$20.99 - $25.99</del> <ins>$10 - $12</ins>
3.0.0:
$10 - $12
Prices with $0
price no longer display as free. This previously caused inconsistencies with ranges and with localization.
3.0.0 instroduces a new product visibility taxonomy; catalog
, search
, hidden
, featured
, outofstock
are terms. These are set on upgrade and help filter products in the catalog during frontend queries.
This column previously showed a toggle list of items in the order for quick viewing, however, this was a performance bottleneck and has been removed. It was loading all items for all orders on screen; loading time is much improved with it gone.
In 2.6.x if you edited a product's downloadable files, it would attempt to find all orders of said product and update download permissions.
This was not only a performance bottleneck, but also unexpected behavior as it would grant access to new files for old perchasers without prompting.
This has been removed in 3.0.0. Editing a file will however still update past purchases as it should.
In 2.6.x, the order in which tax rates were displayed and used were sortable with drag and drop.
In 3.0.0, manual sorting is removed. Tax rates will now sort logically based on the zip codes/cities/postcodes/priorities defined.
2.6.x showed output schema.org markup inline. This has implications if a theme changed markup or missed certain elements.
In 3.0.x, this is now output in the footer of the site in JSON LD format instead. For more details, see https://developers.google.com/schemas/formats/json-ld.
Payments authorized in 2.6.x using PayPal would not be captured at all and would require manual admin intervention to capture funds.
In 3.0.x, these funds will be captured automatically when the order is marked 'complete' using the PayPal API.
Coupons had Cart percent
and Product percent
coupon types in 2.6.x. In 3.0.0 these are merged since they provide the exact same amount of discount regardless.
In some places, 2.6.x returned arrays representing data such as taxes. In 3.0.0, proper classes have been added instead. These new classes implement ArrayAccess so old code trying to reference values in the 'array' still functions.
There is one caveat to this; if you check returned data to see if it's an array with is_array
this check will return false
since it's not an array in 3.0.0, it's an object. This will fail silently so needs to be checked in the extension code.
New classes implementing ArrayAccess as are follows:
WC_Product_Download
WC_Product_Attribute
-
WC_Order_Item
WC_Order_Item_Coupon
WC_Order_Item_Fee
WC_Order_Item_Product
WC_Order_Item_Shipping
WC_Order_Item_Tax
WC_Customer_Download
This is a list of methods which returned arrays in 2.6.x, but objects in 3.0.0:
WC_Product::get_file()
-
WC_Product::get_files()
(returns an array of objects) -
WC_Product::get_attributes()
(returns an array of objects) -
WC_Abstract_Order::get_items();
(returns an array of objects) -
WC_Abstract_Order::get_fees()
(returns an array of objects) -
WC_Abstract_Order::get_taxes()
(returns an array of objects) -
WC_Abstract_Order::get_shipping_methods()
(returns an array of objects)
--
woocommerce_get_regular_price/sale_price
filters were in the abstract in 2.6.x. For products, these hooks are replaced with woocommerce_get_product_regular_price
and woocommerce_get_product_sale_price
and mapped so existing filters continue to function.
The exception is with product variations - these have their own hook prefix making them woocommerce_get_product_variation_regular_price
and woocommerce_get_product_variation_sale_price
. There is no mapping in place for these filters.
If you're being passed a CRUD object via an action or filter hook, changes you make to said object will persist. If you need to change object properties without doing this, clone the variable.
// Create a clone to ensure item totals will not be modified permanently.
$item = clone $item;
In 2.6.x, $variation->id
was the ID of the parent product, and $variation->variation_id
was the ID of the variation. Backwards compatibility is maintained, but when moving to CRUD ensure you use the correct getters and setters.
$variation->get_id()
is the variation ID.
$variation->get_parent_id()
is the parent product ID.
From WC Beta 2, we've migrated to Select2 V4.
Select2 V4 is mostly compatible with Select2 V3 with a few exceptions, the main one being how AJAX search inputs work. WooCommerce has two instances of these which are affected and need some HTML markup changes to function.
These inputs were 'hidden' text inputs in v3. In v4 these needs to be changed to regular multiselect elements.
Example:
<input type="hidden" id="grant_access_id" name="grant_access_id" data-multiple="true" class="wc-product-search" style="width: 400px;" data-placeholder="<?php esc_attr_e( 'Search for a downloadable product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_downloadable_products_and_variations" />
Would be changed to a regular multiselect field:
<select id="grant_access_id" class="wc-product-search" name="grant_access_id[]" multiple="multiple" style="width: 400px;" data-placeholder="<?php esc_attr_e( 'Search for a downloadable product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_downloadable_products_and_variations"></select>
Note that the field name in this case was changed from grant_access_id to grant_access_id[].
data-multiple
is no longer needed. The multiple prop is added instead. This supports multiple selections.
In the previous example, the hidden input would have posted a comma delimited string of IDs. With the switch to multi selects, this code needs to handle an array of values instead.
Handled in the same way as wc-product-search
.
Unlike hidden inputs, if no selections are made multi-selects do not POST. Your code needs to check if the field isset()
to deal with posted values and handles scenarios where no selections are made.
With 2.3.7-2.6.x:
changing order line items via the admin interface would update them to the WC > 2.3.7 structure (in wc_save_order_items()), because of this, it would update the order version. This is the only time the version data is actually different between WC < 2.3.7 and 2.3.7-2.6.14 so it's the only time the order version if updated. changing order line items via any other method, be it the REST API, CLI or another API function (e.g. WC_Abstract_Order::add_tax()) would not definitively update the structure to the WC > 2.3.7 structure, so it would not update the order version. The calling code could update them to the newer structure, and if it chose to, it would be responsible for also updating the order version. changing any other data via any other method won't update the order version, because nothing has changed in terms of how the data is stored. tl;dr - the order version on orders with WC < 3.0.0 almost never changed, because the data structure almost never changed.
With 3.0.0:
changing order line items via the admin interface would update them to the WC > 2.3.7 structure so it would update the order version (even if there are no changes to the structure). changing order line items via any other method, be it the REST API, CLI or another API function would update the structure to the WC > 3.0.0 structure, so it would update the order version (even if there are no changes to the structure). changing any other data via any other method would update the order version, even if nothing has changed in terms of how the order is being stored, but if something has changed, it will be updated. tl;dr - the order version on orders with WC 3.0.0+ will always change, even if the data structure hasn't changed, but the order version will also always reflect the version of the structure.
https://github.com/woocommerce/woocommerce/issues/13381#event-979557696
Order address indexes are introduced in WooCommerce 3.0 to improve search results in the wp-admin, those indexes should be created automatically when an order is created or have changes on the address, although orders placed before 3.0 shouldn't contain any indexes, so in order to generate missing you can use the "Order address indexes" tool that can be found in "WooCommerce" > "Tools", this tool is also avaliable on WP-CLI with the follow command:
wp wc tool run add_order_indexes --user=<USER_ID>
Note: Since WooCommerce 3.6 this tool has been converted into a plugin: https://github.com/woocommerce/woocommerce-recreate-orders-indexes
File | Description |
---|---|
cart/cart.php | CRUD compatibility. |
cart/cross-sells.php | Removes WP_Query for performance reasons. |
checkout/thankyou.php | Mark |
emails/email-order-items.php | CRUD compatibility. |
emails/plain/email-order-items.php | CRUD compatibility. |
myaccount/downloads.php | Improved download table layout. |
order/order-details-customer.php | CRUD compatibility. |
order/order-details-item.php | CRUD compatibility. |
order/order-details.php | CRUD compatibility. |
single-product/add-to-cart/grouped.php | Checks grouped products exist correct, and CRUD compatibility. |
single-product/meta.php | CRUD compatibility. |
single-product/photoswipe.php | Handles the new photoswipe gallery. |
single-product/price.php | CRUD compatibility. |
single-product/product-attributes.php | CRUD compatibility. |
single-product/product-image.php | New image gallery. |
single-product/product-thumbnails.php | New image gallery. |
single-product/related.php | Removes WP_Query for performance reasons. |
single-product/up-sells.php | Removes WP_Query for performance reasons. |
single-product/review-meta.php | CRUD compatibility. |
single-product/review-rating.php | CRUD compatibility. |
single-product/stock.php | New template to output stock HTML. |
single-product/tabs/additional-information.php | CRUD compatibility. |
checkout/form-billing.php | Extra wrappers. |
woocommerce_get_product_schema
_wc_save_product_price
- All methods in the legacy (backwards compatibility) classes:
WC_Legacy_Shipping_Zone
WC_Abstract_Legacy_Product
WC_Legacy_Payment_Token
WC_Abstract_Legacy_Order
WC_Legacy_Coupon
WC_Legacy_Customer
Filter | Replacement |
---|---|
woocommerce_email_order_schema_markup | woocommerce_structured_data_order |
add_to_cart_fragments | woocommerce_add_to_cart_fragments |
add_to_cart_redirect | woocommerce_add_to_cart_redirect |
woocommerce_product_width | woocommerce_product_get_width |
woocommerce_product_height | woocommerce_product_get_height |
woocommerce_product_length | woocommerce_product_get_length |
woocommerce_product_weight | woocommerce_product_get_weight |
woocommerce_get_sku | woocommerce_product_get_sku |
woocommerce_get_price | woocommerce_product_get_price |
woocommerce_get_regular_price | woocommerce_product_get_regular_price |
woocommerce_get_sale_price | woocommerce_product_get_sale_price |
woocommerce_product_tax_class | woocommerce_product_get_tax_class |
woocommerce_get_stock_quantity | woocommerce_product_get_stock_quantity |
woocommerce_get_product_attributes | woocommerce_product_get_attributes |
woocommerce_product_gallery_attachment_ids | woocommerce_product_get_gallery_image_ids |
woocommerce_product_review_count | woocommerce_product_get_review_count |
woocommerce_product_files | woocommerce_product_get_downloads |
woocommerce_get_currency | woocommerce_order_get_currency |
woocommerce_order_amount_discount_total | woocommerce_order_get_discount_total |
woocommerce_order_amount_discount_tax | woocommerce_order_get_discount_tax |
woocommerce_order_amount_shipping_total | woocommerce_order_get_shipping_total |
woocommerce_order_amount_shipping_tax | woocommerce_order_get_shipping_tax |
woocommerce_order_amount_cart_tax | woocommerce_order_get_cart_tax |
woocommerce_order_amount_total | woocommerce_order_get_total |
woocommerce_order_amount_total_tax | woocommerce_order_get_total_tax |
woocommerce_order_amount_total_discount | woocommerce_order_get_total_discount |
woocommerce_order_amount_subtotal | woocommerce_order_get_subtotal |
woocommerce_order_tax_totals | woocommerce_order_get_tax_totals |
woocommerce_refund_amount | woocommerce_get_order_refund_get_amount |
woocommerce_refund_reason | woocommerce_get_order_refund_get_reason |
default_checkout_country | default_checkout_billing_country |
default_checkout_state | default_checkout_billing_state |
default_checkout_postcode | default_checkout_billing_postcode |
woocommerce_single_product_image_html | Removed - new gallery has not 'single' image. All images are ran through woocommerce_single_product_image_thumbnail_html |
WooCommerce is an open source commerce platform built for WordPress and lovingly crafted by Automattic and the WooCommerce community 💜. Come and work with us!
Contribution
- Set up development environment
- Our Git Flow
- SCSS and JS minification
- Naming conventions
- CSS SASS coding guidelines and naming conventions
- Critical Flows
- API Critical Flows
- String localisation guidelines
- Translating WooCommerce
- Deprecation in core
- Adding Actions and Filters
- Common Issues
- Writing high-quality testing instructions
Release Notes
- Release Testing Instructions
- 3.6.x notes/FAQ
- 2.6.x to 3.0.0 Developer Migration Notes
- Select2 fields not working in 3.0.x
- Thumbnail Image Regeneration in 3.3+
- Customizing image sizes in 3.3+
REST API and CLI
CRUD & Data Descriptions
- Database Description
- CRUD Objects in 3.0
- Order and Order Line Item Data
- Coupon Data
- Customer Data
- Product Data
- Data Stores
Internal APIs
Theming
- Enabling product gallery features (zoom, swipe, lightbox)
- Template File Guidelines for Devs and Theme Authors
Examples / Guides