[buddypress-trac] [BuddyPress Trac] #7290: 2.7.0-rc2 breaks GeomyWP + Groups Locator groups list
buddypress-trac
noreply at wordpress.org
Fri Nov 4 04:04:25 UTC 2016
#7290: 2.7.0-rc2 breaks GeomyWP + Groups Locator groups list
-------------------------------+-----------------------
Reporter: dreadedhamish | Owner:
Type: defect (bug) | Status: reopened
Priority: highest | Milestone:
Component: Groups | Version:
Severity: normal | Resolution:
Keywords: reporter-feedback |
-------------------------------+-----------------------
Comment (by boonebgorges):
Hi @ninjew - Thanks for your patience. I needed to find a couple minutes
to sit down and think about this.
First, you're not missing anything obvious. We don't make it very easy to
add data to group objects. We should do this - perhaps by providing a
filter in the `__get()` method, or an action in `populate()`, or something
like that.
Second, it's true that what used to take a single SQL query now requires
two separate steps. This is a bit annoying from the plugin developer's
point of view, but it's actually good in the long run. Fetching your
lat/lng data separately, as I'll demonstrate below, gives you a better
opportunity to add fine-grained caching, to avoid needless queries, etc.
Here's a simplified example of how to adapt your plugin for BP 2.7. I
haven't tested with your plugin - I'm not sure if it's publicly available
- but I made some guesses based on the code that you pasted above. It
should be enough to show you the general technique.
Two parts. The first is to filter the ID queries. The fact that you are
using MySQL to do the math and using `HAVING` is what makes this hard,
because we use `$wpdb->get_col()` to get matching IDs (so the `distance`
alias breaks the syntax). One thing we might look into in BP is switching
to `$wpdb->get_results()` to fetch a single column here - it would require
a bit more logic in BP, but it would make this kind of syntax easier for
plugins like yours. In any case, I think the only way around for the time
being is to convert to a subquery (which might be faster anyway).
Something like this:
{{{#!php
<?php
function bp7290_filter_group_query( $query, $sql, $r ) {
global $wpdb;
$parts = explode( 'WHERE', $query );
$table_name = "{$wpdb->prefix}gmw_groups_locator";
$subquery = $wpdb->prepare( "SELECT gg.id FROM `$table_name` WHERE
gg.id, gg.lat, gg.lng, gg.address, gg.formatted_address, gg.map_icon,
ROUND( %d * acos( cos( radians( %s ) ) * cos( radians( gg.lat ) ) * cos(
radians( gg.lng ) - radians( %s ) ) + sin( radians( %s ) ) * sin( radians(
gg.lat) ) ),1 ) AS distance HAVING distance <= %d OR distance IS NULL",
$radius, $lat, $lng, $lat, $radius );
$parts[1] = "g.id IN ($subquery) AND " . $parts[1];
return implode( ' WHERE ', $parts );
}
add_filter( 'bp_groups_get_paged_groups_sql', 'bp7290_filter_group_query',
10, 3 );
add_filter( 'bp_groups_get_total_groups_sql', 'bp7290_filter_group_query',
10, 3 );
}}}
To add data to the group objects, you'll have to use the
'groups_get_groups' filter. It's the closest filter we've got to the SQL
results themselves, so it should cover all regular uses. You'll also have
to perform a similar query again, but this time only for the matched group
IDs. (This one can be aggressively cached.) Something like this:
{{{#!php
<?php
function bp7290_add_group_data( $groups ) {
global $wpdb;
$group_ids = wp_list_pluck( $groups['groups'], 'id' );
$group_ids_sql = implode( ',', array_map( 'intval', $group_ids )
);
$map_data = $wpdb->prepare( "SELECT gg.id, gg.lat, gg.lng,
gg.address, gg.formatted_address, gg.map_icon, ROUND( %d * acos( cos(
radians( %s ) ) * cos( radians( gg.lat ) ) * cos( radians( gg.lng ) -
radians( %s ) ) + sin( radians( %s ) ) * sin( radians( gg.lat) ) ),1 ) AS
distance FROM {$wpdb->prefix}gmw_groups_locator WHERE gg.id IN
{$group_ids_sql}",
$radius, $lat, $lng, $lat );
// Add located data to BP's group objects
foreach ( $map_data as $group_data ) {
// you might be able to optimize this so you don't need
nested loops
foreach ( $groups['groups'] as &$group ) {
if ( $group_data->id == $group->id ) {
$group->lat = $group_data->lat;
$group->lng = $group_data->lng;
// etc
break;
}
}
}
return $groups;
}
add_filter( 'groups_get_groups', 'bp7290_add_group_data' );
}}}
Hopefully this is enough to get you moving. Please let us know if you're
successful - your feedback will help us to make this kind of thing easier
to do in future versions of BuddyPress.
--
Ticket URL: <https://buddypress.trac.wordpress.org/ticket/7290#comment:25>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac
More information about the buddypress-trac
mailing list