Refactor BP MPO Activity Filter to support proper pagination
Not sure if it's just on my computer, but the recent blog posts are not appearing on the home page of the Commons using IE, FF, and Chrome (screenshot attached).
#2 Updated by Boone Gorges almost 7 years ago
- Priority name changed from Urgent to Normal
- Target version changed from Not tracked to Future release
This is not really a bug, but is a quirk of the way that the Recent Posts widget works.
In order to ensure the Recent Posts widget respects blog privacy levels, some posts get filtered out of the general stream before being displayed on the front page. (Which posts get filtered depend on what kind of user you are - anonymous, a super admin, etc.) The widget is set up to show 7 recent posts, but because of privacy restrictions, this usually isn't the 7 most recent posts. Generally, I can pull up something like 10 or 15 posts, and be relatively certain that, when non-public posts are filtered out, there will be at least 7 remaining to display to all users. In fact, my algorithm is that I pull up the 70 most recent posts - just to be sure. This is almost guaranteed to result in 7 usable posts, except in extreme edge cases.
Today we hit one of those edge cases. A user appears to be moving her blog from a separate WP installation to the Commons. It appears that she created a new Commons blog, set it to Admins Only (the tightest privacy level), and then imported a bunch of posts from a WP export file (around 200, it looks like). As they were imported, new BP activity items were created (BP activity is where the widget pulls from). As a result, there was an hour or two where the 70 most recent blog-related activity items were getting filtered out by the privacy filters for anyone but site admins.
I say "there was an hour or two" because it's already rectifying itself: a new blog post has been posted in the last half hour, pushing itself to the front of the line, so that there's at least one blog post showing up for non-super-admins.
Because the problem will self correct over the next day or so, I'm marking the priority down to Normal. For the moment, I don't think that I should do anything to try to correct this, because any real "fix" will be complex and time-consuming, involving the rewriting of one or two systems. In the long run, there are a few things that could happen:
a) The way the Recent Blog Posts widget works could be rewritten, so that it goes back even further than 70 posts.
b) Rewrite Recent Blog Posts so that it first tries (say) 70 posts, and if it finds itself empty, then it is smart enough to query for some more posts.
c) Refactor the way that the privacy filters work, so that they don't require this sort of overestimating. In theory, I can run filters closer to the query itself that will mean that I can query for exactly 7 items, as long as they are not on a blacklist of protected items.
It'll probably have to be some combination of two of the above.
I'm tentatively putting this item in Future Release, because this kind of rewrite - while important and valuable - will take an amount of effort far out of proportion to its importance at the moment. For now, the privacy filters are doing what they are supposed to be doing (a feature, not a bug :) ) and the sort of empty widget problem seen here will only come up in very rare circumstances that don't really cause any harm and are temporary.
#4 Updated by Boone Gorges almost 7 years ago
- Subject changed from Recent blog posts not appearing on home page to Refactor BP MPO Activity Filter to support proper pagination
While I'm thinking of it, here's my general idea, for future reference:
- Filter bp_activity_get_user_join_filter and bp_activity_total_activities_sql.
- Split at WHERE so we can splice in a WHERE clause.
- That clause will look something like ( component != 'blogs' OR item_id NOT IN (1,2,3) ), where 1,2,3 are off-limits blogs for that user
- Off-limits blogs for that user determined as follows:
- If user is super admin, just use 0
- If user is not logged in, it's a list of all blogs with privacy level < 0
- If user is logged in, it'll be blogs with privacy level >= -1 || ( privacy level == -2 AND blog id is in an array of blogs to which the user belongs )
The problem here is scaling:
- There is no easy way to query for blogs with a given privacy setting. I guess we'll need a setup script that loops through blogs and does get_blog_option() and throws into a transient. The transient should never expire, and should be busted whenever a new privacy level is saved network-wide (at which point we can either sweep through all blogs, or just change the privacy setting for that one blog)
- It's also a bit of a pain to loop through the blogs of a which a user is a member, but this can also be fairly easily cached, and in any case it's easier to query than blog privacy. Also, if we have blog privacy saved in a single place, cross-references are cheap.