Problem/Motivation

I have a Node Edit and Delete links on admin/content, the has permissions to edit/delete some nodes but not all of them.

Expected behavior:

Hidden Dropbutton for not accessible nodes.

Current behavior:

The previous Dropbutton is shown for not accessible nodes.

Steps to reproduce
Create two node types
Create sample content in each of the node types
Give user access to content overview
Edit content overview view to add a dropbutton field
Give user access to edit/delete one content type but not the other
Edit a node that the user has access to so it appears first in the admin page
Visit admin/content as that user
Rows that the user cannot edit get the dropbutton of the previous one they could edit.

Before

After

Proposed resolution

FieldPluginBase keeps state in $this->last_render_text and the Dropbutton uses the saved value. Therefor we should reset $this->last_render_text in renderText or advancedRender.

Remaining tasks

User interface changes

API changes

Data model changes

Comments

webflo’s picture

Status: Active » Needs review
StatusFileSize
new637 bytes
dawehner’s picture

Priority: Normal » Major

Come on, this is at least major

dawehner’s picture

Issue tags: +Needs tests
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -1207,6 +1207,7 @@ public function isValueEmpty($value, $empty_zero, $no_skip_empty = TRUE) {
+    $this->last_render_text = NULL;
 

... I'm pretty convinced that this is the wrong fix. There is a usecase of using the token to itself in D7 for things like the mathfield. We maybe need to store the row index of the last rendered text, so we can compare that for the usecase of the dropbutton.

xjm’s picture

This sounds like a very similar bug to the one that would be caused in #2473873: Entity operations lack cacheability support, resulting in incorrect dropbuttons, but the fix sounds very different. Is it possible it's a duplicate?

xjm’s picture

Status: Needs review » Needs work

NW based on #3.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

xjm’s picture

Issue tags: +Needs issue summary update, +D8 major triage deferred

So let's say I have two nodes, node 3 and node 4. I can edit node 3 but only view node 4. Is the bug here that node 4 shows an edit dropbutton that links to node 3, even immediately after a full cache clear? Clear steps to reproduce and a test case would definitely help evaluate this issue.

acbramley’s picture

@xjm that's what I'm experiencing, yes. The Edit link in views works properly, the operations dropdown doesn't (although the delete button is correctly suppressed).

larowlan’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update

Added STR

larowlan’s picture

Assigned: Unassigned » larowlan
larowlan’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new8.22 KB

failing test

larowlan’s picture

Assigned: larowlan » Unassigned
Issue tags: -Needs tests
StatusFileSize
new9.93 KB

And here's a fix that uses the 'We maybe need to store the row index of the last rendered text, so we can compare that for the usecase of the dropbutton' approach from #3

larowlan’s picture

+++ b/core/modules/views/tests/src/Kernel/Handler/FieldDropbuttonTest.php
@@ -0,0 +1,146 @@
+          return $view->field[$field]->advancedRender($row) . PHP_EOL;
...
+    $this->assertEquals(trim((string) $dropbutton_output[1]), '');

the PHP_EOL can go in next pass, it was for easier debug, so this trim can go too

The last submitted patch, 12: 2530634-last-render-dropbutton.test-only.patch, failed testing.

larowlan’s picture

+++ b/core/modules/views/src/Plugin/views/field/Links.php
@@ -97,4 +105,20 @@ protected function getLinks() {
+      foreach (array_filter($this->options['fields']) as $field) {
+        $this->view->field[$field]->last_render_text = '';
+      }

This will mean it only works for the first row.. test and fix coming

Status: Needs review » Needs work

The last submitted patch, 13: 2530634-last-render-dropbutton.13.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new6.09 KB
new11.35 KB

This is better

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dawehner’s picture

  1. +++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
    @@ -1181,7 +1188,10 @@ public function advancedRender(ResultRow $values) {
    +    if (!empty((string) $this->last_render)) {
    

    As said in IRC, "0" is a total valid rendered value in views.

  2. +++ b/core/modules/views/src/Plugin/views/field/Links.php
    @@ -62,7 +63,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    -    foreach ($this->options['fields'] as $field) {
    +    foreach (array_filter($this->options['fields']) as $field) {
    

    Is this one needed as part of the patch?

larowlan’s picture

StatusFileSize
new1.25 KB
new10.99 KB

Fixes #20

lendude’s picture

Is there a good reason we can't keep this contained to Links/Dropbutton and not get FieldPluginBase involved at all? This passes the test locally, but maybe I'm missing some of the logic behind this.

dawehner’s picture

Less changes in base class are always better. I guess we want to apply some manual testing though?

lendude’s picture

Issue summary: View changes
StatusFileSize
new23.38 KB
new21.2 KB

Less changes in base class are always better

My thoughts exactly.

Manual testing with #22 works too. See screenshots. Also added screenshots to the IS.

Before

After

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Awesome! everyone seems happy here let's fix it then.

alexpott’s picture

@Lendude but might not other plugins have the same problem and isn't the generic fix in #21 better?

lendude’s picture

@alexpott If other plugins have this problem, then hmm maybe, but this is just happening because the dropdown plugin reuses generated values from other field plugins. That is not a pattern that is wide spread (to say the least), so if we can leave it of the base class and make the plugin that wants to do this work a little harder, that sounds acceptable to me.

If this wasn't possible without changes to the base class, sure, put it in, but making all field handlers in all Views track data that currently has one known use case (and there the same effect can be achieved without this data), sounds like data we can do without for now.

So, in short, I don't really see a use case here that warrants a generic fix over a specific fix. Feel free to disagree obviously :)

alexpott’s picture

Well won't \Drupal\contextual\Plugin\views\field\ContextualLinks have the same problem? Also as \Drupal\views\Plugin\views\field\FieldPluginBase sets this value should it clear it?

lendude’s picture

Status: Reviewed & tested by the community » Needs work

#2532200: Adding contextual links via Views fields does not work \Drupal\contextual\Plugin\views\field\ContextualLinks That thing is so broken, I have no idea if that would ever be bothered by this.

Also as \Drupal\views\Plugin\views\field\FieldPluginBase sets this value should it clear it?

Discussed this with @alexpott on IRC, this sounds like a better way to fix this, make FieldPluginBase clean up its own mess. Setting to NW for that.

+++ b/core/modules/views/src/Plugin/views/field/Links.php
@@ -97,4 +98,19 @@ protected function getLinks() {
+    // Clear out the previous rendered values if they are from a different
+    // row.
+    foreach (array_filter($this->options['fields']) as $field) {
+      if ($this->view->field[$field]->lastRenderIndex !== $values->index) {
+        $this->view->field[$field]->last_render_text = '';
+      }
+    }

So I think, moving this logic from #21 into FieldPluginBase instead of having it on Links.

lendude’s picture

Status: Needs work » Needs review
StatusFileSize
new1.58 KB
new10.46 KB

So something like this then.

Interdiff is against #21 for clarity.

thursday_bw’s picture

Status: Needs review » Reviewed & tested by the community

I came across this exact issue myself on my current project.

This patch looks clean, simple, and gets the job done.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I wonder about the difference between last_render_text and last_render...

+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -102,6 +102,13 @@
+  public $lastRenderIndex;

Can be protected now - i think. Which is nice.

acbramley’s picture

Status: Needs work » Needs review
StatusFileSize
new10.46 KB
new446 bytes

Fixed #32

dawehner’s picture

I wonder about the difference between last_render_text and last_render...

One contains just the main output (last_render_text), and one contains the output after all the altering logic.

lendude’s picture

Status: Needs review » Reviewed & tested by the community

Feedback from #32 has been addressed, so back to RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -D8 major triage deferred

Committed and pushed 14afb77 to 8.3.x and c0a0e44 to 8.2.x. Thanks!

diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldDropbuttonTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldDropbuttonTest.php
index 53c9564..b789bd6 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FieldDropbuttonTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FieldDropbuttonTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\views\Kernel\Handler;
 
 use Drupal\Core\Render\RenderContext;
-use Drupal\KernelTests\KernelTestBase;
 use Drupal\simpletest\ContentTypeCreationTrait;
 use Drupal\simpletest\NodeCreationTrait;
 use Drupal\simpletest\UserCreationTrait;

Unused use fixed on commit.

  • alexpott committed 14afb77 on 8.3.x
    Issue #2530634 by larowlan, Lendude, acbramley, webflo, dawehner,...

  • alexpott committed c0a0e44 on 8.2.x
    Issue #2530634 by larowlan, Lendude, acbramley, webflo, dawehner,...

Status: Fixed » Closed (fixed)

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