Forum Replies Created
-
I’d like confirmation of the bug by a 3rd party before making a patch for it. Is this something you can check @shanebp?
I’ve managed to achieve what I wanted – fetching activities for the user, the user’s friends, groups that the user is a member of and groups which are tagged with the sports the user is interested in. I’ve added some custom filtering within BuddyPress core functions – I prefer to use filters and hooks but modifying core was my only option in this case.
My bp_has_activities() request now looks like this:
$args = array( bp_ajax_querystring( 'activity' ), 'custom_filter' => array( 'relation' => 'OR', array( 'user_id' => $user_ids, ), array( 'group_id' => $group_ids ) ) ); ?> <?php if ( bp_has_activities( $args ) ) : ?>
I can share code with anyone interested in this.
Also fixed a bug in the BP_Groups_Group::get() meta_query code which I’ve detailed above and is now on BP Trac here:
Separate issue but I think I’ve found a bug in the BP_Groups_Group::get() function when performing meta_query with OR relationship.
Currently I have 4 groups to test with. Each group is assigned a meta_key => group_sport with values “running”, “swimming”, “mountain”, “winter” respectively. When I perform this:
$meta_query = array( 'relation' => 'OR', array( "key" => "group_sport", "value" => 'mountain', "compare" => 'LIKE' ), array( "key" => "group_sport", "value" => 'running', "compare" => 'LIKE' )); $group_arr = BP_Groups_Group::get(array( 'per_page'=>-1, 'meta_query' => $meta_query ));
it retrieves mountain and running but also incorrectly retrieves swimming and winter.
On further investigation I noticed that table joins in BP_Groups_Group::get() and get_meta_query_sql() are done using commas rather than INNER JOIN, etc. I changed the functions to use INNER JOIN instead and it now works correctly. Can anyone else confirm this please? I’ll post on the Trac as well.
After researching a bit further I think I could easily achieve what I’d like if only this function (in bp-activity-classes.php line 1186):
/** * Create filter SQL clauses. * * @since BuddyPress (1.5.0) * * @param array $filter_array { * Fields and values to filter by. * @type array|string|id $user_id User ID(s). * @type array|string $object Corresponds to the 'component' * column in the database. * @type array|string $action Corresponds to the 'type' column * in the database. * @type array|string|int $primary_id Corresponds to the 'item_id' * column in the database. * @type array|string|int $secondary_id Corresponds to the * 'secondary_item_id' column in the database. * @type int $offset Return only those items with an ID greater * than the offset value. * @type string $since Return only those items that have a * date_recorded value greater than a given MySQL-formatted * date. * } * @return string The filter clause, for use in a SQL query. */ public static function get_filter_sql( $filter_array ) { $filter_sql = array(); if ( !empty( $filter_array['user_id'] ) ) { $user_sql = BP_Activity_Activity::get_in_operator_sql( 'a.user_id', $filter_array['user_id'] ); if ( !empty( $user_sql ) ) $filter_sql[] = $user_sql; } if ( !empty( $filter_array['object'] ) ) { $object_sql = BP_Activity_Activity::get_in_operator_sql( 'a.component', $filter_array['object'] ); if ( !empty( $object_sql ) ) $filter_sql[] = $object_sql; } if ( !empty( $filter_array['action'] ) ) { $action_sql = BP_Activity_Activity::get_in_operator_sql( 'a.type', $filter_array['action'] ); if ( ! empty( $action_sql ) ) $filter_sql[] = $action_sql; } if ( !empty( $filter_array['primary_id'] ) ) { $pid_sql = BP_Activity_Activity::get_in_operator_sql( 'a.item_id', $filter_array['primary_id'] ); if ( !empty( $pid_sql ) ) $filter_sql[] = $pid_sql; } if ( !empty( $filter_array['secondary_id'] ) ) { $sid_sql = BP_Activity_Activity::get_in_operator_sql( 'a.secondary_item_id', $filter_array['secondary_id'] ); if ( !empty( $sid_sql ) ) $filter_sql[] = $sid_sql; } if ( ! empty( $filter_array['offset'] ) ) { $sid_sql = absint( $filter_array['offset'] ); $filter_sql[] = "a.id >= {$sid_sql}"; } if ( ! empty( $filter_array['since'] ) ) { // Validate that this is a proper Y-m-d H:i:s date // Trick: parse to UNIX date then translate back $translated_date = date( 'Y-m-d H:i:s', strtotime( $filter_array['since'] ) ); if ( $translated_date === $filter_array['since'] ) { $filter_sql[] = "a.date_recorded > '{$translated_date}'"; } } if ( empty( $filter_sql ) ) return false; return join( ' AND ', $filter_sql ); }
would allow filters to be combined with OR rather than AND. That way I could easily filter on a bunch of user_ids and group_ids which would get me the results I’m after. I might try extending the class and overriding that function. Watch this space!
I’ll have a go with a complex query now and let you know how it goes. Still open to other suggestions as well…
I think I might have to run a couple of queries to get the list of activity IDs I need and then feed that in to bp_has_activities() using “include” or “in” parameters so I don’t need to mess too much with the templating.
The problem is that over time the comma-separated list of activity IDs is going to get enormous. I don’t like the sound of that.
Hi @danbp. Okay so essentially what you are saying is I need to write a complex custom query?
I’ve been examining the Buddypress class and function files in detail over the last few weeks due to the lack of documentation for BuddyPress – not a criticism btw. Yep I’m familiar with meta_query and using that already to get groups by meta_value. I wrote a function for returning activity IDs based on group meta:
function wfw_get_group_activities_by_sport($sports = array()) { global $bp,$wpdb; if(!$sports) return false; // GET GROUP IDS WHICH HAVE CHOSEN SPORT SELECTED foreach($sports as $sport) { $meta_query[] = array( "key" => "group_sport", "value" => $sport, "compare" => 'LIKE' ); } if(count($meta_query) > 1) $meta_query = array_merge(array('relation' => 'OR'), $meta_query); $group_arr = BP_Groups_Group::get(array( 'per_page'=>-1, 'meta_query' => $meta_query )); if(!$group_arr['total'] || !$group_arr['groups']) return false; foreach($group_arr['groups'] as $group) { $group_id_array[] = $group->;id; } $item_id = implode(",", $group_id_array); $sql = "SELECT id FROM {$bp->activity->table_name} WHERE component = 'groups' AND item_id IN ({$item_id})"; $activity_id_array = $wpdb->get_col( $sql); if(!$activity_id_array) return false; $activity_id = implode(',', $activity_id_array); return $activity_id; }
which I can then use to filter results:
$activity_id = wfw_get_group_activities_by_sport(array($_GET['sport'])); $filter = '&in='.$activity_id.'&object=groups'; if ($activity_id && bp_has_activities( bp_ajax_querystring( 'activity' ).$filter ) ) : ?>
Now I just need to somehow combine what I’m using but it sounds like a complex query is the way to go. I was looking for a more elegant solution using BP functions to achieve this but I guess it’s not yet possible.
Anybody else have experience in this?
Thanks.
I’ve been working on my first BuddyPress site last couple of weeks so stumbling around forum posts quite a lot.
You’ve probably already found a fix @thecorkboard but I used the “bp_get_activity_css_class” to strip out the “mini” class when not required.