Skip to content

Instantly share code, notes, and snippets.

@KaineLabs
Created December 27, 2022 02:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KaineLabs/6d77a12bf5f327ee84d336c06fd1be0c to your computer and use it in GitHub Desktop.
Save KaineLabs/6d77a12bf5f327ee84d336c06fd1be0c to your computer and use it in GitHub Desktop.
Youzify - BuddyPress Sort Activity by Favorites
<?php
class BP_Loop_Filters {
/**
* Constructor
*/
public function __construct() {
$this->setup_actions();
$this->setup_filters();
}
/**
* Actions
*
* @uses bp_is_active()
* @uses is_multisite()
*/
private function setup_actions() {
/**
* Registers the Activity actions so that they are available in the Activity Administration Screen
*/
// You need to check Activity component is available
if ( bp_is_active( 'activity' ) ) {
add_action( 'bp_register_activity_actions', array( $this, 'register_activity_actions' ) );
// Adds a new filter into the select boxes of the Activity directory page,
// of group and member single items activity screens
add_action( 'bp_activity_filter_options', array( $this, 'display_activity_actions' ) );
add_action( 'bp_member_activity_filter_options', array( $this, 'display_activity_actions' ) );
// You need to check Groups component is available
if ( bp_is_active( 'groups' ) ) {
add_action( 'bp_group_activity_filter_options', array( $this, 'display_activity_actions' ) );
}
// You're going to output the favorite count after action buttons
add_action( 'bp_activity_entry_meta', array( $this, 'display_favorite_count' ) );
}
}
/**
* Displays a new option in the Members/Groups & Blogs directories
*
* @return string html output
*/
public function random_order() {
?>
<option value="random"><?php _e( 'Random', 'buddypress' ); ?></option>
<?php
}
/**
* Registering the Activity actions for your component
*
* The registered actions will also be available in Administration
* screens
*
* @uses bp_activity_set_action()
* @uses is_admin()
*/
public function register_activity_actions() {
/* arguments are :
- 'component_id', 'component_action_type' to use in {$wpdb->prefix}bp_activity database
- and 'caption' to display in the select boxes */
bp_activity_set_action( 'bp_plugin', 'bpplugin_action', __( 'BP Plugin Action' ) );
/* Activity Administration screen does not use bp_ajax_querystring
Moreover This action type is reordering instead of filtering so you will only
use it on front end */
if ( ! is_admin() ) {
bp_activity_set_action( 'bp_plugin', 'activity_mostfavs', __( 'Most Favorited' ) );
}
}
/**
* Building an array to loop in from our display function
*
* Using bp_activity_get_types() will list all registered activity actions
* but you need to get the ones for your plugin, and this particular function
* directly returns an array of key => value. As you need to filter activity
* with your component id, the global buddypress()->activity->actions will be
* more helpful.
*
* @uses buddypress()
* @return array the list of your plugin actions.
*/
private function list_actions() {
$bp_activity_actions = buddypress()->activity->actions;
$bp_plugin_actions = array();
if ( !empty( $bp_activity_actions->bp_plugin ) ) {
$bp_plugin_actions = array_values( (array) $bp_activity_actions->bp_plugin );
}
return $bp_plugin_actions;
}
/**
* Displays new actions into the Activity select boxes
* to filter activities
* - Activity Directory
* - Single Group and Member activity screens
*
* @return string html output
*/
public function display_activity_actions() {
$bp_plugin_actions = $this->list_actions();
if ( empty( $bp_plugin_actions ) ) {
return;
}
foreach ( $bp_plugin_actions as $type ):?>
<option value="<?php echo esc_attr( $type['key'] );?>"><?php echo esc_attr( $type['value'] ); ?></option>
<?php endforeach;
}
/**
* Displays a mention to inform about the number of time the activity
* was favorited.
*
* @global BP_Activity_Template $activities_template
* @return string html output
*/
public function display_favorite_count() {
global $activities_template;
// BuddyPress < 2.0 or filtering bp_use_legacy_activity_query
if ( ! empty( $activities_template->activity->favorite_count ) ) {
$fav_count = $activities_template->activity->favorite_count;
} else {
// This meta should already have been cached by BuddyPress :)
$fav_count = (int) bp_activity_get_meta( bp_get_activity_id(), 'favorite_count' );
}
if ( ! empty( $fav_count ) ): ?>
<a name="favorite-<?php bp_activity_id();?>" class="button bp-primary-action">Favorited <span><?php printf( _n( 'once', '%s times', $fav_count ), $fav_count );?></span></a>
<?php endif;
}
/**
* Filters
*/
private function setup_filters() {
add_filter( 'bp_ajax_querystring', array( $this, 'activity_querystring_filter' ), 12, 2 );
add_filter( 'bp_activity_get_user_join_filter', array( $this, 'order_by_most_favorited' ), 10, 6 );
add_filter( 'bp_activity_paged_activities_sql', array( $this, 'order_by_most_favorited'), 10, 2 );
// Maybe Fool Heartbeat Activities!
add_filter( 'bp_before_activity_latest_args_parse_args', array( $this, 'maybe_fool_heartbeat' ), 10, 1 );
}
/**
* Builds an Activity Meta Query to retrieve the favorited activities
*
* @param string $query_string the front end arguments for the Activity loop
* @param string $object the Component object
* @uses wp_parse_args()
* @uses bp_displayed_user_id()
* @return array()|string $query_string new arguments or same if not needed
*/
public function activity_querystring_filter( $query_string = '', $object = '' ) {
if ( $object != 'activity' ) {
return $query_string;
}
// You can easily manipulate the query string
// by transforming it into an array and merging
// arguments with these default ones
$args = wp_parse_args( $query_string, array(
'action' => false,
'type' => false,
'user_id' => false,
'page' => 1
) );
/* most favorited */
if ( $args['type'] == 'activity_mostfavs' ) {
unset( $args['action'], $args['type'] );
// on user's profile, shows the most favorited activities for displayed user
if( bp_is_user() ) {
$args['user_id'] = bp_displayed_user_id();
}
// An activity meta query :)
$args['meta_query'] = array(
array(
/* this is the meta_key you want to filter on */
'key' => 'favorite_count',
/* You need to get all values that are >= to 1 */
'value' => 1,
'type' => 'numeric',
'compare' => '>='
),
);
$query_string = empty( $args ) ? $query_string : $args;
}
return apply_filters( 'bp_plugin_activity_querystring_filter', $query_string, $object );
}
/**
* Ninja Warrior trick to reorder the Activity Loop
* regarding the activities favorite count
*
* @param string $sql the sql query that will be run
* @param string $select_sql the select part of the query
* @param string $from_sql the from part of the query
* @param string $where_sql the where part of the query
* @param string $sort the sort order (leaving it to DESC will be helpful!)
* @param string $pag_sql the offset part of the query
* @return string $sql the current or edited query
*/
public function order_by_most_favorited( $sql = '', $select_sql = '', $from_sql = '', $where_sql = '', $sort = '', $pag_sql = '' ) {
if ( apply_filters( 'bp_use_legacy_activity_query', false ) ) {
preg_match( '/\'favorite_count\' AND CAST\((.*) AS/', $where_sql, $match );
if ( ! empty( $match[1] ) ) {
$new_order_by = 'ORDER BY '. $match[1] .' + 0';
$new_select_sql = $select_sql . ', '. $match[1] .' AS favorite_count';
$sql = str_replace(
array( $select_sql, 'ORDER BY a.date_recorded' ),
array( $new_select_sql, $new_order_by ),
$sql
);
}
// $select_sql is carrying the requested argument since BuddyPress 2.0.0
} else {
$r = $select_sql;
if ( empty( $r['meta_query'] ) || ! is_array( $r['meta_query'] ) ) {
return $sql;
} else {
$meta_query_keys = wp_list_pluck( $r['meta_query'], 'key' );
if ( ! in_array( 'favorite_count', $meta_query_keys ) ) {
return $sql;
}
preg_match( '/\'favorite_count\' AND CAST\((.*) AS/', $sql, $match );
if ( ! empty( $match[1] ) ) {
$sql = str_replace( 'ORDER BY a.date_recorded', 'ORDER BY '. $match[1] .' + 0', $sql );
}
}
}
return $sql;
}
/**
* Cannot pass the favorite data for now so just fool heartbeat activities
*/
public function maybe_fool_heartbeat( $r = array() ) {
if ( empty( $r['meta_query'] ) ) {
return $r;
}
$meta_query_keys = wp_list_pluck( $r['meta_query'], 'key' );
if ( ! in_array( 'favorite_count', $meta_query_keys ) ) {
return $r;
} else {
$r['since'] = '3000-12-31 00:00:00';
}
return $r;
}
}
// 1, 2, 3 go !
function bp_loop_filters() {
return new BP_Loop_Filters();
}
add_action( 'bp_include', 'bp_loop_filters' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment