Tasks to solve before upgrading to Drupal 9.0.0-alpha2
The second alpha release of Drupal 9 caused much fewer issues in my site. Mainly, I only had to deal with a single, really specific problem across all the contrib modules I use.
Earlier, in 2017 and 2018, some of Drupal’s security releases have shown that the render system needs to be stricter about what it allows to be called by a callback. And almost a year ago, we also got a solution: https://dgo.to/2966725. If we check Drupal 9.0.0-alpha2 release notes, it highlights only one major thing (imho):
In this alpha release all previously deprecated APIs have been removed. This means that 9.0.0-alpha2 essentially has the same backend API that 9.0.0 will have, so module developers and site owners can confidently test their modules with 9.0.0-alpha2.
For my site, this meant that I had to patch some contributed modules which missed tracking this change record.
I applied the following pattern for every single procedural #pre_render
callback:
- New PHP class in the module’s src folder with
namespace Drupal\[module_name]
; class name:ModuleNamePreRender
. - Class implements
\Drupal\Core\Security\TrustedCallbackInterface
. - The new class mirrors the procedural
module_name_pre_render()
function as an appropriatepublic static moduleNamePreRender()
class method, which reuses the pre-existing procedural function.
For instance, in the case of Admin Toolbar, the pre render function that I had to fix was admin_toolbar_prerender_toolbar_administration_tray()
. So I changed admin_toolbar.module
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
diff --git a/admin_toolbar.module b/admin_toolbar.module
index 3c5e81b..918c622 100755
--- a/admin_toolbar.module
+++ b/admin_toolbar.module
@@ -10,12 +10,13 @@ use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Component\Utility\Html;
use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\admin_toolbar\AdminToolbarPreRender;
/**
* Implements hook_toolbar_alter().
*/
function admin_toolbar_toolbar_alter(&$items) {
- $items['administration']['tray']['toolbar_administration']['#pre_render'] = ['admin_toolbar_prerender_toolbar_administration_tray'];
+ $items['administration']['tray']['toolbar_administration']['#pre_render'] = [[AdminToolbarPreRender::class, 'adminToolbarPrerenderToolbarAdministrationTray']];
$items['administration']['#attached']['library'][] = 'admin_toolbar/toolbar.tree';
$admin_toolbar_tools = \Drupal::service('module_handler')
->moduleExists('admin_toolbar_tools');
…and I added a new shim class AdminToolbarPreRender
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
namespace Drupal\admin_toolbar;
use Drupal\Core\Security\TrustedCallbackInterface;
class AdminToolbarPreRender implements TrustedCallbackInterface {
/**
* Pre-renders the toolbar's administration tray.
*
* @param array $element
* A renderable array.
*
* @return array
* The updated renderable array.
*/
public static function adminToolbarPrerenderToolbarAdministrationTray(array $element) {
$element = admin_toolbar_prerender_toolbar_administration_tray($element);
return $element;
}
/**
* {@inheritdoc}
*/
public static function trustedCallbacks() {
return ['adminToolbarPrerenderToolbarAdministrationTray'];
}
}
I also had to apply the pattern above for:
- Admin Toolbar
- CAPTCHA
- Field Group
- Token
Simple cases
These where the modules where I only had to add the missing TrustedCallbackInterface
to a preexisting PHP class and define the trustable callbacks:
- Bootstrap (8.x-3.x)
- Entity Browser
- Entity Embed
- For the render elements of Field Group
- Page Manager
- Slick Carousel
For example, the patch I added to Entity Embed was this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
diff --git a/src/Plugin/entity_embed/EntityEmbedDisplay/EntityReferenceFieldFormatter.php b/src/Plugin/entity_embed/EntityEmbedDisplay/EntityReferenceFieldFormatter.php
index a8f8ffe..be58992 100644
--- a/src/Plugin/entity_embed/EntityEmbedDisplay/EntityReferenceFieldFormatter.php
+++ b/src/Plugin/entity_embed/EntityEmbedDisplay/EntityReferenceFieldFormatter.php
@@ -11,6 +11,7 @@ use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\entity_embed\EntityEmbedDisplay\FieldFormatterEntityEmbedDisplayBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Security\TrustedCallbackInterface;
/**
* Entity Embed Display reusing entity reference field formatters.
@@ -25,7 +26,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
* supports_image_alt_and_title = TRUE
* )
*/
-class EntityReferenceFieldFormatter extends FieldFormatterEntityEmbedDisplayBase {
+class EntityReferenceFieldFormatter extends FieldFormatterEntityEmbedDisplayBase implements TrustedCallbackInterface {
/**
* The configuration factory.
@@ -194,4 +195,11 @@ class EntityReferenceFieldFormatter extends FieldFormatterEntityEmbedDisplayBase
return $build;
}
+ /**
+ * {@inheritdoc}
+ */
+ public static function trustedCallbacks() {
+ return ['disableContextualLinks', 'disableQuickEdit'];
+ }
+
}
Missing config_export
definition in @ConfigEntityType
annotations
I have two custom config entity types on this page which were using their config schema as a fallback for their missing config_export
definition. This was also a deprecated feature and was removed in this second alpha release.