0

I started working on existing project and right from beginning, it displayed tons of alerts in specific pages.

This is what Drupal outputs:

Notice: Array to string conversion in Drupal\Core\Template\AttributeArray->__toString() (line 74 of /home/project/drupal/web/core/lib/Drupal/Core/Template/AttributeArray.php) #0 /home/project/drupal/web/core/includes/bootstrap.inc(584): _drupal_error_handler_real(8, 'Array to string...', '/home/jspa/proj...', 74, Array)
#1 [internal function]: _drupal_error_handler(8, 'Array to string...', '/home/jspa/proj...', 74, Array)
#2 /home/project/drupal/web/core/lib/Drupal/Core/Template/AttributeArray.php(74): implode(' ', Array)
#3 /home/project/drupal/web/core/lib/Drupal/Core/Template/AttributeValueBase.php(53): Drupal\Core\Template\AttributeArray->__toString()
#4 /home/project/drupal/web/core/lib/Drupal/Core/Template/Attribute.php(289): Drupal\Core\Template\AttributeValueBase->render()
#5 /home/project/drupal/web/core/lib/Drupal/Core/Render/Element/HtmlTag.php(88): Drupal\Core\Template\Attribute->__toString()
#6 [internal function]: Drupal\Core\Render\Element\HtmlTag::preRenderHtmlTag(Array)
#7 /home/project/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(378): call_user_func(Array, Array)
#8 /home/project/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(450): Drupal\Core\Render\Renderer->doRender(Array)
#9 /home/project/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, true)
#10 /home/project/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(151): Drupal\Core\Render\Renderer->render(Array, true)
#11 /home/project/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}()
#12 /home/project/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(152): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#13 /home/project/drupal/web/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php(325): Drupal\Core\Render\Renderer->renderPlain(Array)
#14 /home/project/drupal/web/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php(206): Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderHtmlResponseAttachmentPlaceholders(Object(Drupal\Core\Render\HtmlResponse), Array, Array)
#15 /home/project/drupal/web/core/modules/big_pipe/src/Render/BigPipeResponseAttachmentsProcessor.php(94): Drupal\Core\Render\HtmlResponseAttachmentsProcessor->processAttachments(Object(Drupal\Core\Render\HtmlResponse))
#16 /home/project/drupal/web/core/lib/Drupal/Core/EventSubscriber/HtmlResponseSubscriber.php(45): Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor->processAttachments(Object(Drupal\Core\Render\HtmlResponse))
#17 [internal function]: Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object(Symfony\Component\HttpKernel\Event\FilterResponseEvent), 'kernel.response', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#18 /home/project/drupal/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\FilterResponseEvent), 'kernel.response', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#19 /home/project/drupal/vendor/symfony/http-kernel/HttpKernel.php(191): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.response', Object(Symfony\Component\HttpKernel\Event\FilterResponseEvent))
#20 /home/project/drupal/vendor/symfony/http-kernel/HttpKernel.php(173): Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object(Drupal\Core\Render\HtmlResponse), Object(Symfony\Component\HttpFoundation\Request), 1)
#21 /home/project/drupal/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#22 /home/project/drupal/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /home/project/drupal/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /home/project/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /home/project/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /home/project/drupal/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#27 /home/project/drupal/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#28 /home/project/drupal/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#29 /home/project/drupal/web/core/lib/Drupal/Core/DrupalKernel.php(693): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#30 /home/project/drupal/web/index.php(21): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#31 {main}.

There is no helpful information in there, no indication that the issue is within project codebase. So I went to Drupal\Core\Template\AttributeArray and changed __toString method from from

  public function __toString() {
    // Filter out any empty values before printing.
    $this->value = array_unique(array_filter($this->value));
    return Html::escape(implode(' ', $this->value));
  }

to this

  public function __toString() {
    // Filter out any empty values before printing.
    $this->value = array_unique(array_filter($this->value));
    $bad = false;
    foreach ($this->value as $k => $v) {
      if (!is_string($v)) {
        $bad = true;
        break;
      }
    }
    if ($bad) {
      ksm($this->value);
    }
    return Html::escape(implode(' ', $this->value));
  }

That resulted in possible cause:

enter image description here

The reason is that php implode function can't implode multi-dimensional array thus resulting in this error.

This happens only in pages where menus are rendered.

The question is - why this could possibly happen, that #allowed_tags are in there?

Update #1: These issues are something that are inconsistent. Some core areas in backend uses that format by default. I made a quick-fix for those issues according to the idea, that there should be only a list of classes at most.

  public function __toString() {
    // Normalize value removing any invalid sub-array structures
    $normalizedValue = [];
    $bad = false;
    foreach ($this->value as $k => $v) {
      if (is_numeric($k) && is_string($v)) {
        $normalizedValue[] = $v;
      } else {
        $bad = true;
      }
    }
    if ($bad) {
      ksm('Invalid attribute array value', $this->value);
    }
    // Filter out any empty values before printing.
    $this->value = array_unique(array_filter($normalizedValue));
    return Html::escape(implode(' ', $normalizedValue));
  }

This worked well in removing errors, but during normal usage, it still popped out ksm output noticing about the fact that reason is still there. But alas - this fix broke inline file upload feature within ckeditor, as my code apparently removed important part of form/model or something like that.

  • No repro here - I have tons of sites based on drupal-project, at 8.6.10 (and previously earlier versions), all rendering menus without this problem. You're probably going to need to start disabling contrib/custom modules/themes one by one to see if you can at least isolate the root cause – Clive Feb 22 '19 at 10:08
  • @Clive I just don't know Drupal enough, to be able to know where to search for an issue, even more, this is not my original system. What should I search for in app code? – Deele Feb 22 '19 at 10:14
  • A full text search where '#markup' => 'Content Menu' and the allowed tags are added mistakenly to an attribute key should reveal the module/theme. – 4k4 Feb 22 '19 at 10:14
  • @4k4 No luck with that. Does Drupal add '#allowed_tags' by itself automatically at certain point? – Deele Feb 22 '19 at 10:25
  • No, not to a key of an Attribute object. A valid AttributeArray value would be ['class1', 'class2']. – 4k4 Feb 22 '19 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.