diff --git src/bp-activity/bp-activity-actions.php src/bp-activity/bp-activity-actions.php index f8c5d52..70c7b40 100644 --- src/bp-activity/bp-activity-actions.php +++ src/bp-activity/bp-activity-actions.php @@ -600,7 +600,7 @@ add_action( 'bp_actions', 'bp_activity_action_mentions_feed' ); * @return bool False on failure. */ function bp_activity_action_favorites_feed() { - if ( ! bp_is_user_activity() || ! bp_is_current_action( 'favorites' ) || ! bp_is_action_variable( 'feed', 0 ) ) { + if ( ! bp_is_user_activity() || ! bp_is_current_action( bp_get_activity_favorites_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) { return false; } @@ -615,7 +615,7 @@ function bp_activity_action_favorites_feed() { /* translators: User activity favorites RSS title - "[Site Name] | [User Display Name] | Favorites" */ 'title' => sprintf( __( '%1$s | %2$s | Favorites', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ), - 'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/', + 'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_activity_favorites_slug() . '/', 'description' => sprintf( __( "Activity feed of %s's favorites.", 'buddypress' ), bp_get_displayed_user_fullname() ), 'activity_args' => 'include=' . $fav_ids ) ); @@ -647,3 +647,105 @@ function bp_activity_setup_akismet() { // Instantiate Akismet for BuddyPress $bp->activity->akismet = new BP_Akismet(); } + +/** + * Add globals for activity favorites + * + * @since BuddyPress (2.1.0) + * + * @uses buddypress() to get main instance + */ +function bp_activity_favorites_globals() { + $bp = buddypress(); + + /** + * Add some globals for names/slugs/strings + * It's easier this way to cutomize all strings at once + * for instance if you prefer the "like" terminology + */ + $bp->activity->favorites = new stdClass; + + // Default + $favorite_default_args = array( + // Activity action args + 'description' => _x( 'Favorited an update', 'favorite activity description', 'buddypress' ), + 'label' => _x( 'Favorites', 'favorite activity dropdown label', 'buddypress' ), + // Wether you want to show the favorites in Activity Directory / group single item activities, + // member single item activities, or the groups tab of member single item activities + 'contexts' => array( 'activity', 'group', 'member', 'member_groups' ), + // Strings + 'directory_tab' => _x( 'My Favorites', 'favorite directory tab', 'buddypress' ), + // The action button in activity stream to favorite an update + 'fav_button' => _x( 'Favorite', 'favorite button', 'buddypress' ), + // The action button in activity stream to remove a favorited update + 'unfav_button' => _x( 'Remove Favorite', 'unfavorite button', 'buddypress' ), + // Nav name + 'subnav' => _x( 'Favorites', 'favorite member subnav', 'buddypress' ), + // Slug + 'slug' => 'favorites' + ); + + // Use this filter to customize the strings the way you want. + $favorite_args = apply_filters( 'bp_activity_favorites_globals', $favorite_default_args ); + + // Set favorite globals + foreach ( $favorite_args as $key => $arg ) { + $bp->activity->favorites->{$key} = $arg; + } +} +add_action( 'bp_activity_setup_globals', 'bp_activity_favorites_globals' ); + +/** + * Handles the saving of favorites privacy + * + * @since BuddyPress (2.1.0) + */ +function bp_activity_favorites_action_settings() { + + // Bail if not a POST action + if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) { + return; + } + + // Bail if no submit action + if ( ! isset( $_POST['favorites-settings-submit'] ) ) { + return; + } + + // 404 if there are any additional action variables attached + if ( bp_action_variables() ) { + bp_do_404(); + return; + } + + // Nonce check + check_admin_referer( 'bp_activity_favorites_settings' ); + + do_action( 'bp_activity_favorites_settings_before_save' ); + + /** Save ******************************************************************/ + + $user_id = bp_displayed_user_id(); + + // Only save if there are field ID's being posted + if ( ! empty( $_POST['bp_favorites_private'] ) ) { + // Save the visibility settings + bp_update_user_meta( $user_id, 'bp_favorites_private', absint( $_POST['bp_favorites_private'] ) ); + // hide favorited activities + bp_activity_hide_user_activity( $user_id, 'activity_favorite' ); + } else { + // Delete the visibility settings + bp_delete_user_meta( $user_id, 'bp_favorites_private' ); + // hide favorited activities + bp_activity_show_user_activity( $user_id, 'activity_favorite' ); + } + + /** Other *****************************************************************/ + + do_action( 'bp_activity_favorites_settings_after_save' ); + + bp_core_add_message( __( 'Favorites privacy saved', 'buddypress' ) ); + // Redirect to the root domain + bp_core_redirect( bp_displayed_user_domain() . bp_get_settings_slug() . '/' . bp_get_activity_favorites_slug() ); +} +add_action( 'bp_activity_screen_favorites_settings', 'bp_activity_favorites_action_settings' ); diff --git src/bp-activity/bp-activity-classes.php src/bp-activity/bp-activity-classes.php index f1e6054..be2883f 100644 --- src/bp-activity/bp-activity-classes.php +++ src/bp-activity/bp-activity-classes.php @@ -324,6 +324,7 @@ class BP_Activity_Activity { // Where conditions $where_conditions = array(); + $excluded_types = array(); // Spam if ( 'ham_only' == $spam ) @@ -337,6 +338,32 @@ class BP_Activity_Activity { $where_conditions['search_sql'] = "a.content LIKE '%%" . esc_sql( like_escape( $search_terms ) ) . "%%'"; } + // In activity administration & stream mode, display favorites + if ( 'stream' !== $display_comments ) { + // Exclude 'activity_favorite' items unless the 'action' filter has + // been explicitly set + if ( empty( $filter['action'] ) ) { + $excluded_types[] = 'activity_favorite'; + + // If explicitly set transform this as a specific meta query + } else if ( 'activity_favorite' == $filter['action'] ) { + $meta_query_args = array( + 'key' => 'activity_favorite', + 'compare' => 'EXISTS' + ); + + if ( ! empty( $filter['user_id'] ) ) { + $meta_query_args['compare'] = '='; + $meta_query_args['value'] = absint( $filter['user_id'] ); + unset( $filter['user_id'] ); + } + + $meta_query = array( $meta_query_args ); + + unset( $filter['action'] ); + } + } + // Filtering if ( $filter && $filter_sql = BP_Activity_Activity::get_filter_sql( $filter ) ) $where_conditions['filter_sql'] = $filter_sql; @@ -376,13 +403,17 @@ class BP_Activity_Activity { // comments in the stream like normal comments or threaded below // the activity. if ( false === $display_comments || 'threaded' === $display_comments ) { - $where_conditions[] = "a.type != 'activity_comment'"; + $excluded_types[] = 'activity_comment'; } // Exclude 'last_activity' items unless the 'action' filter has // been explicitly set if ( empty( $filter['object'] ) ) { - $where_conditions[] = "a.type != 'last_activity'"; + $excluded_types[] = 'last_activity'; + } + + if ( ! empty( $excluded_types ) ) { + $where_conditions[] = "a.type NOT IN( '" . implode( "','", $excluded_types ) . "' )"; } // Filter the where conditions @@ -465,6 +496,9 @@ class BP_Activity_Activity { // Generate action strings $activities = BP_Activity_Activity::generate_action_strings( $activities ); + // Append user_ids who favorited activities + $activities = self::append_favorites( $activities ); + // If $max is set, only return up to the max results if ( !empty( $max ) ) { if ( (int) $total_activities > (int) $max ) @@ -644,13 +678,36 @@ class BP_Activity_Activity { // WP_Meta_Query expects the table name at // $wpdb->activitymeta - $wpdb->activitymeta = buddypress()->activity->table_name_meta; + if( ! empty( $activity_meta_query->queries[0]['key'] ) && 'activity_favorite' == $activity_meta_query->queries[0]['key'] ) { + $wpdb->activitymeta = buddypress()->activity->table_name; + } else { + $wpdb->activitymeta = buddypress()->activity->table_name_meta; + } $meta_sql = $activity_meta_query->get_sql( 'activity', 'a', 'id' ); // Strip the leading AND - BP handles it in get() $sql_array['where'] = preg_replace( '/^\sAND/', '', $meta_sql['where'] ); $sql_array['join'] = $meta_sql['join']; + + if ( buddypress()->activity->table_name == $wpdb->activitymeta ) { + $sql_array['join'] = str_replace( 'JOIN '. $wpdb->activitymeta, 'JOIN '. $wpdb->activitymeta . ' f', $sql_array['join'] ); + $sql_array['join'] = str_replace( $wpdb->activitymeta .'.activity_id' , 'f.item_id', $sql_array['join'] ); + + if ( 'EXISTS' == strtoupper( $activity_meta_query->queries[0]['compare'] ) ) { + $sql_array['where'] = str_replace( $wpdb->activitymeta .'.meta_key', 'f.type', $sql_array['where'] ); + } else { + $user_id = $activity_meta_query->queries[0]['value']; + preg_match( '/CAST\((.*)meta_value(.*)[' .$user_id. ']\'\)/', $sql_array['where'], $matches ); + + if ( ! empty( $matches[1] ) ) { + $table = str_replace( $wpdb->activitymeta, 'f', $matches[1] ); + $sql_array['where'] = $wpdb->prepare( "( f.type = %s AND {$table}user_id = %d )", $activity_meta_query->queries[0]['key'], $user_id ); + } + } + // Restore activitymeta table + $wpdb->activitymeta = buddypress()->activity->table_name_meta; + } } return $sql_array; @@ -811,28 +868,28 @@ class BP_Activity_Activity { else return false; - // Fetch the activity IDs so we can delete any comments for this activity item + // Fetch the activity IDs so we can delete any children for this activity item $activity_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" ); if ( ! $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$where_sql}" ) ) { return false; } - // Handle accompanying activity comments and meta deletion + // Handle accompanying activity children and meta deletion if ( $activity_ids ) { $activity_ids_comma = implode( ',', wp_parse_id_list( $activity_ids ) ); - $activity_comments_where_sql = "WHERE type = 'activity_comment' AND item_id IN ({$activity_ids_comma})"; + $activity_children_where_sql = "WHERE type IN ( 'activity_comment', 'activity_favorite' ) AND item_id IN ({$activity_ids_comma})"; - // Fetch the activity comment IDs for our deleted activity items - $activity_comment_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$activity_comments_where_sql}" ); + // Fetch the activity child IDs for our deleted activity items + $activity_child_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$activity_children_where_sql}" ); // We have activity comments! - if ( ! empty( $activity_comment_ids ) ) { - // Delete activity comments - $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$activity_comments_where_sql}" ); + if ( ! empty( $activity_child_ids ) ) { + // Delete activity children + $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$activity_children_where_sql}" ); // Merge activity IDs with activity comment IDs - $activity_ids = array_merge( $activity_ids, $activity_comment_ids ); + $activity_ids = array_merge( $activity_ids, $activity_child_ids ); } // Delete all activity meta entries for activity items and activity comments @@ -1283,10 +1340,12 @@ class BP_Activity_Activity { * @return int A count of the user's favorites. */ public static function total_favorite_count( $user_id ) { - if ( !$favorite_activity_entries = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ) ) + $favorite_activity_entries = self::get_favorites_by_user_id( $user_id ); + + if ( empty( $favorite_activity_entries ) ) return 0; - return count( maybe_unserialize( $favorite_activity_entries ) ); + return count( $favorite_activity_entries ); } /** @@ -1305,12 +1364,139 @@ class BP_Activity_Activity { * Hide all activity for a given user. * * @param int $user_id The ID of the user whose activity you want to mark hidden. - * @param int + * @param string $type the activity type */ - public static function hide_all_for_user( $user_id ) { + public static function hide_all_for_user( $user_id, $type = '' ) { global $wpdb, $bp; - return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) ); + $where = array( + $wpdb->prepare( "user_id = %d", $user_id ) + ); + + if ( ! empty( $type ) ) { + $where[] = "type = 'activity_favorite'"; + } + + $where = 'WHERE ' . implode( ' AND ', $where ); + + return $wpdb->get_var( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 {$where}" ); + } + + /** + * Show activity for a given user and a given type. + * + * @param int $user_id The ID of the user whose activity you want to mark hidden. + * @param string $type the activity type + */ + public static function show_activity_for_user( $user_id, $type ) { + global $wpdb, $bp; + + if ( empty( $type ) ) { + return false; + } + + return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 0 WHERE user_id = %d AND type = %s", $user_id, $type ) ); + } + + /** + * Append user_ids who favorited activities. + * + * @since BuddyPress (2.1.0) + * + * @param array $activities Activities to fetch user who favorited. + * @return array The updated activities with attached user ids. + */ + public static function append_favorites( $activities = array() ) { + + // Now fetch the user who favorited matching activities. + foreach ( (array) $activities as $key => $activity ) { + if ( 'activity_favorite' == $activity->type ) { + $activities[$key]->favorites = array(); + } + + $activities[$key]->favorites = self::get_favorites_by_activity_id( $activity->id ); + } + + return $activities; + } + + /** + * Get user_ids who favorited activities. + * + * @since BuddyPress (2.1.0) + * + * @param int $activity_id + * @return array $users The users who favorited the activities. + */ + public static function get_favorites_by_activity_id( $activity_id = 0 ) { + global $wpdb; + $bp = buddypress(); + + $users = array(); + + if ( empty( $activity_id ) ) { + return $users; + } + + // Users need to have the possibility to set their privacy preferences, else don't show them in favorites + $public_favorites = apply_filters( 'bp_activity_favorites_privacy', bp_is_active( 'settings' ) ); + + if ( empty( $public_favorites ) ) { + return $users; + } + + $users = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, hide_sitewide FROM {$bp->activity->table_name} WHERE type = 'activity_favorite' AND item_id = %d", $activity_id ) ); + + // Admins can see all favorites + if( bp_current_user_can( 'bp_moderate' ) ) { + $users = wp_list_pluck( $users, 'user_id' ); + + // Only loggedin users can see their private favorites + } else { + $public = array(); + foreach( $users as $key => $user ) { + // favorite is private and loggedin user is not the one who favorited the activity + if( bp_loggedin_user_id() == $user->user_id || 0 == $user->hide_sitewide ) { + $public[] = $user->user_id; + } + } + $users = $public; + } + + return $users; + } + + /** + * Get user_ids who favorited activities. + * + * @since BuddyPress (2.1.0) + * + * @param int $user_id + * @param int $activity_id + * @return array $favorites The favorited activities. + */ + public static function get_favorites_by_user_id( $user_id = 0, $activity_id = 0 ) { + global $wpdb; + $bp = buddypress(); + + $favorites = array(); + + if ( empty( $user_id ) ) + return $favorites; + + $where = array( + "type = 'activity_favorite'", + $wpdb->prepare( "user_id = %d", $user_id ) + ); + + if ( ! empty( $activity_id ) ) { + $where[] = $wpdb->prepare( "item_id = %d", $activity_id ); + } + + $where = 'WHERE ' . implode( ' AND ', $where ); + + $favorites = $wpdb->get_col( "SELECT item_id FROM {$bp->activity->table_name} {$where}" ); + return $favorites; } } @@ -1530,7 +1716,7 @@ class BP_Activity_Feed { switch ( $this->id ) { // also output parent activity item if we're on a specific feed - case 'favorites' : + case bp_get_activity_favorites_slug() : case 'friends' : case 'mentions' : case 'personal' : diff --git src/bp-activity/bp-activity-functions.php src/bp-activity/bp-activity-functions.php index 507387e..5f0935f 100644 --- src/bp-activity/bp-activity-functions.php +++ src/bp-activity/bp-activity-functions.php @@ -367,7 +367,7 @@ function bp_activity_get_types() { * * @since BuddyPress (1.2) * - * @uses bp_get_user_meta() + * @uses BP_Activity_Activity::get_favorites_by_user_id() to get user's favorites * @uses apply_filters() To call the 'bp_activity_get_user_favorites' hook. * * @param int $user_id ID of the user whose favorites are being queried. @@ -380,21 +380,82 @@ function bp_activity_get_user_favorites( $user_id = 0 ) { $user_id = bp_displayed_user_id(); // Get favorites for user - $favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ); + $favs = BP_Activity_Activity::get_favorites_by_user_id( $user_id ); return apply_filters( 'bp_activity_get_user_favorites', $favs ); } /** + * Get a users favorite privacy settings. + * + * @since BuddyPress (2.1.0) + * + * @uses bp_get_user_meta() + * + * @param int $user_id ID of the user + * @return bool True if private, false if public. + */ +function bp_activity_favorites_get_user_settings( $user_id = 0 ) { + // Bail if no user_id to check + if ( empty( $user_id ) ) { + return false; + } + + return (bool) bp_get_user_meta( $user_id, 'bp_favorites_private', true ); +} + +/** + * Get a users favorite privacy preferences. + * + * @since BuddyPress (2.1.0) + * + * @uses bp_activity_favorites_get_user_settings() + * @uses apply_filters() To call the 'bp_activity_favorites_privacy' hook. + * + * @param int $user_id ID of the user whose favorites are being queried. + * @return bool True if public, false if private. + */ +function bp_activity_favorites_privacy( $user_id = 0 ) { + // Bail if no user_id to check + if ( empty( $user_id ) ) { + return false; + } + + $public = true; + + // Admins can always view + if ( bp_current_user_can( 'bp_moderate' ) ) { + return $public; + + // Self can always view their favorites + } else if ( $user_id == bp_loggedin_user_id() ) { + return $public; + + // If user had no way to set privacy, default to false + } else if ( ! bp_is_active( 'settings' ) ) { + $public = false; + + // Check user's preference + } else { + // if private is set public is false + $public = ! bp_activity_favorites_get_user_settings( $user_id ); + } + + // An admin can force public for his community + return apply_filters( 'bp_activity_favorites_privacy', $public ); +} + +/** * Add an activity stream item as a favorite for a user. * * @since BuddyPress (1.2) * * @uses is_user_logged_in() - * @uses bp_get_user_meta() + * @uses bp_loggedin_user_id() to default to current user logged in + * @uses BP_Activity_Activity::get_favorites_by_user_id() to check if the activity to favorite is not already favorited * @uses bp_activity_get_meta() - * @uses bp_update_user_meta() * @uses bp_activity_update_meta() + * @uses bp_activity_add_favorite() to create the 'activity_favorite' activity * @uses do_action() To call the 'bp_activity_add_user_favorite' hook. * @uses do_action() To call the 'bp_activity_add_user_favorite_fail' hook. * @@ -405,35 +466,29 @@ function bp_activity_get_user_favorites( $user_id = 0 ) { function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { // Favorite activity stream items are for logged in users only - if ( !is_user_logged_in() ) + if ( ! is_user_logged_in() ) return false; // Fallback to logged in user if no user_id is passed if ( empty( $user_id ) ) $user_id = bp_loggedin_user_id(); - $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ); - if ( empty( $my_favs ) || ! is_array( $my_favs ) ) { - $my_favs = array(); - } + $is_fav = BP_Activity_Activity::get_favorites_by_user_id( $user_id, $activity_id ); - // Bail if the user has already favorited this activity item - if ( in_array( $activity_id, $my_favs ) ) { + // Bail if Already favorited + if ( ! empty( $is_fav ) ) { return false; } - // Add to user's favorites - $my_favs[] = $activity_id; - // Update the total number of users who have favorited this activity $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' ); - $fav_count = !empty( $fav_count ) ? (int) $fav_count + 1 : 1; + $fav_count = ! empty( $fav_count ) ? (int) $fav_count + 1 : 1; - // Update user meta - bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs ); + // Update activity meta counts for backcompat + bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ); - // Update activity meta counts - if ( bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ) ) { + // Save the favorite + if ( bp_activity_add_favorite( $activity_id, $user_id ) ) { // Execute additional code do_action( 'bp_activity_add_user_favorite', $activity_id, $user_id ); @@ -456,10 +511,10 @@ function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { * @since BuddyPress (1.2) * * @uses is_user_logged_in() - * @uses bp_get_user_meta() + * @uses bp_loggedin_user_id() to default to current user logged in + * @uses bp_activity_delete_by_item_id() to delete the favorite * @uses bp_activity_get_meta() * @uses bp_activity_update_meta() - * @uses bp_update_user_meta() * @uses do_action() To call the 'bp_activity_remove_user_favorite' hook. * * @param int $activity_id ID of the activity item being unfavorited. @@ -469,53 +524,111 @@ function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) { // Favorite activity stream items are for logged in users only - if ( !is_user_logged_in() ) + if ( ! is_user_logged_in() ) return false; // Fallback to logged in user if no user_id is passed if ( empty( $user_id ) ) $user_id = bp_loggedin_user_id(); - $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ); - $my_favs = array_flip( (array) $my_favs ); + // the favorite is an activity, so let's delete it + $removed = bp_activity_delete_by_item_id( array( + 'item_id' => $activity_id, + 'type' => 'activity_favorite', + 'user_id' => $user_id, + ) ); // Bail if the user has not previously favorited the item - if ( ! isset( $my_favs[ $activity_id ] ) ) { + if ( empty( $removed ) ) { return false; } - // Remove the fav from the user's favs - unset( $my_favs[$activity_id] ); - $my_favs = array_unique( array_flip( $my_favs ) ); + $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' ); + + // Error getting favorite count + if ( empty( $fav_count ) ) { + return false; + } + + // Deduct from total favorites + $count_updated = bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 ); - // Update the total number of users who have favorited this activity - if ( $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' ) ) { + // Error updating favorite count + if ( empty( $count_updated ) ) { + return false; + } - // Deduct from total favorites - if ( bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 ) ) { + // Execute additional code + do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id ); - // Update users favorites - if ( bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs ) ) { + return true; +} - // Execute additional code - do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id ); +/** + * Add an activity typed 'activity_favorite' for the favorited activity + * + * @since BuddyPress (2.1.0) + * @uses BP_Activity_Activity + * @uses bp_activity_get_permalink() + * @uses bp_core_get_userlink() + * @uses bp_activity_add() + * @return int|bool the activity id created or false if it fails + */ +function bp_activity_add_favorite( $activity_id = 0, $user_id = 0 ) { + if ( empty( $activity_id ) || empty( $user_id ) ) + return false; - // Success - return true; + $bp = buddypress(); - // Error updating - } else { - return false; - } + // Parent activity exists ? + $activity = new BP_Activity_Activity( $activity_id ); - // Error updating favorite count - } else { - return false; + if ( empty( $activity->type ) || 'activity_favorite' == $activity->type ) { + return false; + } + + $primary_link = bp_activity_get_permalink( $activity_id, $activity ); + $description = $bp->activity->actions->{$bp->activity->id}->activity_favorite['value']; + + $action = sprintf( _x( '%1$s %2$s', 'favorite action string', 'buddypress' ), bp_core_get_userlink( $user_id ), $description ); + $hide_sitewide = ! bp_is_active( 'settings' ) ? true : bp_activity_favorites_get_user_settings( $user_id ); + + $args = array( + 'user_id' => $user_id, + 'component' => $bp->activity->id, + 'type' => 'activity_favorite', + 'action' => $action, + 'content' => '', + 'primary_link' => $primary_link, + 'item_id' => $activity_id, + 'secondary_item_id' => $activity->user_id, + 'hide_sitewide' => $hide_sitewide, + ); + + return bp_activity_add( $args ); +} + +/** + * Migrate user's favorite (previously in bp_favorite_activities user meta) to activity table + * + * @since BuddyPress (2.1.0) + * @uses bp_activity_add_favorite() to create the 'activity_favorite' activities + */ +function bp_activity_favorites_migrate() { + global $wpdb; + + $user_favorites = $wpdb->get_results( "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = 'bp_favorite_activities'" ); + + foreach( $user_favorites as $meta ) { + $meta_value = maybe_unserialize( $meta->meta_value ); + + if ( empty( $meta_value ) ) + continue; + + foreach( $meta_value as $favorite ) { + bp_activity_add_favorite( $favorite, $meta->user_id ); } - // Error getting favorite count - } else { - return false; } } @@ -854,6 +967,19 @@ function bp_activity_register_activity_actions() { __( 'Activity Comments', 'buddypress' ) ); + $public_favorites = apply_filters( 'bp_activity_favorites_privacy', bp_is_active( 'settings' ) ); + + if ( ! empty( $public_favorites ) ) { + bp_activity_set_action( + $bp->activity->id, + 'activity_favorite', + $bp->activity->favorites->description, + 'bp_activity_format_activity_action_activity_favorites', + $bp->activity->favorites->label, + $bp->activity->favorites->contexts + ); + } + do_action( 'bp_activity_register_activity_actions' ); // Backpat. Don't use this. @@ -919,6 +1045,20 @@ function bp_activity_format_activity_action_activity_comment( $action, $activity return apply_filters( 'bp_activity_comment_action', $action, $activity ); } +/** + * Format 'activity_favorite' activity actions. + * + * @since BuddyPress (2.1.0) + * + * @param string $action Static activity action. + * @param object $activity Activity data object. + * @return string + */ +function bp_activity_format_activity_action_activity_favorites( $action, $activity ) { + $action = sprintf( _x( '%1$s %2$s', 'favorite action string', 'buddypress' ), bp_core_get_userlink( $activity->user_id ), buddypress()->activity->favorites->description ); + return apply_filters( 'bp_activity_favorite_action', $action, $activity ); +} + /****************************************************************************** * Business functions are where all the magic happens in BuddyPress. They will * handle the actual saving or manipulation of information. Usually they will @@ -1599,7 +1739,7 @@ function bp_activity_get_permalink( $activity_id, $activity_obj = false ) { $activity_obj = $activity_obj->current_comment; } - if ( 'new_blog_post' == $activity_obj->type || 'new_blog_comment' == $activity_obj->type || 'new_forum_topic' == $activity_obj->type || 'new_forum_post' == $activity_obj->type ) { + if ( 'new_blog_post' == $activity_obj->type || 'new_blog_comment' == $activity_obj->type || 'new_forum_topic' == $activity_obj->type || 'new_forum_post' == $activity_obj->type || 'activity_favorite' == $activity_obj->type ) { $link = $activity_obj->primary_link; } else { if ( 'activity_comment' == $activity_obj->type ) { @@ -1620,10 +1760,26 @@ function bp_activity_get_permalink( $activity_id, $activity_obj = false ) { * @uses BP_Activity_Activity::hide_all_for_user() {@link BP_Activity_Activity} * * @param int $user_id The ID of the user whose activity is being hidden. + * @param string $type the activity type to hide (Defaults to all) + * @return bool True on success, false on failure. + */ +function bp_activity_hide_user_activity( $user_id, $type = '' ) { + return BP_Activity_Activity::hide_all_for_user( $user_id, $type ); +} + +/** + * Show a user's activity. + * + * @since BuddyPress (2.1.0) + * + * @uses BP_Activity_Activity::show_activity_for_user() {@link BP_Activity_Activity} + * + * @param int $user_id The ID of the user whose activity is being hidden. + * @param string $type the activity type to hide (Defaults to all) * @return bool True on success, false on failure. */ -function bp_activity_hide_user_activity( $user_id ) { - return BP_Activity_Activity::hide_all_for_user( $user_id ); +function bp_activity_show_user_activity( $user_id, $type = '' ) { + return BP_Activity_Activity::show_activity_for_user( $user_id, $type ); } /** diff --git src/bp-activity/bp-activity-loader.php src/bp-activity/bp-activity-loader.php index 0f68f91..210fc74 100644 --- src/bp-activity/bp-activity-loader.php +++ src/bp-activity/bp-activity-loader.php @@ -33,6 +33,8 @@ class BP_Activity_Component extends BP_Component { 'adminbar_myaccount_order' => 10 ) ); + + $this->setup_hooks(); } /** @@ -185,13 +187,14 @@ class BP_Activity_Component extends BP_Component { // Favorite activity items $sub_nav[] = array( - 'name' => __( 'Favorites', 'buddypress' ), - 'slug' => 'favorites', + 'name' => bp_get_activity_favorites_nav(), + 'slug' => bp_get_activity_favorites_slug(), 'parent_url' => $activity_link, 'parent_slug' => $this->slug, 'screen_function' => 'bp_activity_screen_favorites', 'position' => 30, - 'item_css_id' => 'activity-favs' + 'item_css_id' => 'activity-favs', + 'user_has_access' => bp_activity_favorites_privacy( bp_displayed_user_id() ) ); // Additional menu if friends is active @@ -221,6 +224,18 @@ class BP_Activity_Component extends BP_Component { } parent::setup_nav( $main_nav, $sub_nav ); + + /*if ( bp_is_active( 'settings' ) ) { + bp_core_new_subnav_item( array( + 'name' => bp_get_activity_favorites_nav(), + 'slug' => bp_get_activity_favorites_slug(), + 'parent_slug' => bp_get_settings_slug(), + 'parent_url' => trailingslashit( $user_domain . bp_get_settings_slug() ), + 'screen_function' => 'bp_activity_screen_favorite_settings', + 'position' => 40, + 'user_has_access' => bp_core_can_edit_settings() + ) ); + }*/ } /** @@ -291,8 +306,8 @@ class BP_Activity_Component extends BP_Component { $wp_admin_nav[] = array( 'parent' => 'my-account-' . $this->id, 'id' => 'my-account-' . $this->id . '-favorites', - 'title' => __( 'Favorites', 'buddypress' ), - 'href' => trailingslashit( $activity_link . 'favorites' ) + 'title' => bp_get_activity_favorites_nav(), + 'href' => trailingslashit( $activity_link . bp_get_activity_favorites_slug() ) ); // Friends? @@ -320,6 +335,15 @@ class BP_Activity_Component extends BP_Component { } /** + * Add custom hooks. + * + * @since BuddyPress (2.1.0) + */ + public function setup_hooks() { + add_filter( 'bp_settings_admin_nav', array( $this, 'setup_settings_admin_nav' ), 3 ); + } + + /** * Set up the title for pages and