Our configuration
- Drupal Core 8.3.4
- Display Suite 8.x-3.1
- Panelizer 8.x-4.0
- Panels 8.x-4.1
- Workbench moderation 8.x-1.2
The problem
We experienced Fatal error: Call to a member function id() on null in .../docroot/modules/contrib/ds/ds.module on line 640
when editing a node and saving it.
The problem is in the "Display Suite" (ds
) module. The line $entity_id = $variables['content']['#' . $variables['content']['#entity_type']]->id();
in ds_theme_suggestions_alter()
function implementing the hook hook_theme_suggestions_alter()
tries to access $variables['content']['#node']
value which does not exist. The code is executed only for the base theme hook ds_entity_view
. What is strange is that the value $variables['content']['#entity']
exists and probably should be used instead.
I suspect that there may have been dona related change in the Drupal Core. We updated the Drupal Core from 8.3.2
to 8.3.4
recently. Other option would be that some contrib module is hiding the $variables['content']['#node']
value, suspected contribs: panels
, panelizer
.
I believe the problem is more about the rendering system than the theming system.
Deeper Investigation
The code line mentioned above $entity_id = $variables['content']['#' . $variables['content']['#entity_type']]->id();
is part of old commit:
1d553a3 aspilicious on 24/11/15 at 3:54 AM (committed by Bram Goffings) [ds]
Issue #2503653 by aspilicious, bceyssens: Per node template suggestion
The problem has to be caused by a more recent action.
During the node's post save process a node_access_records()
hook is invoked and "Search API" kicks in and the search_api_node_access_records_alter()
function is run. The inserted or updated items are tracked by "Search API" so the entity is rendered for indexing reasons and this triggers the "Display Suite" function ds_theme_suggestions_alter()
. We have the content type indexed by "Search API".
The entity built rendered array used as a $variables
parameter for the ds_theme_suggestions_alter()
@ function is built in following steps:
* Drupal\search_api\Datasource\DatasourceInterface::viewItem(ComplexDataInterface $item, $view_mode, $langcode = NULL)
* Drupal\search_api\Plugin\search_api\datasource\ContentEntity::viewItem(ComplexDataInterface $item, $view_mode, $langcode = NULL)
* Drupal\panelizer\PanelizerEntityViewBuilder::view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL)
* Drupal\panelizer\PanelizerEntityViewBuilder::buildPanelized(EntityInterface $entity, PanelsDisplayVariant $panels_display, $view_mode, $langcode)
contains a code:
$build = [
'#theme' => [
'panelizer_view_mode__' . $this->entityTypeId . '__' . $entity->id(),
'panelizer_view_mode__' . $this->entityTypeId . '__' . $entity->bundle(),
'panelizer_view_mode__' . $this->entityTypeId,
'panelizer_view_mode',
],
'#panelizer_plugin' => $this->getPanelizerPlugin(),
'#panels_display' => $panels_display,
'#entity' => $entity,
'#view_mode' => $view_mode,
'#langcode' => $langcode,
'content' => $panels_display->build(),
];
that was added/modified in the commit:
9fb5cd6 David Snopek on 30/01/16 at 2:05 AM [panelizer]
Correctly render teaser (and similar non-full.view modes).
so it is there for quite a while. It means that the $variables['content']['#entity']
value is not a new thing.
Additional info
We also updated twig/twig
package from v1.33.2
to v1.34.3
. I checked it and it should not be able to change the built entity rendered array in any way (at least I believe).