Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Task, as it makes core more consistent, helps contrib/custom module authors
Issue priority Major, because it allows us to get rid of quite some code
Disruption Unless someone would have subclassed those specific classes, there would be no API change. Existing configurations have just to be adapted for schema purposes, the existing views will continue to work, see
@@ -239,7 +239,7 @@ display:
           hide_alter_empty: true
           text: Edit
           entity_type: node
-          plugin_id: node_link_edit
+          plugin_id: entity_link_edit
         delete_node:

Problem/Motivation

There are a lot of code out there to provide some kind of links/information for all entities in views.

  • Add a link to the entity view page.
  • Add a link to the entity edit form.
  • Add a link to the entity delete form.
  • Show the human readable version of the bundle of the current result
  • ...

https://www.drupal.org/node/2281185 has a couple of those added.

Proposed resolution

Implement all kind of generic entity handlers and drop existing code in as many places as possible.

Remaining tasks

User interface changes

API changes

See beta evaluation.

CommentFileSizeAuthor
#112 views-entity_links-2322949-112.patch86.34 KBplach
#112 views-entity_links-2322949-112.interdiff.txt1.07 KBplach
#109 views-entity_links-2322949-109.patch86.52 KBplach
#109 views-entity_links-2322949-109.interdiff.txt479 bytesplach
#108 views-entity_links-2322949-108.patch86.53 KBplach
#108 views-entity_links-2322949-108.interdiff.txt1.75 KBplach
#105 views-entity_links-2322949-105.patch86.45 KBplach
#101 views-entity_links-2322949-100.patch88.72 KBplach
#101 views-entity_links-2322949-100.interdiff.txt2.67 KBplach
#94 views-entity_links-2322949-94.patch88.72 KBplach
#94 views-entity_links-2322949-94.interdiff.txt6.14 KBplach
#91 views-entity_links-2322949-90.patch87.73 KBplach
#91 views-entity_links-2322949-90.interdiff.txt14.43 KBplach
views-entity_links-2322949-90.interdiff.txt14.43 KBplach
views-entity_links-2322949-90.patch87.73 KBplach
#89 views-entity_links-2322949-89.patch71.45 KBplach
#89 views-entity_links-2322949-89.interdiff.txt4.72 KBplach
#87 views-entity_links-2322949-87.patch73.31 KBplach
#87 views-entity_links-2322949-87.interdiff.txt2.34 KBplach
#86 views-entity_links-2322949-86.patch72.09 KBplach
#86 views-entity_links-2322949-86.interdiff.txt1.83 KBplach
#84 views-entity_links-2322949-84.patch70.14 KBplach
#84 views-entity_links-2322949-84.interdiff.txt32.33 KBplach
#76 interdiff.txt1.56 KBkgoel
#76 2322949-76.patch56.18 KBkgoel
#74 interdiff.txt651 byteskgoel
#74 2322949-74.patch56.2 KBkgoel
#72 interdiff.txt5.98 KBkgoel
#72 2322949-72.patch56.01 KBkgoel
#70 interdiff.txt995 byteskgoel
#70 2322949-70.patch57.46 KBkgoel
#68 interdiff-2322949-65-67.txt7.42 KBfgm
#67 2322949-entity_link-67.patch55.12 KBfgm
#65 interdiff.txt1.9 KBkgoel
#65 2322949-65.patch52.71 KBkgoel
#63 interdiff-2322949-55-63.txt7.07 KBfgm
#63 2322949-63.patch52.77 KBfgm
#61 0001-Issue-2322959-entity-links.patch52.19 KBfgm
#59 interdiff.txt736 byteskgoel
#59 2322949-59.patch48.2 KBkgoel
#55 interdiff.txt4.6 KBkgoel
#55 2322949-55.patch48.21 KBkgoel
#52 interdiff.txt23.28 KBkgoel
#52 2322949-52.patch49.27 KBkgoel
#48 interdiff.txt639 byteskgoel
#48 2322949-48.patch28.01 KBkgoel
#46 interdiff.txt2.43 KBkgoel
#46 2322949-46.patch28.64 KBkgoel
#40 2322949-40.patch27.8 KBkgoel
#32 interdiff-2322949-32.txt515 bytesdamiankloip
#32 2322949-32.patch26.43 KBdamiankloip
#30 2322949-30.patch26.45 KBdamiankloip
#24 2322949-23-interdiff.txt2.09 KBBerdir
#24 2322949-23.patch28.44 KBBerdir
#18 2322949-18-interdiff.txt651 bytesBerdir
#18 2322949-18.patch27.9 KBBerdir
#16 2322949-16-interdiff.txt1.63 KBBerdir
#16 2322949-16.patch27.89 KBBerdir
#14 2322949-14.patch26.25 KBBerdir
#4 2322949-4.patch36.36 KBdawehner
#1 entity_view-2322949-1.patch15.43 KBdawehner
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

Status: Active » Needs review
FileSize
15.43 KB

Here is s start.

Status: Needs review » Needs work

The last submitted patch, 1: entity_view-2322949-1.patch, failed testing.

dawehner’s picture

Assigned: Unassigned » dawehner

Working on it.

dawehner’s picture

Title: Get generic bundles from entity_view module. » Get generic entity link fields from entity_view module.
Status: Needs work » Needs review
FileSize
36.36 KB

.

Status: Needs review » Needs work

The last submitted patch, 4: 2322949-4.patch, failed testing.

jhodgdon’s picture

Can we get an actual issue summary? ... The patch looks interesting, but it would be good to know what problem it is supposed to be solving. :)

dawehner’s picture

Issue summary: View changes

That is maybe a bit better ... sorry.

jhodgdon’s picture

Ah thanks. That is kind of what I thought by reading the patch; good to confirm that this is the intention.

A few notes on the current patch:

a) The error here is real:

Fatal error: Uncaught exception 'LogicException' with message 'Missing phpDoc on Drupal\views\Tests\Handler\FieldEntityTest.' in /var/lib/drupaltestbot/sites/default/files/checkout/core/modules/simpletest/src/TestDiscovery.php:394

This file in the patch has a pretty-much empty test in it with no docs header; test runner cannot handle this.

b) Generally I think this patch looks good! Making the link stuff standardized across entities seems like an excellent idea.

c) It also looks like you're doing something about consolidating bundle stuff? Such as in NodeViewsData:

-    $data['node_field_data']['type']['field']['id'] = 'node_type';

That may be missing from the issue summary? Or should that be a separate fix? Doesn't seem related to these links....

d)

+/**
+ * Field handler to present a bundle to the entity_bundle.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_view")
+ */
+class Entity extends FieldPluginBase {

The docs header is wrong, I think... what is this actually?

e)

+/**
+ * Field handler to present a link to the entity_link.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_link")
+ */
+class EntityLink extends FieldPluginBase {

The first line here... what is this supposed to mean? I don't understand it.

f) Looks like a few tests still need to be filled in?

dawehner’s picture

Assigned: dawehner » Unassigned

Thank you for providing so much feedback in various issues in a reasonable timeframe, this is really valuable, as you know.

That may be missing from the issue summary? Or should that be a separate fix? Doesn't seem related to these links....

Well, the issue started to merge in some code from the "entity_views" module, but yeah I am not sure whether this approach now is valid.
entity_views is a nice playground for better integrations we want to have in core as well. One random example which also exists now is proper support for UUIDs everywhere you can reference to an entity in views.

The docs header is wrong, I think... what is this actually?

Yeah copy and paste error, sorry :) Will improve things on my next run unless someone beets me

f) Looks like a few tests still need to be filled in?

TRUE

jhodgdon’s picture

It seems like maybe on this issue, we should limit it to making a unified method for entity view/edit/delete/translate links (is that the full list?). And if there are other nice things in entity_views, we can get them on other issues. That should keep things manageable?

I guess my other question after looking at this patch is whether we could maybe get rid of some of the specific handler plugins, like aggregator/src/Plugin/views/field/TitleLink.php and ... are the specific types of links needed, like DeleteLink and EditLink, or could they be taken care of with one master EntityLink class that has some ... what's it called, not configuration but when you specify the options for the handler in the hook_views_data()? Might make the patch even smaller.

dawehner’s picture

OKay sure, let's remove the bundle field for now, see #2363811: Add a generic entity bundle field

Whoever continues to work on this patch, the bundle code should be removed, if possible.

jibran’s picture

chx’s picture

it's clear that contrib (ex-core in this case) needs this, see #2409887: Views integration

Berdir’s picture

Status: Needs work » Needs review
FileSize
26.25 KB

First attempt at reroll, tried to remove the bundle and view stuff, removed the empty test classes.

Status: Needs review » Needs work

The last submitted patch, 14: 2322949-14.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
27.89 KB
1.63 KB

Config schema fixes.

Status: Needs review » Needs work

The last submitted patch, 16: 2322949-16.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
27.9 KB
651 bytes

More schema fixes.

Status: Needs review » Needs work

The last submitted patch, 18: 2322949-18.patch, failed testing.

jhodgdon’s picture

+100000000! This is great (plus or minus a few test failures).

dawehner’s picture

berdir++
yched’s picture

Looks awesome, even though I'm probably not the right person for a thorough review.

Just noticed :

+++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
@@ -0,0 +1,121 @@
+  protected function renderLink($entity, ResultRow $values) {
+    if ($entity->access('view')) {

+++ b/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php
@@ -0,0 +1,46 @@
+  protected function renderLink($entity, ResultRow $values) {
+    // Ensure user has access to delete this node.
+    if ($entity && $entity->access('delete')) {

+++ b/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php
@@ -0,0 +1,46 @@
+  protected function renderLink($entity, ResultRow $values) {
+    // Ensure user has access to delete this node.
+    if ($entity && $entity->access('update')) {

So does renderLink() need to check the $entity or not ?

Berdir’s picture

Status: Needs work » Needs review

Some test fixes, tricky stuff.

Berdir’s picture

FileSize
28.44 KB
2.09 KB

Status: Needs review » Needs work

The last submitted patch, 24: 2322949-23.patch, failed testing.

jhodgdon’s picture

I related #2393339: [META] Make sure Views base fields are using Field API for formatting, and do not lose functionality to this issue as well. The summary on that issue lists all of the specific field handler plugins in Core that we'd like to standardize and get rid of if possible, several of which are links. For instance, in the Node section there are:
node_link
node_link_edit
node_link_delete
node_revision_link
node_revision_link_revert
node_revision_link_delete

User, Comment, and Taxonomy have additional link fields, and some of the others have things similar to the generic "node", which prints the node title and allows you to make it a link (which #2342045: Standard views base fields need to use same rendering as Field UI fields, for formatting, access checking, and translation consistency is taking out anyway in favor of using the generic "field" handler).

There is also content_translation_link, which is added to most entities.

So... It looks like the latest patch here doesn't actually get rid of most of the handler classes (yet), and I don't think it covers all of the cases above, but it looks like a good start. One idea would be to reduce this patch further by having it create the infrastructure for doing this, and actually only remove the specific handlers for one entity (like Node), and then do the others in follow-up patches, rather than trying to do all of them at once? Since we have that other meta issue now, we won't lose track of the fact that not everything was converted to use the new system.

jhodgdon’s picture

Priority: Normal » Major

#2393339: [META] Make sure Views base fields are using Field API for formatting, and do not lose functionality is now a critical meta-issue.

On that issue, we need to convert a lot of entity link views pseudo-fields to use some kind of entity-aware rendering in Views rather than one-off plugins. This issue would presumably solve the problem, and due to the number of entities and pseudo-fields that are depending on this, I think this issue is at least Major if not Critical.

dawehner’s picture

This is not true ... those fields are not driven by entity fields but instead they are just ordinary views field plugins ... so you really don't have to care about them here ..
but no question, we really want have them to be generic so people have no problems with exposing them with their custom entity types.

damiankloip’s picture

Status: Needs work » Needs review
FileSize
26.45 KB

Start with a reroll. There have been quite some changes in core since the last patch.

Status: Needs review » Needs work

The last submitted patch, 30: 2322949-30.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
FileSize
26.43 KB
515 bytes

conflict fail, resolving conflict in YAML files is HORRIBLE :)

Yeah, there are certain things that we will still need specialist field implementations for, like most of these, but the entity system is such that we should be able to solve most cases generically.

Status: Needs review » Needs work

The last submitted patch, 32: 2322949-32.patch, failed testing.

dawehner’s picture

+++ b/core/modules/views/src/EntityViewsData.php
@@ -230,6 +232,44 @@ public function getViewsData() {
+  protected function addEntityLinks(array &$data) {
...
+    if ($this->entityType->hasLinkTemplate('edit-form')) {
...
+    }
+    if ($this->entityType->hasLinkTemplate('delete-form')) {

Nice!

jhodgdon’s picture

So... I took a look at this patch.

A few comments/concerns:

a) The aggregator stuff:
- The aggregator title field plugin is going away on #2456701: Replace aggregator_title_link Views formatter with Field API formatter, which is about 99% RTBC and should be completed today, so all the Aggregator code in the patch is not necessary.

b) But anyway, it's kind of a different beast from the others, so I think it wouldn't have been good to include it here... I think the point of this issue is to replace the generic "Make a link to X" fields, the ones that allow you to define the link text in Views (with some plain text or presumably a views-token-replacement-thing). So for instance, the "make a generic link to the node" field just makes a link to node/12345 and you define the link text. Every other plain-text field (not only Title but any now) also allows you to turn it into a link to the entity, but we have these special fields for making plain-old links to view, edit, etc.

So to me, fields like Title (or in this case Aggregator Item Title), are not the same, because instead of putting in some plain-text for the link text, they are instead getting the link text from a specific field, and then allowing you to make it into a link, right? To me, that's different, and I think this patch should just be dealing with those plain-text-make-a-link pseudo-fields, not the this-is-a-field-turn-it-into-a-link... besides which all text fields already have this ability now in Views.

Hope that made sense...

c) I don't think we actually want to turn on the links for all entities in all cases that the entity defines in its canonical link list. So I think maybe we just need a generic method on EntityViewsData that will create such a link field, and then let each specific entity ViewsData class call it to get those methods if it makes sense. ?? Not sure about this, but right now, for instance, Node, Comment, and User have these links, and Taxonomy has some, but File doesn't and Aggregator doesn't... But then again maybe it's good to turn them on generically? OK I think I'm undecided on this, but probably agree with turning it on generically and standardizing all entities. ;)

d) Is it going to be possible to do something about things that aren't canonical entity-defined links? For instance the Node views data defines links for viewing/reverting revisions. These are just defined as generic routes in node.routing.yml, and they're not in the links section of the entity annotation on the Node class. Can anything be done for them?

kgoel’s picture

Assigned: Unassigned » kgoel
Issue tags: +drupaldevdays

Working on this at Drupal Dev Days...

jhodgdon’s picture

Sitting with kgoel... here are some questions / comments [including the open questions from #35]:

1. Do we want the call to EntityViewsData::addEntityLinks() to be done by default for all entities in EntityViewsData::getViewsData(), or should we (at least initially) just make the method exist, and let Node, Comment, User, and Taxonomy call it in their own Entity ViewsData classes, to reproduce what is in Core now?

2. Here is a list of the existing entity link pseudo-views-fields and plugins. Can we replace all of them in this patch?

- plugin node_link (pseudo-field: view_node)
- node_link_edit (pseudo-field: edit_node)
- node_link_delete (pseudo-field: delete_node)
- node_path (pseudo-field: path)
- node_revision_link (pseudo-field: link_to_revision on node_revision)
- node_revision_link_revert (pseudo-field: revert_revision on node_revision)
- node_revision_link_delete (pseudo-field: delete_revision on node_revision)

- user_link_edit (pseudo-field: UserFieldData - edit_node, which despite the name is actually a link to edit the user)
- user_link_cancel (pseudo-field: UserFieldData - cancel_node, which despite the name is actually a link to cancel the user)

- comment_link: Used in CommentViewsData for pseudo-field view_comment
- comment_link_edit: Used in CommentViewsData for pseudo-field edit_comment
- comment_link_delete: Used in CommentViewsData for pseudo-field delete_comment
- comment_link_approve: Used in CommentViewsData for pseudo-field approve_comment
- comment_link_reply: Used in CommentViewsData for pseudo-field replyto_comment

- term_edit_link - field edit_term

- content_translation_link (Used in pseudo-fields called translation_link in: NodeViewsData, UserViewsData, BlockContentViewsData, CommentViewsData, TermViewsData)

Note: Other entities do not currently have these link fields: File, AggregatorItem, AggregatorFeed, BlockContent

3. Since all text/string fields on Entities (such as Title) now have the ability to link to the entity (canonical link), do you agree that converting title and similar fields is out of scope for this issue? I think we should limit this issue to the plain "link" fields that let you define the link text, and exclude fields like "title with ability to make link" from this one.

4. Note: In the list in item 2 here, some of the link fields are not actually part of the entity-defined link list. For example, on Node, the revision view, delete, and revert links are not part of the Node link annotation, which looks like this:

 *   links = {
 *     "canonical" = "/node/{node}",
 *     "delete-form" = "/node/{node}/delete",
 *     "edit-form" = "/node/{node}/edit",
 *     "version-history" = "/node/{node}/revisions",
 *   }

The revision links are just regular routes, defined in node.routing.yml, like this:

node.revision_revert_confirm:
  path: '/node/{node}/revisions/{node_revision}/revert'
...

Can we handle them in this issue, or is that out of scope?

jhodgdon’s picture

Proposed answers to the questions in #37:

1. Go ahead and do this for all entities. Will add some links, but that is OK.

2. See item 1 and 4.

3. Limit to the fields listed in 2 or a subset; others out of scope.

4. Limit to fields defined in entity annotation, not routing.yml files like revision revert/delete for node.

jhodgdon’s picture

Given these answers, the patch kgoel is about to post will contain:
- A reroll of the previous patch
- Leaving out aggregator stuff [out of scope text fields and covered elsewhere anyway]
- Leaving out the changes to the Drupal\node\Plugin\views\field\Node class [out of scope text fields]
- Added content translation to the mix. Used existing content translation plugin, but edited to subclass the new EntityLink class instead of what it did before ==> no new schema or views changes needed since ID is same and so are options (phew!)

Previous patch didn't exactly apply; interdiff difficult; please excuse the mess. ;)

kgoel’s picture

Status: Needs work » Needs review
FileSize
27.8 KB

Need to add couple lines for content_translation in EntityViewsDataTest.php

jibran’s picture

Status: Needs review » Needs work

@kgoel interdiff please. :)

+++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
@@ -712,6 +712,33 @@ protected function assertField($data, $field_name) {
+    $this->assertEquals('entity_link', $data['entity_test']['view_entity_test']['field']['id']);
+    $this->assertEquals('entity_link_edit', $data['entity_test']['edit_entity_test']['field']['id']);
+    $this->assertEquals('entity_link_delete', $data['entity_test']['delete_entity_test']['field']['id']);

Let's add assert for translation link.

kgoel’s picture

@jibran - Please see jhodgdon's comment...

Previous patch didn't exactly apply; interdiff difficult; please excuse the mess. ;)

Let's add assert for translation link.

Please see my comment- https://www.drupal.org/node/2322949#comment-9838445

The last submitted patch, 40: 2322949-40.patch, failed testing.

jibran’s picture

Those line were not there before when I was last here. j/k :P
Don't mind me carry on :)

dawehner’s picture

I think the point of this issue is to replace the generic "Make a link to X" fields, the ones that allow you to define the link text in Views (with some plain text or presumably a views-token-replacement-thing).

Exactly. For the Delete link for example, we want to fallback to t( 'Delete') though, for example.

OK I think I'm undecided on this, but probably agree with turning it on generically and standardizing all entities. ;)

That would be super super cool!

For instance the Node views data defines links for viewing/reverting revisions. These are just defined as generic routes in node.routing.yml, and they're not in the links section of the entity annotation on the Node class. Can anything be done for them?

This statement was true a while ago, but with #2455153: Switch revision log views fields to use 'field' formatter we can check for 'entity.$entity_type.revision', I think.

1. Do we want the call to EntityViewsData::addEntityLinks() to be done by default

I would vote for that, given that we head towards that in much more areas now already. Its IMHO just really good DX

node_revision_link (pseudo-field: link_to_revision on node_revision)
- node_revision_link_revert (pseudo-field: revert_revision on node_revision)
- node_revision_link_delete (pseudo-field: delete_revision on node_revision)

MH, maybe we could add them as link templates onto the node entity type.

- user_link_edit (pseudo-field: UserFieldData - edit_node, which despite the name is actually a link to edit the user)

Yeah, this is kinda a hidden easteregg of shame.

- content_translation_link (Used in pseudo-fields called translation_link in: NodeViewsData, UserViewsData, BlockContentViewsData, CommentViewsData, TermViewsData)

It would be certainly helpful to have that provided for all entity types as well.

think we should limit this issue to the plain "link" fields that let you define the link text, and exclude fields like "title with ability to make link" from this one.

Yeah, I absolutely agree.

Can we handle them in this issue, or is that out of scope?

Well, I handled the renaming as part of #2455153: Switch revision log views fields to use 'field' formatter and noone complained about it :)

kgoel’s picture

Status: Needs work » Needs review
FileSize
28.64 KB
2.43 KB
jhodgdon’s picture

This patch is looking like it's pretty close, assuming the bot agrees. One change crept in by mistake:

+++ b/core/modules/node/src/Plugin/views/field/Node.php
@@ -37,9 +37,6 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
-  /**
-   * {@inheritdoc}
-   */
   protected function defineOptions() {
     $options = parent::defineOptions();

This shouldn't have been removed in the patch.

kgoel’s picture

FileSize
28.01 KB
639 bytes
jhodgdon’s picture

Several of the link plugins that are mentioned in comment #37 item 2 are not actually removed or replaced in this patch... so I think there is a bit more work to do.

The last submitted patch, 46: 2322949-46.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 48: 2322949-48.patch, failed testing.

kgoel’s picture

Status: Needs work » Needs review
FileSize
49.27 KB
23.28 KB
jhodgdon’s picture

Closer!

Looks like this still needs some work though:

  1. +++ b/core/modules/comment/config/schema/comment.views.schema.yml
    @@ -8,49 +8,10 @@ views.field.comment_depth:
    -views.field.comment_entity_link:
    -  type: views_field
    -  label: 'Comment link'
    -  mapping:
    

    (and following lines) - I think we need to keep this one. This is some kind of weird link thing that shows links to the node the comment is on or something.

  2. +++ b/core/modules/comment/config/schema/comment.views.schema.yml
    @@ -8,49 +8,10 @@ views.field.comment_depth:
    -views.field.comment_link_approve:
    -  type: views.field.comment_link
    -  label: 'Comment approve link'
    -
    

    We'll need this: this class (and the reply plugin below) are replaced with new code, but still exist as special plugins.

  3. +++ b/core/modules/comment/config/schema/comment.views.schema.yml
    @@ -8,49 +8,10 @@ views.field.comment_depth:
    -views.field.comment_link_reply:
    -  type: views.field.comment_link
    -  label: 'Comment reply link'
    -
    

    See comment above.

  4. +++ b/core/modules/comment/src/CommentViewsData.php
    @@ -102,46 +102,6 @@ public function getViewsData() {
    -    $data['comment']['approve_comment'] = array(
    -      'field' => array(
    -        'title' => t('Link to approve comment'),
    -        'help' => t('Provide a simple link to approve the comment.'),
    -        'id' => 'comment_link_approve',
    -      ),
    -    );
    -
    -    $data['comment']['replyto_comment'] = array(
    -      'field' => array(
    -        'title' => t('Link to reply-to comment'),
    -        'help' => t('Provide a simple link to reply to the comment.'),
    -        'id' => 'comment_link_reply',
    -      ),
    -    );
    -
    

    Still need these, see above.

  5. +++ b/core/modules/node/config/schema/node.views.schema.yml
    @@ -94,37 +94,13 @@ views.argument_validator.node:
     views.field.node:
    -  type: views_field
    +  type: views.field.entity_link
       label: 'Node'
    

    We're not doing anything to this plugin any more, so just leave this as it was.

  6. +++ b/core/modules/taxonomy/src/TermViewsData.php
    --- a/core/modules/user/config/schema/user.views.schema.yml
    +++ b/core/modules/user/config/schema/user.views.schema.yml
    

    Need to also get rid of the section for the now-deleted views.field.user_link too.

  7. +++ b/core/modules/views/config/schema/views.field.schema.yml
    @@ -171,11 +171,22 @@ views.field.url:
     views.field.language:
       type: views_field
       label: 'Language'
    +
    +views.field.entity_link:
    +  type: views_field
    +  label: 'Entity link'
       mapping:
         native_language:
           type: boolean
           label: 'Display in native language'
    +    text:
    +      type: label
    +      label: 'Text to display'
     
    

    This is garbled. It looks like in the reroll something happened? There's a mix of stuff from the language field and the entity link field here....

  8. +++ b/core/modules/views/config/schema/views.field.schema.yml
    @@ -171,11 +171,22 @@ views.field.url:
    +views.field.entity_link_delete:
    +  type: views.field.entity_link
    +  label: 'Entity delete link'
    +  mapping:
     views.field.bulk_form:
    

    This is also messed up...

    ok this schema file just needs to be redone.

  9. +++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
    @@ -0,0 +1,120 @@
    +    // @FIXME
    +    // $this->additional_fields['langcode'] = ['table' => 'node_field_data', 'field' => 'langcode'];
    +  }
    

    Hm... something missing here?

Status: Needs review » Needs work

The last submitted patch, 52: 2322949-52.patch, failed testing.

kgoel’s picture

Status: Needs work » Needs review
FileSize
48.21 KB
4.6 KB

I am not sure about #9, need to look into that more.

jhodgdon’s picture

OK, I think this is all good now except for the @fixme comment and maybe some test fails.

kgoel’s picture

Status: Needs review » Needs work

The last submitted patch, 55: 2322949-55.patch, failed testing.

kgoel’s picture

Status: Needs work » Needs review
FileSize
48.2 KB
736 bytes

Status: Needs review » Needs work

The last submitted patch, 59: 2322949-59.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
52.19 KB

Some class names have changed (Link became EntityLink). Rerolled.

Status: Needs review » Needs work

The last submitted patch, 61: 0001-Issue-2322959-entity-links.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
52.77 KB
7.07 KB

Should pass better: type-hinting renderLink on EntityInterface on other classes exteding EntityLink.

Status: Needs review » Needs work

The last submitted patch, 63: 2322949-63.patch, failed testing.

kgoel’s picture

Status: Needs work » Needs review
FileSize
52.71 KB
1.9 KB

Status: Needs review » Needs work

The last submitted patch, 65: 2322949-65.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
55.12 KB

Extra hinting on NodeNewComment.

Also renamed $data to $entity since it implements EntityInterface: this is better for DX.

fgm’s picture

FileSize
7.42 KB

Gaaah, missed interdiff again.

Status: Needs review » Needs work

The last submitted patch, 67: 2322949-entity_link-67.patch, failed testing.

kgoel’s picture

Status: Needs work » Needs review
FileSize
57.46 KB
995 bytes
dawehner’s picture

Status: Needs review » Needs work
Issue tags: +D8 Accelerate Dev Days
  1. +++ b/core/modules/block_content/src/BlockContentViewsData.php
    @@ -28,18 +28,6 @@ public function getViewsData() {
    -    // @todo Figure out the way to integrate this automatic in
    -    //   content_translation https://www.drupal.org/node/2410261.
    -    if ($this->moduleHandler->moduleExists('content_translation')) {
    -      $data['block_content']['translation_link'] = array(
    -        'title' => $this->t('Translation link'),
    
    +++ b/core/modules/views/src/EntityViewsData.php
    @@ -230,6 +232,53 @@ public function getViewsData() {
    +    if ($this->entityType->hasLinkTemplate('drupal:content-translation-overview')) {
    +      $data['translate_' . $entity_type_id] = [
    +        'field' => [
    

    Yes, using 'translation_' . $entity_type_id makes things more consistent, but at the same time, we should think about existing configurations out there. For them, we should better try to not require them to update their views, ... again, so I'd recommend to use 'translation_link' itself. Feel free to disagree

  2. +++ b/core/modules/comment/src/Plugin/views/field/LinkApprove.php
    @@ -40,7 +42,7 @@ public function access(AccountInterface $account) {
    +  protected function renderLink(EntityInterface $entity, ResultRow $values) {
         $status = $this->getValue($values, 'status');
    

    I'm really suprised that its works ... given that nothing seems to ensure that the 'status' column is there. What about pulling it from the entity instead?

  3. +++ b/core/modules/views/config/schema/views.field.schema.yml
    @@ -176,6 +176,31 @@ views.field.language:
    +views.field.entity_link:
    +  type: views_field
    +  label: 'Entity link'
    +  mapping:
    +    text:
    +      type: label
    +      label: 'Text to display'
    ...
    +  label: 'Entity delete link'
    +  mapping:
    +    text:
    +      type: label
    ...
    +   type: views.field.entity_link
    +   label: 'Entity edit link'
    +   mapping:
    +     text:
    +       type: label
    +       label: 'Text to display'
    

    If we kinda subclass that entity_link field handler, we don't have to specify the mapping again. So just skip it for entity_link_delete and entity_link_edit

  4. +++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
    @@ -0,0 +1,118 @@
    +    $options = parent::defineOptions();
    +    $options['text'] = ['default' => '', 'translatable' => TRUE];
    

    Quick comment: We don't need the 'translatable' here anymore ... That bit just doesn't exist anymore in Drupal 8.

  5. +++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
    @@ -0,0 +1,118 @@
    +      $langcode = $this->getEntity($values, 'langcode');
    +      if (isset($languages[$langcode])) {
    +        $this->options['alter']['language'] = $languages[$langcode];
    +      }
    +      else {
    +        unset($this->options['alter']['language']);
    +      }
    +    }
    

    You could probably do it by this single line: $this->options['alter']['language'] = $this->getEntity($values)->language();

  6. +++ b/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php
    @@ -0,0 +1,39 @@
    +      $this->options['alter']['path'] = $entity->getSystemPath('delete-form');
    
    +++ b/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php
    @@ -0,0 +1,39 @@
    +      $this->options['alter']['path'] = $entity->getSystemPath('edit-form');
    

    We should use $this->options['alter']['url'] = $entity->urlInfo('delete-form') instead, and similar to the edit form.

  7. +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
    @@ -712,6 +712,35 @@ protected function assertField($data, $field_name) {
    +  public function testEntityLinks() {
    ...
    +  public function testEntityLinksJustEditForm() {
    

    I like that we have additional test coverage in EntityViewsDataTest

kgoel’s picture

Status: Needs work » Needs review
FileSize
56.01 KB
5.98 KB

Status: Needs review » Needs work

The last submitted patch, 72: 2322949-72.patch, failed testing.

kgoel’s picture

Status: Needs work » Needs review
FileSize
56.2 KB
651 bytes

Status: Needs review » Needs work

The last submitted patch, 74: 2322949-74.patch, failed testing.

kgoel’s picture

Status: Needs work » Needs review
FileSize
56.18 KB
1.56 KB
dawehner’s picture

Issue summary: View changes

Thank you, I think its a sane idea to not break existing views if possible. Updated the issue summary

kgoel’s picture

Manually tested and I do see view, edit and delete links on entities page.

kgoel’s picture

Assigned: kgoel » Unassigned
dawehner’s picture

We already have some test coverage for those links, maybe a generic would be nice, so create a view of entity_test entities and check whether those links appear as expected.

I really like this patch so far!

plach’s picture

Assigned: Unassigned » plach
Priority: Major » Critical

This is blocking #2450897: Cache Field views row output, so promoting to critical, I'll try to complete the work here, since Daniel believes this is almost ready.

Here is a quick review:

  1. +++ b/core/modules/views/config/schema/views.field.schema.yml
    @@ -223,6 +240,7 @@ views.field.field:
           type: label
           label: 'Separator'
    +      label: 'Text to display'
    

    Is this correct? Does not look so.

  2. +++ b/core/modules/views/src/EntityViewsData.php
    @@ -230,6 +232,53 @@ public function getViewsData() {
    +    if ($this->entityType->hasLinkTemplate('drupal:content-translation-overview')) {
    +      $data['translation_link'] = [
    +        'field' => [
    +          'title' => $this->t('Link to translate @entity_type_label', $t_arguments),
    +          'help' => $this->t('Provide a translation link to the @entity_type_label.', $t_arguments),
    +          'id' => 'content_translation_link',
    +        ],
    +      ];
    +    }
    +  }
    

    This should be added by the Content Translation module.

  3. +++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
    @@ -0,0 +1,111 @@
    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
    +    parent::init($view, $display, $options);
    +  }
    +
    ...
    +  /**
    +   * {@inheritdoc}
    +   */
    +  protected function defineOptions() {
    +    $options = parent::defineOptions();
    +    return $options;
    +  }
    +
    

    Looks like these methods are redundant...

plach’s picture

Issue tags: +blocker
Related issues: +#2450897: Cache Field views row output
plach’s picture

Title: Get generic entity link fields from entity_view module. » Implement generic entity link view field handlers

More accurate title

plach’s picture

This merges the work I did in #2450897: Cache Field views row output, basically it provides automatic route access checking.

#81.2 still to be addressed. Let's see how many things I broke.

Status: Needs review » Needs work

The last submitted patch, 84: views-entity_links-2322949-84.patch, failed testing.

plach’s picture

Status: Needs work » Needs review
FileSize
1.83 KB
72.09 KB

This should fix the failing tests.

plach’s picture

This implements #81.2, working on some additional test coverage now.

Status: Needs review » Needs work

The last submitted patch, 87: views-entity_links-2322949-87.patch, failed testing.

plach’s picture

Status: Needs work » Needs review
FileSize
4.72 KB
71.45 KB

Some fixes/clean-ups...

plach’s picture

This adds a couple of small fixes and the missing test coverage.

Edit: I don't know why but the patch appears only as attachment in the issue summary.

plach’s picture

Attaching again, just in case

dawehner’s picture

Status: Needs review » Needs work

The patch looks really awesome, so much saved code.

  1. +++ b/core/modules/comment/src/Plugin/views/field/LinkApprove.php
    @@ -19,43 +18,28 @@
    +  protected function getUrlInfo(ResultRow $row) {
    +    return Url::fromRoute('comment.approve', ['comment' => $this->getEntity($row)->id()]);
       }
    ...
    +  protected function renderLink(ResultRow $row) {
    +    $this->options['alter']['query'] = $this->getDestinationArray();
    +    return parent::renderLink($row);
    +  }
    

    Here is a question, why do we override both renderLink and getUrlInfo even the query could be theoretically added to the $url object in getUrlInfo() as well.

  2. +++ b/core/modules/contact/src/Plugin/views/field/ContactLink.php
    @@ -90,7 +29,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    -    $form['text']['#default_value'] = empty($this->options['text']) ? $this->t('contact') : $this->options['text'];
    +    $form['text']['#default_value'] = empty($this->options['text']) ? $this->getDefaultLabel() : $this->options['text'];
    

    Here is a question, why is the default text of $this->options['text'] not directly $this->getDefaultLabel()? The defineOptions() method could use it.

  3. +++ b/core/modules/node/src/Plugin/views/field/RevisionLink.php
    @@ -21,78 +20,47 @@
       public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
         parent::init($view, $display, $options);
    -
         $this->additional_fields['node_vid'] = array('table' => 'node_field_revision', 'field' => 'vid');
       }
     
    ...
    -  function get_revision_entity($values, $op) {
    -    $vid = $this->getValue($values, 'node_vid');
    -    $node = $this->getEntity($values);
    

    I think we should be able to remove the init() method as well.

  4. +++ b/core/modules/views/config/schema/views.field.schema.yml
    @@ -223,6 +240,7 @@ views.field.field:
           label: 'Separator'
    +      label: 'Text to display'
    

    Seems to be an accident ...

  5. +++ b/core/modules/views/src/Plugin/views/field/LinkBase.php
    @@ -0,0 +1,195 @@
    +abstract class LinkBase extends FieldPluginBase {
    +  use RedirectDestinationTrait;
    

    newline needed ...

  6. +++ b/core/modules/views/src/Plugin/views/field/LinkBase.php
    @@ -0,0 +1,195 @@
    +
    +  /**
    +   * Gets the current active user.
    +   *
    +   * @todo: https://drupal.org/node/2105123 put this method in
    +   *   \Drupal\Core\Plugin\PluginBase instead.
    +   *
    +   * @return \Drupal\Core\Session\AccountInterface
    +   *   The current user.
    +   */
    +  protected function currentUser() {
    +    if (!$this->currentUser) {
    +      $this->currentUser = \Drupal::currentUser();
    +    }
    +    return $this->currentUser;
    +  }
    

    ... Why do we not inject it, if we already inject the access manager?

  7. +++ b/core/modules/views/src/Plugin/views/field/LinkBase.php
    @@ -0,0 +1,195 @@
    +    $options['text'] = array('default' => '');
    ...
    +  protected function getDefaultLabel() {
    +    return $this->t('link');
    +  }
    

    As written before, let's use $options['text'] = ['default' => $this->getDefaultLabel()]

  8. +++ b/core/modules/views/src/Plugin/views/field/LinkBase.php
    @@ -0,0 +1,195 @@
    +    $form['alter']['path'] = ['#access' => FALSE];
    +    $form['alter']['external'] = ['#access' => FALSE];
    

    Why do you not use +=? I mean if we replace the entire array we can also remove it with unset().

  9. +++ b/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php
    @@ -0,0 +1,134 @@
    + * Definition of \Drupal\views\Tests\Handler\FieldEntityOperationsTest.
    

    Contains ...

  10. +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
    @@ -712,6 +712,33 @@ protected function assertField($data, $field_name) {
    +   */
    +  public function testEntityLinks() {
    +    $this->baseEntityType->setLinkTemplate('canonical', '/entity_test/{entity_test}');
    +    $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit');
    +    $this->baseEntityType->setLinkTemplate('delete-form', '/entity_test/{entity_test}/delete');
    ...
    +   */
    +  public function testEntityLinksJustEditForm() {
    +    $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit');
    +
    

    Nice test coverage!

Fabianx’s picture

Except what Daniel found, this would be RTBC for me.

plach’s picture

This should address #92. I was performing some manual testing and I noticed revision links are broken in HEAD, I implemented a quick fix, but deferred providing a proper fix and test coverage to #1863898: Add test coverage for Views revision link handlers.

1: That's the only class where doing what you suggest makes sense, for consistency with the others I'd keep it as-is.
6: There's a @todo (see the PHP doc) to add the current user PluginBase, so I'd keep it as-is for now.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Thank you! It looks great for me now!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 94: views-entity_links-2322949-94.patch, failed testing.

Status: Needs work » Needs review
plach’s picture

Status: Needs review » Reviewed & tested by the community

Green, back to RTBC

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +D8 upgrade path, +Needs change record
  1. +++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php
    @@ -138,9 +138,7 @@ function testAnonymous() {
    -    $this->assertText('You are not authorized to post comments', 'Error attempting to post comment.');
    -    $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.');
    -    $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.');
    +    $this->assertResponse(403, 'Error attempting to post comment.');
    
    +++ b/core/modules/comment/src/Tests/CommentNonNodeTest.php
    @@ -344,9 +344,7 @@ function testCommentFunctionality() {
    -    $this->assertText('You are not authorized to post comments', 'Error attempting to post comment.');
    -    $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.');
    -    $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.');
    +    $this->assertResponse(403, 'Error attempting to post comment.');
    

    So are we going to leave the post comments check in CommentController::getReplyForm()? And if so should we be testing it?

  2. +++ b/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php
    @@ -0,0 +1,44 @@
    +use Drupal\Core\Entity\EntityInterface;
    

    Not used.

  3. Looks like a change record will be necessary.
dawehner’s picture

Added the change record ...

plach’s picture

Status: Needs work » Needs review
FileSize
2.67 KB
88.72 KB

This reverts the changes to the comment reply access control to avoid regressions, as I don't completely understand the current logic and I suspect there might be something I'm missing. Moreover those changes are a bit out of scope here and can be easily addressed as a follow-up.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

This reverts the changes to the comment reply access control to avoid regressions, as I don't completely understand the current logic and I suspect there might be something I'm missing. Moreover those changes are a bit out of scope here and can be easily addressed as a follow-up.

@larowlan I guess you understand more so you could file a follow up?

andypost’s picture

Status: Reviewed & tested by the community » Needs work

Interdiff is not in last patch - NW

The reason behind reply form to check access within controller is to Give user ability to login and back to reply form, because visitors could came to the replay form via email notifications and getting 403 does not tell exactly what's up...

+++ b/core/modules/comment/comment.routing.yml
@@ -57,7 +57,7 @@ comment.reply:
-    _access: 'TRUE'
+    _permission: 'post comments'

it's not reverted

plach’s picture

@larowlan found these two related issues:

#56942: Comment cids should belong to the associated node in comment/reply
#50835: Reply to non existent comments

I think at least the check introduced in the first one was lost in translation. We should probably open a follow-up to verify the new code is still addressing the original use cases and improve it to just use access callback where needed.

plach’s picture

Status: Needs work » Needs review
FileSize
86.45 KB

Sorry, forgot to commit. This time for reals.

plach’s picture

Wim Leers’s picture

Status: Needs review » Needs work

This looks very close!

  1. +++ b/core/modules/contact/src/Plugin/views/field/ContactLink.php
    @@ -101,26 +40,25 @@ public function access(AccountInterface $account) {
    +    // Check access when we pull up the user account so we know if the user has
    +    // made the contact page available.
    

    The description makes sense, but doesn't explain where that is then happening.

    Could use an @see.

  2. +++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
    @@ -0,0 +1,53 @@
    + * Contains \Drupal\views\Plugin\views\field\EntityLinkBase.
    ...
    +class EntityLink extends LinkBase {
    

    Docs mismatch.

  3. +++ b/core/modules/views/src/Plugin/views/field/LinkBase.php
    @@ -0,0 +1,197 @@
    + * Contains \Drupal\views\Plugin\views\field\EntityLinkBase.
    ...
    +abstract class LinkBase extends FieldPluginBase {
    ...
    +   * Constructs a ContactLink object.
    

    More docs mismatches.

  4. +++ b/core/modules/views/src/Plugin/views/field/LinkBase.php
    @@ -0,0 +1,197 @@
    +  protected function currentUser() {
    

    Why not inject, this, like AccessManager?

    Beecause the todo will move it to PluginBase, and so injecting it here would cause more work elsewhere?

plach’s picture

Status: Needs work » Needs review
FileSize
1.75 KB
86.53 KB

Why not inject, this, like AccessManager?
Beecause the todo will move it to PluginBase, and so injecting it here would cause more work elsewhere?

Yep, and it wouldn't just be more work, it'd also be an API break :)

plach’s picture

Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community

Thanks!

Checked that #103 is also addressed. Back to RTBC per #102.

catch’s picture

+++ b/core/modules/contact/src/Plugin/views/field/ContactLink.php
@@ -101,26 +40,26 @@ public function access(AccountInterface $account) {
+    // Check access when we pull up the user account so we know if the user has
+    // made the contact page available. See contact_form_user_form_alter() and
+    // contact_user_profile_form_submit().

Don't really understand the comment. When do we 'pull up the user account'? Was the comment just moved without updating it?

Struggled to find much else though, this really cleans a lot up.

plach’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.07 KB
86.34 KB

That comment was originally in the ::renderLink() method, but you are right that now it makes no sense, it's only confusing, removed it. I also removed the ::access() method as its parent implementation is more correct.

Fabianx’s picture

Status: Needs review » Reviewed & tested by the community

RTBC, looks great!

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.0.x, thanks!

  • catch committed 9d61b04 on 8.0.x
    Issue #2322949 by plach, kgoel, Berdir, fgm, damiankloip, dawehner:...
plach’s picture

Yay, thanks!

Published the CR

plach’s picture

Issue tags: +D8 cacheability

Retroactively tagging, as this was blocking #2450897: Cache Field views row output.

plach’s picture

Assigned: plach » Unassigned

Status: Fixed » Closed (fixed)

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

quietone credited vasike.

quietone’s picture