SVG-only image fields cause error with Layout Builder

Created on 10 September 2020, over 4 years ago
Updated 19 September 2023, about 1 year ago

Problem/Motivation

If you create an image field that only allows SVG files (by setting "svg" as the only extension), and you enable Layout Builder for the entity's display, you get a fatal error like this when trying to "Manage layout" for the entity:

Error: Call to undefined function image() in Drupal\Component\Utility\Random->image() (line 299 of /app/web/core/lib/Drupal/Component/Utility/Random.php)
#0 /app/web/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php(357): Drupal\Component\Utility\Random->image('/tmp/generateIm...', '100x100', '600x600')
#1 /app/web/core/lib/Drupal/Core/Field/FieldItemList.php(253): Drupal\image\Plugin\Field\FieldType\ImageItem::generateSampleValue(Object(Drupal\field\Entity\FieldConfig))
#2 /app/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(162): Drupal\Core\Field\FieldItemList->generateSampleItems()
#3 /app/web/core/modules/layout_builder/src/Entity/LayoutBuilderSampleEntityGenerator.php(55): Drupal\Core\Entity\ContentEntityStorageBase->createWithSampleValues('location')
#4 /app/web/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php(267): Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator->get('taxonomy_term', 'location')
#5 /app/web/core/modules/layout_builder/src/Context/LayoutBuilderContextTrait.php(49): Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->getContextsDuringPreview()
#6 /app/web/core/modules/layout_builder/src/Element/LayoutBuilder.php(250): Drupal\layout_builder\Element\LayoutBuilder->getAvailableContexts(Object(Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage))
#7 /app/web/core/modules/layout_builder/src/Element/LayoutBuilder.php(123): Drupal\layout_builder\Element\LayoutBuilder->buildAdministrativeSection(Object(Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage), 0)
#8 /app/web/core/modules/layout_builder/src/Element/LayoutBuilder.php(97): Drupal\layout_builder\Element\LayoutBuilder->layout(Object(Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage))
#9 [internal function]: Drupal\layout_builder\Element\LayoutBuilder->preRender(Array)
#10 /app/web/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php(100): call_user_func_array(Array, Array)
#11 /app/web/core/lib/Drupal/Core/Render/Renderer.php(781): Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_ren...', 'silenced_deprec...', 'Drupal\\Core\\Ren...')
#12 /app/web/core/lib/Drupal/Core/Render/Renderer.php(372): Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array)
#13 /app/web/core/lib/Drupal/Core/Render/Renderer.php(444): Drupal\Core\Render\Renderer->doRender(Array)
#14 /app/web/core/lib/Drupal/Core/Render/Renderer.php(200): Drupal\Core\Render\Renderer->doRender(Array, false)
#15 /app/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(226): Drupal\Core\Render\Renderer->render(Array, false)
#16 /app/web/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
#17 /app/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(227): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#18 /app/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(117): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
#19 /app/web/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
#20 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#21 /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#22 /app/vendor/symfony/http-kernel/HttpKernel.php(156): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent))
#23 /app/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#24 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#27 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#28 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#29 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#30 /app/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#31 /app/web/core/lib/Drupal/Core/DrupalKernel.php(708): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#32 /app/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#33 {main}

This is happening first because \Drupal\Component\Utility\Random::image() is getting called with a $destination with no file extension. This leads to it trying to call a non-existent function named image() here:

    $save_function = 'image' . ($extension == 'jpg' ? 'jpeg' : $extension);
    $save_function($im, $destination);

But, even if the proper extension (.svg) were passed in to this function, the function imagesvg() doesn't exist. Note that functions like imagepng(), imagejpeg(), etc. are defined by GD.

Steps to reproduce

  1. Create image field with "Allowed file extensions" set to "svg" only.
  2. Check "Use Layout Builder" for the entity under "Manage display", save settings.
  3. Click "Manage layout".

Proposed resolution

Would need to make sure the proper extension is passed to \Drupal\Component\Utility\Random::image(), then define a function imagesvg(). Or, update \Drupal\Component\Utility\Random::image() to check that the image function it's trying to call actually exists and use some type of fallback if it doesn't. This second option would make this a core bug, I guess.

Workaround

To just get things working, you can add a second allowable file extension for the field like "png, svg". This other extension probably needs to be first. This will allow Layout builder to use a random image that it can actually generate.

๐Ÿ› Bug report
Status

Active

Version

1.14

Component

Code

Created by

๐Ÿ‡บ๐Ÿ‡ธUnited States jrb Raleigh-Durham Area, NC, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • ๐Ÿ‡จ๐Ÿ‡ดColombia canomogollon

    Same error, i have to avoid de SVG only image and use png / WEBp and the drupal work.

    Drupal: 9.5.10
    PHP: 7.4
    Mysql

    Error: Call to undefined function imagetmp() en Drupal\Component\Utility\Random->image() (lรญnea 300 de \htdocs\cluster\web\core\lib\Drupal\Component\Utility\Random.php)
    
    #0 \htdocs\cluster\web\core\modules\image\src\Plugin\Field\FieldType\ImageItem.php(352): Drupal\Component\Utility\Random->image('htdocs...', '90x90', '256x256')
    #1 \htdocs\cluster\web\core\lib\Drupal\Core\Field\FieldItemList.php(253): Drupal\image\Plugin\Field\FieldType\ImageItem::generateSampleValue(Object(Drupal\field\Entity\FieldConfig))
    #2 \htdocs\cluster\web\core\lib\Drupal\Core\Entity\ContentEntityStorageBase.php(245): Drupal\Core\Field\FieldItemList->generateSampleItems()
    #3 \htdocs\cluster\web\core\modules\layout_builder\src\Entity\LayoutBuilderSampleEntityGenerator.php(55): Drupal\Core\Entity\ContentEntityStorageBase->createWithSampleValues('sectorcompetiti...')
    #4 \htdocs\cluster\web\core\modules\layout_builder\src\Plugin\SectionStorage\DefaultsSectionStorage.php(229): Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator->get('node', 'sectorcompetiti...')
    #5 \htdocs\cluster\web\core\modules\layout_builder\src\Context\LayoutBuilderContextTrait.php(71): Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->getContextsDuringPreview()
    #6 \htdocs\cluster\web\core\modules\layout_builder\src\Element\LayoutBuilder.php(236): Drupal\layout_builder\Element\LayoutBuilder->getPopulatedContexts(Object(Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage))
    #7 \htdocs\cluster\web\core\modules\layout_builder\src\Element\LayoutBuilder.php(124): Drupal\layout_builder\Element\LayoutBuilder->buildAdministrativeSection(Object(Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage), 0)
    #8 \htdocs\cluster\web\core\modules\layout_builder\src\Element\LayoutBuilder.php(98): Drupal\layout_builder\Element\LayoutBuilder->layout(Object(Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage))
    #9 [internal function]: Drupal\layout_builder\Element\LayoutBuilder->preRender(Array)
    #10 \htdocs\cluster\web\core\lib\Drupal\Core\Security\DoTrustedCallbackTrait.php(101): call_user_func_array(Array, Array)
    #11 \htdocs\cluster\web\core\lib\Drupal\Core\Render\Renderer.php(788): Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_ren...', 'exception', 'Drupal\\Core\\Ren...')
    #12 \htdocs\cluster\web\core\lib\Drupal\Core\Render\Renderer.php(374): Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array)
    #13 \htdocs\cluster\web\core\lib\Drupal\Core\Render\Renderer.php(446): Drupal\Core\Render\Renderer->doRender(Array)
    #14 \htdocs\cluster\web\core\lib\Drupal\Core\Render\Renderer.php(204): Drupal\Core\Render\Renderer->doRender(Array, false)
    #15 \htdocs\cluster\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(242): Drupal\Core\Render\Renderer->render(Array, false)
    #16 \htdocs\cluster\web\core\lib\Drupal\Core\Render\Renderer.php(580): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
    #17 \htdocs\cluster\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(243): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
    #18 \htdocs\cluster\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(132): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
    #19 \htdocs\cluster\web\core\lib\Drupal\Core\EventSubscriber\MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
    #20 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
    #21 \htdocs\cluster\web\core\lib\Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher.php(142): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
    #22 \htdocs\cluster\vendor\symfony\http-kernel\HttpKernel.php(174): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view')
    #23 \htdocs\cluster\vendor\symfony\http-kernel\HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
    #24 \htdocs\cluster\web\core\lib\Drupal\Core\StackMiddleware\Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #25 \htdocs\cluster\web\core\lib\Drupal\Core\StackMiddleware\KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #26 \htdocs\cluster\web\core\modules\page_cache\src\StackMiddleware\PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #27 \htdocs\cluster\web\core\modules\page_cache\src\StackMiddleware\PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #28 \htdocs\cluster\web\core\lib\Drupal\Core\StackMiddleware\ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #29 \htdocs\cluster\web\core\lib\Drupal\Core\StackMiddleware\NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #30 \htdocs\cluster\vendor\stack\builder\src\Stack\StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #31 \htdocs\cluster\web\core\lib\Drupal\Core\DrupalKernel.php(718): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #32 \htdocs\cluster\web\index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
    #33 {main}
    
Production build 0.71.5 2024