Problem/Motivation

Steps to reproduce:

  1. Standard installation of Drupal 8
  2. Configure the Image field on the Article content type to add a default image
  3. Create an article node with no image
  4. Navigate to the article node
  5. See a PHP notice: Notice: Trying to get property of non-object in template_preprocess_field() (line 1523 of core/includes/theme.inc).

Proposed resolution

The most obvious solution is to add back the is_object() check removed in #2550225: quickedit_test_entity_view_alter() creates a non compliant field render array, but there may be a more correct solution.

Remaining tasks

Patch
Tests
Review

User interface changes

n/a

API changes

n/a

Data model changes

n/a

Original report by @jonasdk

I have article content type with an image and I have assigned a default value to the image under Manage fields. I started to get the error (in the bottom of this text) in my printout when loading a page that haven't had a image assigned to its node. When I assigned an image to the node the error message disappears.

The strange thing is that I can see that it is related to the label in Manage display being hidden. When I set it to any other settings Above, Inline or Visually hidden the error message disappears to. Is this a freak error on my setup or something that other have seen?

 Notice: Trying to get property of non-object in template_preprocess_field() (line 1526 of core/includes/theme.inc).

template_preprocess_field(Array, 'field', Array)
Drupal\Core\Theme\ThemeManager->render('field', Array)
Drupal\Core\Render\Renderer->doRender(Array)
Drupal\Core\Render\Renderer->doRender(Array, )
Drupal\Core\Render\Renderer->render(Array)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1)
__TwigTemplate_a02dce0f9b24214a75ff925dd6dc1741e87fd96dd320e87a8a727ae08c036877->doDisplay(Array, Array)
Twig_Template->displayWithErrorHandling(Array, Array)
Twig_Template->display(Array)
Twig_Template->render(Array)
twig_render_template('themes/custom/THEMENAME/templates/content/node.html.twig', Array)
Drupal\Core\Theme\ThemeManager->render('node', Array)
Drupal\Core\Render\Renderer->doRender(Array, )
Drupal\Core\Render\Renderer->render(Array, )
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1)
Stack\StackedHttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jonasdk created an issue. See original summary.

jonasdk’s picture

PS. my node.html.twig is taken from the core theme classy and I have removed the part about meta data, apart from that everything have been left alone (even the comments).

 {% if display_submitted %}
    <footer class="node__meta">
      {{ author_picture }}
      <div{{ author_attributes.addClass('node__submitted') }}>
        {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
        {{ metadata }}
      </div>
    </footer>
  {% endif %}
star-szr’s picture

Title: Default image with hidden label » PHP notice for single value image field configured with a default image (no image present) and a hidden label
Component: field system » theme system
Issue summary: View changes
Status: Active » Needs review
Issue tags: -label, -field, -hidden, -default image +Needs tests
Related issues: +#2550225: quickedit_test_entity_view_alter() creates a non compliant field render array, +#2214241: Field default markup - removing the divitis
FileSize
629 bytes

Not sure if this is the right fix but it's a fix. Thanks for the report @jonasdk!

dawehner’s picture

While notices can be annoying sometimes, they are often a sign of an actual bug somewhere else in the system. Did you checked how this happens?
Can we check for that condition earlier so it never gets passed in? Given

foreach ($entity->get($name) as $item) {
            $item->_attributes = array();
          }

we should be able to check for a specific interface here.

star-szr’s picture

Status: Needs review » Needs work

Agreed @dawehner, this definitely needs more digging but the patch and steps to reproduce hopefully show where to start digging :)

swentel’s picture

Hmm a bit further in the same function, this happens

    $variables['items'][$delta]['attributes'] = !empty($element['#items'][$delta]->_attributes) ? new Attribute($element['#items'][$delta]->_attributes) : clone($default_attributes);

So I guess we can just do !empty($element['#items'][0]->_attributes) here. Or we have to declare an empty attribute property more upstream in the code somewhere, which in some way sounds sane too, but maybe a little 'overheadish' ?

yched’s picture

Status: Needs work » Needs review
FileSize
639 bytes

/me shakes fist at the "fallback image" feature, long-standing pita :-)

So the thing here is that the field *is* empty, so $element['#items'][0] is NULL.
Typically, in such cases the formatters return nothing, and there is no render array for the field to begin with (so the field template and template_preprocess_field() do not run at all)

But formatters do have the possibility to run and return something for empty fields, and that's how the "fallback image" works.
In this case, there is a render array for the field, with :

'#theme' => 'field',
'#items' => a FieldItemList with no items,
'0' => the render array returned by the formatter...

This case where $element[0] exists while not corresponding to an actual item, is like totally not the most common case, and can be overlooked :-/

Note that template_preprocess_field() has an empty() check on $element['#items'][$delta]->_attributes a couple lines below, so we might as well fix this by doing the same check here ?

yched’s picture

Also, ImageFieldDefaultImagesTest is supposed to test the "fallback image" behavior, but it doesn't actually render the fields, it just builds the render array, and checks that $render[$field_name][0] contains the expected data :

$article_built = $this->drupalBuildEntityView($article = $node_storage->load($article->id()));
$this->assertEqual(
  $article_built[$field_name][0]['#item']->target_id,
  $default_images['field']->id()
);

This doesn't render template_preprocess_field(), and thus doesn't detect the issue.

yched’s picture

Weird, I would have thought that this would be enough to test the bug, but this seems to pass.
WebTestBase::drupalGet() is supposed to show notices and trigger a fail on them, right ?

Jonathan Lauer’s picture

I have the same issue. Test and review

fomenkoandrey’s picture

drupal 8.0.1
any modules.
PHP7
i have notice:

Notice: Trying to get property of non-object in template_preprocess_field() (line 1523 of core/includes/theme.inc)

patch 2604220-fallback_image_notice-test-only-9.patch dont help me

joelpittet’s picture

@yched usually it does report notices from what I recall.

swentel’s picture

'fixing' the tests - the label isn't hidden by default in the view display :)

The last submitted patch, 13: 2604220-13-fail.patch, failed testing.

yched’s picture

Oh d'oh, thanks @swentel ! - I forgot that the fail was only triggered by the label being hidden...

Just adding a comment to the test then, since it's not exactly self-explanatory why we do this :-)

Then I guess this should be RTBCable ?

star-szr’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me, thanks!

fomenkoandrey’s picture

works for me

catch’s picture

Status: Reviewed & tested by the community » Fixed

I dropped the reference back to this issue - comment is self-explanatory and git blame gets you back here if you need it.

Otherwise looks great so committed/pushed to 8.1.x and cherry-picked to 8.0.x, thanks!

  • catch committed d186883 on
    Issue #2604220 by yched, swentel, Cottser: PHP notice for single value...

  • catch committed 3ca5f12 on 8.0.x
    Issue #2604220 by yched, swentel, Cottser: PHP notice for single value...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.