Problem/Motivation
When using the recently released PHP 5.4.24 (dotdeb), the Text editor administration test fails in a rather spectacular way with the following message/trace.
Fatal error: Call to a member function getDefinition() on a non-object in core/lib/Drupal/Core/Plugin/Factory/ContainerFactory.php on line 20
Stack trace:
1. {main}() index.php:0
2. drupal_handle_request() index.php:15
3. Drupal\\Core\\DrupalKernel->handle() core/includes/bootstrap.inc:1842
4. Drupal\\Core\\HttpKernel->handle() core/lib/Drupal/Core/DrupalKernel.php:283
5. Symfony\\Component\\HttpKernel\\HttpKernel->handle() core/lib/Drupal/Core/HttpKernel.php:52
6. Symfony\\Component\\HttpKernel\\HttpKernel->handleRaw() core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:66
7. call_user_func_array() core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:126
8. Drupal\\Core\\Controller\\AjaxController->content() core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:126
9. Drupal\\Core\\Controller\\AjaxController->getContentResult() core/lib/Drupal/Core/Controller/AjaxController.php:53
10. call_user_func_array() core/lib/Drupal/Core/Controller/AjaxController.php:110
11. Drupal\\system\\Controller\\FormAjaxController->content() core/lib/Drupal/Core/Controller/AjaxController.php:110
12. drupal_process_form() core/modules/system/lib/Drupal/system/Controller/FormAjaxController.php:37
13. Drupal\\Core\\Form\\FormBuilder->processForm() core/includes/form.inc:233
14. Drupal\\Core\\Form\\FormBuilder->rebuildForm() core/lib/Drupal/Core/Form/FormBuilder.php:685
15. Drupal\\Core\\Form\\FormBuilder->prepareForm() core/lib/Drupal/Core/Form/FormBuilder.php:342
16. Drupal\\Core\\Extension\\ModuleHandler->alter() core/lib/Drupal/Core/Form/FormBuilder.php:834
17. editor_form_filter_format_form_alter() core/lib/Drupal/Core/Extension/ModuleHandler.php:406
18. Drupal\\Component\\Plugin\\PluginManagerBase->createInstance() core/modules/editor/editor.module:222
19. Drupal\\Core\\Plugin\\Factory\\ContainerFactory->createInstance() core/lib/Drupal/Component/Plugin/PluginManagerBase.php:65
Upon closer inspection I traced down the origin of this problem to the following code fragment from the editor.module:
159 function editor_form_filter_format_form_alter(&$form, &$form_state) {
160 if (!isset($form_state['editor'])) {
161 $format_id = $form_state['controller']->getEntity()->id();
162 $form_state['editor'] = editor_load($format_id);
163 $form_state['editor_manager'] = \Drupal::service('plugin.manager.editor');
164 }
165 $editor = $form_state['editor'];
166 $manager = $form_state['editor_manager'];
The problem is that when using 5.4.24, $form_state['editor_manager']->factory->discovery
somehow turns into an empty array()
upon a form-rebuild. This will blow up during the invocation of ContainerFactory->createInstance()
further down:
220 // Add editor-specific validation and submit handlers.
221 if ($editor) {
222 $plugin = $manager->createInstance($editor->editor);
@berdir pointed out that it is complete nonsense to cache a service anyway.
Proposed resolution
Do not attempt to cache the editor-manager instance.
Comment | File | Size | Author |
---|---|---|---|
#1 | 2182077-do-not-cache-manager-service-in-form-state.diff | 875 bytes | znerol |
Comments
Comment #1
znerol CreditAttribution: znerol commentedComment #2
Wim LeersHah, I have no idea why we did it that way. I totally agree with @berdir's "complete nonsense" statement :)
Code changes look good, tests are green, manual testing doesn't reveal any problems.
Thank you!
Comment #3
Wim LeersComment #4
Damien Tournoud CreditAttribution: Damien Tournoud commentedIt would be a good idea to figure out why this is failing the way it is on this particular version of PHP.
Comment #5
znerol CreditAttribution: znerol commentedYes indeed. I will post a new issue as soon as I find the time to take a closer look.
Comment #6
SebCorbin CreditAttribution: SebCorbin commentedSame thing here with PHP 5.4.10.
Patch tested manually and works nicely!
Comment #7
webchickCommitted and pushed to 8.x. Thanks!
Comment #8
yched CreditAttribution: yched commentedBumped into that same behavior and came up with the same fix in #2190643: Serializing the container is a very very bad idea, let's prevent it?, so, great :-)
From the OP:
On my localhost (5.5.3), $form_state['editor_manager']->factory->discovery was == 'breakpoint' (string)
(its normal value should be a reference to the editor_manager object itself)
Serialization is full of worrying surprises across versions of PHP :-/