Problem/Motivation

A fatal error occurs when creating a new vocabulary with content translation:

  1. Install using the minimal install profile.
  2. Enable Taxonomy, Language and Content Translation.
  3. Go to admin/structure/taxonomy/add.
  4. Enter a name for the vocabulary, check the option Enable translation and click Save.

Result: a fatal error occurs:

Fatal error:  Call to a member function setThirdPartySetting() on null in core/modules/content_translation/src/ContentTranslationManager.php on line 90
Stack trace:
  1. {main}() index.php:0
  2. Drupal\Core\DrupalKernel->handle() index.php:23
  3. Stack\StackedHttpKernel->handle() core/lib/Drupal/Core/DrupalKernel.php:599
  4. Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() core/vendor/stack/builder/src/Stack/StackedHttpKernel.php:23
  5. Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php:65
  6. Drupal\page_cache\StackMiddleware\PageCache->handle() core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php:58
  7. Drupal\page_cache\StackMiddleware\PageCache->pass() core/modules/page_cache/src/StackMiddleware/PageCache.php:83
  8. Drupal\Core\DependencyInjection\Container\prod\Drupal_Core_StackMiddleware_KernelPreHandle_Proxy->handle() core/modules/page_cache/src/StackMiddleware/PageCache.php:104
  9. Drupal\Core\StackMiddleware\KernelPreHandle->handle() sites/default/files/php/service_container/service_container_prod/d60e5a140fd69a30c54dcaf8458526771531ef03b05f7af17937104a08984e6d.php:9209
 10. Drupal\Core\DependencyInjection\Container\prod\Drupal_Core_StackMiddleware_Session_Proxy->handle() core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php:53
 11. Drupal\Core\StackMiddleware\Session->handle() sites/default/files/php/service_container/service_container_prod/d60e5a140fd69a30c54dcaf8458526771531ef03b05f7af17937104a08984e6d.php:9259
 12. Drupal\Core\DependencyInjection\Container\prod\Symfony_Component_HttpKernel_HttpKernel_Proxy->handle() core/lib/Drupal/Core/StackMiddleware/Session.php:62
 13. Symfony\Component\HttpKernel\HttpKernel->handle() sites/default/files/php/service_container/service_container_prod/d60e5a140fd69a30c54dcaf8458526771531ef03b05f7af17937104a08984e6d.php:9149
 14. Symfony\Component\HttpKernel\HttpKernel->handleRaw() core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:66
 15. call_user_func_array:{core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:145}() core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:145
 16. Drupal\Core\Controller\FormController->getContentResult() core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:145
 17. Drupal\Core\Form\FormBuilder->buildForm() core/lib/Drupal/Core/Controller/FormController.php:79
 18. Drupal\Core\Form\FormBuilder->processForm() core/lib/Drupal/Core/Form/FormBuilder.php:258
 19. Drupal\Core\Form\FormSubmitter->doSubmitForm() core/lib/Drupal/Core/Form/FormBuilder.php:500
 20. Drupal\Core\Form\FormSubmitter->executeSubmitHandlers() core/lib/Drupal/Core/Form/FormSubmitter.php:56
 21. call_user_func_array:{core/lib/Drupal/Core/Form/FormSubmitter.php:116}() core/lib/Drupal/Core/Form/FormSubmitter.php:116
 22. content_translation_language_configuration_element_submit() core/lib/Drupal/Core/Form/FormSubmitter.php:116
 23. Drupal\content_translation\ContentTranslationManager->setEnabled() core/modules/content_translation/content_translation.module:509

Proposed resolution

Fix the bug.

Remaining tasks

  1. Identify the problem.
  2. Fix the problem.
  3. Provide a test

User interface changes

None.

API changes

None.

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug
Issue priority Major because it is a fatal error that is easy to replicate.
Disruption Not disruptive

Comments

berdir’s picture

loadContentLanguageSettings() returns NULL if there's no entity_type_id or $bundle. Which looks a bit strange, as those are required arguments. Removing that might actually give you a better error. And if not that, then it should throw an exception instead, again to give you a better error.

Apparently content_translation_language_configuration_element_submit() is unable to extract the correct context, i guess you also get some php notices logged about undefined keys and so on.

pfrenssen’s picture

Title: Calling setThirdPartySetting() on NULL in ContentTranslationManager » Fatal error when creating a translatable vocabulary type

The bundle is NULL because we are creating a new entity type. I can replicate this very easily now, just create a new vocabulary and tick the "Enable translation" checkbox. I'll update the issue summary.

pfrenssen’s picture

Issue summary: View changes
pfrenssen’s picture

Priority: Major » Critical

For some reason the content_translation_language_configuration_element_submit submit handler is present twice in the list of submit handlers. The first one runs before language_configuration_element_submit has the chance to set the bundle on the form state.

pfrenssen’s picture

Priority: Critical » Major

Woops.

pfrenssen’s picture

Status: Active » Needs review
StatusFileSize
new1.23 KB

The first time the content_translation_language_configuration_element_submit handler is added happens in VocabularyForm::actions():

  protected function actions(array $form, FormStateInterface $form_state) {
    // If we are displaying the delete confirmation skip the regular actions.
    if (!$form_state->get('confirm_delete')) {
      $actions = parent::actions($form, $form_state);
      // We cannot leverage the regular submit handler definition because we
      // have button-specific ones here. Hence we need to explicitly set it for
      // the submit action, otherwise it would be ignored.
      if ($this->moduleHandler->moduleExists('content_translation')) {
        array_unshift($actions['submit']['#submit'], 'content_translation_language_configuration_element_submit');
      }
      return $actions;
    }
    else {
      return array();
    }
  }

The second time occurs in content_translation_language_configuration_element_process():

function content_translation_language_configuration_element_process(array $element, FormStateInterface $form_state, array &$form) {
  if (empty($element['#content_translation_skip_alter']) && \Drupal::currentUser()->hasPermission('administer content translation')) {
    // ...
    $submit_name = isset($form['actions']['save_continue']) ? 'save_continue' : 'submit';
    $form['actions'][$submit_name]['#submit'][] = 'content_translation_language_configuration_element_submit';
  }
  return $element;
}

The second was added in #2408439: Language / Translation settings are not saved when adding a new bundle. which makes it look like the first one was never functional.

Let's see if anything breaks if we simply remove the first one.

plach’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Looks quite reasonable to me, thanks. That submit handler was never meant to be added manually. We just need some test coverage now.

pfrenssen’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new1.92 KB
new3.15 KB

Added a test.

The last submitted patch, 8: 2493557-8-test-only.patch, failed testing.

plach’s picture

Status: Needs review » Reviewed & tested by the community

Awesome, thanks!

pfrenssen’s picture

Issue summary: View changes
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 6531264 and pushed to 8.0.x. Thanks!

Thanks for adding the beta evaluation to the issue summary.

  • alexpott committed 6531264 on 8.0.x
    Issue #2493557 by pfrenssen: Fatal error when creating a translatable...

Status: Fixed » Closed (fixed)

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