Commerce Commerce 1.x Upgrades v1.3

Most upgrades are automatically applied, but sometimes you may need to update custom templates, or configuration, to take advantage of new features or improvements. Those changes are discussed here.

Commerce v1.3 brings along a variety of new features as we move closer towards :magic-emoji: subscriptions :magic-emoji:

PHP 7.4+

Commerce now requires PHP 7.4.0 or up. If you’re not yet on 7.4, the package will not allow you to update.

Guzzle 6 replaced with Guzzle 7

We’ve removed Guzzle 6 from Commerce, and are now automatically installing the guzzle7 package instead. This helps avoid dependency conflicts which have gotten increasingly common, especially on MODX3.

While the core seamlessly updated from Guzzle 6 to 7, it is possible custom extensions or third-party packages are affected by this major upgrade. Those will need to be updated to the Guzzle 7 syntax. Learn more about upgrading Guzzle 6 to 7

There was also an even older version of guzzle/guzzle previously shipped with Commerce (as a dependency of Omnipay), that is now no longer included either.

Twig updated to 3.5

Previously, Commerce used the rather old 1.x version of Twig because of our wider PHP support. In Commerce 1.3, we’re now up-to-date with Twig 3.5.

We found this update to be pretty straightforward, with one notable change that is needed to custom templates:

{% spaceless %}...{% endspaceless %} needs to be replaced with {% apply spaceless %}...{% endapply %}

Commerce 1.3 will scan your template folders on upgrade and attempt to fix the syntax automatically. A backup will be placed alongside updated files, with a .comm13.bk extension, and the installation log will tell you exactly which files were changed.

However, this automatic upgrade may not catch everything, and also does not check extension templates that are loaded dynamically. We recommend doing a quick find & replace across any custom themes and extensions to identify any usages of “spaceless” to update proactively, so you don’t run into issues with the upgrade.

As the apply syntax also exists in v1, you can use {% apply spaceless %} now, before the upgrade to v1.3. This works all the way back to Commerce v1.0.1.

If you have any advanced Twig implementations (custom twig extensions, or making calls to $commerce->twig rather than $commerce->view()), additional steps may be needed to be compatible with Commerce 1.3, depending on what was previously implemented. If you have such a use case and aren’t sure how to prepare that for 1.3, drop us an email. We’re happy to help!

Accept Terms module can now be used on different steps

We’ve added some more flexibility to the Accept Terms & Conditions, allowing you to choose the step the checkbox is displayed on.

If you have existing templates, this won’t work until you update them to use the new partial template. See the Accept Terms & Conditions documentation for the exact markup to add in each relevant template.

New: Scheduler

Commerce now comes with a built-in scheduler for background or asynchronous processing. This can be used for both one-off tasks that need to happen as soon as possible or at a certain time, as well as recurring tasks such as nightly imports or cleanup.

To start using the scheduler, you need to setup a cron job per these instructions.

Where possible, tasks will be executed synchronously if the cron job is not running, however we strongly recommend setting up the cron job when updating to make sure you can take advantage of it. This scheduler will be a vital part of Commerce in the not too distant future, and new modules are likely to start taking advantage of it right away.

Asynchronous processing has initially been implemented in the following:

  • Sending emails as part of the status workflow. To enable, go to Configuration > Statuses and click on the status change action you’d like to process asynchronously (e.g. the 2 emails sent when payment is completed) and tick “Send asynchronously” at the bottom. This speeds up the initial order processing at the cost of slightly delaying when emails are processed.
  • Nightly generation of future dates according to a schedule in the TimeSlots module.

In addition, we’re starting to move internal maintenance and cleanup tasks to the Scheduler as well. This includes:

  • Cleaning up Scheduler tasks every 30 minutes
  • Revoking expired order processing locks (see below) every minute

As 1.3 is still in development, we’ll likely add more asynchronous options closer to release.

Templates: email and phone in emails

For some inexplicable reason, we never added the customers’ email or phone number in the default email templates. That has now been rectified.

To incorporate them in your own templates, you may use the following examples:

<!-- For shipping address: -->
{% if shipping_address.email %}{{ shipping_address.email }}{% endif %}
{% if shipping_address.phone %}<br>{{ shipping_address.phone }}{% endif %}

<!-- For billing address: -->
{% if billing_address.email %}{{ billing_address.email }}{% endif %}
{% if billing_address.phone %}<br>{{ billing_address.phone }}{% endif %}

These can go in all email templates. In the default template, we’ve updated emails/message.twig, emails/order-received.twig, and emails/order-to-merchant.twig.

Regular price now available in cart

Using sale prices and want to show what the price used to be? Now you can.

In your frontend/checkout/cart/items.twig template find where you’re rendering the price ({{ item.price_formatted }}, in the default it’s around line 40), and add the following to it:

{% if item.regular_price > 0 and item.regular_price != item.price %}
    <del class="product-price__old">
        {{- item.regular_price_formatted -}}
    </del>
{% endif %}

Do note that different types of discounts are applied differently. Sale price types are applied to the item price, while coupon and other discounts are applied to the subtotal (price * quantity). Order item adjustments are, depending on their options, usually applied to the price as well.

This can lead to somewhat confusing cart summaries in certain combinations. Depending on what you use, it’s worthwhile looking at how you want to render those. Commerce by default will show a fairly basic view suitable for most shops.

Developer: simpler shipment >< shipping method integration

We’ve added a new comOrderShipment::getFieldsForShippingMethod method which allows a custom Shipment to add additional fields to the shipping method form in the dashboard. This may make some integrations easier, reducing the need for a matching set of Shipment/Shipping Method when you just need an extra configuration option.

This does not impact existing shipment/shipping method types but may be worth revisiting custom integrations for.

Order Processing Locks

As of Commerce 1.3, we’re using a new locking mechanism to avoid duplicate order processing when multiple processes (such as a webhook and a customer returning to checkout) trigger the recalculation and status workflows simultaneously.

The order locks are stored in the database using a primary key constraint that only allows a single successful lock to be written. The process that got the lock should make sure to release it when it is done processing.