This version is a great step forward and I'm really looking forward to using it. However, there appears to be a pretty severe issue in the code that forces any view to only display activity from the current user. It ignores any arguments that you add. As far as I can tell, the culprit appears to be here:
/**
* Implementation of hook_db_rewrite_sql().
*/
function activity_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
if ($primary_field == 'amid') {
$return['join'] = "INNER JOIN {activity_access} aa ON " . $primary_table . "." . $primary_field . " = aa.amid";
$return['where'] = _activity_access_sql("aa", $GLOBALS['user']);
$return['distinct'] = 1;
return $return;
}
Since this is in hook_db_rewrite_sql, it always adds the WHERE clause for the current user, meaning that Views arguments aren't going to do much of anything.
Comments
Comment #1
sirkitree commentedActually the where is for the explicit purpose of verifying that the current user has been granted access to the activity.
Here is the full SQL statement that is generated:
So when an activity is recorded, an entry is also recorded into the {activity_access} table for everyone who has access to this activity. Each person who has access will then be added to the WHERE statement's IN qualifier.
In order to expand upon what user are recorded as having access to this activity, we have the hook_activity_access_grants(). There is an example in the DEVELOPER.txt of how Flag Friend will implement such a hook.
What this does is check to see if the $account has any friends and give them access and add them to the WHERE statement's IN qualifier. So if user 1 is friend with user 3, 6, and 9, the statement would look like this instead:
In order to record these ids whom have access in the first place, hook_activity_grants() is used.
Comment #2
Scott Reynolds commentedTo piggy back on this, sirkitree is almost right :-D. The final query actually looks just a little different.
So the activity module comes out of the box with an access control called 'activity' and all its values are the uid of the "Actor". Flag_friend provides an access control as well that says any activity from whom the current user is friends with hence the multiple values.
Something that I haven't brought up yet is whether or not we store and use the 'activity' access control. Seems redundant and useless but I wrote it orginally as an example. Probably needs to go so that the final query looks like
That way we don't store such a simple access implementation.
Comment #3
sirkitree commentedComment #4
sirkitree commentedScott, maybe you can help explain hook_activity_grants() as well?
Comment #5
mrothroc commentedThanks for the suggestion, but I still can't see how this works. Following your suggestion I created a new module that implements hook_activity_access_grants() but the behavior (and query) aren't as I would expect from what you've described above. I'm using User Relationships, so I created the following function:
My function is being called as expected, but the resulting SQL is:
(This was run as user 1 who is friends with user 1932.)
Still, no output. I see that it's looking for access entries associated with my module. Does this mean that I also have to add an entry to that table as well? What happens if I want to provide access to historical activity messages when someone is added as a friend? Do I have to query all of the prior messages for that user and then add a corresponding entry in AA? If so, I'm not sure how well this will scale over the long run.
Comment #6
Scott Reynolds commentedNo you don't have to query for prior messages. It works just like node_access system works. Which means it is just as hard to explain :-D but I will try.
sortof. Really hard to explain without a concrete example. So I will do flag_friend, since I use that all the time
Lets start first with a copy and paste from the DEVELOPER.txt
This hook adds to the access table, module = 'flag_friend', value = 'THE ACTOR'. This will be used later in the following hook. This will be used later in the query. This is what you are missing in your example. The activity module has no record of 'my_module' providing access control on this particular activity.
I think of this hook as saying "Activity module, I am providing access control for this activity. Use the following ids as the value column"
This says to activity, "Allow access to any activity message that is created by a friend of $account". This is what adds the (module = 'flag_friend' AND value IN (explode($realm_ids)).
What this means is that if Sirkitree creates a node, but were not friends, I don't have access to it. But we become friends later, and then I have access to it. And all that takes for storage is one row in the activity_access table:
And if we no longer are friends, then I will not have access to those. All with one row in a table.
It models exactly node_access system and you must implement both hooks. If you module implements hook_activity_access_grants AFTER the activity is recorded you won't have access to it as the activity module, at the time of the activity's creation, didn't know about you.
The node access system provides a way to rebuild access control. This too needs to be explored. So that we can resync access control and so that people arn't so confused.
Sry, hope this all makes sense. I promise it works and is more efficient then your thinking.
Comment #7
mrothroc commentedIt took some time but I think I'm starting to understand the mechanism. (Right now, I have working code, but without complete understanding it still seems like it's powered by a little bit of magic.)
Thanks for the explanation!
Comment #8
vermario commentedHi!
this issue seems related to what I am currently trying to achieve (with no luck): getting all the activity that a user and his friends (through user relationship api) have generated.
What is the current way to do this? Mrothroc, would you post the code which got this to work? Which kind of view would one build to accomplish this?
Any info would be great, i'm currently very stuck with this in my project. Thank you! :)
Comment #9
Scott Reynolds commentedvermario, that is way off topic. And a cursorily search of user relationships issue queue would have found you this.
#445698: Default view for activity2
Comment #10
vermario commentedOuch! I read that issue many times, but I thought it was only to get "User A is now friend with user B". It turns out it should do what I need... I'll try again. Sorry for the inconvenience.
Comment #11
sirkitree commentedThis looks to be fixed to me.