Skip to:
Content

BuddyPress.org

Ticket #5644: 5644.activity_table.02.patch

File 5644.activity_table.02.patch, 63.5 KB (added by imath, 10 years ago)
  • src/bp-activity/bp-activity-actions.php

    diff --git src/bp-activity/bp-activity-actions.php src/bp-activity/bp-activity-actions.php
    index f8c5d52..70c7b40 100644
    add_action( 'bp_actions', 'bp_activity_action_mentions_feed' ); 
    600600 * @return bool False on failure.
    601601 */
    602602function bp_activity_action_favorites_feed() {
    603         if ( ! bp_is_user_activity() || ! bp_is_current_action( 'favorites' ) || ! bp_is_action_variable( 'feed', 0 ) ) {
     603        if ( ! bp_is_user_activity() || ! bp_is_current_action( bp_get_activity_favorites_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) {
    604604                return false;
    605605        }
    606606
    function bp_activity_action_favorites_feed() { 
    615615                /* translators: User activity favorites RSS title - "[Site Name] | [User Display Name] | Favorites" */
    616616                'title'         => sprintf( __( '%1$s | %2$s | Favorites', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
    617617
    618                 'link'          => bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/',
     618                'link'          => bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_activity_favorites_slug() . '/',
    619619                'description'   => sprintf( __( "Activity feed of %s's favorites.", 'buddypress' ), bp_get_displayed_user_fullname() ),
    620620                'activity_args' => 'include=' . $fav_ids
    621621        ) );
    function bp_activity_setup_akismet() { 
    647647        // Instantiate Akismet for BuddyPress
    648648        $bp->activity->akismet = new BP_Akismet();
    649649}
     650
     651/**
     652 * Add globals for activity favorites
     653 *
     654 * @since BuddyPress (2.1.0)
     655 *
     656 * @uses buddypress() to get main instance
     657 */
     658function bp_activity_favorites_globals() {
     659        $bp = buddypress();
     660
     661        /**
     662         * Add some globals for names/slugs/strings
     663         * It's easier this way to cutomize all strings at once
     664         * for instance if you prefer the "like" terminology
     665         */
     666        $bp->activity->favorites = new stdClass;
     667
     668        // Default
     669        $favorite_default_args = array(
     670                // Activity action args
     671                'description'   => _x( 'Favorited an update', 'favorite activity description', 'buddypress' ),
     672                'label'         => _x( 'Favorites', 'favorite activity dropdown label', 'buddypress' ),
     673                // Wether you want to show the favorites in Activity Directory / group single item activities,
     674                // member single item activities, or the groups tab of member single item activities
     675                'contexts'      => array( 'activity', 'group', 'member', 'member_groups' ),
     676                // Strings
     677                'directory_tab' => _x( 'My Favorites', 'favorite directory tab', 'buddypress' ),
     678                // The action button in activity stream to favorite an update
     679                'fav_button'    => _x( 'Favorite', 'favorite button', 'buddypress' ),
     680                // The action button in activity stream to remove a favorited update
     681                'unfav_button'  => _x( 'Remove Favorite', 'unfavorite button', 'buddypress' ),
     682                // Nav name
     683                'subnav'        => _x( 'Favorites', 'favorite member subnav', 'buddypress' ),
     684                // Slug
     685                'slug'          => 'favorites'
     686        );
     687
     688        // Use this filter to customize the strings the way you want.
     689        $favorite_args = apply_filters( 'bp_activity_favorites_globals', $favorite_default_args );
     690
     691        // Set favorite globals
     692        foreach ( $favorite_args as $key => $arg ) {
     693                $bp->activity->favorites->{$key} = $arg;
     694        }
     695}
     696add_action( 'bp_activity_setup_globals', 'bp_activity_favorites_globals' );
     697
     698/**
     699 * Handles the saving of favorites privacy
     700 *
     701 * @since BuddyPress (2.1.0)
     702 */
     703function bp_activity_favorites_action_settings() {
     704
     705        // Bail if not a POST action
     706        if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
     707                return;
     708        }
     709
     710        // Bail if no submit action
     711        if ( ! isset( $_POST['favorites-settings-submit'] ) ) {
     712                return;
     713        }
     714
     715        // 404 if there are any additional action variables attached
     716        if ( bp_action_variables() ) {
     717                bp_do_404();
     718                return;
     719        }
     720
     721        // Nonce check
     722        check_admin_referer( 'bp_activity_favorites_settings' );
     723
     724        do_action( 'bp_activity_favorites_settings_before_save' );
     725
     726        /** Save ******************************************************************/
     727
     728        $user_id = bp_displayed_user_id();
     729
     730        // Only save if there are field ID's being posted
     731        if ( ! empty( $_POST['bp_favorites_private'] ) ) {
     732                // Save the visibility settings
     733                bp_update_user_meta( $user_id, 'bp_favorites_private', absint( $_POST['bp_favorites_private'] ) );
     734                // hide favorited activities
     735                bp_activity_hide_user_activity( $user_id, 'activity_favorite' );
     736        } else {
     737                // Delete the visibility settings
     738                bp_delete_user_meta( $user_id, 'bp_favorites_private' );
     739                // hide favorited activities
     740                bp_activity_show_user_activity( $user_id, 'activity_favorite' );
     741        }
     742
     743        /** Other *****************************************************************/
     744
     745        do_action( 'bp_activity_favorites_settings_after_save' );
     746
     747        bp_core_add_message( __( 'Favorites privacy saved', 'buddypress' ) );
     748        // Redirect to the root domain
     749        bp_core_redirect( bp_displayed_user_domain() . bp_get_settings_slug() . '/' . bp_get_activity_favorites_slug() );
     750}
     751add_action( 'bp_activity_screen_favorites_settings', 'bp_activity_favorites_action_settings' );
  • src/bp-activity/bp-activity-classes.php

    diff --git src/bp-activity/bp-activity-classes.php src/bp-activity/bp-activity-classes.php
    index f1e6054..be2883f 100644
    class BP_Activity_Activity { 
    324324
    325325                // Where conditions
    326326                $where_conditions = array();
     327                $excluded_types = array();
    327328
    328329                // Spam
    329330                if ( 'ham_only' == $spam )
    class BP_Activity_Activity { 
    337338                        $where_conditions['search_sql'] = "a.content LIKE '%%" . esc_sql( like_escape( $search_terms ) ) . "%%'";
    338339                }
    339340
     341                // In activity administration & stream mode, display favorites
     342                if ( 'stream' !== $display_comments ) {
     343                        // Exclude 'activity_favorite' items unless the 'action' filter has
     344                        // been explicitly set
     345                        if ( empty( $filter['action'] ) ) {
     346                                $excluded_types[] = 'activity_favorite';
     347
     348                        // If explicitly set transform this as a specific meta query
     349                        } else if ( 'activity_favorite' == $filter['action'] ) {
     350                                $meta_query_args = array(
     351                                                'key'     => 'activity_favorite',
     352                                                'compare' => 'EXISTS'
     353                                );
     354
     355                                if ( ! empty( $filter['user_id'] ) ) {
     356                                        $meta_query_args['compare'] = '=';
     357                                        $meta_query_args['value'] = absint( $filter['user_id'] );
     358                                        unset( $filter['user_id'] );
     359                                }
     360
     361                                $meta_query = array( $meta_query_args );
     362
     363                                unset( $filter['action'] );
     364                        }
     365                }
     366
    340367                // Filtering
    341368                if ( $filter && $filter_sql = BP_Activity_Activity::get_filter_sql( $filter ) )
    342369                        $where_conditions['filter_sql'] = $filter_sql;
    class BP_Activity_Activity { 
    376403                // comments in the stream like normal comments or threaded below
    377404                // the activity.
    378405                if ( false === $display_comments || 'threaded' === $display_comments ) {
    379                         $where_conditions[] = "a.type != 'activity_comment'";
     406                        $excluded_types[] = 'activity_comment';
    380407                }
    381408
    382409                // Exclude 'last_activity' items unless the 'action' filter has
    383410                // been explicitly set
    384411                if ( empty( $filter['object'] ) ) {
    385                         $where_conditions[] = "a.type != 'last_activity'";
     412                        $excluded_types[] = 'last_activity';
     413                }
     414
     415                if ( ! empty( $excluded_types ) ) {
     416                        $where_conditions[] = "a.type NOT IN( '" . implode( "','", $excluded_types ) . "' )";
    386417                }
    387418
    388419                // Filter the where conditions
    class BP_Activity_Activity { 
    465496                // Generate action strings
    466497                $activities = BP_Activity_Activity::generate_action_strings( $activities );
    467498
     499                // Append user_ids who favorited activities
     500                $activities = self::append_favorites( $activities );
     501
    468502                // If $max is set, only return up to the max results
    469503                if ( !empty( $max ) ) {
    470504                        if ( (int) $total_activities > (int) $max )
    class BP_Activity_Activity { 
    644678
    645679                        // WP_Meta_Query expects the table name at
    646680                        // $wpdb->activitymeta
    647                         $wpdb->activitymeta = buddypress()->activity->table_name_meta;
     681                        if( ! empty( $activity_meta_query->queries[0]['key'] ) && 'activity_favorite' == $activity_meta_query->queries[0]['key'] ) {
     682                                $wpdb->activitymeta = buddypress()->activity->table_name;
     683                        } else {
     684                                $wpdb->activitymeta = buddypress()->activity->table_name_meta;
     685                        }
    648686
    649687                        $meta_sql = $activity_meta_query->get_sql( 'activity', 'a', 'id' );
    650688
    651689                        // Strip the leading AND - BP handles it in get()
    652690                        $sql_array['where'] = preg_replace( '/^\sAND/', '', $meta_sql['where'] );
    653691                        $sql_array['join']  = $meta_sql['join'];
     692
     693                        if ( buddypress()->activity->table_name == $wpdb->activitymeta ) {
     694                                $sql_array['join']  = str_replace( 'JOIN '. $wpdb->activitymeta, 'JOIN '. $wpdb->activitymeta . ' f', $sql_array['join'] );
     695                                $sql_array['join']  = str_replace( $wpdb->activitymeta .'.activity_id' , 'f.item_id', $sql_array['join'] );
     696
     697                                if ( 'EXISTS' == strtoupper( $activity_meta_query->queries[0]['compare'] ) ) {
     698                                        $sql_array['where'] = str_replace( $wpdb->activitymeta .'.meta_key', 'f.type', $sql_array['where'] );
     699                                } else {
     700                                        $user_id = $activity_meta_query->queries[0]['value'];
     701                                        preg_match( '/CAST\((.*)meta_value(.*)[' .$user_id. ']\'\)/', $sql_array['where'], $matches );
     702                                       
     703                                        if ( ! empty( $matches[1] ) ) {
     704                                                $table = str_replace( $wpdb->activitymeta, 'f', $matches[1] );
     705                                                $sql_array['where'] = $wpdb->prepare( "( f.type = %s AND {$table}user_id = %d )", $activity_meta_query->queries[0]['key'], $user_id );
     706                                        }
     707                                }
     708                                // Restore activitymeta table
     709                                $wpdb->activitymeta = buddypress()->activity->table_name_meta;
     710                        }
    654711                }
    655712
    656713                return $sql_array;
    class BP_Activity_Activity { 
    811868                else
    812869                        return false;
    813870
    814                 // Fetch the activity IDs so we can delete any comments for this activity item
     871                // Fetch the activity IDs so we can delete any children for this activity item
    815872                $activity_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
    816873
    817874                if ( ! $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$where_sql}" ) ) {
    818875                        return false;
    819876                }
    820877
    821                 // Handle accompanying activity comments and meta deletion
     878                // Handle accompanying activity children and meta deletion
    822879                if ( $activity_ids ) {
    823880                        $activity_ids_comma          = implode( ',', wp_parse_id_list( $activity_ids ) );
    824                         $activity_comments_where_sql = "WHERE type = 'activity_comment' AND item_id IN ({$activity_ids_comma})";
     881                        $activity_children_where_sql = "WHERE type IN ( 'activity_comment', 'activity_favorite' ) AND item_id IN ({$activity_ids_comma})";
    825882
    826                         // Fetch the activity comment IDs for our deleted activity items
    827                         $activity_comment_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$activity_comments_where_sql}" );
     883                        // Fetch the activity child IDs for our deleted activity items
     884                        $activity_child_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$activity_children_where_sql}" );
    828885
    829886                        // We have activity comments!
    830                         if ( ! empty( $activity_comment_ids ) ) {
    831                                 // Delete activity comments
    832                                 $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$activity_comments_where_sql}" );
     887                        if ( ! empty( $activity_child_ids ) ) {
     888                                // Delete activity children
     889                                $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$activity_children_where_sql}" );
    833890
    834891                                // Merge activity IDs with activity comment IDs
    835                                 $activity_ids = array_merge( $activity_ids, $activity_comment_ids );
     892                                $activity_ids = array_merge( $activity_ids, $activity_child_ids );
    836893                        }
    837894
    838895                        // Delete all activity meta entries for activity items and activity comments
    class BP_Activity_Activity { 
    12831340         * @return int A count of the user's favorites.
    12841341         */
    12851342        public static function total_favorite_count( $user_id ) {
    1286                 if ( !$favorite_activity_entries = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ) )
     1343                $favorite_activity_entries = self::get_favorites_by_user_id( $user_id );
     1344
     1345                if ( empty( $favorite_activity_entries ) )
    12871346                        return 0;
    12881347
    1289                 return count( maybe_unserialize( $favorite_activity_entries ) );
     1348                return count( $favorite_activity_entries );
    12901349        }
    12911350
    12921351        /**
    class BP_Activity_Activity { 
    13051364         * Hide all activity for a given user.
    13061365         *
    13071366         * @param int $user_id The ID of the user whose activity you want to mark hidden.
    1308          * @param int
     1367         * @param string $type the activity type
    13091368         */
    1310         public static function hide_all_for_user( $user_id ) {
     1369        public static function hide_all_for_user( $user_id, $type = '' ) {
    13111370                global $wpdb, $bp;
    13121371
    1313                 return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
     1372                $where = array(
     1373                        $wpdb->prepare( "user_id = %d", $user_id )
     1374                );
     1375
     1376                if ( ! empty( $type ) ) {
     1377                        $where[] = "type = 'activity_favorite'";
     1378                }
     1379
     1380                $where = 'WHERE ' . implode( ' AND ', $where );
     1381
     1382                return $wpdb->get_var( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 {$where}" );
     1383        }
     1384
     1385        /**
     1386         * Show activity for a given user and a given type.
     1387         *
     1388         * @param int $user_id The ID of the user whose activity you want to mark hidden.
     1389         * @param string $type the activity type
     1390         */
     1391        public static function show_activity_for_user( $user_id, $type ) {
     1392                global $wpdb, $bp;
     1393
     1394                if ( empty( $type ) ) {
     1395                        return false;
     1396                }
     1397
     1398                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 ) );
     1399        }
     1400
     1401        /**
     1402         * Append user_ids who favorited activities.
     1403         *
     1404         * @since BuddyPress (2.1.0)
     1405         *
     1406         * @param array $activities Activities to fetch user who favorited.
     1407         * @return array The updated activities with attached user ids.
     1408         */
     1409        public static function append_favorites( $activities = array() ) {
     1410
     1411                // Now fetch the user who favorited matching activities.
     1412                foreach ( (array) $activities as $key => $activity ) {
     1413                        if ( 'activity_favorite' == $activity->type ) {
     1414                                $activities[$key]->favorites = array();
     1415                        }
     1416
     1417                        $activities[$key]->favorites = self::get_favorites_by_activity_id( $activity->id );
     1418                }
     1419
     1420                return $activities;
     1421        }
     1422
     1423        /**
     1424         * Get user_ids who favorited activities.
     1425         *
     1426         * @since BuddyPress (2.1.0)
     1427         *
     1428         * @param int $activity_id
     1429         * @return array $users The users who favorited the activities.
     1430         */
     1431        public static function get_favorites_by_activity_id( $activity_id = 0 ) {
     1432                global $wpdb;
     1433                $bp = buddypress();
     1434
     1435                $users = array();
     1436
     1437                if ( empty( $activity_id ) ) {
     1438                        return $users;
     1439                }
     1440
     1441                // Users need to have the possibility to set their privacy preferences, else don't show them in favorites
     1442                $public_favorites = apply_filters( 'bp_activity_favorites_privacy', bp_is_active( 'settings' ) );
     1443
     1444                if ( empty( $public_favorites ) ) {
     1445                        return $users;
     1446                }
     1447
     1448                $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 ) );
     1449               
     1450                // Admins can see all favorites
     1451                if( bp_current_user_can( 'bp_moderate' ) ) {
     1452                        $users = wp_list_pluck( $users, 'user_id' );
     1453
     1454                // Only loggedin users can see their private favorites
     1455                } else {
     1456                        $public = array();
     1457                        foreach( $users as $key => $user ) {
     1458                                // favorite is private and loggedin user is not the one who favorited the activity
     1459                                if( bp_loggedin_user_id() == $user->user_id || 0 == $user->hide_sitewide ) {
     1460                                        $public[] = $user->user_id;
     1461                                }
     1462                        }
     1463                        $users = $public;
     1464                }
     1465
     1466                return $users;
     1467        }
     1468
     1469        /**
     1470         * Get user_ids who favorited activities.
     1471         *
     1472         * @since BuddyPress (2.1.0)
     1473         *
     1474         * @param int $user_id
     1475         * @param int $activity_id
     1476         * @return array $favorites The favorited activities.
     1477         */
     1478        public static function get_favorites_by_user_id( $user_id = 0, $activity_id = 0 ) {
     1479                global $wpdb;
     1480                $bp = buddypress();
     1481
     1482                $favorites = array();
     1483
     1484                if ( empty( $user_id ) )
     1485                        return $favorites;
     1486
     1487                $where = array(
     1488                        "type = 'activity_favorite'",
     1489                        $wpdb->prepare( "user_id = %d", $user_id )
     1490                );
     1491
     1492                if ( ! empty( $activity_id ) ) {
     1493                        $where[] = $wpdb->prepare( "item_id = %d", $activity_id );
     1494                }
     1495
     1496                $where = 'WHERE ' . implode( ' AND ', $where );
     1497
     1498                $favorites = $wpdb->get_col( "SELECT item_id FROM {$bp->activity->table_name} {$where}" );
     1499                return $favorites;
    13141500        }
    13151501}
    13161502
    class BP_Activity_Feed { 
    15301716                switch ( $this->id ) {
    15311717
    15321718                        // also output parent activity item if we're on a specific feed
    1533                         case 'favorites' :
     1719                        case bp_get_activity_favorites_slug() :
    15341720                        case 'friends' :
    15351721                        case 'mentions' :
    15361722                        case 'personal' :
  • src/bp-activity/bp-activity-functions.php

    diff --git src/bp-activity/bp-activity-functions.php src/bp-activity/bp-activity-functions.php
    index 507387e..5f0935f 100644
    function bp_activity_get_types() { 
    367367 *
    368368 * @since BuddyPress (1.2)
    369369 *
    370  * @uses bp_get_user_meta()
     370 * @uses BP_Activity_Activity::get_favorites_by_user_id() to get user's favorites
    371371 * @uses apply_filters() To call the 'bp_activity_get_user_favorites' hook.
    372372 *
    373373 * @param int $user_id ID of the user whose favorites are being queried.
    function bp_activity_get_user_favorites( $user_id = 0 ) { 
    380380                $user_id = bp_displayed_user_id();
    381381
    382382        // Get favorites for user
    383         $favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
     383        $favs = BP_Activity_Activity::get_favorites_by_user_id( $user_id );
    384384
    385385        return apply_filters( 'bp_activity_get_user_favorites', $favs );
    386386}
    387387
    388388/**
     389 * Get a users favorite privacy settings.
     390 *
     391 * @since BuddyPress (2.1.0)
     392 *
     393 * @uses bp_get_user_meta()
     394 *
     395 * @param int $user_id ID of the user
     396 * @return bool True if private, false if public.
     397 */
     398function bp_activity_favorites_get_user_settings( $user_id = 0 ) {
     399        // Bail if no user_id to check
     400        if ( empty( $user_id ) ) {
     401                return false;
     402        }
     403
     404        return (bool) bp_get_user_meta( $user_id, 'bp_favorites_private', true );
     405}
     406
     407/**
     408 * Get a users favorite privacy preferences.
     409 *
     410 * @since BuddyPress (2.1.0)
     411 *
     412 * @uses bp_activity_favorites_get_user_settings()
     413 * @uses apply_filters() To call the 'bp_activity_favorites_privacy' hook.
     414 *
     415 * @param int $user_id ID of the user whose favorites are being queried.
     416 * @return bool True if public, false if private.
     417 */
     418function bp_activity_favorites_privacy( $user_id = 0 ) {
     419        // Bail if no user_id to check
     420        if ( empty( $user_id ) ) {
     421                return false;
     422        }
     423
     424        $public = true;
     425
     426        // Admins can always view
     427        if ( bp_current_user_can( 'bp_moderate' ) ) {
     428                return $public;
     429
     430        // Self can always view their favorites
     431        } else if ( $user_id == bp_loggedin_user_id() ) {
     432                return $public;
     433
     434        // If user had no way to set privacy, default to false
     435        } else if ( ! bp_is_active( 'settings' ) ) {
     436                $public = false;
     437
     438        // Check user's preference
     439        } else {
     440                // if private is set public is false
     441                $public = ! bp_activity_favorites_get_user_settings( $user_id );
     442        }
     443
     444        // An admin can force public for his community
     445        return apply_filters( 'bp_activity_favorites_privacy', $public );
     446}
     447
     448/**
    389449 * Add an activity stream item as a favorite for a user.
    390450 *
    391451 * @since BuddyPress (1.2)
    392452 *
    393453 * @uses is_user_logged_in()
    394  * @uses bp_get_user_meta()
     454 * @uses bp_loggedin_user_id() to default to current user logged in
     455 * @uses BP_Activity_Activity::get_favorites_by_user_id() to check if the activity to favorite is not already favorited
    395456 * @uses bp_activity_get_meta()
    396  * @uses bp_update_user_meta()
    397457 * @uses bp_activity_update_meta()
     458 * @uses bp_activity_add_favorite() to create the 'activity_favorite' activity
    398459 * @uses do_action() To call the 'bp_activity_add_user_favorite' hook.
    399460 * @uses do_action() To call the 'bp_activity_add_user_favorite_fail' hook.
    400461 *
    function bp_activity_get_user_favorites( $user_id = 0 ) { 
    405466function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
    406467
    407468        // Favorite activity stream items are for logged in users only
    408         if ( !is_user_logged_in() )
     469        if ( ! is_user_logged_in() )
    409470                return false;
    410471
    411472        // Fallback to logged in user if no user_id is passed
    412473        if ( empty( $user_id ) )
    413474                $user_id = bp_loggedin_user_id();
    414475
    415         $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
    416         if ( empty( $my_favs ) || ! is_array( $my_favs ) ) {
    417                 $my_favs = array();
    418         }
     476        $is_fav = BP_Activity_Activity::get_favorites_by_user_id( $user_id, $activity_id );
    419477
    420         // Bail if the user has already favorited this activity item
    421         if ( in_array( $activity_id, $my_favs ) ) {
     478        // Bail if Already favorited
     479        if ( ! empty( $is_fav ) ) {
    422480                return false;
    423481        }
    424482
    425         // Add to user's favorites
    426         $my_favs[] = $activity_id;
    427 
    428483        // Update the total number of users who have favorited this activity
    429484        $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
    430         $fav_count = !empty( $fav_count ) ? (int) $fav_count + 1 : 1;
     485        $fav_count = ! empty( $fav_count ) ? (int) $fav_count + 1 : 1;
    431486
    432         // Update user meta
    433         bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs );
     487        // Update activity meta counts for backcompat
     488        bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count );
    434489
    435         // Update activity meta counts
    436         if ( bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ) ) {
     490        // Save the favorite
     491        if ( bp_activity_add_favorite( $activity_id, $user_id ) ) {
    437492
    438493                // Execute additional code
    439494                do_action( 'bp_activity_add_user_favorite', $activity_id, $user_id );
    function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { 
    456511 * @since BuddyPress (1.2)
    457512 *
    458513 * @uses is_user_logged_in()
    459  * @uses bp_get_user_meta()
     514 * @uses bp_loggedin_user_id() to default to current user logged in
     515 * @uses bp_activity_delete_by_item_id() to delete the favorite
    460516 * @uses bp_activity_get_meta()
    461517 * @uses bp_activity_update_meta()
    462  * @uses bp_update_user_meta()
    463518 * @uses do_action() To call the 'bp_activity_remove_user_favorite' hook.
    464519 *
    465520 * @param int $activity_id ID of the activity item being unfavorited.
    function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { 
    469524function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
    470525
    471526        // Favorite activity stream items are for logged in users only
    472         if ( !is_user_logged_in() )
     527        if ( ! is_user_logged_in() )
    473528                return false;
    474529
    475530        // Fallback to logged in user if no user_id is passed
    476531        if ( empty( $user_id ) )
    477532                $user_id = bp_loggedin_user_id();
    478533
    479         $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
    480         $my_favs = array_flip( (array) $my_favs );
     534        // the favorite is an activity, so let's delete it
     535        $removed = bp_activity_delete_by_item_id(  array(
     536                'item_id' => $activity_id,
     537                'type'    => 'activity_favorite',
     538                'user_id' => $user_id,
     539        ) );
    481540
    482541        // Bail if the user has not previously favorited the item
    483         if ( ! isset( $my_favs[ $activity_id ] ) ) {
     542        if ( empty( $removed ) ) {
    484543                return false;
    485544        }
    486545
    487         // Remove the fav from the user's favs
    488         unset( $my_favs[$activity_id] );
    489         $my_favs = array_unique( array_flip( $my_favs ) );
     546        $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
     547 
     548        // Error getting favorite count
     549        if ( empty( $fav_count ) ) {
     550                return false;
     551        }
     552       
     553        // Deduct from total favorites
     554        $count_updated = bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 );
    490555
    491         // Update the total number of users who have favorited this activity
    492         if ( $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' ) ) {
     556        // Error updating favorite count
     557        if ( empty( $count_updated ) ) {
     558                return false;
     559        }
    493560
    494                 // Deduct from total favorites
    495                 if ( bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 ) ) {
     561        // Execute additional code
     562        do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id );
    496563
    497                         // Update users favorites
    498                         if ( bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs ) ) {
     564        return true;
     565}
    499566
    500                                 // Execute additional code
    501                                 do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id );
     567/**
     568 * Add an activity typed 'activity_favorite' for the favorited activity
     569 *
     570 * @since BuddyPress (2.1.0)
     571 * @uses  BP_Activity_Activity
     572 * @uses  bp_activity_get_permalink()
     573 * @uses  bp_core_get_userlink()
     574 * @uses  bp_activity_add()
     575 * @return int|bool the activity id created or false if it fails
     576 */
     577function bp_activity_add_favorite( $activity_id = 0, $user_id = 0 ) {
     578        if ( empty( $activity_id ) || empty( $user_id ) )
     579                return false;
    502580
    503                                 // Success
    504                                 return true;
     581        $bp = buddypress();
    505582
    506                         // Error updating
    507                         } else {
    508                                 return false;
    509                         }
     583        // Parent activity exists ?
     584        $activity = new BP_Activity_Activity( $activity_id );
    510585
    511                 // Error updating favorite count
    512                 } else {
    513                         return false;
     586        if ( empty( $activity->type ) || 'activity_favorite' == $activity->type ) {
     587                return false;
     588        }
     589
     590        $primary_link = bp_activity_get_permalink( $activity_id, $activity );
     591        $description  = $bp->activity->actions->{$bp->activity->id}->activity_favorite['value'];
     592
     593        $action = sprintf( _x( '%1$s %2$s', 'favorite action string', 'buddypress' ), bp_core_get_userlink( $user_id ), $description );
     594        $hide_sitewide = ! bp_is_active( 'settings' ) ? true : bp_activity_favorites_get_user_settings( $user_id );
     595
     596        $args = array(
     597                'user_id'           => $user_id,
     598                'component'         => $bp->activity->id,
     599                'type'              => 'activity_favorite',
     600                'action'            => $action,
     601                'content'           => '',
     602                'primary_link'      => $primary_link,
     603                'item_id'           => $activity_id,
     604                'secondary_item_id' => $activity->user_id,
     605                'hide_sitewide'     => $hide_sitewide,
     606        );
     607
     608        return bp_activity_add( $args );
     609}
     610
     611/**
     612 * Migrate user's favorite (previously in bp_favorite_activities user meta) to activity table
     613 *
     614 * @since BuddyPress (2.1.0)
     615 * @uses  bp_activity_add_favorite() to create the 'activity_favorite' activities
     616 */
     617function bp_activity_favorites_migrate() {
     618        global $wpdb;
     619
     620        $user_favorites = $wpdb->get_results( "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = 'bp_favorite_activities'" );
     621       
     622        foreach( $user_favorites as $meta ) {
     623                $meta_value = maybe_unserialize( $meta->meta_value );
     624
     625                if ( empty( $meta_value ) )
     626                        continue;
     627
     628                foreach( $meta_value as $favorite ) {
     629                        bp_activity_add_favorite( $favorite, $meta->user_id );
    514630                }
    515631
    516         // Error getting favorite count
    517         } else {
    518                 return false;
    519632        }
    520633}
    521634
    function bp_activity_register_activity_actions() { 
    854967                __( 'Activity Comments', 'buddypress' )
    855968        );
    856969
     970        $public_favorites = apply_filters( 'bp_activity_favorites_privacy', bp_is_active( 'settings' ) );
     971
     972        if ( ! empty( $public_favorites ) ) {
     973                bp_activity_set_action(
     974                        $bp->activity->id,
     975                        'activity_favorite',
     976                        $bp->activity->favorites->description,
     977                        'bp_activity_format_activity_action_activity_favorites',
     978                        $bp->activity->favorites->label,
     979                        $bp->activity->favorites->contexts
     980                );
     981        }
     982
    857983        do_action( 'bp_activity_register_activity_actions' );
    858984
    859985        // Backpat. Don't use this.
    function bp_activity_format_activity_action_activity_comment( $action, $activity 
    9191045        return apply_filters( 'bp_activity_comment_action', $action, $activity );
    9201046}
    9211047
     1048/**
     1049 * Format 'activity_favorite' activity actions.
     1050 *
     1051 * @since BuddyPress (2.1.0)
     1052 *
     1053 * @param string $action Static activity action.
     1054 * @param object $activity Activity data object.
     1055 * @return string
     1056 */
     1057function bp_activity_format_activity_action_activity_favorites( $action, $activity ) {
     1058        $action = sprintf( _x( '%1$s %2$s', 'favorite action string', 'buddypress' ), bp_core_get_userlink( $activity->user_id ), buddypress()->activity->favorites->description );
     1059        return apply_filters( 'bp_activity_favorite_action', $action, $activity );
     1060}
     1061
    9221062/******************************************************************************
    9231063 * Business functions are where all the magic happens in BuddyPress. They will
    9241064 * handle the actual saving or manipulation of information. Usually they will
    function bp_activity_get_permalink( $activity_id, $activity_obj = false ) { 
    15991739                $activity_obj = $activity_obj->current_comment;
    16001740        }
    16011741
    1602         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 ) {
     1742        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 ) {
    16031743                $link = $activity_obj->primary_link;
    16041744        } else {
    16051745                if ( 'activity_comment' == $activity_obj->type ) {
    function bp_activity_get_permalink( $activity_id, $activity_obj = false ) { 
    16201760 * @uses BP_Activity_Activity::hide_all_for_user() {@link BP_Activity_Activity}
    16211761 *
    16221762 * @param int $user_id The ID of the user whose activity is being hidden.
     1763 * @param string $type the activity type to hide (Defaults to all)
     1764 * @return bool True on success, false on failure.
     1765 */
     1766function bp_activity_hide_user_activity( $user_id, $type = '' ) {
     1767        return BP_Activity_Activity::hide_all_for_user( $user_id, $type );
     1768}
     1769
     1770/**
     1771 * Show a user's activity.
     1772 *
     1773 * @since BuddyPress (2.1.0)
     1774 *
     1775 * @uses BP_Activity_Activity::show_activity_for_user() {@link BP_Activity_Activity}
     1776 *
     1777 * @param int $user_id The ID of the user whose activity is being hidden.
     1778 * @param string $type the activity type to hide (Defaults to all)
    16231779 * @return bool True on success, false on failure.
    16241780 */
    1625 function bp_activity_hide_user_activity( $user_id ) {
    1626         return BP_Activity_Activity::hide_all_for_user( $user_id );
     1781function bp_activity_show_user_activity( $user_id, $type = '' ) {
     1782        return BP_Activity_Activity::show_activity_for_user( $user_id, $type );
    16271783}
    16281784
    16291785/**
  • src/bp-activity/bp-activity-loader.php

    diff --git src/bp-activity/bp-activity-loader.php src/bp-activity/bp-activity-loader.php
    index 0f68f91..210fc74 100644
    class BP_Activity_Component extends BP_Component { 
    3333                                'adminbar_myaccount_order' => 10
    3434                        )
    3535                );
     36
     37                $this->setup_hooks();
    3638        }
    3739
    3840        /**
    class BP_Activity_Component extends BP_Component { 
    185187
    186188                // Favorite activity items
    187189                $sub_nav[] = array(
    188                         'name'            => __( 'Favorites', 'buddypress' ),
    189                         'slug'            => 'favorites',
     190                        'name'            => bp_get_activity_favorites_nav(),
     191                        'slug'            => bp_get_activity_favorites_slug(),
    190192                        'parent_url'      => $activity_link,
    191193                        'parent_slug'     => $this->slug,
    192194                        'screen_function' => 'bp_activity_screen_favorites',
    193195                        'position'        => 30,
    194                         'item_css_id'     => 'activity-favs'
     196                        'item_css_id'     => 'activity-favs',
     197                        'user_has_access' => bp_activity_favorites_privacy( bp_displayed_user_id() )
    195198                );
    196199
    197200                // Additional menu if friends is active
    class BP_Activity_Component extends BP_Component { 
    221224                }
    222225
    223226                parent::setup_nav( $main_nav, $sub_nav );
     227
     228                /*if ( bp_is_active( 'settings' ) ) {
     229                        bp_core_new_subnav_item( array(
     230                                'name'                => bp_get_activity_favorites_nav(),
     231                                'slug'                => bp_get_activity_favorites_slug(),
     232                                'parent_slug'     => bp_get_settings_slug(),
     233                                'parent_url'      => trailingslashit( $user_domain . bp_get_settings_slug() ),
     234                                'screen_function' => 'bp_activity_screen_favorite_settings',
     235                                'position'            => 40,
     236                                'user_has_access' => bp_core_can_edit_settings()
     237                        ) );
     238                }*/
    224239        }
    225240
    226241        /**
    class BP_Activity_Component extends BP_Component { 
    291306                        $wp_admin_nav[] = array(
    292307                                'parent' => 'my-account-' . $this->id,
    293308                                'id'     => 'my-account-' . $this->id . '-favorites',
    294                                 'title'  => __( 'Favorites', 'buddypress' ),
    295                                 'href'   => trailingslashit( $activity_link . 'favorites' )
     309                                'title'  => bp_get_activity_favorites_nav(),
     310                                'href'   => trailingslashit( $activity_link . bp_get_activity_favorites_slug() )
    296311                        );
    297312
    298313                        // Friends?
    class BP_Activity_Component extends BP_Component { 
    320335        }
    321336
    322337        /**
     338         * Add custom hooks.
     339         *
     340         * @since BuddyPress (2.1.0)
     341         */
     342        public function setup_hooks() {
     343                add_filter( 'bp_settings_admin_nav', array( $this, 'setup_settings_admin_nav' ), 3 );
     344        }
     345
     346        /**
    323347         * Set up the title for pages and <title>.
    324348         *
    325349         * @since BuddyPress (1.5)
    class BP_Activity_Component extends BP_Component { 
    348372                parent::setup_title();
    349373        }
    350374
     375        public function setup_settings_subnav() {
     376                // Determine user to use
     377                if ( bp_displayed_user_domain() ) {
     378                        $user_domain = bp_displayed_user_domain();
     379                } elseif ( bp_loggedin_user_domain() ) {
     380                        $user_domain = bp_loggedin_user_domain();
     381                } else {
     382                        return;
     383                }
     384
     385                bp_core_new_subnav_item( array(
     386                        'name'                => bp_get_activity_favorites_nav(),
     387                        'slug'                => bp_get_activity_favorites_slug(),
     388                        'parent_slug'     => bp_get_settings_slug(),
     389                        'parent_url'      => trailingslashit( $user_domain . bp_get_settings_slug() ),
     390                        'screen_function' => 'bp_activity_screen_favorites_settings',
     391                        'position'            => 40,
     392                        'user_has_access' => bp_core_can_edit_settings()
     393                ) );
     394        }
     395
     396        /**
     397         * Adds "Settings > Favorites" subnav item under the "Settings" adminbar menu.
     398         *
     399         * @since BuddyPress (2.1.0)
     400         *
     401         * @param array $wp_admin_nav The settings adminbar nav array.
     402         * @return array
     403         */
     404        public function setup_settings_admin_nav( $wp_admin_nav ) {
     405                // Setup the logged in user variables
     406                $settings_link = trailingslashit( bp_loggedin_user_domain() . bp_get_settings_slug() );
     407
     408                // Add the "Favorites" subnav item
     409                $wp_admin_nav[] = array(
     410                        'parent' => 'my-account-' . buddypress()->settings->id,
     411                        'id'     => 'my-account-' . buddypress()->settings->id . '-favorites',
     412                        'title'  => bp_get_activity_favorites_nav(),
     413                        'href'   => trailingslashit( $settings_link . bp_get_activity_favorites_slug() )
     414                );
     415
     416                return $wp_admin_nav;
     417        }
     418
    351419        /**
    352420         * Set up actions necessary for the component.
    353421         *
    class BP_Activity_Component extends BP_Component { 
    356424        public function setup_actions() {
    357425                // Spam prevention
    358426                add_action( 'bp_include', 'bp_activity_setup_akismet' );
     427                add_action( 'bp_settings_setup_nav', array( $this, 'setup_settings_subnav' ) );
    359428
    360429                parent::setup_actions();
    361430        }
  • src/bp-activity/bp-activity-screens.php

    diff --git src/bp-activity/bp-activity-screens.php src/bp-activity/bp-activity-screens.php
    index 2406771..765dee6 100644
    function bp_activity_reset_my_new_mentions() { 
    143143}
    144144add_action( 'bp_activity_screen_mentions', 'bp_activity_reset_my_new_mentions' );
    145145
     146
     147function bp_activity_screen_favorites_settings() {
     148        // Redirect if no privacy settings page is accessible
     149        if ( bp_action_variables() || ! bp_is_active( 'activity' ) ) {
     150                bp_do_404();
     151                return;
     152        }
     153
     154        do_action( 'bp_activity_screen_favorites_settings' );
     155
     156        add_action( 'bp_template_content', 'bp_activity_favorites_template_settings' );
     157
     158        // Load the template
     159        bp_core_load_template( apply_filters( 'bp_settings_screen_activity_favorites', '/members/single/plugins' ) );
     160}
     161
    146162/**
    147163 * Load the page for a single activity item.
    148164 *
  • src/bp-activity/bp-activity-template.php

    diff --git src/bp-activity/bp-activity-template.php src/bp-activity/bp-activity-template.php
    index cad209f..685c3ff 100644
    function bp_activity_directory_permalink() { 
    8383        }
    8484
    8585/**
     86 * Output the activity favorite slug.
     87 *
     88 * @since BuddyPress (2.1.0)
     89 *
     90 * @uses bp_get_activity_favorites_slug()
     91 */
     92function bp_activity_favorites_slug() {
     93        echo bp_get_activity_favorites_slug();
     94}
     95        /**
     96         * Return the activity favorite slug.
     97         *
     98         * @since BuddyPress (2.1.0)
     99         *
     100         * @uses apply_filters() To call the 'bp_get_activity_favorites_slug' hook.
     101         * @uses buddypress() to get main instance
     102         *
     103         * @return string The activity favorite slug.
     104         */
     105        function bp_get_activity_favorites_slug() {
     106                return apply_filters( 'bp_get_activity_favorites_slug', buddypress()->activity->favorites->slug );
     107        }
     108
     109/**
     110 * Output the activity favorite nav name.
     111 *
     112 * @since BuddyPress (2.1.0)
     113 *
     114 * @uses bp_get_activity_favorites_nav()
     115 */
     116function bp_activity_favorites_nav() {
     117        echo bp_get_activity_favorites_nav();
     118}
     119        /**
     120         * Return the activity favorite nav name.
     121         *
     122         * @since BuddyPress (2.1.0)
     123         *
     124         * @uses apply_filters() To call the 'bp_get_activity_favorites_nav' hook.
     125         * @uses buddypress() to get main instance
     126         *
     127         * @return string The activity favorite nav name.
     128         */
     129        function bp_get_activity_favorites_nav() {
     130                return apply_filters( 'bp_get_activity_favorites_nav', buddypress()->activity->favorites->subnav );
     131        }
     132
     133/**
     134 * Output the activity favorite fav button caption.
     135 *
     136 * @since BuddyPress (2.1.0)
     137 *
     138 * @uses bp_get_activity_favorites_fav_button()
     139 */
     140function bp_activity_favorites_fav_button() {
     141        echo bp_get_activity_favorites_fav_button();
     142}
     143        /**
     144         * Return the activity favorite fav button caption.
     145         *
     146         * @since BuddyPress (2.1.0)
     147         *
     148         * @uses apply_filters() To call the 'bp_get_activity_favorites_fav_button' hook.
     149         * @uses buddypress() to get main instance
     150         *
     151         * @return string The activity favorite fav button caption.
     152         */
     153        function bp_get_activity_favorites_fav_button() {
     154                return apply_filters( 'bp_get_activity_favorites_fav_button', buddypress()->activity->favorites->fav_button );
     155        }
     156
     157/**
     158 * Output the activity favorite unfav button caption.
     159 *
     160 * @since BuddyPress (2.1.0)
     161 *
     162 * @uses bp_get_activity_favorites_unfav_button()
     163 */
     164function bp_activity_favorites_unfav_button() {
     165        echo bp_get_activity_favorites_unfav_button();
     166}
     167        /**
     168         * Return the activity favorite unfav button caption.
     169         *
     170         * @since BuddyPress (2.1.0)
     171         *
     172         * @uses apply_filters() To call the 'bp_get_activity_favorites_unfav_button' hook.
     173         * @uses buddypress() to get main instance
     174         *
     175         * @return string The activity favorite unfav button caption.
     176         */
     177        function bp_get_activity_favorites_unfav_button() {
     178                return apply_filters( 'bp_get_activity_favorites_unfav_button', buddypress()->activity->favorites->unfav_button );
     179        }
     180
     181/**
     182 * Output the activity favorite directory tab caption.
     183 *
     184 * @since BuddyPress (2.1.0)
     185 *
     186 * @uses bp_get_activity_favorites_directory_tab()
     187 */
     188function bp_activity_favorites_directory_tab() {
     189        echo bp_get_activity_favorites_directory_tab();
     190}
     191        /**
     192         * Return the activity favorite directory tab caption.
     193         *
     194         * @since BuddyPress (2.1.0)
     195         *
     196         * @uses apply_filters() To call the 'bp_get_activity_favorites_directory_tab' hook.
     197         * @uses buddypress() to get main instance
     198         *
     199         * @return string The activity favorite directory tab caption.
     200         */
     201        function bp_get_activity_favorites_directory_tab() {
     202                return apply_filters( 'bp_get_activity_favorites_directory_tab', buddypress()->activity->favorites->directory_tab );
     203        }
     204
     205/**
    86206 * The main activity template loop class.
    87207 *
    88208 * This is responsible for loading a group of activity items and displaying them.
    class BP_Activity_Template { 
    184304                // Check if blog/forum replies are disabled
    185305                $this->disable_blogforum_replies = isset( $bp->site_options['bp-disable-blogforum-comments'] ) ? $bp->site_options['bp-disable-blogforum-comments'] : false;
    186306
    187                 // Get an array of the logged in user's favorite activities
    188                 $this->my_favs = maybe_unserialize( bp_get_user_meta( bp_loggedin_user_id(), 'bp_favorite_activities', true ) );
    189 
    190307                // Fetch specific activity items based on ID's
    191308                if ( !empty( $include ) ) {
    192309                        $this->activities = bp_activity_get_specific( array(
    function bp_has_activities( $args = '' ) { 
    519636        else
    520637                $scope = bp_current_action();
    521638
     639        // A lot of Ajax/js is done threw markup let's come back to favorites
     640        if ( bp_get_activity_favorites_slug() == $scope ) {
     641                $scope = 'favorites';
     642        }
     643
    522644        // Support for permalinks on single item pages: /groups/my-group/activity/124/
    523645        if ( bp_is_current_action( bp_get_activity_slug() ) )
    524646                $include = bp_action_variable( 0 );
    function bp_has_activities( $args = '' ) { 
    610732                                        }
    611733                                        break;
    612734                                case 'favorites':
    613                                         $favs = bp_activity_get_user_favorites( $user_id );
    614                                         if ( empty( $favs ) )
    615                                                 return false;
    616 
    617                                         $in = implode( ',', (array) $favs );
     735                                        $action = 'activity_favorite';
    618736                                        $display_comments = true;
    619                                         $user_id = 0;
    620737                                        break;
    621738                                case 'mentions':
    622739
    function bp_activity_is_favorite() { 
    17521869        function bp_get_activity_is_favorite() {
    17531870                global $activities_template;
    17541871
    1755                 return apply_filters( 'bp_get_activity_is_favorite', in_array( $activities_template->activity->id, (array) $activities_template->my_favs ) );
     1872                return apply_filters( 'bp_get_activity_is_favorite', in_array( bp_loggedin_user_id(), (array) $activities_template->activity->favorites ) );
    17561873        }
    17571874
    17581875/**
    function bp_activity_can_comment_reply( $comment ) { 
    26992816 * @return bool $can_favorite True if comment can receive comments.
    27002817 */
    27012818function bp_activity_can_favorite() {
     2819        global $activities_template;
     2820
    27022821        $can_favorite = true;
    27032822
     2823        if ( ! empty( $activities_template->activity->type ) && 'activity_favorite' == $activities_template->activity->type ) {
     2824                $can_favorite = false;
     2825        }
     2826
    27042827        return apply_filters( 'bp_activity_can_favorite', $can_favorite );
    27052828}
    27062829
     2830 /**
     2831 * Count the users who favorited the current activity.
     2832 *
     2833 * @since BuddyPress (2.1.0)
     2834 *
     2835 * @uses apply_filters() To call the 'bp_activity_get_favorite_count' hook.
     2836 *
     2837 * @return int the number of users who favorited the activity.
     2838 */
     2839function bp_activity_get_favorite_count() {
     2840        global $activities_template;
     2841
     2842        $count = 0;
     2843
     2844        if ( ! empty( $activities_template->activity->favorites ) ) {
     2845                $count = count( (array) $activities_template->activity->favorites );
     2846        }
     2847
     2848        return apply_filters( 'bp_activity_get_favorite_count', $count );
     2849}
     2850
    27072851/**
    27082852 * Output the total favorite count for a specified user.
    27092853 *
    function bp_total_favorite_count_for_user( $user_id = 0 ) { 
    27392883        add_filter( 'bp_get_total_favorite_count_for_user', 'bp_core_number_format' );
    27402884
    27412885/**
     2886 * Output the List of users who favorited the activity
     2887 *
     2888 * To maximize theme backcompat uses the hook bp_after_activity_entry_comments
     2889 *
     2890 * @since BuddyPress (2.1.0)
     2891 *
     2892 * @uses bp_get_activity_favorites()
     2893 */
     2894function bp_activity_favorites() {
     2895        echo bp_get_activity_favorites();
     2896}
     2897add_action( 'bp_after_activity_entry_comments', 'bp_activity_favorites' );
     2898       
     2899        /**
     2900         * Return the List of users who favorited the activity
     2901         *
     2902         * @since BuddyPress (2.1.0)
     2903         *
     2904         * @uses bp_activity_list_favorites()
     2905         */
     2906        function bp_get_activity_favorites() {
     2907
     2908                if ( 0 == bp_activity_get_comment_count() ) {
     2909                        $output = '<div class="activity-favorites">';
     2910                } else {
     2911                        $output = '<div class="activity-favorites hide">';
     2912                }
     2913               
     2914                $output .= bp_activity_list_favorites() . '</div>';
     2915
     2916                return $output;
     2917        }
     2918
     2919        /**
     2920         * Build the List of users who favorited the activity
     2921         *
     2922         * @since BuddyPress (2.1.0)
     2923         */
     2924        function bp_activity_list_favorites() {
     2925                global $activities_template;
     2926
     2927                $output = '<ul class="favorites-list">';
     2928
     2929                foreach( (array) $activities_template->activity->favorites as $user_id ) {
     2930                        $user_avatar = bp_core_fetch_avatar( array(
     2931                                'item_id' => $user_id,
     2932                                'object'  => 'user',
     2933                                'type'    => 'thumb',
     2934                                'width'   => 50,
     2935                                'height'  => 50,
     2936                                'html'    => true,
     2937                                'class'   => 'user-favorited-' . $user_id
     2938                        ) );
     2939                        $output .= '<li><a href="' . bp_core_get_userlink( $user_id, false, true ) .'">' . $user_avatar . '</a></li>';
     2940                }
     2941
     2942                $output .= '</ul>';
     2943
     2944                return apply_filters( 'bp_activity_list_favorites', $output, $activities_template->activity->id, $activities_template->activity->favorites );
     2945        }
     2946
     2947/**
     2948 * Output the interaction nav to switch between comments & favorites
     2949 *
     2950 * To maximize theme backcompat uses the hook bp_before_activity_entry_comments
     2951 *
     2952 * @since BuddyPress (2.1.0)
     2953 *
     2954 * @uses bp_get_activity_interactions_nav()
     2955 */
     2956function bp_activity_interactions_nav() {
     2957        echo bp_get_activity_interactions_nav();
     2958}
     2959add_action( 'bp_before_activity_entry_comments', 'bp_activity_interactions_nav' );
     2960       
     2961        /**
     2962         * Return the interaction nav to switch between comments & favorites
     2963         *
     2964         * @since BuddyPress (2.1.0)
     2965         */
     2966        function bp_get_activity_interactions_nav() {
     2967                global $activities_template;
     2968
     2969                $can_comment = bp_activity_can_comment();
     2970
     2971                if ( ( is_user_logged_in() && $can_comment ) || ( is_user_logged_in() && bp_activity_can_favorite() ) || bp_is_single_activity() ) {
     2972
     2973                        $class_nav = $class_favorite = $class_comment = '';
     2974                        $comments_count  = bp_activity_get_comment_count();
     2975                        $favorites_count = bp_activity_get_favorite_count();
     2976
     2977                        if ( 0 ==  $comments_count + $favorites_count )  {
     2978                                $class_nav = ' hide';
     2979                        }
     2980
     2981                        $output = '<ul class="activity-interactions-nav'. $class_nav .'">';
     2982
     2983                        if ( ! $can_comment  ) {
     2984                                $class_comment = ' hide';
     2985                        } else if ( 0 !=  $comments_count ) {
     2986                                $class_comment = ' current';
     2987                        }
     2988
     2989                        $output .= '<li class="activity-interactions'. $class_comment .'"><a href="#" class="activity-comments-interaction">' .  __( 'Replies', 'buddypress' ) . '</a></li>';
     2990
     2991                        if ( 0 == $favorites_count ) {
     2992                                $class_favorite = ' hide';
     2993                        } else if ( ! $can_comment || 0 ==  $comments_count ) {
     2994                                $class_favorite = ' current';
     2995                        }
     2996
     2997                        $output .= '<li class="activity-interactions'. $class_favorite .'"><a href="#" class="activity-favorites-interaction">' .  bp_get_activity_favorites_nav() . '</a></li>';
     2998
     2999                        $output .= '</ul>';
     3000
     3001                } else {
     3002                        $output = false;
     3003                }
     3004
     3005                return apply_filters( 'bp_get_activity_interactions_nav', $output );
     3006        }
     3007
     3008/**
    27423009 * Output the total mention count for a specified user.
    27433010 *
    27443011 * @since BuddyPress (1.2)
    function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link 
    31713438                        $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/feed/';
    31723439                elseif ( bp_is_active( 'groups'  ) && bp_is_current_action( bp_get_groups_slug()  ) )
    31733440                        $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/feed/';
    3174                 elseif ( 'favorites' == bp_current_action() )
    3175                         $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/feed/';
     3441                elseif ( bp_get_activity_favorites_slug() == bp_current_action() )
     3442                        $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_activity_favorites_slug() . '/feed/';
    31763443                elseif ( 'mentions' == bp_current_action() && bp_activity_do_mentions() )
    31773444                        $link = bp_displayed_user_domain() . bp_get_activity_slug() . '/mentions/feed/';
    31783445                else
    function bp_activity_show_filters( $context = '' ) { 
    34603727
    34613728                return apply_filters( 'bp_get_activity_show_filters', $output, $filters, $context );
    34623729        }
     3730
     3731function bp_activity_favorites_template_settings() {
     3732        do_action( 'bp_before_member_settings_template' ); ?>
     3733
     3734        <form action="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_settings_slug() . '/' . bp_get_activity_favorites_slug() ); ?>" method="post" class="standard-form" id="settings-form">
     3735
     3736                <table class="profile-settings" id="favorites-settings">
     3737                        <thead>
     3738                                <tr>
     3739                                        <th class="title field-group-name"></th>
     3740                                        <th class="title"><?php _e( 'Visibility', 'buddypress' ); ?></th>
     3741                                </tr>
     3742                        </thead>
     3743
     3744                        <tbody>
     3745
     3746                                <tr>
     3747                                        <td class="field-name"><?php esc_html_e( 'Favorited Activities', 'buddypress' ); ?></td>
     3748                                        <td class="field-visibility"><?php bp_activity_favorites_settings_visibility_select(); ?></td>
     3749                                </tr>
     3750
     3751                        </tbody>
     3752                </table>
     3753
     3754                <?php do_action( 'bp_activity_favorites_settings_before_submit' ); ?>
     3755
     3756                <div class="submit">
     3757                        <input id="submit" type="submit" name="favorites-settings-submit" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ); ?>" class="auto" />
     3758                </div>
     3759
     3760                <?php do_action( 'bp_activity_favorites_settings_after_submit' ); ?>
     3761
     3762                <?php wp_nonce_field( 'bp_activity_favorites_settings' ); ?>
     3763
     3764        </form>
     3765
     3766        <?php do_action( 'bp_after_member_settings_template' );
     3767}
     3768
     3769function bp_activity_favorites_settings_visibility_select() {
     3770        $selected = bp_activity_favorites_get_user_settings( bp_displayed_user_id() );
     3771
     3772        $privacy_options = array(
     3773                __( 'Everyone', 'buddypress' ),
     3774                __( 'Only Me', 'buddypress' )
     3775        );
     3776
     3777        ?>
     3778        <select name="bp_favorites_private">
     3779                <?php foreach( $privacy_options as $key => $option ) : ?>
     3780                        <option value="<?php echo esc_attr( $key );?>" <?php selected( $selected, $key );?>><?php echo esc_html( $option ); ?></option>
     3781                <?php endforeach ;?>
     3782        </select>
     3783        <?php
     3784}
  • src/bp-core/bp-core-update.php

    diff --git src/bp-core/bp-core-update.php src/bp-core/bp-core-update.php
    index 20bdb6c..9dca4c5 100644
    function bp_version_updater() { 
    240240                if ( $raw_db_version < 8311 ) {
    241241                        bp_update_to_2_0_1();
    242242                }
     243
     244                // 2.1
     245                if ( $raw_db_version < 8312 ) {
     246                        bp_update_to_2_1();
     247                }
    243248        }
    244249
    245250        /** All done! *************************************************************/
    function bp_update_to_2_0_1() { 
    388393        bp_core_maybe_install_signups();
    389394}
    390395
     396 /**
     397 * 2.1 database upgrade routine
     398 *
     399 * @since BuddyPress (2.1.0)
     400 *
     401 * @return void
     402 */
     403function bp_update_to_2_1() {
     404        /** Migrate favorites data ******************************************/
     405        if ( bp_is_active( 'activity' ) ) {
     406                bp_activity_favorites_migrate();
     407        }
     408}
     409
    391410/**
    392411 * Redirect user to BP's What's New page on first page load after activation.
    393412 *
  • src/bp-loader.php

    diff --git src/bp-loader.php src/bp-loader.php
    index bdd3012..ca5aea5 100644
    class BuddyPress { 
    302302                /** Versions **********************************************************/
    303303
    304304                $this->version    = '2.1-alpha';
    305                 $this->db_version = 8311;
     305                $this->db_version = 8312;
    306306
    307307                /** Loading ***********************************************************/
    308308
  • src/bp-templates/bp-legacy/buddypress-functions.php

    diff --git src/bp-templates/bp-legacy/buddypress-functions.php src/bp-templates/bp-legacy/buddypress-functions.php
    index 784b2dc..5b1f4d2 100644
    class BP_Legacy extends BP_Theme_Compat { 
    232232
    233233                // Add words that we need to use in JS to the end of the page
    234234                // so they can be translated and still used.
    235                 $params = apply_filters( 'bp_core_get_js_strings', array(
     235                $params = array(
    236236                        'accepted'            => __( 'Accepted', 'buddypress' ),
    237237                        'close'               => __( 'Close', 'buddypress' ),
    238238                        'comments'            => __( 'comments', 'buddypress' ),
    239239                        'leave_group_confirm' => __( 'Are you sure you want to leave this group?', 'buddypress' ),
    240                         'mark_as_fav'         => __( 'Favorite', 'buddypress' ),
    241                         'my_favs'             => __( 'My Favorites', 'buddypress' ),
    242240                        'rejected'            => __( 'Rejected', 'buddypress' ),
    243                         'remove_fav'          => __( 'Remove Favorite', 'buddypress' ),
    244241                        'show_all'            => __( 'Show all', 'buddypress' ),
    245242                        'show_all_comments'   => __( 'Show all comments for this thread', 'buddypress' ),
    246243                        'show_x_comments'     => __( 'Show all %d comments', 'buddypress' ),
    247244                        'unsaved_changes'     => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
    248245                        'view'                => __( 'View', 'buddypress' ),
    249                 ) );
     246                );
     247
     248                // Favorite strings
     249                if ( bp_is_active( 'activity' ) ) {
     250                        $params = array_merge( $params, array(
     251                                'mark_as_fav' => bp_get_activity_favorites_fav_button(),
     252                                'remove_fav'  => bp_get_activity_favorites_unfav_button(),
     253                                'my_favs'     => bp_get_activity_favorites_directory_tab(),
     254                        ) );
     255                }
     256               
     257                // Allow strings to be filtered
     258                $params = apply_filters( 'bp_core_get_js_strings', $params );
     259
    250260                wp_localize_script( $asset['handle'], 'BP_DTheme', $params );
    251261
    252262                // Maybe enqueue comment reply JS
    function bp_legacy_theme_activity_template_loader() { 
    648658                        $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/groups/feed/';
    649659                        break;
    650660                case 'favorites':
    651                         $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/feed/';
     661                        $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_activity_favorites_slug() . '/feed/';
    652662                        break;
    653663                case 'mentions':
    654664                        $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/feed/';
    function bp_legacy_theme_mark_activity_favorite() { 
    919929        if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
    920930                return;
    921931
    922         if ( bp_activity_add_user_favorite( $_POST['id'] ) )
    923                 _e( 'Remove Favorite', 'buddypress' );
    924         else
    925                 _e( 'Favorite', 'buddypress' );
     932        $result = array();
     933
     934        if ( bp_activity_add_user_favorite( $_POST['id'] ) ){
     935                $result['button'] = bp_get_activity_favorites_unfav_button();
     936               
     937                $user_id = bp_loggedin_user_id();
     938                $user_avatar = bp_core_fetch_avatar( array(
     939                        'item_id' => $user_id,
     940                        'object'  => 'user',
     941                        'type'    => 'thumb',
     942                        'width'   => 50,
     943                        'height'  => 50,
     944                        'html'    => true,
     945                        'class'   => 'user-favorited-' . $user_id
     946                ) );
     947                $result['avatar'] = '<li><a href="' . bp_core_get_userlink( $user_id, false, true ) .'">' . $user_avatar . '</a></li>';
     948       
     949        } else {
     950                $result['button'] = bp_get_activity_favorites_fav_button();
     951                $result['avatar'] = 0;
     952        }
    926953
    927         exit;
     954        exit( json_encode( $result ) );
    928955}
    929956
    930957/**
    function bp_legacy_theme_unmark_activity_favorite() { 
    938965        if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
    939966                return;
    940967
    941         if ( bp_activity_remove_user_favorite( $_POST['id'] ) )
    942                 _e( 'Favorite', 'buddypress' );
    943         else
    944                 _e( 'Remove Favorite', 'buddypress' );
     968        $result = array();
    945969
    946         exit;
     970        if ( bp_activity_remove_user_favorite( $_POST['id'] ) ) {
     971                $result['button'] = bp_get_activity_favorites_fav_button();
     972                $result['avatar'] = bp_loggedin_user_id();
     973        } else {
     974                $result['button'] = bp_get_activity_favorites_unfav_button();
     975                $result['avatar'] = 0;
     976        }
     977               
     978
     979        exit( json_encode( $result ) );
    947980}
    948981
    949982/**
  • src/bp-templates/bp-legacy/buddypress/activity/entry.php

    diff --git src/bp-templates/bp-legacy/buddypress/activity/entry.php src/bp-templates/bp-legacy/buddypress/activity/entry.php
    index 24e296b..2f230df 100644
     
    6363
    6464                                        <?php if ( !bp_get_activity_is_favorite() ) : ?>
    6565
    66                                                 <a href="<?php bp_activity_favorite_link(); ?>" class="button fav bp-secondary-action" title="<?php esc_attr_e( 'Mark as Favorite', 'buddypress' ); ?>"><?php _e( 'Favorite', 'buddypress' ); ?></a>
     66                                                <a href="<?php bp_activity_favorite_link(); ?>" class="button fav bp-primary-action" title="<?php echo esc_attr( sprintf( __( 'Mark as %s', 'buddypress' ), bp_get_activity_favorites_fav_button() ) ); ?>"><?php printf( _x( '%1$s <span>%2$s</span>', 'favorites fav button', 'buddypress' ), bp_get_activity_favorites_fav_button(), bp_activity_get_favorite_count() ); ?></a>
    6767
    6868                                        <?php else : ?>
    6969
    70                                                 <a href="<?php bp_activity_unfavorite_link(); ?>" class="button unfav bp-secondary-action" title="<?php esc_attr_e( 'Remove Favorite', 'buddypress' ); ?>"><?php _e( 'Remove Favorite', 'buddypress' ); ?></a>
     70                                                <a href="<?php bp_activity_unfavorite_link(); ?>" class="button unfav bp-primary-action" title="<?php echo esc_attr( bp_get_activity_favorites_unfav_button() ); ?>"><?php printf( _x( '%1$s <span>%2$s</span>', 'favorites unfav button', 'buddypress' ), bp_get_activity_favorites_unfav_button(), bp_activity_get_favorite_count() ); ?></a>
    7171
    7272                                        <?php endif; ?>
    7373
  • src/bp-templates/bp-legacy/buddypress/activity/index.php

    diff --git src/bp-templates/bp-legacy/buddypress/activity/index.php src/bp-templates/bp-legacy/buddypress/activity/index.php
    index 40d7725..db22e8c 100644
     
    4848
    4949                                <?php if ( bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ) : ?>
    5050
    51                                         <li id="activity-favorites"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/'; ?>" title="<?php esc_attr_e( "The activity I've marked as a favorite.", 'buddypress' ); ?>"><?php printf( __( 'My Favorites <span>%s</span>', 'buddypress' ), bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
     51                                        <li id="activity-favorites"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_activity_favorites_slug() . '/'; ?>" title="<?php esc_attr_e( "The activity I've marked as a favorite.", 'buddypress' ); ?>"><?php printf( _x( '%1$s <span>%2$s</span>', 'favorite directory tab output', 'buddypress' ), bp_get_activity_favorites_directory_tab(), bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
    5252
    5353                                <?php endif; ?>
    5454
  • src/bp-templates/bp-legacy/css/buddypress.css

    diff --git src/bp-templates/bp-legacy/css/buddypress.css src/bp-templates/bp-legacy/css/buddypress.css
    index 6441cd3..f70595b 100644
    Hello, this is the BuddyPress Legacy stylesheet. 
    1212        3.1 - Activity
    1313                3.1.1 - Activity Listing
    1414                3.1.2 - Activity Comments
     15                3.1.3 - Activity Favorites
    1516        3.2 - Toolbar
    1617        3.3 - Directories - Members, Groups, Blogs, Forums
    1718        3.4 - Error / Success Messages
    body.activity-permalink #buddypress div.activity-comments div.acomment-content { 
    485486}
    486487
    487488/*--------------------------------------------------------------
     489+3.1.3 - Activity Likes
     490+--------------------------------------------------------------*/
     491#buddypress .activity-list li ul.activity-interactions-nav {
     492        list-style: none;
     493        margin: 20px 0 10px 70px;
     494        overflow: hidden; /* IE fix */
     495        position: relative;
     496        width: auto;
     497        clear: both;
     498}
     499
     500body.activity-permalink #buddypress li ul.activity-interactions-nav {
     501        background: none;
     502        margin-left: 170px;
     503        width: auto;
     504}
     505
     506#buddypress .activity-list li ul.activity-interactions-nav.hide,
     507#buddypress .activity-list li ul.activity-interactions-nav li.hide {
     508        display:none;
     509}
     510
     511
     512#buddypress .activity-list li ul.activity-interactions-nav li {
     513        float: left;
     514        margin:0;
     515        padding: 4px 8px;
     516        font-size: 90%;
     517        border-bottom: none;
     518}
     519
     520#buddypress .activity-list li ul.activity-interactions-nav li a {
     521        text-decoration: none;
     522        color:#555;
     523}
     524
     525#buddypress .activity-list li ul.activity-interactions-nav li.current {
     526        background-color: #eee;
     527        color: #555;
     528        opacity: .8;
     529        font-weight: bold;
     530}
     531
     532#buddypress div.activity-favorites {
     533        margin: 0 0 0 70px;
     534        overflow: hidden; /* IE fix */
     535        position: relative;
     536        width: auto;
     537        clear: both;
     538}
     539
     540#buddypress div.activity-favorites.hide,
     541body.activity-permalink #buddypress div.activity-favorites.hide {
     542        display:none;
     543}
     544
     545body.activity-permalink #buddypress div.activity-favorites {
     546        margin-left: 170px;
     547}
     548
     549#buddypress div.activity-favorites ul.favorites-list li {
     550        padding:0;
     551        float: left;
     552        border-bottom: none;
     553}
     554
     555#buddypress div.activity-favorites ul.favorites-list {
     556        overflow: hidden;
     557        list-style: none;
     558        width: auto;
     559        clear: both;
     560}
     561
     562#buddypress div.activity-favorites ul.favorites-list li img {
     563        border-width: 1px;
     564        float: left;
     565        height: 25px;
     566        margin-right: 10px;
     567        width: 25px;
     568}
     569
     570/*--------------------------------------------------------------
    4885713.3 - Directories - Members, Groups, Blogs, Forums
    489572--------------------------------------------------------------*/
    490573#buddypress div.dir-search {
  • src/bp-templates/bp-legacy/js/buddypress.js

    diff --git src/bp-templates/bp-legacy/js/buddypress.js src/bp-templates/bp-legacy/js/buddypress.js
    index 63eb97f..56965c5 100644
    jq(document).ready( function() { 
    272272                        li, id, link_href, nonce, timestamp,
    273273                        oldest_page, just_posted;
    274274
     275                if ( target.parent().hasClass( 'fav' ) || target.parent().hasClass( 'unfav' ) ) {
     276                        target = target.parent();
     277                }
     278
    275279                /* Favoriting activity stream items */
    276280                if ( target.hasClass('fav') || target.hasClass('unfav') ) {
    277281                        type      = target.hasClass('fav') ? 'fav' : 'unfav';
    278282                        parent    = target.closest('.activity-item');
    279283                        parent_id = parent.attr('id').substr( 9, parent.attr('id').length );
     284                        count     = Number( jq( target ).find( 'span' ).html() );
     285
     286                        jq( '#activity-' + parent_id + ' .activity-interactions-nav' ).removeClass( 'hide' );
     287                        jq( '#activity-' + parent_id + ' a.activity-favorites-interaction' ).parent( 'li' ).removeClass( 'hide' );
     288                        jq( '#activity-' + parent_id + ' a.activity-favorites-interaction' ).trigger( 'click' );
    280289
    281290                        target.addClass('loading');
    282291
    jq(document).ready( function() { 
    289298                                target.removeClass('loading');
    290299
    291300                                target.fadeOut( 200, function() {
    292                                         jq(this).html(response);
     301                                        jq(this).html(response['button']);
     302                                        count = ( 'fav' === type ) ? Number( count ) + 1 : Number( count ) - 1;
     303                                        jq(this).html( response['button'] + ' <span>' + count +'</span>' );
    293304                                        jq(this).attr('title', 'fav' === type ? BP_DTheme.remove_fav : BP_DTheme.mark_as_fav);
    294305                                        jq(this).fadeIn(200);
    295306                                });
    296307
     308                                if ( ! jq( '#activity-' + parent_id + ' .favorites-list' ).length ) {
     309                                        jq( '#activity-' + parent_id + ' .activity-favorites' ).append( '<ul class="favorites-list"></ul>' );
     310                                }
     311
    297312                                if ( 'fav' === type ) {
    298313                                        if ( !jq('.item-list-tabs #activity-favs-personal-li').length ) {
    299314                                                if ( !jq('.item-list-tabs #activity-favorites').length ) {
    jq(document).ready( function() { 
    306321                                        target.removeClass('fav');
    307322                                        target.addClass('unfav');
    308323
     324                                        if ( 0 != response['avatar'] ){
     325                                                jq( '#activity-' + parent_id + ' .favorites-list' ).append( response['avatar'] );
     326                                        }
     327
    309328                                } else {
    310329                                        target.removeClass('unfav');
    311330                                        target.addClass('fav');
    jq(document).ready( function() { 
    319338
    320339                                                jq('.item-list-tabs ul #activity-favorites').remove();
    321340                                        }
     341
     342                                        if ( 0 != response['avatar'] ){
     343                                                jq( '#activity-' + parent_id + ' .favorites-list .user-favorited-' + response['avatar'] ).parent().parent().remove();
     344
     345                                                if ( 0 == jq( '#activity-' + parent_id + ' .favorites-list').children().length ) {
     346                                                        jq( '#activity-' + parent_id + ' a.activity-comments-interaction' ).trigger( 'click' );
     347                                                        jq( '#activity-' + parent_id + ' a.activity-favorites-interaction' ).parent( 'li' ).addClass( 'hide' );
     348                                                }
     349                                        }
    322350                                }
    323351
    324352                                if ( 'activity-favorites' === jq( '.item-list-tabs li.selected').attr('id') ) {
    325353                                        target.closest( '.activity-item' ).slideUp( 100 );
    326354                                }
    327                         });
     355                        }, 'json' );
    328356
    329357                        return false;
    330358                }
    331359
     360                /* Display Replies or favorites */
     361                if ( target.parent().hasClass( 'activity-interactions' ) ) {
     362                       
     363                        event.preventDefault();
     364
     365                        var css_class = target.attr('class').split( ' ' ),
     366                                current_div = css_class[0].replace( '-interaction', '' ),
     367                                div_tohide = '',
     368                                parent_li = target.parent(),
     369                                parent_ul = parent_li.parent();
     370
     371                        parent_ul.children( 'li' ).each( function() {
     372                                jq( this ).removeClass( 'current' );
     373
     374                                if ( jq( this ).find('a').prop( 'class' ) != target.prop( 'class' ) ) {
     375                                        div_tohide = jq.trim( jq( this ).find('a').prop( 'class' ) ).replace( '-interaction', '' );
     376                                }
     377                        });
     378
     379                        jq( parent_li ).addClass( 'current' );
     380
     381                        if ( ! div_tohide.length )
     382                                return
     383                       
     384                        parent_ul.parent().find( '.' + div_tohide  ).first().hide();
     385                        parent_ul.parent().find( '.' + current_div  ).first().show();
     386                }
     387
    332388                /* Delete activity stream items */
    333389                if ( target.hasClass('delete-activity') ) {
    334390                        li        = target.parents('div.activity ul li');
    jq(document).ready( function() { 
    512568
    513569                /* Comment / comment reply links */
    514570                if ( target.hasClass('acomment-reply') || target.parent().hasClass('acomment-reply') ) {
     571                        target.parent().parent().parent().find( '.activity-comments-interaction' ).first().trigger( 'click' );
     572
    515573                        if ( target.parent().hasClass('acomment-reply') ) {
    516574                                target = target.parent();
    517575                        }
    jq(document).ready( function() { 
    618676
    619677                                        /* Increase the "Reply (X)" button count */
    620678                                        jq('#activity-' + form_id[2] + ' a.acomment-reply span').html( Number( jq('#activity-' + form_id[2] + ' a.acomment-reply span').html() ) + 1 );
     679                                        jq('#activity-' + form_id[2] + ' ul.activity-interactions-nav').removeClass('hide');
    621680
    622681                                        // Increment the 'Show all x comments' string, if present
    623682                                        show_all_a = activity_comments.find('.show-all').find('a');