Problem/Motivation

The translations page of a webform ( /admin/structure/webform/manage/webform_id/translate/langcode/edit ) crashes with an error if a custom email handler is enabled in the webform.

Steps to reproduce

Create a custom webform handler:


use Drupal\webform\Plugin\WebformHandler\EmailWebformHandler;

/**
 * Test custom webform handler
 *
 * @WebformHandler(
 *   id = "custom_webform_handler",
 *   label = @Translation("Custom webform handler"),
 *   category = @Translation("Custom webform handler"),
 *   description = @Translation("Test webform handler."),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_UNLIMITED,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 *   submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_OPTIONAL,
 *   tokens = TRUE,
 * )
 */
class CustomWebformHandler extends EmailWebformHandler {
}

Add and enable it in your webform under admin/structure/webform/manage/webform_id/handlers , then fill in the required fields in the settings.

You can see that the handlers list page does not show the configuration of this handler, the same way that a normal email handler would show it (it is missing for example: To, From, Subject, Settings, Sent when). This issue existed also when I was on version 6.0.1.

You open the webform translation page ( /admin/structure/webform/manage/webform_id/translate/langcode/edit ) and it crashes with an error. This part was fine when I was on version 6.0.1 though it could be that the reason is not the webform module upgrade. The error looks like this:

TypeError: Argument 1 passed to Drupal\webform\WebformTranslationConfigManager::alterTextareaElement() must be of the type array, null given, called in /var/www/html/web/modules/contrib/webform/src/WebformTranslationConfigManager.php on line 336 in Drupal\webform\WebformTranslationConfigManager->alterTextareaElement() (line 895 of /var/www/html/web/modules/contrib/webform/src/WebformTranslationConfigManager.php)

#0 /var/www/html/web/modules/contrib/webform/src/WebformTranslationConfigManager.php(336): Drupal\webform\WebformTranslationConfigManager->alterTextareaElement(NULL, 'twig')
#1 /var/www/html/web/modules/contrib/webform/src/WebformTranslationConfigManager.php(237): Drupal\webform\WebformTranslationConfigManager->alterConfigWebformFormHandlers('webform.webform...', Array, Array, Object(Drupal\Core\Form\FormState))
#2 /var/www/html/web/modules/contrib/webform/src/WebformTranslationConfigManager.php(128): Drupal\webform\WebformTranslationConfigManager->alterConfigWebformForm('webform.webform...', Array, Array, Object(Drupal\Core\Form\FormState))
#3 /var/www/html/web/modules/contrib/webform/includes/webform.translation.inc(75): Drupal\webform\WebformTranslationConfigManager->alterForm(Array, Object(Drupal\Core\Form\FormState))
#4 /var/www/html/web/core/lib/Drupal/Core/Extension/ModuleHandler.php(539): webform_form_config_translation_edit_form_alter(Array, Object(Drupal\Core\Form\FormState), 'config_translat...')
#5 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(836): Drupal\Core\Extension\ModuleHandler->alter('form', Array, Object(Drupal\Core\Form\FormState), 'config_translat...')
#6 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(279): Drupal\Core\Form\FormBuilder->prepareForm('config_translat...', Array, Object(Drupal\Core\Form\FormState))
#7 /var/www/html/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\config_translation\Form\ConfigTranslationEditForm), Object(Drupal\Core\Form\FormState))
#8 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#9 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#10 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#11 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#12 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#13 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#14 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#15 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(706): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#24 {main}

In practice in the alterConfigWebformFormHandlers() method in the $config_element the handler with $handler_id == 'custom_webform_handler' does not have any settings for it, unlike a normal email handler (without a custom subclass) would.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#13 3215471-webform.patch573 bytesraminu
#3 3215471-3.patch1.61 KBjrockowitz

Comments

nikolay.m created an issue. See original summary.

jrockowitz’s picture

New community member and active community member requests will be prioritized.
Please consider getting involved, funding development, and hiring professional support.
jrockowitz’s picture

Status: Active » Needs review
StatusFileSize
new1.61 KB
nikolay.m’s picture

Status: Needs review » Needs work

Hello, and thank you @jrockowitz so much for pushing a patch so fast!

I tried the patch from #3 and loading the translation interface succeeds. However, when I press the save button it gets a different kind of error:

TypeError: Argument 4 passed to Drupal\webform\Twig\WebformTwigExtension::webformToken() must be of the type array, null given, called in /var/www/html/web/sites/default/files/php/twig/60acd221b19be___string_template__8e363a_tFFTrhMFJOlZuiJfU1qVVgLaI/4phA_ainXAM6L_34R9skH7i5RvOtVoNouwQ3d1qLE3k.php on line 43 funktiossa Drupal\webform\Twig\WebformTwigExtension->webformToken() (rivi 102 tiedostossa /var/www/html/web/modules/contrib/webform/src/Twig/WebformTwigExtension.php)

#0 /var/www/html/web/sites/default/files/php/twig/60acd221b19be___string_template__8e363a_tFFTrhMFJOlZuiJfU1qVVgLaI/4phA_ainXAM6L_34R9skH7i5RvOtVoNouwQ3d1qLE3k.php(43): Drupal\webform\Twig\WebformTwigExtension->webformToken('[webform_submis...', NULL, Array, NULL)
#1 /var/www/html/vendor/twig/twig/src/Template.php(405): __TwigTemplate_9f3a27b5b4001b855703b90e66bd8d0501582e6de61ed6594d6951d465588c59->doDisplay(Array, Array)
#2 /var/www/html/vendor/twig/twig/src/Template.php(378): Twig\Template->displayWithErrorHandling(Array, Array)
#3 /var/www/html/vendor/twig/twig/src/Template.php(390): Twig\Template->display(Array)
#4 /var/www/html/vendor/twig/twig/src/TemplateWrapper.php(45): Twig\Template->render(Array, Array)
#5 /var/www/html/web/core/lib/Drupal/Core/Template/TwigEnvironment.php(235): Twig\TemplateWrapper->render(Array)
#6 /var/www/html/web/core/lib/Drupal/Core/Render/Element/InlineTemplate.php(52): Drupal\Core\Template\TwigEnvironment->renderInline('{# inline_templ...', Array)
#7 [internal function]: Drupal\Core\Render\Element\InlineTemplate::preRenderInlineTemplate(Array)
#8 /var/www/html/web/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php(101): call_user_func_array(Array, Array)
#9 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(781): Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_ren...', 'exception', 'Drupal\\Core\\Ren...')
#10 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(372): Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array)
#11 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(200): Drupal\Core\Render\Renderer->doRender(Array, true)
#12 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(156): Drupal\Core\Render\Renderer->render(Array, true)
#13 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}()
#14 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(157): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#15 /var/www/html/web/modules/contrib/webform/src/Element/WebformCodeMirror.php(322): Drupal\Core\Render\Renderer->renderPlain(Array)
#16 /var/www/html/web/modules/contrib/webform/src/Element/WebformCodeMirror.php(193): Drupal\webform\Element\WebformCodeMirror::validateTwig(Array, Object(Drupal\Core\Form\FormState), Array)
#17 /var/www/html/web/modules/contrib/webform/src/Element/WebformCodeMirror.php(147): Drupal\webform\Element\WebformCodeMirror::getErrors(Array, Object(Drupal\Core\Form\FormState), Array)
#18 [internal function]: Drupal\webform\Element\WebformCodeMirror::validateWebformCodeMirror(Array, Object(Drupal\Core\Form\FormState), Array)
#19 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(280): call_user_func_array(Array, Array)
#20 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#21 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#22 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#23 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#24 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#25 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#26 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#27 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(236): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState))
#28 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(118): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState), 'config_translat...')
#29 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(589): Drupal\Core\Form\FormValidator->validateForm('config_translat...', Array, Object(Drupal\Core\Form\FormState))
#30 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(321): Drupal\Core\Form\FormBuilder->processForm('config_translat...', Array, Object(Drupal\Core\Form\FormState))
#31 /var/www/html/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\config_translation\Form\ConfigTranslationEditForm), Object(Drupal\Core\Form\FormState))
#32 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#33 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#34 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#35 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#36 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#37 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#38 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#39 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#40 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#41 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#42 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#43 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#44 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#45 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#46 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(706): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#47 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#48 {main}

On the translation page when I preview my email handlers that don't use a custom class they have a lot of extra things that can be translated, compared to my email handlers that use a custom class. That's not a big issue to me at least though so I liked your approach that the attempt is to simply get the translation interface to work again.

jrockowitz’s picture

Status: Needs work » Postponed (maintainer needs more info)

I am not able to replicate that issue because it is coming from custom code.

If you can post a very simple example module that can be used to replicate this issue, I should be able to fix it.

antoniya’s picture

Also hitting this on 6.0.3 with one custom handler for multiple webforms. The patch in #3 helps work around the issue, I was able to edit a webform translation and save it. Thanks @jrockowitz!

paulocs’s picture

Hallo @antoniya?
Could you please post a simple module with the EmailWebformHandler so we can be able to reproduce the error?

Cheers, Paulo.

antoniya’s picture

hi @paulocs, you can easily reproduce the error using the example email handler from this page.

It looks like some code was added recently to improve the UX of the translation form in https://www.drupal.org/node/3202515. In my case, the form crashes on WebformTranslationConfigManager::alterHtmlEditorElement (line 340), so just a few lines later than the usage of WebformTranslationConfigManager::alterTextareaElement (which is the original report of this issue).

For what I can tell so far is that $config_element['handlers'][$handler_id] in custom handlers doesn't have a 'settings' key and so $body_element ends up being NULL for those (s. usage of Drupal\Component\Utility\NestedArray on line 333).

Here's the exact error message for the sake of completeness:

The website encountered an unexpected error. Please try again later.
TypeError: Argument 1 passed to Drupal\webform\WebformTranslationConfigManager::alterHtmlEditorElement() must be of the type array, null given, called in /var/www/d9dev/web/modules/contrib/webform/src/WebformTranslationConfigManager.php on line 340 in Drupal\webform\WebformTranslationConfigManager->alterHtmlEditorElement() (line 879 of modules/contrib/webform/src/WebformTranslationConfigManager.php).
Drupal\webform\WebformTranslationConfigManager->alterHtmlEditorElement(NULL) (Line: 340)
Drupal\webform\WebformTranslationConfigManager->alterConfigWebformFormHandlers('webform.webform.contact', Array, Array, Object) (Line: 237)
Drupal\webform\WebformTranslationConfigManager->alterConfigWebformForm('webform.webform.contact', Array, Array, Object) (Line: 128)
Drupal\webform\WebformTranslationConfigManager->alterForm(Array, Object) (Line: 75)
webform_form_config_translation_edit_form_alter(Array, Object, 'config_translation_edit_form') (Line: 539)
Drupal\Core\Extension\ModuleHandler->alter('form', Array, Object, 'config_translation_edit_form') (Line: 836)
Drupal\Core\Form\FormBuilder->prepareForm('config_translation_edit_form', Array, Object) (Line: 279)
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: 573)
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: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
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: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 706)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
jrockowitz’s picture

Status: Postponed (maintainer needs more info) » Fixed

Since the main issue issue is resolved via the patch, I committed it. Please create a new ticket for the second issue from #4.

  • jrockowitz authored 190db46 on 6.x
    Issue #3215471 by jrockowitz: Translation interface not reachable when...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

raminu’s picture

This patch fixes it

--- /src/Twig/WebformTwigExtension.php	2021-09-08 19:43:44.000000000 +0300
+++ /src/Twig/WebformTwigExtension.php	2021-09-08 19:49:39.000000000 +0300
@@ -99,7 +99,7 @@
    *
    * @see \Drupal\Core\Utility\Token::replace
    */
-  public function webformToken($token, EntityInterface $entity = NULL, array $data = [], array $options = []) {
+  public function webformToken($token, EntityInterface $entity = NULL, array $data = [], $options = []) {
     // Allow the webform_token function to be tested during validation without
     // a valid entity.
     if (!$entity) {
raminu’s picture

StatusFileSize
new573 bytes

Quick-fixed it with this by removing webformToken function's last parameter type checking.

guillaumeduveau’s picture

With 6.0.5, in which this patch is included, I still have the original issue of the settings summary not appearing. I must add a hook_token and a template for it to appear.

As for the translation page, it does not crash, but there's no Email accordion with the settings. Guess I must add a .yml file for the config translation as well.