Problem/Motivation

The following notice message is being thrown:
Notice: Undefined property: Drupal\views\ViewExecutable::$render_time in Drupal\views_ui\ViewUI->renderPreview() (line 715 of core/modules/views_ui/src/ViewUI.php).

This is actually just a symptom of a deeper issue, which is that the views statistics information is only displayed if the query is configured to display (and then, due to the notice, render time is always blank).

Proposed resolution

Add tests to ensure that statistics are displayed (if so configured) even if the query is set to not be displayed. This will also fix the PHP notice.

Remaining tasks

  • Make a patch
  • Test the patch

User interface changes

N/A

API changes

N/A

Comments

sachbearbeiter’s picture

views settings

display_extenders: {  }
skip_cache: false
sql_signature: false
ui:
  show:
    additional_queries: false
    advanced_column: true
    master_display: true
    performance_statistics: true
    preview_information: true
    sql_query:
      enabled: true
      where: above
    display_embed: true
  always_live_preview: true
  exposed_filter_any_label: old_any
field_rewrite_elements:
  div: DIV
  span: SPAN
  h1: H1
  h2: H2
  h3: H3
  h4: H4
  h5: H5
  h6: H6
  p: P
  header: HEADER
  footer: FOOTER
  article: ARTICLE
  section: SECTION
  aside: ASIDE
  details: DETAILS
  blockquote: BLOCKQUOTE
  figure: FIGURE
  address: ADDRESS
  code: CODE
  pre: PRE
  var: VAR
  samp: SAMP
  kbd: KBD
  strong: STRONG
  em: EM
  del: DEL
  ins: INS
  q: Q
  s: S
sachbearbeiter’s picture

view

uuid: cc4e52e7-076a-493d-9800-a7eee7b04557
langcode: en
status: true
dependencies:
  module:
    - node
    - user
id: public_exhibitors
label: 'Public Exhibitors'
module: views
description: ''
tag: ''
base_table: node
base_field: nid
core: 8.x
display:
  default:
    display_plugin: default
    id: default
    display_title: Master
    position: 0
    display_options:
      access:
        type: perm
        options:
          perm: 'access content'
      cache:
        type: none
        options: {  }
      query:
        type: views_query
        options:
          disable_sql_rewrite: false
          distinct: false
          replica: false
          query_comment: false
          query_tags: {  }
      exposed_form:
        type: basic
        options:
          submit_button: Apply
          reset_button: false
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      pager:
        type: some
        options:
          items_per_page: 5
          offset: 0
      style:
        type: default
      row:
        type: fields
      fields:
        title:
          id: title
          table: node_field_data
          field: title
          link_to_node: true
          plugin_id: node
          relationship: none
          group_type: group
          admin_label: ''
          label: ''
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: ''
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
      filters:
        status:
          value: true
          table: node_field_data
          field: status
          plugin_id: boolean
          entity_type: node
          entity_field: status
          id: status
          expose:
            operator: ''
          group: 1
      sorts:
        created:
          id: created
          table: node_field_data
          field: created
          order: DESC
          entity_type: node
          entity_field: created
          plugin_id: date
          relationship: none
          group_type: group
          admin_label: ''
          exposed: false
          expose:
            label: ''
          granularity: second
      title: Exhibitors
      header:
        entity_block_content:
          id: entity_block_content
          table: views
          field: entity_block_content
          relationship: none
          group_type: group
          admin_label: ''
          empty: false
          tokenize: true
          entity_id: block-dieseisteincustomblock-2
          view_mode: default
          bypass_access: false
          plugin_id: entity
      footer: {  }
      empty: {  }
      relationships: {  }
      arguments: {  }
      display_extenders: {  }
      field_langcode: '***LANGUAGE_language_content***'
      field_langcode_add_to_query: null
  block_1:
    display_plugin: block
    id: block_1
    display_title: Block
    position: 1
    display_options:
      display_extenders: {  }
      field_langcode: '***LANGUAGE_language_content***'
      field_langcode_add_to_query: null
      block_hide_empty: true
      header: {  }
      defaults:
        header: false
dawehner’s picture

Version: 8.0.0-beta4 » 8.0.x-dev
Issue tags: +VDC

Note:

      $this->render_time = Timer::stop('entity.view.preview_form');

should be

      $this->executable->render_time = Timer::stop('entity.view.preview_form');
dawehner’s picture

Issue tags: +Novice

Adds a novice tag.

zealfire’s picture

Status: Active » Needs review
StatusFileSize
new533 bytes

Please review.
Thanks.

Status: Needs review » Needs work

The last submitted patch, 5: undefined-property-render-time-2404039-5.patch, failed testing.

zealfire’s picture

Assigned: Unassigned » zealfire

@dawehner,i think the above assignment is wrong because the return type of Timer::stop('entity.view.preview_form'); is array type but of $render_time is int.Please give you opinion.

adci_contributor’s picture

Status: Needs work » Needs review
StatusFileSize
new536 bytes

just fix corrupted endline in patch

dawehner’s picture

Issue tags: +Needs tests

Thank you @zealfire

Now it would be nice if we could have some kind of testcoverage.

mcmilo’s picture

Issue summary: View changes
StatusFileSize
new104.08 KB

I am unable to reproduce this issue. After imported the view using settings in #2 and place its block in the sidebar I do not get the notice reported in the summary, instead I am getting a different notice that says:
Notice: Undefined index: #rows in Drupal\views\Plugin\views\display\DisplayPluginBase->elementPreRender() (line 2064 of /Users/ccortes/Projects/drupalcon/sprint/drupal8/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php).

The steps I am following to reproduce this issue are:

  1. Install Drupal.
  2. Go to reports/dblog check that the notice message in the summary is not displayed.
  3. Import the view using configuration settings from #2.
  4. Go to reports/dblog check that the notice message in the summary is not displayed yet.
  5. Place the "Public Exhibitors" view block in the sidebar.
  6. Go to reports/dblog check that the notice message is not displayed in the report.
  7. Go to the home page by clicking the "Back to site" button so the view is render.
  8. Go to reports/dblog check that the notice message is displayed in the report. The notice in the summary is not displayed instead a different one is displayed twice (see attached screenshot for evidence).

Additional details: Applying the patch does not remove the notice message I am getting. Also, If the "Public Exhibitors" view block is disable the notice message is not displayed anymore.

jhedstrom’s picture

This can probably be removed since with this fix, that variable no longer exists on the ViewUI class.

  /**
   * How long the view takes to render.
   *
   * @var int
   */
  public $render_time;
jhedstrom’s picture

Er, actually, render_time isn't defined on the ViewExecutable class either, so the fix here should probably consistently use $this->render_time instead of $this->executable->render_time.

fgm’s picture

StatusFileSize
new3.29 KB

Patched on ViewUI.

fgm’s picture

StatusFileSize
new713 bytes

Oops, wrong patch.

The last submitted patch, 13: 2404039-viewui_render_time.patch, failed testing.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Right fix.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Still needs tests - no?

jhedstrom’s picture

Assigned: zealfire » jhedstrom

I'm working on a test (good thing, because it's uncovering several issues).

jhedstrom’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new3.54 KB
new1.4 KB
new3.54 KB

So, statistic display is currently tied very tightly to query display, to the point that it doesn't display at all unless queries are also displayed.

I've updated the issue to indicate this (the php notice is just a symptom of further broken logic).

jhedstrom’s picture

Title: Notice: Undefined property: Drupal\views\ViewExecutable::$render_time » Views performance statistics to not properly display
jhedstrom’s picture

Title: Views performance statistics to not properly display » Views performance statistics do not properly display
jhedstrom’s picture

Issue summary: View changes

The last submitted patch, 19: views-preview-2404039-19-TEST-ONLY.patch, failed testing.

dawehner’s picture

+++ b/core/modules/views_ui/src/Tests/PreviewTest.php
@@ -90,6 +90,23 @@ function testPreviewUI() {
+    // Statistics and query.
+    $settings->set('ui.show.sql_query.enabled', TRUE)->save();
+    $this->drupalPostForm(NULL, $edit = array('view_args' => '100'), t('Update preview'));
+    $this->assertText(t('Query build time'));
+    $this->assertText(t('Query execute time'));
+    $this->assertText(t('View render time'));

Should we not test that the query is somehow displayed? Its confusing that we have twice the same asserts

lendude’s picture

StatusFileSize
new839 bytes
new3.64 KB

Per #24, added tests to check if Query is shown or not with different settings.

dawehner’s picture

Well + the actual query, not just the title?

lendude’s picture

Assigned: jhedstrom » Unassigned
StatusFileSize
new629 bytes
new3.81 KB

plus the actual query now.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Great, thank you. IMHO this is enough

xjm’s picture

+++ b/core/modules/views_ui/src/ViewUI.php
@@ -45,27 +45,13 @@ class ViewUI implements ViewEntityInterface {
-   * How long the view takes to build.
...
-   * @var int
-   */
-  public $build_time;
...
-   * How long the view takes to execute.
-   *
-   * @var int
-   */
-  public $execute_time;

Sooo, technically, these are public properties on ViewUI. But they are never used nor set in core, and here they are only being declared as null. Therefore, these hunks are just essentially removing wrong class documentation. If other code sets public properties on a ViewUI instance, well ballyhoo, good for them. It shouldn't affect their code at all since Views doesn't do anything with it ever.

So this looks okay for 8.0.x to me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -832,13 +818,13 @@ public function renderPreview($display_id, $args = array()) {
+      elseif ($show_stats) {
+        $table['#rows'] = $rows['statistics'];
+      }
...
-    elseif ($show_stats === 'above' || $show_stats === 'below') {
-      $table['#rows'] = $rows['statistics'];
-    }

What is really confusing about this change is that the whole outer if ($show_location === 'above' || $show_location === 'below') { is unnecessary Since the only possible values are above or below. Let's remove that here now we're adding testing.

alexpott’s picture

Also it's be great if the testing could be improved to cover both the above and below cases.

lendude’s picture

Status: Needs work » Needs review
StatusFileSize
new2.68 KB
new5.2 KB

Bit of a clean up as suggested in #30. Also took out the double check for $show_stats and $show_location since both contain the same information if $show_stats is set, so testing only $show_location should be enough.

Added a test for above and below. Not sure if this is the most elegant way to do it, but seems to work.

dawehner’s picture

  1. +++ b/core/modules/views_ui/src/ViewUI.php
    @@ -45,27 +45,13 @@ class ViewUI implements ViewEntityInterface {
    +   * @var numeric
    

    IMHO we should use float here.

  2. +++ b/core/modules/views_ui/src/ViewUI.php
    @@ -827,26 +813,25 @@ public function renderPreview($display_id, $args = array()) {
    +    // The info rows are are added to $rows['query']. $rows['query'] contains
    +    // only the info rows if $show_query is not set.
    +    if ($show_info || $show_query) {
    +      $table['#rows'] = array_merge($table['#rows'], $rows['query']);
         }
    -    elseif ($show_stats === 'above' || $show_stats === 'below') {
    -      $table['#rows'] = $rows['statistics'];
    +    if ($show_stats) {
    +      $table['#rows'] = array_merge($table['#rows'], $rows['statistics']);
         }
     
    

    So I'm wondering whether we need the if in the first place. Can't we provide a default empty $rows['query'] bit?

lendude’s picture

StatusFileSize
new1.83 KB
new5.28 KB

#33.1 Timer returns a float, so yeah that makes more sense.
#33.2 Cleaned it up a bit, initialised the arrays before they get filled so they can just be merged later without worrying about what's in there.

Also cleaned up the ifelse since, like @alexpott pointed out in #30, 'above' and 'below' are the only options, seems pointless to specifically test for both, one should be enough.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Nice, this is much better now!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 34: views-preview-2404039-34.patch, failed testing.

lendude’s picture

Status: Needs work » Reviewed & tested by the community

Unrelated fail, back to RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

We're removing public properties that do nothing (and because of this I think it okay to remove), making the code easier to understand, fixing a bug and adding a test. Nice.

Committed 5fd3567 and pushed to 8.0.x and 8.1x. Thanks!

  • alexpott committed 87986e3 on 8.1.x
    Issue #2404039 by Lendude, jhedstrom, fgm, zealfire, adci_contributor,...

  • alexpott committed 5fd3567 on
    Issue #2404039 by Lendude, jhedstrom, fgm, zealfire, adci_contributor,...

Status: Fixed » Closed (fixed)

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