[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