diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module index 6d2559a90b848d564e8c7ee5ee3ea76819e4d31e..5628bf0d45db96213fe7715d64f4a9c59e4d16b9 100644 --- a/core/modules/responsive_image/responsive_image.module +++ b/core/modules/responsive_image/responsive_image.module @@ -91,10 +91,20 @@ function responsive_image_theme() { * - url: An optional \Drupal\Core\Url object. */ function template_preprocess_responsive_image_formatter(&$variables) { - $variables['responsive_image'] = array( - '#type' => 'responsive_image', - '#responsive_image_style_id' => $variables['responsive_image_style_id'], - ); + // Provide fallback to standard image if valid responsive image style is not + // provided in the responsive image formatter. + $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']); + if ($responsive_image_style) { + $variables['responsive_image'] = array( + '#type' => 'responsive_image', + '#responsive_image_style_id' => $variables['responsive_image_style_id'], + ); + } + else { + $variables['responsive_image'] = array( + '#theme' => 'image', + ); + } $item = $variables['item']; $attributes = array(); // Do not output an empty 'title' attribute. @@ -147,6 +157,13 @@ function template_preprocess_responsive_image(&$variables) { $image = \Drupal::service('image.factory')->get($variables['uri']); $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']); + // If a responsive image style is not selected, log the error and stop + // execution. + if (!$responsive_image_style) { + $variables['img_element'] = []; + \Drupal::logger('responsive_image')->log(\Drupal\Core\Logger\RfcLogLevel::ERROR, 'Failed to load responsive image style: “@style“ while displaying responsive image.', ['@style' => $variables['responsive_image_style_id']]); + return; + } // Retrieve all breakpoints and multipliers and reverse order of breakpoints. // By default, breakpoints are ordered from smallest weight to largest: // the smallest weight is expected to have the smallest breakpoint width, diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php index 410bd893c478d305d6ce11fbf2d8532d6295b9c4..06fd862346596b407791dca352f471ecf45bfd69 100644 --- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php +++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php @@ -12,6 +12,7 @@ use Drupal\image\Entity\ImageStyle; use Drupal\node\Entity\Node; use Drupal\file\Entity\File; +use Drupal\responsive_image\Plugin\Field\FieldFormatter\ResponsiveImageFormatter; use Drupal\user\RoleInterface; /** @@ -190,6 +191,28 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = ); $default_output = str_replace("\n", NULL, $renderer->renderRoot($image)); $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.'); + + // Test field not being configured. This should not cause a fatal error. + $display_options = array( + 'type' => 'responsive_image_test', + 'settings' => ResponsiveImageFormatter::defaultSettings(), + ); + $display = $this->container->get('entity.manager') + ->getStorage('entity_view_display') + ->load('node.article.default'); + if (!$display) { + $values = [ + 'targetEntityType' => 'node', + 'bundle' => 'article', + 'mode' => 'default', + 'status' => TRUE, + ]; + $display = $this->container->get('entity.manager')->getStorage('entity_view_display')->create($values); + } + $display->setComponent($field_name, $display_options)->save(); + + $this->drupalGet('node/' . $nid); + // Test theme function for responsive image, but using the test formatter. $display_options = array( 'type' => 'responsive_image_test',