Problem/Motivation

The location of the entity in the $build array passed to hook_entity_view_alter isn't consistent between invocations, this means that implementing modules can not be sure where to look for the entity. For example:

$build['#comment'] = $entity (comment)
$build['#node'] = $entity (node)
$build['#account'] = $entity (user)
$build['#term'] = $entity (taxonomy_term)

Proposed resolution

Add an additional value in the $build array that declares the key in the array where the entity is located. This is called: #build_name and it's value is the key of the $build array where the entity can be found.
This is to minimise API change and provide a valid backport route for D7.

Remaining tasks

This approach needs to be reviewed really, and tests written.

User interface changes

None.

API changes

We'd be adding a new key/value to the $build array passed to hook_entity_view_alter, so that's an API change of sorts (an addition).

Original report by BTMash

I couldn't find an issue that seems to mark what I am finding so I posted a new issue. I was recently working with trying to get views (using the eva module) to display on the taxonomy term page. However, because taxonomy does not actually invoke hook_entity_view() (to note, only nodes, users, comments have such an implementation) but does allow for hook_entity_view_alter(), I went about to build out an implementation using that. However, I am finding that the build array when passed it has a different variable name for each of the entities that get passed in (and they are all different from the type. So:

$build['#comment'] = $entity (comment)
$build['#node'] = $entity (node)
$build['#account'] = $entity (user)
$build['#term'] = $entity (taxonomy_term)

So if someone wanted to try and build a generic module to tackle altering the view on an entity, they would need to put in if/else checks to get the entity appropriately. I think the simplest solution would be for all of these cases to set $build['#entity']. Its clear for various modules to understand, and module developers know what to look for in such situations. The other way is that anything that implements entities should invoke hook_entity_view() (along with hook_entity_view_alter().

Comments

joachim’s picture

Issue tags: -inconsistent

Couldn't you just say:

$build['#' . $entity->type] ?

chx’s picture

Category: bug » task
Priority: Major » Normal

$build['#'. $entity_type] sounds sane to me. Whether we want $build['#entity'] is a matter to discuss. Can't see a harm in it but then you need #entity_type in there as well.

btmash’s picture

Agree. $build['#'. $entity_type] is fine as well (although I don't think $build['#entity_type'] is necessary given that the alter, entity_view, etc all pass through the type of entity as an argument for the hooks). So long as a module has an easy way to figure out which build variable is the entity.

catch’s picture

Component: base system » entity system
btmash’s picture

I never ended up getting back on this issue. So would the first step to try and get this into core be to add this to the various types of entities currently in core? Just so I remember to tackle them correctly (I don't miss out on any by mistake), would they be:

  • Node
  • User
  • Comment
  • Vocabulary
  • Taxonomy
joachim’s picture

Is File an entity in core?

btmash’s picture

You're right. File is also an entity in core (see it in the system module file) though does it have any functions where it goes through build a build mode?

catch’s picture

This sounds good but we should consider going straight to having view() etc. methods in the entity system which do this and applying those to the individual entities compared to cleaning up each individual pipeline for consistency - I'm personally fine whichever way we do that.

btmash’s picture

In all honesty...I am *way* more in favor of your approach (view / build() methods as part of the entity system) than what I have asked for in my issue (though this will likely come into play as a part of it)) as I do think the individual entities having their own view methods (and each one, barring the taxonomy but would be with #1067120: Missing hook_taxonomy_term_view() or hook_entity_view() when viewing a term, pretty much being copy/paste jobs of each other) is inefficient usage of development time and more importantly can lead to (and has lead to) inconsistent behavior. I have been afraid of creating an issue on that one (a few folk have mentioned that this might be a 8.x thing only which leads to 'what happens for D7?') but am happy to help out with whichever path we end up on.

catch’s picture

Generic entity rendering is definitely an 8.x thing only.

Adding standard #build keys on top of the existing ones for D7 might be backportable, depends how an intrusive a change it might be.

btmash’s picture

From what chx said, $build['#'. $entity_type] is one possible approach. Another can be $build['#entity_type'] = (name of variable holding the entity build like 'term' or 'account' or 'node'). Seems a bit silly to grab the name of the variable that way though.

pjbarry21’s picture

Subscribe

btmash’s picture

Status: Active » Needs review
StatusFileSize
new1.73 KB

To start things off and hopefully see it go somewhere better, I added a '#build_name' to each of the core entities that have a drupal_alter happening. Since there are only 4 entities that bring this out in core (atleast I hope it is only these), they have the build name added in. And it seems like it could be backportable to D7 in this scenario.

xjm’s picture

Issue tags: +Needs backport to D7

#13 looks like a simple, backportable fix to me. Patch looks good to me, for what it's worth.

I wonder if we could do something similar to standardize entities in FAPI? (E.g. see #1261310: uid is not available in hook_field_attach_validate() and #1220212: Provide original entity in hook_field_attach_validate()).

xjm’s picture

One thought; would we maybe just want to use the full name of the key? E.g.:
'#build_name' => '#node',

It's worth noting that in the user case it is called #account rather than #user, which is why this specific approach seems more viable than just referencing $build['#' . $entity->type].

btmash’s picture

Ok, updated the patch to have the # in there. And what you have said is precisely the reason. user gets account and taxonomy_term gets term which is why it has to go in this route until entity building gets standardized.

btmash’s picture

Forgot to attach the actual patch...

btmash’s picture

Status: Needs review » Needs work

Needs to get rerolled.

xjm’s picture

Status: Needs work » Needs review
StatusFileSize
new1.81 KB

Did someone say "reroll"?

btmash’s picture

Status: Needs review » Needs work
Issue tags: +Needs backport to D7

The last submitted patch, entity_build_variable_name-1170198-19.patch, failed testing.

xjm’s picture

Issue tags: +Novice

Apparently someone still needs to say "reroll."

kim.pepper’s picture

Assigned: Unassigned » kim.pepper
kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new1.81 KB

Re-rolled

Zgear’s picture

renamed to .patch ^^

xjm’s picture

Issue tags: +Needs tests

Thanks for the reroll! That looks good.

If we want to add this property, we should probably add automated tests that use it (or at least assert that it is available).

steven jones’s picture

Assigned: kim.pepper » steven jones
Status: Needs review » Needs work

Going to have a look at this.

steven jones’s picture

Assigned: steven jones » Unassigned
Status: Needs work » Needs review
StatusFileSize
new8.12 KB

So...here's a patch that adds some tests, I'm fairly certain that the tests are broken, sorry.

I've tried to keep the tests near the code that we're actually testing, but added the hook that allows us to test in a bit of a random place, so that would need cleaning up too.

Status: Needs review » Needs work

The last submitted patch, drupal-1170198-entity-build-name.patch, failed testing.

bas.hr’s picture

Assigned: Unassigned » bas.hr

I'm rewriting the patch

bas.hr’s picture

Status: Needs work » Needs review
StatusFileSize
new6.44 KB
new8.26 KB

Tests are fixed

tim.plunkett’s picture

bas.hr, you should upload the test without that suffix so we actually see the failures. If you upload the test as the first patch and the combined as the second, the bot will leave it as needs review.
The do-not-test thing is for D7 patches on a D8 issue, for example.

Also an interdiff would have been good to have here.

bas.hr’s picture

OK thanks for pointing that out. I'm attaching the interdiff too.

Status: Needs review » Needs work

The last submitted patch, entity_build_variable_name-1170198-31-tests.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review

It won't do that if you upload the tests patch first. This looks pretty good, are there going to be any docs about the new #build_mode part?

xjm’s picture

Status: Needs review » Needs work

Thanks @bas.hr! Those tests look sufficient to me. It looks like there's coverage for comments, nodes, terms, and users; vocabularies and files do not have view modes in core currently (right?).

I agree with @tim.plunkett that we should also add documentation for the new property.

Additionally, there are a few minor cleanups we can make to the patch in the next reroll:

  1. +++ b/core/modules/comment/comment.testundefined
    @@ -1857,6 +1863,43 @@ class CommentContentRebuild extends CommentHelperCase {
    + * Tests comment view altering.
    ...
    +      'description' => 'Test to make sure the comment view altering is consistent with other entities.',
    
    +++ b/core/modules/node/node.testundefined
    @@ -1991,6 +1991,35 @@ class NodeBuildContent extends NodeWebTestCase {
    + * Tests comment view altering.
    ...
    +      'description' => 'Test to make sure the node view altering is consistent with other entities.',
    
    +++ b/core/modules/taxonomy/taxonomy.testundefined
    @@ -1950,3 +1950,31 @@ class TaxonomyEFQTestCase extends TaxonomyWebTestCase {
    + * Tests taxononmy term view altering.
    ...
    +      'description' => 'Test to make sure the taxonomy term view altering is consistent with other entities.',
    
    +++ b/core/modules/user/user.testundefined
    @@ -2409,3 +2409,31 @@ class UserEntityCallbacksTestCase extends DrupalWebTestCase {
    + * Tests taxononmy term view altering.
    ...
    +      'description' => 'Test to make sure the user view altering is consistent with other entities.',
    

    Let's improve these docs. (They're a bit ambiguous, the user test case is mislabeled, and "taxonomy" is misspelled.) I think for both the class summary and the getInfo() description we can simply say:
    Tests hook_entity_view_alter() for insert_entity_name_here.

  2. +++ b/core/modules/comment/comment.testundefined
    @@ -1857,6 +1863,43 @@ class CommentContentRebuild extends CommentHelperCase {
    +   * Tests the .
    
    +++ b/core/modules/node/node.testundefined
    @@ -1991,6 +1991,35 @@ class NodeBuildContent extends NodeWebTestCase {
    +   * Tests the .
    
    +++ b/core/modules/taxonomy/taxonomy.testundefined
    @@ -1950,3 +1950,31 @@ class TaxonomyEFQTestCase extends TaxonomyWebTestCase {
    +   * Tests the .
    
    +++ b/core/modules/user/user.testundefined
    @@ -2409,3 +2409,31 @@ class UserEntityCallbacksTestCase extends DrupalWebTestCase {
    +   * Tests the .
    

    For these, let's say:
    Tests that the #build_name is set correctly for insert_entity_name_here.

  3. +++ b/core/modules/comment/comment.testundefined
    @@ -1857,6 +1863,43 @@ class CommentContentRebuild extends CommentHelperCase {
    +    $this->assertText('hook_entity_view_alter:build_name:#comment', 'Build name for comment is specified in hook_entity_view_alter');
    
    +++ b/core/modules/node/node.testundefined
    @@ -1991,6 +1991,35 @@ class NodeBuildContent extends NodeWebTestCase {
    +    $this->assertText('hook_entity_view_alter:build_name:#node', 'Build name for node is specified in hook_entity_view_alter');
    
    +++ b/core/modules/taxonomy/taxonomy.testundefined
    @@ -1950,3 +1950,31 @@ class TaxonomyEFQTestCase extends TaxonomyWebTestCase {
    +    $this->assertText('hook_entity_view_alter:build_name:#term', 'Build name for taxonomy term is specified in hook_entity_view_alter');
    
    +++ b/core/modules/user/user.testundefined
    @@ -2409,3 +2409,31 @@ class UserEntityCallbacksTestCase extends DrupalWebTestCase {
    +    $this->assertText('hook_entity_view_alter:build_name:#account', 'Build name for user is specified in hook_entity_view_alter');
    

    I think we can leave off the assertion messages for these. (It will then say, e.g. hook_entity_view_alter:build_name:#comment found, which is fairly self-explanatory).

  4. +++ b/core/modules/user/user.testundefined
    @@ -2409,3 +2409,31 @@ class UserEntityCallbacksTestCase extends DrupalWebTestCase {
    +}
    \ No newline at end of file
    

    We need a newline at the end of the file here.

Thanks everyone!

tim.plunkett’s picture

Assigned: bas.hr » tim.plunkett
Status: Needs work » Needs review
StatusFileSize
new7.58 KB

This is a straight port since node, comment, and user tests went PSR-0. I'll address the concerns from #35-36 in the next patch.

Status: Needs review » Needs work

The last submitted patch, drupal-1170198-37.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new7.57 KB

Whoops, extra closing brace

Status: Needs review » Needs work

The last submitted patch, drupal-1170198-39.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new8.54 KB

Left out the setUp hunk by mistake. I think we're good now, but I'll wait one more time before actually improving the patch.

tim.plunkett’s picture

StatusFileSize
new8.81 KB

Well, this is immensely useless now in D8, since each view_alter function now gets the entire entity as a second parameter: #1618136: Remove $type from entity hooks

But, rerolled nonetheless. I addressed all of the feedback from #36, except that part about documenting the #build_mode, since I don't know how to explain a useless addition. This should likely just go into D7, but leaving here for now.

tim.plunkett’s picture

Assigned: tim.plunkett » Unassigned
tim.plunkett’s picture

Issue tags: -Needs tests

Still applies.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

berdir’s picture

42: drupal-1170198-42.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 42: drupal-1170198-42.patch, failed testing.

btmash’s picture

Looking at D8 and the new hook_entity_view_alter, *seems* like this would be useless (unless the view is still based off what is in the build array). I'll take a look and see how things look for alterations sometime this week.

fabianx’s picture

Version: 8.0.x-dev » 7.x-dev
Issue tags: -Needs backport to D7

This is really nice, back to 7.x for now as it is fixed superior in D8.

Note even implementing that for core would leave contrib authors like entity module to update the build key first, which would probably happen sometime ...

Status: Needs work » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.