Skip to:
Content

BuddyPress.org

Ticket #5644: 5644.bp_activity_favorites_table.patch

File 5644.bp_activity_favorites_table.patch, 38.0 KB (added by imath, 10 years ago)
  • 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..08baf50 100644
    class BP_Activity_Activity { 
    337337                        $where_conditions['search_sql'] = "a.content LIKE '%%" . esc_sql( like_escape( $search_terms ) ) . "%%'";
    338338                }
    339339
     340                // User Favorites
     341                if ( ! empty( $filter['action'] ) && 'user_favorites' == $filter['action'] ) {
     342                        $meta_query_args = array(
     343                                        'key'     => 'user_favorites',
     344                                        'compare' => 'EXISTS'
     345                        );
     346
     347                        if ( ! empty( $filter['user_id'] ) ) {
     348                                $meta_query_args['compare'] = '=';
     349                                $meta_query_args['value'] = absint( $filter['user_id'] );
     350                                unset( $filter['user_id'] );
     351                        }
     352
     353                        $meta_query = array( $meta_query_args );
     354
     355                        unset( $filter['action'] );
     356                }
     357
    340358                // Filtering
    341359                if ( $filter && $filter_sql = BP_Activity_Activity::get_filter_sql( $filter ) )
    342360                        $where_conditions['filter_sql'] = $filter_sql;
    class BP_Activity_Activity { 
    465483                // Generate action strings
    466484                $activities = BP_Activity_Activity::generate_action_strings( $activities );
    467485
     486                // Append favorites
     487                $activities = self::append_favorites( $activities );
     488
    468489                // If $max is set, only return up to the max results
    469490                if ( !empty( $max ) ) {
    470491                        if ( (int) $total_activities > (int) $max )
    class BP_Activity_Activity { 
    644665
    645666                        // WP_Meta_Query expects the table name at
    646667                        // $wpdb->activitymeta
    647                         $wpdb->activitymeta = buddypress()->activity->table_name_meta;
     668                        if( ! empty( $activity_meta_query->queries[0]['key'] ) && 'user_favorites' == $activity_meta_query->queries[0]['key'] ) {
     669                                $wpdb->activitymeta = buddypress()->activity->table_name_favorites;
     670                        } else {
     671                                $wpdb->activitymeta = buddypress()->activity->table_name_meta;
     672                        }
    648673
    649674                        $meta_sql = $activity_meta_query->get_sql( 'activity', 'a', 'id' );
    650675
    651676                        // Strip the leading AND - BP handles it in get()
    652677                        $sql_array['where'] = preg_replace( '/^\sAND/', '', $meta_sql['where'] );
    653678                        $sql_array['join']  = $meta_sql['join'];
     679
     680                        if ( buddypress()->activity->table_name_favorites == $wpdb->activitymeta ) {
     681                                if ( 'EXISTS' == strtoupper( $activity_meta_query->queries[0]['compare'] ) ) {
     682                                        $sql_array['where'] = str_replace( "meta_key = 'user_favorites'", "user_id IS NOT NULL", $sql_array['where'] );
     683                                } else {
     684                                       
     685                                        $user_id = $activity_meta_query->queries[0]['value'];
     686                                       
     687                                        preg_match( '/CAST\((.*)meta_value(.*)[' .$user_id. ']\'\)/', $sql_array['where'], $matches );
     688                                       
     689                                        if ( ! empty( $matches[1] ) ) {
     690                                                $sql_array['where'] = $wpdb->prepare( "({$matches[1]}user_id = %d)", $user_id );
     691                                        }
     692                                }
     693                        }
    654694                }
    655695
    656696                return $sql_array;
    class BP_Activity_Activity { 
    837877
    838878                        // Delete all activity meta entries for activity items and activity comments
    839879                        BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
     880
     881                        // Delete all activity favorite entries for activity items and activity comments
     882                        BP_Activity_Activity::delete_activity_favorites( $activity_ids );
    840883                }
    841884
    842885                return $activity_ids;
    class BP_Activity_Activity { 
    12831326         * @return int A count of the user's favorites.
    12841327         */
    12851328        public static function total_favorite_count( $user_id ) {
    1286                 if ( !$favorite_activity_entries = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ) )
     1329                $favorite_activity_entries = self::get_favorites_by_user( $user_id );
     1330               
     1331                if ( empty( $favorite_activity_entries ) )
    12871332                        return 0;
    12881333
    1289                 return count( maybe_unserialize( $favorite_activity_entries ) );
     1334                return count( $favorite_activity_entries );
    12901335        }
    12911336
    12921337        /**
    class BP_Activity_Activity { 
    13121357
    13131358                return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
    13141359        }
     1360
     1361        /**
     1362         * Append user_ids who favorited activities.
     1363         *
     1364         * @since BuddyPress (2.1.0)
     1365         *
     1366         * @param array $activities Activities to fetch comments for.
     1367         * @param bool $spam Optional. 'ham_only' (default), 'spam_only' or 'all'.
     1368         * @return array The updated activities with nested comments.
     1369         */
     1370        public static function append_favorites( $activities = array() ) {
     1371                $user_favorites = array();
     1372
     1373                // Now fetch the user who favorited matching activities.
     1374                foreach ( (array) $activities as $key => $activity ) {
     1375                        $activities[$key]->user_favorites = self::get_user_favorites_by_activity( $activity->id );
     1376                }
     1377
     1378                return $activities;
     1379        }
     1380
     1381        /**
     1382         * Get users who favorited an activity.
     1383         *
     1384         * @since BuddyPress (2.1.0)
     1385         *
     1386         * @param int $activity_id.
     1387         * @return array $user_ids list of user ids
     1388         */
     1389        public static function get_user_favorites_by_activity( $activity_id = 0 ) {
     1390                global $wpdb;
     1391                $bp = buddypress();
     1392
     1393                $user_ids = array();
     1394
     1395                if ( empty( $activity_id ) )
     1396                        return $user_ids;
     1397
     1398                $user_ids = $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->activity->table_name_favorites} WHERE activity_id = %d", $activity_id ) );
     1399
     1400                return $user_ids;
     1401        }
     1402
     1403        /**
     1404         * Get user's favorites.
     1405         *
     1406         * @since BuddyPress (2.1.0)
     1407         *
     1408         * @param int $user_id.
     1409         * @return array $activity_ids list of activity ids
     1410         */
     1411        public static function get_favorites_by_user( $user_id = 0 ) {
     1412                global $wpdb;
     1413                $bp = buddypress();
     1414
     1415                $activity_ids = array();
     1416
     1417                if ( empty( $user_id ) )
     1418                        return $activity_ids;
     1419
     1420                $activity_ids = $wpdb->get_col( $wpdb->prepare( "SELECT activity_id FROM {$bp->activity->table_name_favorites} WHERE user_id = %d", $user_id ) );
     1421
     1422                return $activity_ids;
     1423        }
     1424
     1425        /**
     1426         * Save a user's favorite.
     1427         *
     1428         * @since BuddyPress (2.1.0)
     1429         *
     1430         * @param array $args.
     1431         * @return bool true\false
     1432         */
     1433        public static function save_favorite( $args = array() ) {
     1434                global $wpdb;
     1435                $bp = buddypress();
     1436
     1437                if ( empty( $args['activity_id'] ) || empty( $args['user_id'] ) )
     1438                        return false;
     1439
     1440                $saved = $wpdb->insert(
     1441                        buddypress()->activity->table_name_favorites,
     1442                        $args,
     1443                        array( '%d', '%d', '%s' )
     1444                );
     1445
     1446                return $saved;
     1447        }
     1448
     1449        /**
     1450         * Delete a user's favorite.
     1451         *
     1452         * @since BuddyPress (2.1.0)
     1453         *
     1454         * @param array $args.
     1455         * @return bool true\false
     1456         */
     1457        public static function delete_favorite( $args = array() ) {
     1458                global $wpdb;
     1459                $bp = buddypress();
     1460
     1461                if ( empty( $args['activity_id'] ) || empty( $args['user_id'] ) )
     1462                        return false;
     1463
     1464                $deleted = $wpdb->delete(
     1465                        buddypress()->activity->table_name_favorites,
     1466                        $args,
     1467                        array( '%d', '%d' )
     1468                );
     1469
     1470                return $deleted;
     1471        }
     1472
     1473        /**
     1474         * Delete favorites for one or more activities.
     1475         *
     1476         * @since BuddyPress (2.1.0)
     1477         *
     1478         * @param array $args.
     1479         * @return bool true\false
     1480         */
     1481        public static function delete_activity_favorites( $activity_ids = array() ) {
     1482                global $wpdb;
     1483                $bp = buddypress();
     1484
     1485                if ( empty( $activity_ids ) )
     1486                        return false;
     1487
     1488                $in = implode( ',', wp_parse_id_list( $activity_ids ) );
     1489
     1490                return $wpdb->query( "DELETE FROM {$bp->activity->table_name_favorites} WHERE activity_id IN ({$in})" );
     1491        }
    13151492}
    13161493
    13171494/**
  • 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..5f14587 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()
    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( $user_id );
    384384
    385385        return apply_filters( 'bp_activity_get_user_favorites', $favs );
    386386}
    function bp_activity_get_user_favorites( $user_id = 0 ) { 
    391391 * @since BuddyPress (1.2)
    392392 *
    393393 * @uses is_user_logged_in()
    394  * @uses bp_get_user_meta()
     394 * @uses bp_activity_get_user_favorites()
    395395 * @uses bp_activity_get_meta()
    396  * @uses bp_update_user_meta()
    397396 * @uses bp_activity_update_meta()
     397 * @uses bp_activity_add_meta()
    398398 * @uses do_action() To call the 'bp_activity_add_user_favorite' hook.
    399399 * @uses do_action() To call the 'bp_activity_add_user_favorite_fail' hook.
    400400 *
    function bp_activity_get_user_favorites( $user_id = 0 ) { 
    405405function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
    406406
    407407        // Favorite activity stream items are for logged in users only
    408         if ( !is_user_logged_in() )
     408        if ( ! is_user_logged_in() )
    409409                return false;
    410410
    411411        // Fallback to logged in user if no user_id is passed
    412412        if ( empty( $user_id ) )
    413413                $user_id = bp_loggedin_user_id();
    414414
    415         $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
     415        $my_favs = bp_activity_get_user_favorites( $user_id );
    416416        if ( empty( $my_favs ) || ! is_array( $my_favs ) ) {
    417417                $my_favs = array();
    418418        }
    function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { 
    422422                return false;
    423423        }
    424424
    425         // Add to user's favorites
    426         $my_favs[] = $activity_id;
    427 
    428425        // Update the total number of users who have favorited this activity
    429426        $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
    430427        $fav_count = !empty( $fav_count ) ? (int) $fav_count + 1 : 1;
    431428
    432         // Update user meta
    433         bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs );
     429        // Update activity meta counts for backcompat
     430        bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count );
    434431
    435         // Update activity meta counts
    436         if ( bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ) ) {
     432        if ( bp_activity_add_favorite( $activity_id, $user_id ) ) {
    437433
    438434                // Execute additional code
    439435                do_action( 'bp_activity_add_user_favorite', $activity_id, $user_id );
    function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { 
    456452 * @since BuddyPress (1.2)
    457453 *
    458454 * @uses is_user_logged_in()
    459  * @uses bp_get_user_meta()
     455 * @uses bp_activity_delete_meta()
    460456 * @uses bp_activity_get_meta()
    461457 * @uses bp_activity_update_meta()
    462458 * @uses bp_update_user_meta()
    function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) { 
    469465function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
    470466
    471467        // Favorite activity stream items are for logged in users only
    472         if ( !is_user_logged_in() )
     468        if ( ! is_user_logged_in() )
    473469                return false;
    474470
    475471        // Fallback to logged in user if no user_id is passed
    476472        if ( empty( $user_id ) )
    477473                $user_id = bp_loggedin_user_id();
    478474
    479         $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
    480         $my_favs = array_flip( (array) $my_favs );
     475        // Remove the user favorite
     476        $removed = bp_activity_remove_favorite( $activity_id, $user_id );
    481477
    482         // Bail if the user has not previously favorited the item
    483         if ( ! isset( $my_favs[ $activity_id ] ) ) {
     478        if ( empty( $removed ) ) {
    484479                return false;
    485480        }
    486481
    487         // Remove the fav from the user's favs
    488         unset( $my_favs[$activity_id] );
    489         $my_favs = array_unique( array_flip( $my_favs ) );
    490 
    491482        // Update the total number of users who have favorited this activity
    492         if ( $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' ) ) {
    493 
    494                 // Deduct from total favorites
    495                 if ( bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 ) ) {
    496 
    497                         // Update users favorites
    498                         if ( bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs ) ) {
    499 
    500                                 // Execute additional code
    501                                 do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id );
     483        $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
    502484
    503                                 // Success
    504                                 return true;
     485        // Error getting favorite count
     486        if ( empty( $fav_count ) ) {
     487                return false;
     488        }
    505489
    506                         // Error updating
    507                         } else {
    508                                 return false;
    509                         }
     490        // Deduct from total favorites
     491        $count_updated = bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 );
    510492
    511                 // Error updating favorite count
    512                 } else {
    513                         return false;
    514                 }
    515 
    516         // Error getting favorite count
    517         } else {
     493        // Error updating favorite count
     494        if ( empty( $count_updated ) ) {
    518495                return false;
    519496        }
     497
     498        // Execute additional code
     499        do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id );
     500
     501        return true;
    520502}
    521503
    522504/**
    function bp_activity_remove_all_user_data( $user_id = 0 ) { 
    708690        // Clear the user's activity from the sitewide stream and clear their activity tables
    709691        bp_activity_delete( array( 'user_id' => $user_id ) );
    710692
    711         // Remove any usermeta
    712         bp_delete_user_meta( $user_id, 'bp_latest_update' );
    713         bp_delete_user_meta( $user_id, 'bp_favorite_activities' );
    714 
    715693        // Execute additional code
    716694        do_action( 'bp_activity_remove_data', $user_id ); // Deprecated! Do not use!
    717695
    function bp_activity_do_heartbeat() { 
    19521930
    19531931        return $retval;
    19541932}
     1933
     1934/**
     1935 * Add a user's favorite
     1936 *
     1937 * @since BuddyPress (2.1.0)
     1938 *
     1939 * @param int $activity_id the activity to favorite
     1940 * @param int $user_id the user wishing to favorite the activity
     1941 * @uses  bp_parse_args()
     1942 * @uses  bp_loggedin_user_id()
     1943 * @uses  bp_core_current_time()
     1944 * @uses  BP_Activity_Activity::save_favorite()
     1945 * @return bool true|false
     1946 */
     1947function bp_activity_add_favorite( $activity_id = 0, $user_id = 0 ) {
     1948        // Bail if no activity id to favorite
     1949        if ( empty( $activity_id ) )
     1950                return false;
     1951
     1952        $r = bp_parse_args( array(
     1953                        'user_id'        => $user_id,
     1954                ),
     1955                array(
     1956                        'activity_id'    => $activity_id,
     1957                        'user_id'        => bp_loggedin_user_id(),
     1958                        'date_favorited' => bp_core_current_time(),
     1959        ), 'activity_add_favorite_args' );
     1960
     1961        return BP_Activity_Activity::save_favorite( $r );
     1962}
     1963
     1964/**
     1965 * Remove a user's favorite
     1966 *
     1967 * @since BuddyPress (2.1.0)
     1968 *
     1969 * @param int $activity_id the activity to favorite
     1970 * @param int $user_id the user wishing to favorite the activity
     1971 * @uses  bp_parse_args()
     1972 * @uses  bp_loggedin_user_id()
     1973 * @uses  BP_Activity_Activity::delete_favorite
     1974 * @return bool true|false
     1975 */
     1976function bp_activity_remove_favorite( $activity_id = 0, $user_id = 0 ) {
     1977        // Bail if no activity id to unfav
     1978        if ( empty( $activity_id ) )
     1979                return false;
     1980
     1981        $r = bp_parse_args( array(
     1982                        'user_id'        => $user_id,
     1983                ),
     1984                array(
     1985                        'activity_id'    => $activity_id,
     1986                        'user_id'        => bp_loggedin_user_id(),
     1987        ), 'activity_remove_favorite_args' );
     1988
     1989        return BP_Activity_Activity::delete_favorite( $r );
     1990}
     1991
     1992/**
     1993 * Add filters to list favorited activities to Show dropdowns.
     1994 *
     1995 * @since BuddyPress (2.1.0)
     1996 */
     1997function bp_activity_activity_favorite_filter_options() {
     1998        if ( bp_is_user() && bp_is_current_action( 'favorites' ) )
     1999                return;
     2000        ?>
     2001
     2002        <option value="user_favorites"><?php _e( 'Favorited Updates', 'buddypress' ) ?></option>
     2003
     2004        <?php
     2005}
     2006add_action( 'bp_activity_filter_options', 'bp_activity_activity_favorite_filter_options' );
     2007add_action( 'bp_member_activity_filter_options', 'bp_activity_activity_favorite_filter_options' );
     2008add_action( 'bp_group_activity_filter_options', 'bp_activity_activity_favorite_filter_options' );
     2009
     2010/**
     2011 * Migrate user's favorite previously in bp_favorite_activities user meta to new table
     2012 *
     2013 * @since BuddyPress (2.1.0)
     2014 */
     2015function bp_activity_favorites_migrate() {
     2016        global $wpdb;
     2017
     2018        $user_favorites = $wpdb->get_results( "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = 'bp_favorite_activities'" );
     2019       
     2020        foreach( $user_favorites as $meta ) {
     2021                $meta_value = maybe_unserialize( $meta->meta_value );
     2022
     2023                if ( empty( $meta_value ) )
     2024                        continue;
     2025
     2026                foreach( $meta_value as $favorite ) {
     2027                        bp_activity_add_favorite( $favorite, $meta->user_id );
     2028                }
     2029
     2030        }
     2031}
  • 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..32aabaa 100644
    class BP_Activity_Component extends BP_Component { 
    9191
    9292                // Global tables for activity component
    9393                $global_tables = array(
    94                         'table_name'      => $bp->table_prefix . 'bp_activity',
    95                         'table_name_meta' => $bp->table_prefix . 'bp_activity_meta',
     94                        'table_name'           => $bp->table_prefix . 'bp_activity',
     95                        'table_name_meta'      => $bp->table_prefix . 'bp_activity_meta',
     96                        'table_name_favorites' => $bp->table_prefix . 'bp_activity_favorites',
    9697                );
    9798
    9899                // Metadata tables for groups component
  • src/bp-activity/bp-activity-template.php

    diff --git src/bp-activity/bp-activity-template.php src/bp-activity/bp-activity-template.php
    index 834e4a6..f90a920 100644
    class BP_Activity_Template { 
    184184                // Check if blog/forum replies are disabled
    185185                $this->disable_blogforum_replies = isset( $bp->site_options['bp-disable-blogforum-comments'] ) ? $bp->site_options['bp-disable-blogforum-comments'] : false;
    186186
    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 
    190187                // Fetch specific activity items based on ID's
    191188                if ( !empty( $include ) ) {
    192189                        $this->activities = bp_activity_get_specific( array(
    function bp_has_activities( $args = '' ) { 
    610607                                        }
    611608                                        break;
    612609                                case 'favorites':
    613                                         $favs = bp_activity_get_user_favorites( $user_id );
    614                                         if ( empty( $favs ) )
    615                                                 return false;
    616 
    617                                         $in = implode( ',', (array) $favs );
     610                                        $action = 'user_favorites';
    618611                                        $display_comments = true;
    619                                         $user_id = 0;
    620612                                        break;
    621613                                case 'mentions':
    622614
    function bp_activity_is_favorite() { 
    17511743        function bp_get_activity_is_favorite() {
    17521744                global $activities_template;
    17531745
    1754                 return apply_filters( 'bp_get_activity_is_favorite', in_array( $activities_template->activity->id, (array) $activities_template->my_favs ) );
     1746                return apply_filters( 'bp_get_activity_is_favorite', in_array( bp_loggedin_user_id(), (array) $activities_template->activity->user_favorites ) );
    17551747        }
    17561748
    17571749/**
    function bp_total_favorite_count_for_user( $user_id = 0 ) { 
    27372729        }
    27382730        add_filter( 'bp_get_total_favorite_count_for_user', 'bp_core_number_format' );
    27392731
     2732
     2733function bp_activity_get_favorite_count() {
     2734        global $activities_template;
     2735
     2736        $count = 0;
     2737
     2738        if ( ! empty( $activities_template->activity->user_favorites ) ) {
     2739                $count = count( (array) $activities_template->activity->user_favorites );
     2740        }
     2741
     2742        return apply_filters( 'bp_activity_get_favorite_count', $count );
     2743}
     2744
     2745
     2746function bp_activity_user_favorites() {
     2747        echo bp_get_activity_user_favorites();
     2748}
     2749
     2750        function bp_get_activity_user_favorites() {
     2751                global $activities_template;
     2752
     2753                if ( empty( $activities_template->activity->user_favorites ) ) {
     2754                        return;
     2755                }
     2756
     2757                $output = '<ul class="user-favorites-list">';
     2758
     2759                foreach( (array) $activities_template->activity->user_favorites as $user_id ) {
     2760                        $user_avatar = bp_core_fetch_avatar( array(
     2761                                'item_id' => $user_id,
     2762                                'object'  => 'user',
     2763                                'type'    => 'thumb',
     2764                                'width'   => 50,
     2765                                'height'  => 50,
     2766                                'html'    => true,
     2767                                'class'   => 'user-favorite-' . $user_id
     2768                        ) );
     2769                        $output .= '<li><a href="' . bp_core_get_userlink( $user_id, false, true ) .'">' . $user_avatar . '</a></li>';
     2770                }
     2771
     2772                $output .= '</ul>';
     2773
     2774                return apply_filters( 'bp_get_activity_user_favorites', $output, $activities_template->activity->id, $activities_template->activity->user_favorites );
     2775        }
     2776
     2777
     2778function bp_activity_interactions_nav() {
     2779        echo bp_get_activity_interactions_nav();
     2780}
     2781
     2782        function bp_get_activity_interactions_nav() {
     2783                global $activities_template;
     2784
     2785                if ( ( is_user_logged_in() && bp_activity_can_comment() ) || ( is_user_logged_in() && bp_activity_can_favorite() ) || bp_is_single_activity() ) {
     2786
     2787                        $class_nav = $class_favorite = '';
     2788                        $comments_count  = bp_activity_get_comment_count();
     2789                        $favorites_count = bp_activity_get_favorite_count();
     2790
     2791                        if ( 0 ==  $comments_count + $favorites_count )  {
     2792                                $class_nav = ' hide';
     2793                        }
     2794
     2795                        $output = '<ul class="activity-interactions-nav'. $class_nav .'">';
     2796                        $output .= '<li class="activity-interactions current"><a href="#" class="activity-comments-interaction">' .  sprintf( __( 'Replies <span>%s</span>', 'buddypress' ), $comments_count ) . '</a></li>';
     2797
     2798                        if ( 0 == $favorites_count ) {
     2799                                $class_favorite = ' hide';
     2800                        }
     2801
     2802                        $output .= '<li class="activity-interactions'. $class_favorite .'"><a href="#" class="activity-favorites-interaction">' .  sprintf( __( 'Favorites <span>%s</span>', 'buddypress' ), $favorites_count ) . '</a></li>';
     2803
     2804                        $output .= '</ul>';
     2805
     2806                } else {
     2807                        $output = false;
     2808                }
     2809
     2810                return apply_filters( 'bp_get_activity_interactions_nav', $output );
     2811        }
     2812
    27402813/**
    27412814 * Output the total mention count for a specified user.
    27422815 *
  • src/bp-core/admin/bp-core-schema.php

    diff --git src/bp-core/admin/bp-core-schema.php src/bp-core/admin/bp-core-schema.php
    index 106f628..5503171 100644
    function bp_core_install_activity_streams() { 
    125125                                KEY meta_key (meta_key)
    126126                           ) {$charset_collate};";
    127127
     128        $sql[] = "CREATE TABLE {$bp_prefix}bp_activity_favorites (
     129                                id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
     130                                activity_id bigint(20) NOT NULL,
     131                                user_id bigint(20) NOT NULL,
     132                                date_favorited datetime NOT NULL,
     133                                KEY activity_id (activity_id),
     134                                KEY user_id (user_id),
     135                                KEY date_favorited (date_favorited)
     136                        ) {$charset_collate};";
     137
    128138        dbDelta( $sql );
    129139}
    130140
  • 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..5671247 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() { 
    389394}
    390395
    391396/**
     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        /** Install activity tables for favorites table *********************/
     405
     406        bp_core_install_activity_streams();
     407
     408        /** Migrate favorites data ******************************************/
     409
     410        bp_activity_favorites_migrate();
     411}
     412
     413/**
    392414 * Redirect user to BP's What's New page on first page load after activation.
    393415 *
    394416 * @since BuddyPress (1.7.0)
  • src/bp-loader.php

    diff --git src/bp-loader.php src/bp-loader.php
    index 96e517f..42ce83a 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-members/bp-members-functions.php

    diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
    index eea5790..0e3efb3 100644
    function bp_update_user_last_activity( $user_id = 0, $time = '' ) { 
    938938        // As of BuddyPress 2.0, last_activity is no longer stored in usermeta.
    939939        // However, we mirror it there for backward compatibility. Do not use!
    940940        // Remove our warning and re-add.
    941         remove_filter( 'update_user_metadata', '_bp_update_user_meta_last_activity_warning', 10, 4 );
    942         remove_filter( 'get_user_metadata', '_bp_get_user_meta_last_activity_warning', 10, 3 );
     941        remove_filter( 'update_user_metadata', '_bp_update_user_meta_activity_warning', 10, 4 );
     942        remove_filter( 'get_user_metadata', '_bp_get_user_meta_activity_warning', 10, 3 );
    943943        update_user_meta( $user_id, 'last_activity', $time );
    944         add_filter( 'update_user_metadata', '_bp_update_user_meta_last_activity_warning', 10, 4 );
    945         add_filter( 'get_user_metadata', '_bp_get_user_meta_last_activity_warning', 10, 3 );
     944        add_filter( 'update_user_metadata', '_bp_update_user_meta_activity_warning', 10, 4 );
     945        add_filter( 'get_user_metadata', '_bp_get_user_meta_activity_warning', 10, 3 );
    946946
    947947        return BP_Core_User::update_last_activity( $user_id, $time );
    948948}
    949949
    950950/**
    951  * Backward compatibility for 'last_activity' usermeta fetching.
     951 * Backward compatibility for 'last_activity' && bp_favorite_activities usermeta fetching.
    952952 *
    953953 * In BuddyPress 2.0, user last_activity data was moved out of usermeta. For
    954954 * backward compatibility, we continue to mirror the data there. This function
    955955 * serves two purposes: it warns plugin authors of the change, and it returns
    956956 * the data from the proper location.
     957 *
     958 * In BuddyPress 2.1, bp_favorite_activities was also moved out of usermeta.
    957959 *
    958960 * @since BuddyPress (2.0.0)
    959961 *
    function bp_update_user_last_activity( $user_id = 0, $time = '' ) { 
    963965 * @param int $object_id ID of the user.
    964966 * @param string $meta_key Meta key being fetched.
    965967 */
    966 function _bp_get_user_meta_last_activity_warning( $retval, $object_id, $meta_key ) {
    967         static $warned;
     968function _bp_get_user_meta_activity_warning( $retval, $object_id, $meta_key ) {
     969        static $warned = array();
    968970
    969971        if ( 'last_activity' === $meta_key ) {
    970972                // Don't send the warning more than once per pageload
    971                 if ( empty( $warned ) ) {
     973                if ( empty( $warned['last_activity'] ) ) {
    972974                        _doing_it_wrong( 'get_user_meta( $user_id, \'last_activity\' )', __( 'User last_activity data is no longer stored in usermeta. Use bp_get_user_last_activity() instead.', 'buddypress' ), '2.0.0' );
    973                         $warned = 1;
     975                        $warned['last_activity'] = 1;
    974976                }
    975977
    976978                return bp_get_user_last_activity( $object_id );
    977979        }
    978980
     981        if ( 'bp_favorite_activities' === $meta_key ) {
     982                // Don't send the warning more than once per pageload
     983                if ( empty( $warned['bp_favorite_activities'] ) ) {
     984                        _doing_it_wrong( 'get_user_meta( $user_id, \'bp_favorite_activities\' )', __( 'User bp_favorite_activities data is no longer stored in usermeta. Use bp_activity_get_user_favorites() instead.', 'buddypress' ), '2.1.0' );
     985                        $warned['bp_favorite_activities'] = 1;
     986                }
     987
     988                return bp_activity_get_user_favorites( $object_id );
     989        }
     990
    979991        return $retval;
    980992}
    981 add_filter( 'get_user_metadata', '_bp_get_user_meta_last_activity_warning', 10, 3 );
     993add_filter( 'get_user_metadata', '_bp_get_user_meta_activity_warning', 10, 3 );
    982994
    983995/**
    984996 * Backward compatibility for 'last_activity' usermeta setting.
    add_filter( 'get_user_metadata', '_bp_get_user_meta_last_activity_warning', 10, 
    9971009 * @param string $meta_key Meta key being fetched.
    9981010 * @param string $meta_value Active time.
    9991011 */
    1000 function _bp_update_user_meta_last_activity_warning( $meta_id, $object_id, $meta_key, $meta_value ) {
     1012function _bp_update_user_meta_activity_warning( $meta_id, $object_id, $meta_key, $meta_value ) {
    10011013        if ( 'last_activity' === $meta_key ) {
    10021014                _doing_it_wrong( 'update_user_meta( $user_id, \'last_activity\' )', __( 'User last_activity data is no longer stored in usermeta. Use bp_update_user_last_activity() instead.', 'buddypress' ), '2.0.0' );
    10031015                bp_update_user_last_activity( $object_id, $meta_value );
    10041016        }
     1017
     1018        if ( 'bp_favorite_activities' === $meta_key ) {
     1019                _doing_it_wrong( 'update_user_meta( $user_id, \'bp_favorite_activities\' )', __( 'User bp_favorite_activities data is no longer stored in usermeta. Use bp_activity_add_user_favorite() or bp_activity_remove_user_favorite() instead.', 'buddypress' ), '2.1.0' );
     1020        }
    10051021}
    1006 add_filter( 'update_user_metadata', '_bp_update_user_meta_last_activity_warning', 10, 4 );
     1022add_filter( 'update_user_metadata', '_bp_update_user_meta_activity_warning', 10, 4 );
    10071023
    10081024/**
    10091025 * Get the last activity for a given user.
  • 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..5ecb49c 100644
    function bp_legacy_theme_mark_activity_favorite() { 
    919919        if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
    920920                return;
    921921
    922         if ( bp_activity_add_user_favorite( $_POST['id'] ) )
    923                 _e( 'Remove Favorite', 'buddypress' );
    924         else
    925                 _e( 'Favorite', 'buddypress' );
     922        $result = array();
     923        $user_id = bp_loggedin_user_id();
     924
     925        if ( bp_activity_add_user_favorite( $_POST['id'] ) ) {
     926                $result['button'] = __( 'Remove Favorite', 'buddypress' );
     927                $user_avatar = bp_core_fetch_avatar( array(
     928                        'item_id' => $user_id,
     929                        'object'  => 'user',
     930                        'type'    => 'thumb',
     931                        'width'   => 50,
     932                        'height'  => 50,
     933                        'html'    => true,
     934                        'class'   => 'user-favorite-' . $user_id
     935                ) );
     936                $result['avatar'] = '<li><a href="' . bp_core_get_userlink( $user_id, false, true ) .'">' . $user_avatar . '</a></li>';
     937        } else {
     938                $result['button'] = __( 'Favorite', 'buddypress' );
     939                $result['avatar'] = 0;
     940        }
    926941
    927         exit;
     942        exit( json_encode( $result ) );
    928943}
    929944
    930945/**
    function bp_legacy_theme_unmark_activity_favorite() { 
    938953        if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
    939954                return;
    940955
    941         if ( bp_activity_remove_user_favorite( $_POST['id'] ) )
    942                 _e( 'Favorite', 'buddypress' );
    943         else
    944                 _e( 'Remove Favorite', 'buddypress' );
     956        $result = array();
    945957
    946         exit;
     958        if ( bp_activity_remove_user_favorite( $_POST['id'] ) ){
     959                $result['button'] = __( 'Favorite', 'buddypress' );
     960                $result['avatar'] = bp_loggedin_user_id();
     961        } else {
     962                $result['button'] = __( 'Remove Favorite', 'buddypress' );
     963                $result['avatar'] = 0;
     964        }
     965
     966        exit( json_encode( $result ) );
    947967}
    948968
    949969/**
  • 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..9825c25 100644
     
    5555
    5656                                <?php if ( bp_activity_can_comment() ) : ?>
    5757
    58                                         <a href="<?php bp_activity_comment_link(); ?>" class="button acomment-reply bp-primary-action" id="acomment-comment-<?php bp_activity_id(); ?>"><?php printf( __( 'Comment <span>%s</span>', 'buddypress' ), bp_activity_get_comment_count() ); ?></a>
     58                                        <a href="<?php bp_activity_comment_link(); ?>" class="button acomment-reply bp-primary-action" id="acomment-comment-<?php bp_activity_id(); ?>"><?php esc_html_e( 'Comment', 'buddypress' ); ?></a>
    5959
    6060                                <?php endif; ?>
    6161
     
    8383
    8484        </div>
    8585
     86        <?php bp_activity_interactions_nav(); ?>
     87
    8688        <?php do_action( 'bp_before_activity_entry_comments' ); ?>
    8789
    8890        <?php if ( ( is_user_logged_in() && bp_activity_can_comment() ) || bp_is_single_activity() ) : ?>
     
    117119
    118120        <?php do_action( 'bp_after_activity_entry_comments' ); ?>
    119121
     122        <?php if ( ( is_user_logged_in() && bp_activity_can_favorite() ) || bp_is_single_activity() ) : ?>
     123
     124                <div class="activity-favorites">
     125
     126                        <?php bp_activity_user_favorites(); ?>
     127
     128                </div>
     129
     130        <?php endif; ?>
     131
     132        <?php do_action( 'bp_after_activity_entry_favorites' ); ?>
     133
    120134</li>
    121135
    122136<?php do_action( 'bp_after_activity_entry' ); ?>
  • 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 36a16c7..c0d7975 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 { 
    484485        color: inherit;
    485486}
    486487
     488
     489/*--------------------------------------------------------------
     4903.1.3 - Activity Favorites
     491--------------------------------------------------------------*/
     492#buddypress .activity-list li ul.activity-interactions-nav {
     493        list-style: none;
     494        margin: 20px 0 10px 70px;
     495        overflow: hidden; /* IE fix */
     496        position: relative;
     497        width: auto;
     498        clear: both;
     499}
     500
     501#buddypress .activity-list li ul.activity-interactions-nav.hide,
     502#buddypress .activity-list li ul.activity-interactions-nav li.hide {
     503        display:none;
     504}
     505
     506
     507#buddypress .activity-list li ul.activity-interactions-nav li {
     508        float: left;
     509        margin:0;
     510        padding: 4px 8px;
     511        font-size: 90%;
     512        border-bottom: none;
     513}
     514
     515#buddypress .activity-list li ul.activity-interactions-nav li a {
     516        text-decoration: none;
     517        color:#555;
     518}
     519
     520#buddypress .activity-list li ul.activity-interactions-nav li.current {
     521        background-color: #eee;
     522        color: #555;
     523        opacity: .8;
     524        font-weight: bold;
     525}
     526
     527#buddypress .activity-list li ul.activity-interactions-nav li.current span {
     528        background-color: #fff;
     529}
     530
     531#buddypress .activity-list li ul.activity-interactions-nav li span {
     532        background: #eee;
     533        border-radius: 50%;
     534        border: 1px solid #ccc;
     535        color: #999;
     536        display: inline;
     537        font-size: 70%;
     538        margin-left: 2px;
     539        padding: 3px 6px;
     540        text-align: center;
     541        vertical-align: middle;
     542}
     543
     544#buddypress div.activity-favorites {
     545        display:none;
     546        margin: 0 0 0 70px;
     547        overflow: hidden; /* IE fix */
     548        position: relative;
     549        width: auto;
     550        clear: both;
     551}
     552
     553#buddypress div.activity-favorites ul.user-favorites-list li {
     554        padding:0;
     555        float: left;
     556        border-bottom: none;
     557}
     558
     559#buddypress div.activity-favorites ul.user-favorites-list {
     560        overflow: hidden;
     561        list-style: none;
     562        width: auto;
     563        clear: both;
     564}
     565
     566#buddypress div.activity-favorites ul.user-favorites-list li img {
     567        border-width: 1px;
     568        float: left;
     569        height: 25px;
     570        margin-right: 10px;
     571        width: 25px;
     572}
     573
     574
    487575/*--------------------------------------------------------------
    4885763.3 - Directories - Members, Groups, Blogs, Forums
    489577--------------------------------------------------------------*/
  • 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 dd009ea..2a9d045 100644
    jq(document).ready( function() { 
    284284                                target.removeClass('loading');
    285285
    286286                                target.fadeOut( 200, function() {
    287                                         jq(this).html(response);
     287                                        jq(this).html(response['button']);
    288288                                        jq(this).attr('title', 'fav' === type ? BP_DTheme.remove_fav : BP_DTheme.mark_as_fav);
    289289                                        jq(this).fadeIn(200);
    290290                                });
    jq(document).ready( function() { 
    297297
    298298                                                jq('.item-list-tabs ul #activity-favorites span').html( Number( jq('.item-list-tabs ul #activity-favorites span').html() ) + 1 );
    299299                                        }
     300                                        jq('#activity-' + parent_id + ' ul.activity-interactions-nav').removeClass('hide');
     301                                        jq('#activity-' + parent_id + ' a.activity-favorites-interaction').parent().removeClass('hide');
     302                                        jq('#activity-' + parent_id + ' a.activity-favorites-interaction span').html( Number( jq('#activity-' + parent_id + ' a.activity-favorites-interaction span').html() ) + 1 );
     303
     304                                        if ( ! jq( '#activity-' + parent_id + ' .user-favorites-list' ).length ) {
     305                                                jq( '#activity-' + parent_id + ' .activity-favorites' ).append('<ul class="user-favorites-list"></ul>');
     306                                        }
     307
     308                                        if ( 0 != response['avatar'] ){
     309                                                jq( '#activity-' + parent_id + ' .user-favorites-list' ).append( response['avatar'] );
     310                                        }
    300311
    301312                                        target.removeClass('fav');
    302313                                        target.addClass('unfav');
    jq(document).ready( function() { 
    306317                                        target.addClass('fav');
    307318
    308319                                        jq('.item-list-tabs ul #activity-favorites span').html( Number( jq('.item-list-tabs ul #activity-favorites span').html() ) - 1 );
     320                                        jq('#activity-' + parent_id + ' a.activity-favorites-interaction span').html( Number( jq('#activity-' + parent_id + ' a.activity-favorites-interaction span').html() ) - 1 );
     321
     322                                        if ( jq( '#activity-' + parent_id + ' .user-favorites-list' ).length ) {
     323                                                jq( '#activity-' + parent_id + ' .user-favorites-list li' ).each( function() {
     324                                                        avatar = jq(this).find('img').prop( 'class' ).match( /user-favorite-([0-9]+)/ );
     325
     326                                                        if ( typeof avatar != 'undefined' && avatar[1] == response['avatar'] ) {
     327                                                                jq(this).remove();
     328                                                        }
     329                                                });
     330                                        }
    309331
    310332                                        if ( !Number( jq('.item-list-tabs ul #activity-favorites span').html() ) ) {
    311333                                                if ( jq('.item-list-tabs ul #activity-favorites').hasClass('selected') ) {
    jq(document).ready( function() { 
    319341                                if ( 'activity-favorites' === jq( '.item-list-tabs li.selected').attr('id') ) {
    320342                                        target.closest( '.activity-item' ).slideUp( 100 );
    321343                                }
    322                         });
     344                        }, 'json' );
    323345
    324346                        return false;
    325347                }
    jq(document).ready( function() { 
    459481                        // reset the newest activities now they're displayed
    460482                        newest_activities = '';
    461483                }
     484
     485                if ( target.parent().hasClass( 'activity-interactions' ) ) {
     486                       
     487                        event.preventDefault();
     488
     489                        var css_class = target.attr('class').split( ' ' ),
     490                                current_div = css_class[0].replace( '-interaction', '' ),
     491                                div_tohide = '',
     492                                parent_li = target.parent(),
     493                                parent_ul = parent_li.parent();
     494
     495                        parent_ul.children( 'li' ).each( function() {
     496                                jq( this ).removeClass( 'current' );
     497
     498                                if ( jq( this ).find('a').prop( 'class' ) != target.prop( 'class' ) ) {
     499                                        div_tohide = jq.trim( jq( this ).find('a').prop( 'class' ) ).replace( '-interaction', '' );
     500                                }
     501                        });
     502
     503                        jq( parent_li ).addClass( 'current' );
     504
     505                        if ( ! div_tohide.length )
     506                                return
     507                       
     508                        parent_ul.parent().find( '.' + div_tohide  ).first().hide();
     509                        parent_ul.parent().find( '.' + current_div  ).first().show();
     510                }
    462511        });
    463512
    464513        // Activity "Read More" links
    jq(document).ready( function() { 
    507556
    508557                /* Comment / comment reply links */
    509558                if ( target.hasClass('acomment-reply') || target.parent().hasClass('acomment-reply') ) {
     559
     560                        target.parent().parent().parent().find( '.activity-comments-interaction' ).first().trigger( 'click' );
     561
    510562                        if ( target.parent().hasClass('acomment-reply') ) {
    511563                                target = target.parent();
    512564                        }
    jq(document).ready( function() { 
    612664                                        jq( '#' + form.attr('id') + ' textarea').val('');
    613665
    614666                                        /* Increase the "Reply (X)" button count */
    615                                         jq('#activity-' + form_id[2] + ' a.acomment-reply span').html( Number( jq('#activity-' + form_id[2] + ' a.acomment-reply span').html() ) + 1 );
     667                                        jq('#activity-' + form_id[2] + ' ul.activity-interactions-nav').removeClass('hide');
     668                                        jq('#activity-' + form_id[2] + ' a.activity-comments-interaction span').html( Number( jq('#activity-' + form_id[2] + ' a.activity-comments-interaction span').html() ) + 1 );
    616669
    617670                                        // Increment the 'Show all x comments' string, if present
    618671                                        show_all_a = activity_comments.find('.show-all').find('a');