Breaking change notice: woocommerce_emogrifier hook

As we announced back in January, as of WooCommerce 6.5, to be released in May, the minimum PHP version required will be 7.2. The version bump work is done, and while doing it we noticed that unfortunately we’ll need to introduce a breaking change regarding how the woocommerce_emogrifier hook works. The TLDR is that the code hooking there will now receive a different type of object as a parameter.

The problem

One of the main drivers for the PHP requirement bump was the impossibility to install WooCommerce as a Composer package in PHP 8, due to the incompatibility of the Emogrifier package version we were using (v3, since that was the newest one supporting PHP 7.0; but that one was incompatible with PHP 8).

Emogrifier added compatibility with PHP 8 in v5, and since WooCommerce is now PHP 7.2+, we are able to upgrade the Emogrifier version it uses too and thus get the PHP 8 compatibility. There’s a catch, though: the main class that this package used to expose its functionality, named Emogrifier as well, was removed in v4 of the package (it’s now replaced by the CssInliner class). The relevant code in WooCommerce has been updated accordingly.

And here’s the problem, that you’ll be able to see if you take a look at the above code: the WC_Email::style_inline method fires a woocommerce_emogrifier hook passing an Emogrifier object as a parameter, so that external code is able to further customize the email styles. But there’s no such thing as an Emogrifier class anymore.

The solution

Or rather, the workaround, since no perfect solution is possible.

Starting with WooCommerce 6.5, the woocommerce_emogrifier hook will receive an instance of CssInliner as a parameter, instead of an instance of Emogrifier. This new class keeps some of the methods of the old one, but not all. More precisely, this is the list of methods from Emogrifier that still exist in CssInliner:

  • addAllowedMediaType
  • addExcludedSelector
  • disableInlineStyleAttributesParsing
  • removeAllowedMediaType
  • removeExcludedSelector
  • setDebug

And this is the list of methods from Emogrifier that don’t exist in CssInliner:

  • setHtml
  • getDomDocument
  • setCss
  • emogrify
  • emogrifyBodyContent
  • disableStyleBlocksParsing
  • addUnprocessableHtmlTag
  • removeUnprocessableHtmlTag
  • handleXpathQueryWarnings

So in case you are using that hook in your code, if you only use the methods from the first list you’re probably good to go; otherwise you’ll need to make changes in your code.

How to check if this affects you?

If you maintain a WooCommerce extension you are definitely affected if you make use of the woocommerce_emogrifier hook in your code and you use any method of the Emogrifier object that you receive that is not in the above list. If you use the hook but your usage of the Emogrifier class is limited to these methods, then your code could be unaffected, but it’s still worth taking a look and performing some testing as soon as the first beta of WooCommerce 6.5 is published.


2 responses to “Breaking change notice: woocommerce_emogrifier hook”

  1. naveoadmin Avatar
    naveoadmin

    It wouldn’t be 100% fix, as there is a mention of removed methods, but could the class not be aliased with use?

    1. konamiman Avatar
      konamiman

      Hi, you mean that any code that tries to explicitly cast the object passed to the hook as Emogrifier will fail? Then yes, that’s true; as I said there’s no perfect solution for this and any code that uses that hook will likely require changes. Thanks for pointing out this, though; I had missed that while writing the post.

Leave a Reply

Your email address will not be published. Required fields are marked *