One of the major problems observed in getting contributed modules Drupal 10 compatible was maintaining support for Drupal 9.5, which remains in security support (or remained if it is now past November 1, 2023.) Contributed modules should be compatible with all security-supported versions of Drupal core or more if they so choose. This can be difficult as Drupal 9.5 contained deprecated code removed in Drupal 10. It was up to maintainers and contributors to find workarounds and copy-pasting tricks using if
/else
statements with version_compare
.
If you're interested in these challenges, I recommend catching my talk from MidCamp this year – Lessons learned from helping port the top contrib projects to Drupal 10.
Making backward-compatible calls possible
Luckily, Drupal 10.1.3 released a new utility class that will make supporting multiple versions of Drupal core easier while addressing deprecated code. The new class \Drupal\Component\Utility\DeprecationHelper
and its backwardsCompatibleCall
method allow code to be executed conditionally based on the current Drupal core version (change record.)
For instance, the user_roles()
function has been deprecated in Drupal 10.2.0. Here's an example of using the deprecated user_roles
function and its replacement using the DeprecationHelper::backwardsCompatibleCall
method. Note – the example uses named arguments for demonstration purposes and is not required.
$result = DeprecationHelper::backwardsCompatibleCall(
currentVersion: \Drupal::VERSION,
deprecatedVersion: '10.2',
currentCallable: fn() => Role::loadMultiple(),
deprecatedCallable: fn() => user_roles(),
);
Let's break down this code. DeprecationHelper::backwardsCompatibleCall
has four arguments
currentVersion
is the version to be checked, which is the version of Drupal from\Drupal::VERSION
.deprecatedVersion
is the version that introduced the deprecated code path, which happened in the release of Drupal 10.2.0.currentCallable
is the callable to be invoked for the new code path.deprecatedCallable
is the callable to be invoked for the deprecated code path
The method uses PHP's version_compare function to determine if currentVersion
is greater than or equal to deprecatedVersion
.
I sincerely appreciate everyone's discussions and bikeshedding of this code. There was a lot of back and forth over naming and documentation, which is extremely important for a tool like this. It may only be a few lines of code, but we needed to nail the developer experience.
There is a caveat, however. Modules using DeprecationHelper
must support a minimum version of 10.1.3 for Drupal core. With the release of Drupal 10.2.0 during the week of December 11, 2023, Drupal 10.0.x will no longer receive security support. That means modules can begin choosing to drop support for 10.0.x
and bump their minimum supported version to 10.1
.
Making drupal-rector backwards compatible
Earlier this year, I wrote about the need to add backward compatibility to automated code fixes provided through Rector. Björn Brala (bbrala) has made this a reality: https://github.com/palantirnet/drupal-rector/pull/250!
As the Project Update Bot delivers automatic code fixes to projects for Drupal 11 compatibility through Rector, we can use DeprecationHelper
to ensure breaking changes are not introduced. This is a giant leap forward in innovation for Drupal as the community works to reduce manual upkeep and maintenance of Drupal sites.
I'm available for one-on-one consulting calls – click here to book a meeting with me 🗓️
Want more? Sign up for my weekly newsletter