Problem/Motivation
This module fails spectacularly on Drupal 10:
ArgumentCountError: Too few arguments to function Twig\Environment::loadTemplate(), 1 passed in /var/www/html/web/modules/contrib/config_enforce_devel/src/TargetModuleBuilder.php on line 342 and at least 2 expected in Twig\Environment->loadTemplate() (line 330 of /var/www/html/vendor/twig/twig/src/Environment.php).
Drupal\config_enforce_devel\TargetModuleBuilder->getInfoFileContents() (Line: 287)
Drupal\config_enforce_devel\TargetModuleBuilder->writeInfoFile() (Line: 149)
Drupal\config_enforce_devel\TargetModuleBuilder->createModule() (Line: 93)
Drupal\config_enforce_devel\TargetModuleCollection->ensureDefaultTargetModuleIsSet() (Line: 50)
Drupal\config_enforce_devel\TargetModuleCollection->getDefaultTargetModule() (Line: 534)
Drupal\config_enforce_devel\Form\EnforcedConfigs->getTargetModuleField() (Line: 185)
Drupal\config_enforce_devel\Form\EnforcedConfigs->addUpdateTargetModule() (Line: 170)
Drupal\config_enforce_devel\Form\EnforcedConfigs->addUpdateEnforcedConfigs() (Line: 32)
Drupal\config_enforce_devel\Form\EnforcedConfigs->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 536)
Drupal\Core\Form\FormBuilder->retrieveForm('config_enforce_enforced_configs_form', Object) (Line: 283)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 163)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 74)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 686)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Steps to reproduce
Install "Config Enforce - Devel" on a Drupal 10 site; navigate to the "Enforced configs" overview page; get the above fatal error.
Proposed resolution
It looks like this is due to
Drupal 10 upgrading the Twig major version from 2.x to 3.4.3 →
; the method that we call to render the template now expects two parameters rather than the one we're passing it.
Compare v2.15.3 (in Drupal 9.5) and v3.5.1 (in Drupal 10.0).
Given that the function is marked as @internal
, that it specifically states that it should never be called externally, and that we can do the same thing by rendering a render array of '#type' => 'inline_template'
, we should refactor this so doesn't need to call Twig directly but use the Drupal renderer and let it handle all this for us.
So instead of
return (string) \Drupal::service('twig')
->loadTemplate($template)
->render([
'name' => $this->getName(),
'description' => $this->getDescription(),
// Needed to prevent notices when Twig debugging is enabled.
'theme_hook_original' => 'not-applicable',
]);
we do
/** @var array Render array for the extension .info.yml contents. */
$renderArray = [
'#type' => 'inline_template',
'#template' => \file_get_contents($template),
'#context' => [
'name' => $this->getName(),
'description' => $this->getDescription(),
],
];
return (string) $this->renderer->renderPlain($renderArray);
Remaining tasks
Make the above changes.
User interface changes
None, well, other than not throwing a fatal error.
API changes
None.
Data model changes
None.