Entity loader broke the comment publishing status.

The query joins on {user} to fetch user data and the user's status.

Both comments and users have a status. The comment status is always overridden by the user's status.

I've encountered this major flaw a couple of times in the meantime. With the entity loader, the underlying API design flaw becomes even more apparent. The real solution would be to have:

$comment (object)
$comment->cid
$comment->subject
$comment->comment
$comment->status
$comment->name [anonymous comments]

$comment->user (object)
$comment->user->uid
$comment->user->status
$comment->user->name

And that we need also for nodes and all the other stuff. Historically, we only have these ambiguous object properties to make simple list queries faster - which has always been a pain for developers and themers, because you never really know whether you get a half-baked object, which is a different object in reality, or whether it is a proper, fully loaded object of the assumed entity type.

For example, that is the reason for why you can't theme usernames differently depending on their status: theme_username() gets an arbitrary $object. And if you'd try to theme users differently based on $object->status, then you are theming a user based on the status of some arbitrary other object in reality.

This patch fixes comment publishing, which is completely broken currently. Which also means that there are no tests for comment moderation - or - those tests rely on comment_load() instead of the real database values, or whatever...

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

catch’s picture

We moved node user fields into user_node_load() and removed the join - should consider doing same for comments. We should also consider whether to change these from direct queries to real user_load_multiple() calls as well - this assumes modules don't do crazy things like load entire nodes into the $user object though.

I'm pretty sure there's some tests for comment publishing - so must be incomplete rather than completely missing.

sun’s picture

change these from direct queries to real user_load_multiple() calls

That is what I think is badly needed, as mentioned in the OP. The new *_load_multiple() entity loaders should allow to do this quite fast. However, we'd have to move the $user object into a single property of the parent $object, i.e. $object->user->..., as also mentioned above.

Should we get the existing patch committed first? Removed the 'status' completely, like in user_node_load().

sun’s picture

Issue tags: +D7 API clean-up

Tagging absolutely critical clean-ups for D7. Do not touch this tag. Please either help with this or one of the other patches having this tag.

Dave Reid’s picture

This chunk:
if (!$user->uid && variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) != COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
- $form_state['#attached']['js'][] = drupal_get_path('module', 'comment') . '/comment.js';
+ $form['#attached']['js'][] = drupal_get_path('module', 'comment') . '/comment.js';
}

Is also being fixed in #440876: Reuse comment.module's anonymous cookie information fyi.

sun’s picture

Re-rolled against HEAD.

catch’s picture

Status: Needs review » Reviewed & tested by the community

Fine patch. RTBC.

Dries’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Committed the quick fix in #5, but (i) we'll want tests and (ii) I agree that we'll want a bigger architectural fix (and API clean-up).

sun’s picture

Title: {comment}.status broken » Mixing of object properties breaks entity loader
Component: comment.module » base system

Thanks! Trying to find a better title, corrections welcome.

sun’s picture

To move forward here, we need to agree on a possible workaround and/or solution, and a target and time-line.

I'd guess that all we could do is to move those user properties into $object->user, and I actually think that it wouldn't be _that_ much that needs to be changed. Perhaps it can even be done with some regex magic.

For now, I'm not arguing for loading entire/proper objects. We can still load/attach that fake user data, but if we'd move it into a dedicated property, then at least a contrib module would be able to lazy-load a full user object, replacing that $object->user, without hi-jacking the node's or comment's or whatever's properties.

Thoughts?

effulgentsia’s picture

subscribe

catch’s picture

We already have a user_node_load(). Ideally I'd like to see us do user_comment_load() an stick it into a $comment->user property. That also might possibly be faster with very, very large datasets.

scor’s picture

@catch: user_node_load(), user_comment_load(), and many more? why not using the new hook_entity_load() here?

catch’s picture

user_entity_load() would indeed be a perfect use-case for that hook.

sun’s picture

Version: 7.x-dev » 8.x-dev

It's somehow funky, but I don't think we can do anything about this issue for D7.

@Dries: Feel free to overrule me ;)

sun’s picture

Issue tags: -D7 API clean-up

.

catch’s picture

At a minimum we could move things to a hook implementation with the same node structure, then in Drupal 8 do $entity->user generically?

catch’s picture

Title: Mixing of object properties breaks entity loader » Consider a generic $entity->user property
Priority: Critical » Major
chx’s picture

Category: bug » feature
Wim Leers’s picture

Status: Needs work » Closed (works as designed)

Zero complaints/comments on this since November 2009 — seems like we don't need to solve this anymore :)

Feel free to reopen, but if you do, you should move it to Drupal 9.

andypost’s picture

Issue tags: -Needs tests

Let's make it via interface #2078387: Add an EntityOwnerInterface