Skip to:
Content

BuddyPress.org

Opened 8 years ago

Last modified 7 years ago

#7343 accepted enhancement

Add the_group filter to allow group object modification

Reported by: ninjew's profile ninjew Owned by: dcavins's profile dcavins
Milestone: Awaiting Contributions Priority: normal
Severity: normal Version:
Component: Groups Keywords: dev-feedback
Cc:

Description (last modified by slaFFik)

Possible to add the_group filter, probably inside the_group() function, to allow to easily modify the group object in the loop? In a similar way to how the the_post filter works.

One scenario where the group objects needs to be modify is explained in ticket:7290. And the only solution at the moment is to modify the groups_template object using nested loops ticket:7290#comment:25 ( which I personally don't like ).

Same filter, I believe, should be applied to the the_member() function. Perhaps this should be created as a separate ticket.

Change History (11)

#1 @slaFFik
8 years ago

  • Keywords reporter-feedback dev-feedback added
  • Milestone changed from Awaiting Review to Under Consideration

So in general you are requesting something like this in ->the_group()?

$this->group = apply_filters( 'bp_groups_template_the_group', $this->next_group(), $this );

or in ->next_group():

return apply_filters( 'bp_groups_template_next_group', $this->group, $this );

Right?

If implemented, I would go with the second filter.

#2 @slaFFik
8 years ago

  • Description modified (diff)

#3 @ninjew
8 years ago

  • Keywords reporter-feedback removed

Thank you @slaFFik for the reply.

Yes, that is exactly what I was hoping to have ( any of your suggestions above ). That will make things so much easier when the group's object needs to be modified. Until now I was relaying on action hooks within the groups ( and members ) loop. But this cannot be 100% reliable since some themes with custom loop pages might not have the original BP hooks.

#4 @ninjew
7 years ago

HI @slaFFik,
Any thoughts on the above?

#5 @dcavins
7 years ago

  • Owner set to dcavins
  • Status changed from new to accepted

Hi @ninjew-

This is an interesting idea. The groups in the $groups_template are populated using groups_get_groups() which offers several filter options:
https://buddypress.trac.wordpress.org/browser/branches/2.8/src/bp-groups/bp-groups-functions.php#L701

Could you filter the group objects there? Maybe in combination with a bp_is_groups_directory() scoping check?

Other notes: the_post filter occurs in WP_Query::setup_postdata():
https://core.trac.wordpress.org/browser/branches/4.7/src/wp-includes/class-wp-query.php#L3975

Which seems more like filtering groups_get_group to me. @boonebgorges, what about instead of using new BP_Groups_Group( $id ) here:
https://buddypress.trac.wordpress.org/browser/branches/2.8/src/bp-groups/classes/class-bp-groups-group.php#L1164
we called groups_get_group( $id ), which would apply the groups_get_group filter to each group object?

Alternatively, we could add a the_bp_group filter at the end of BP_Groups_Group::populate() which would be very similar to the_post filter.

-David

Last edited 7 years ago by dcavins (previous) (diff)

This ticket was mentioned in Slack in #buddypress by dcavins. View the logs.


7 years ago

#7 follow-up: @boonebgorges
7 years ago

I'd prefer not to use apply_filters(). We have some implicit conventions (both here and in WP) about passing objects through filters: it tends to encourage plugin developers to pass their own objects back to the filter, which causes forward-compatibility problems. We could revisit this if our primary objects had interfaces that developers could rely on, but that's some way off.

Technically similar, but semantically more in-line with the rest of WP, is a do_action() call at the end of BP_Groups_Group::populate(). the_bp_group parallels WP in some ways, but BP_Groups_Group is called in places other than a loop, so let's steer clear of that naming convention. Maybe something like:

do_action( 'bp_groups_group', $this );

or 'bp_groups_group_populated' (ick)?

#8 @ninjew
7 years ago

Hello @dcavins and @boonebgorges,

I apologize for missing out the previous reply.

Having an action hook ( ex. do_action( 'bp_groups_group', $this ); ) inside BP_Groups_Group::populate() would be a great solution ( for my case at least ) if it will allow to add custom data to the group object.

I will try explain my scenario in short:

My geolocation plugin ( GEO my WP ) allows geotagging posts, groups, members and so on. GEO my WP saves the geolocation information in a custom table in database. data like address fields, coordinates, object_type ( post, user, group...), object_id ( to relate to the object it belongs to ) and more.

GEO my WP also has a forms builder for admins to build custom proximity search forms. The forms can search for geotagged data ( posts, members, groups... ) based on address, radius and other filters. For these forms, GEO my WP uses the native search query class/function of each object, for example, WP_Query, bp_has_memebrs(), bp_has_groups(), and modify it to display results nearby.

GEO my WP forms made of search form and search results template files. The search results template file contains the original object loop and its functions, with additional custom functions to display distance, maps, and other location data.

This is http://demo.geomywp.com/buddypress-members-search-form a demo for Members search form and http://demo.geomywp.com/search-post-type-with-categories/ Posts search form created by GEO my WP.

The current version of GEO my WP modifies the main search query in the FIELDS clause and by adding a JOIN clause to join the locations table and modify the results by location. Doing so, the results already contains the location data per object ( because of the FIELDS clause ). So the $post, $memebr and $group object will have address fields and coords added to it, which could then be used in the loop. This makes it easy to use the different functions in the loop.

In new version of GEO my WP that I have been working on, I changed the way the plugin modify the search queries. Mainly because of the issue discussed in ticket:7290, but also because it is easier to maintain and cache. Now the plugin first does the proximity search query on the location table only to retrieve a list of locations, when each location contains the location data and the object ID. Then it passes the locations ID as an array into the "include" argument of the search query ( WP_Query, bp_has_members().... ), which works well and returns only nearby objects. However, now the location data is not included in the object results. Rather, we end up with 2 objects; One contains the objects data and another contains the locations.

With the new way of querying the locations I need to merge the location data with each object before it "enters" the results loop. Which is easy to do for the $post object using the "the_post" filter, but not for $member or $group. For members and groups I now need to run an additional custom loop before the results loop to merge the objects with the locations. This additional loop is not only a waste of memory and performance, but it also ends up adding the location data into each object, which is what we are trying to prevent by not having a filter similar to "the_post".

( Well, this wasn't as short as I wanted it to be :) )

I hope this is not too confusing and that it makes sense.

#9 in reply to: ↑ 7 @dcavins
7 years ago

Replying to boonebgorges:

I'd prefer not to use apply_filters(). We have some implicit conventions (both here and in WP) about passing objects through filters: it tends to encourage plugin developers to pass their own objects back to the filter, which causes forward-compatibility problems. We could revisit this if our primary objects had interfaces that developers could rely on, but that's some way off.

Technically similar, but semantically more in-line with the rest of WP, is a do_action() call at the end of BP_Groups_Group::populate(). the_bp_group parallels WP in some ways, but BP_Groups_Group is called in places other than a loop, so let's steer clear of that naming convention. Maybe something like:

do_action( 'bp_groups_group', $this );

or 'bp_groups_group_populated' (idk)?

Does $this need to be passed by reference here?

#11 @DJPaul
7 years ago

  • Milestone changed from Under Consideration to Future Release

If someone wants to patch this, I'll put it into 3.0.

Note: See TracTickets for help on using tickets.