<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[BuddyPress] [2231] trunk:
  Added activity meta support for plugins and total favorite count.</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd>2231</dd>
<dt>Author</dt> <dd>apeatling</dd>
<dt>Date</dt> <dd>2009-12-31 13:39:22 +0000 (Thu, 31 Dec 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>Added activity meta support for plugins and total favorite count. Moved favorite business functions back into the activity plugin. Renamed activity table, this will need testing.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkbpactivitybpactivityclassesphp">trunk/bp-activity/bp-activity-classes.php</a></li>
<li><a href="#trunkbpactivityphp">trunk/bp-activity.php</a></li>
<li><a href="#trunkbpblogsphp">trunk/bp-blogs.php</a></li>
<li><a href="#trunkbpgroupsphp">trunk/bp-groups.php</a></li>
<li><a href="#trunkbploaderphp">trunk/bp-loader.php</a></li>
<li><a href="#trunkbpthemesbpdefault_incajaxphp">trunk/bp-themes/bp-default/_inc/ajax.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkbpactivitybpactivityclassesphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-activity/bp-activity-classes.php (2230 => 2231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-activity/bp-activity-classes.php        2009-12-31 10:14:47 UTC (rev 2230)
+++ trunk/bp-activity/bp-activity-classes.php        2009-12-31 13:39:22 UTC (rev 2231)
</span><span class="lines">@@ -96,10 +96,17 @@
</span><span class="cx">                 /* Fetch the activity IDs so we can delete any comments for this activity item */
</span><span class="cx">                 $activity_ids = $wpdb-&gt;get_col( $wpdb-&gt;prepare( &quot;SELECT id FROM {$bp-&gt;activity-&gt;table_name} WHERE item_id = %s {$secondary_sql} AND component_name = %s {$component_action_sql} {$user_sql}&quot;, $item_id, $component_name ) );
</span><span class="cx"> 
</span><del>-                if ( $activity_ids )
</del><ins>+                if ( !$wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE item_id = %s {$secondary_sql} AND component_name = %s {$component_action_sql} {$user_sql}&quot;, $item_id, $component_name ) ) )
+                        return false;
+
+                if ( $activity_ids ) {
</ins><span class="cx">                         BP_Activity_Activity::delete_activity_item_comments( $activity_ids );
</span><ins>+                        BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
</ins><span class="cx"> 
</span><del>-                return $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE item_id = %s {$secondary_sql} AND component_name = %s {$component_action_sql} {$user_sql}&quot;, $item_id, $component_name ) );
</del><ins>+                        return $activity_ids;
+                }
+
+                return true;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         function delete_by_item_id( $item_id, $component_name, $component_action, $user_id = false, $secondary_item_id = false ) {
</span><span class="lines">@@ -109,22 +116,33 @@
</span><span class="cx">         function delete_by_activity_id( $activity_id ) {
</span><span class="cx">                 global $bp, $wpdb;
</span><span class="cx"> 
</span><ins>+                if ( !$wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE id = %d&quot;, $activity_id ) ) )
+                        return false;
+
</ins><span class="cx">                 /* Delete the comments for this activity ID */
</span><span class="cx">                 BP_Activity_Activity::delete_activity_item_comments( $activity_id );
</span><ins>+                BP_Activity_Activity::delete_activity_meta_entries( $activity_id );
</ins><span class="cx"> 
</span><del>-                return $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE id = %d&quot;, $activity_id ) );
</del><ins>+                return true;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         function delete_by_content( $user_id, $content, $component_name, $component_action ) {
</span><span class="cx">                 global $bp, $wpdb;
</span><span class="cx"> 
</span><span class="cx">                 /* Fetch the activity ID so we can delete any comments for this activity item */
</span><del>-                $activity_id = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT id FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d AND content = %s AND component_name = %s AND component_action = %s&quot;, $user_id, $content, $component_name, $component_action ) );
</del><ins>+                $activity_ids = $wpdb-&gt;get_col( $wpdb-&gt;prepare( &quot;SELECT id FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d AND content = %s AND component_name = %s AND component_action = %s&quot;, $user_id, $content, $component_name, $component_action ) );
</ins><span class="cx"> 
</span><del>-                if ( $activity_id )
-                        BP_Activity_Activity::delete_activity_item_comments( $activity_id );
</del><ins>+                if ( !$wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d AND content = %s AND component_name = %s AND component_action = %s&quot;, $user_id, $content, $component_name, $component_action ) ) )
+                        return false;
</ins><span class="cx"> 
</span><del>-                return $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d AND content = %s AND component_name = %s AND component_action = %s&quot;, $user_id, $content, $component_name, $component_action ) );
</del><ins>+                if ( $activity_ids ) {
+                        BP_Activity_Activity::delete_activity_item_comments( $activity_ids );
+                        BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
+
+                        return $activity_ids;
+                }
+
+                return true;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         function delete_for_user_by_component( $user_id, $component_name ) {
</span><span class="lines">@@ -133,10 +151,17 @@
</span><span class="cx">                 /* Fetch the activity IDs so we can delete any comments for this activity item */
</span><span class="cx">                 $activity_ids = $wpdb-&gt;get_col( $wpdb-&gt;prepare( &quot;SELECT id FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d AND component_name = %s&quot;, $user_id, $component_name ) );
</span><span class="cx"> 
</span><del>-                if ( $activity_ids )
</del><ins>+                if ( !$wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d AND component_name = %s&quot;, $user_id, $component_name ) ) )
+                        return false;
+
+                if ( $activity_ids ) {
</ins><span class="cx">                         BP_Activity_Activity::delete_activity_item_comments( $activity_ids );
</span><ins>+                        BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
</ins><span class="cx"> 
</span><del>-                return $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d AND component_name = %s&quot;, $user_id, $component_name ) );
</del><ins>+                        return $activity_ids;
+                }
+
+                return true;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         function delete_for_user( $user_id ) {
</span><span class="lines">@@ -145,10 +170,15 @@
</span><span class="cx">                 /* Fetch the activity IDs so we can delete any comments for this activity item */
</span><span class="cx">                 $activity_ids = $wpdb-&gt;get_col( $wpdb-&gt;prepare( &quot;SELECT id FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d&quot;, $user_id ) );
</span><span class="cx"> 
</span><del>-                if ( $activity_ids )
</del><ins>+                if ( !$wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d&quot;, $user_id ) ) )
+                        return false;
+
+                if ( $activity_ids ) {
</ins><span class="cx">                         BP_Activity_Activity::delete_activity_item_comments( $activity_ids );
</span><ins>+                        BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
</ins><span class="cx"> 
</span><del>-                return $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE user_id = %d&quot;, $user_id ) );
</del><ins>+                        return $activity_ids;
+                }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         function delete_activity_item_comments( $activity_ids ) {
</span><span class="lines">@@ -162,6 +192,17 @@
</span><span class="cx">                 return $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name} WHERE component_action = 'activity_comment' AND item_id IN ({$activity_ids})&quot; ) );
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        function delete_activity_meta_entries( $activity_ids ) {
+                global $bp, $wpdb;
+
+                if ( is_array($activity_ids) )
+                        $activity_ids = implode( ',', $activity_ids );
+
+                $activity_ids = $wpdb-&gt;escape( $activity_ids );
+
+                return $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name_meta} WHERE activity_id IN ({$activity_ids})&quot; ) );
+        }
+
</ins><span class="cx">         function get( $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $search_terms = false, $filter = false, $display_comments = false, $show_hidden = false ) {
</span><span class="cx">                 global $wpdb, $bp;
</span><span class="cx"> 
</span><span class="lines">@@ -229,7 +270,7 @@
</span><span class="cx">                         $sort = 'DESC';
</span><span class="cx"> 
</span><span class="cx">                 $activities = $wpdb-&gt;get_results( $wpdb-&gt;prepare( &quot;SELECT * FROM {$bp-&gt;activity-&gt;table_name} WHERE id IN ({$activity_ids}) ORDER BY date_recorded {$sort} $pag_sql $max_sql&quot; ) );
</span><del>-                $total_activities = $wpdb-&gt;get_results( $wpdb-&gt;prepare( &quot;SELECT count(id) FROM {$bp-&gt;activity-&gt;table_name} WHERE id IN ({$activity_ids}) ORDER BY date_recorded {$sort}&quot; ) );
</del><ins>+                $total_activities = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT count(id) FROM {$bp-&gt;activity-&gt;table_name} WHERE id IN ({$activity_ids})&quot; ) );
</ins><span class="cx"> 
</span><span class="cx">                 if ( $display_comments )
</span><span class="cx">                         $activities = BP_Activity_Activity::append_comments( $activities );
</span></span></pre></div>
<a id="trunkbpactivityphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-activity.php (2230 => 2231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-activity.php        2009-12-31 10:14:47 UTC (rev 2230)
+++ trunk/bp-activity.php        2009-12-31 13:39:22 UTC (rev 2231)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> &lt;?php
</span><span class="cx"> 
</span><del>-define ( 'BP_ACTIVITY_DB_VERSION', '1900' );
</del><ins>+define ( 'BP_ACTIVITY_DB_VERSION', '2020' );
</ins><span class="cx"> 
</span><span class="cx"> /* Define the slug for the component */
</span><span class="cx"> if ( !defined( 'BP_ACTIVITY_SLUG' ) )
</span><span class="lines">@@ -16,6 +16,9 @@
</span><span class="cx">         if ( !empty($wpdb-&gt;charset) )
</span><span class="cx">                 $charset_collate = &quot;DEFAULT CHARACTER SET $wpdb-&gt;charset&quot;;
</span><span class="cx"> 
</span><ins>+        /* Rename the old user activity cached table if needed. */
+        $wpdb-&gt;query( &quot;RENAME TABLE {$wpdb-&gt;base_prefix}bp_activity_user_activity_cached TO {$bp-&gt;activity-&gt;table_name}&quot; );
+
</ins><span class="cx">         $sql[] = &quot;CREATE TABLE {$bp-&gt;activity-&gt;table_name} (
</span><span class="cx">                                   id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
</span><span class="cx">                                 user_id bigint(20) NOT NULL,
</span><span class="lines">@@ -35,16 +38,18 @@
</span><span class="cx">                                 KEY component_name (component_name)
</span><span class="cx">                             ) {$charset_collate};&quot;;
</span><span class="cx"> 
</span><ins>+        $sql[] = &quot;CREATE TABLE {$bp-&gt;activity-&gt;table_name_meta} (
+                                id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+                                activity_id bigint(20) NOT NULL,
+                                meta_key varchar(255) DEFAULT NULL,
+                                meta_value longtext DEFAULT NULL,
+                                KEY activity_id (activity_id),
+                                KEY meta_key (meta_key)
+                              ) {$charset_collate};&quot;;
+
</ins><span class="cx">         require_once( ABSPATH . 'wp-admin/upgrade-functions.php' );
</span><span class="cx">         dbDelta($sql);
</span><span class="cx"> 
</span><del>-        /* Drop the old sitewide and user activity tables */
-        $wpdb-&gt;query( &quot;DROP TABLE IF EXISTS {$wpdb-&gt;base_prefix}bp_activity_user_activity&quot; );
-        $wpdb-&gt;query( &quot;DROP TABLE IF EXISTS {$wpdb-&gt;base_prefix}bp_activity_sitewide&quot; );
-
-        /* TODO: Rename the old user activity cached table */
-        //$wpdb-&gt;query( &quot;RENAME TABLE {$wpdb-&gt;base_prefix}bp_activity_user_activity_cached TO {$bp-&gt;activity-&gt;table_name}&quot; );
-
</del><span class="cx">         update_site_option( 'bp-activity-db-version', BP_ACTIVITY_DB_VERSION );
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -54,7 +59,8 @@
</span><span class="cx">         /* Internal identifier */
</span><span class="cx">         $bp-&gt;activity-&gt;id = 'activity';
</span><span class="cx"> 
</span><del>-        $bp-&gt;activity-&gt;table_name = $wpdb-&gt;base_prefix . 'bp_activity_user_activity_cached';
</del><ins>+        $bp-&gt;activity-&gt;table_name = $wpdb-&gt;base_prefix . 'bp_activity';
+        $bp-&gt;activity-&gt;table_name_meta = $wpdb-&gt;base_prefix . 'bp_activity_meta';
</ins><span class="cx">         $bp-&gt;activity-&gt;slug = BP_ACTIVITY_SLUG;
</span><span class="cx"> 
</span><span class="cx">         /* Register this in the active components array */
</span><span class="lines">@@ -377,9 +383,9 @@
</span><span class="cx"> function bp_activity_get_specific( $args = '' ) {
</span><span class="cx">         $defaults = array(
</span><span class="cx">                 'activity_ids' =&gt; false, // A single activity_id or array of IDs.
</span><del>-                'max' =&gt; false, // Maximum number of results to return
</del><span class="cx">                 'page' =&gt; 1, // page 1 without a per_page will result in no pagination.
</span><span class="cx">                 'per_page' =&gt; false, // results per page
</span><ins>+                'max' =&gt; false, // Maximum number of results to return
</ins><span class="cx">                 'sort' =&gt; 'DESC', // sort ASC or DESC
</span><span class="cx">                 'display_comments' =&gt; false // true or false to display threaded comments for these specific activity items
</span><span class="cx">         );
</span><span class="lines">@@ -480,7 +486,20 @@
</span><span class="cx">         return $comment_id;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-/* There are multiple ways to delete activity items, depending on the information you have at the time. */
</del><ins>+/***
+ * Deleting Activity
+ *
+ * There are multiple ways to delete activity items, depending on
+ * the information you have at the time.
+ *
+ * If you're looking to hook into one action that provides the ID(s) of
+ * the activity/activities deleted, then use:
+ *
+ * add_action( 'bp_activity_deleted_activities', 'my_function' );
+ *
+ * The action passes one parameter that is a single activity ID or an
+ * array of activity IDs depending on the number deleted.
+*/
</ins><span class="cx"> 
</span><span class="cx"> function bp_activity_delete_by_item_id( $args = '' ) {
</span><span class="cx">         global $bp;
</span><span class="lines">@@ -496,10 +515,11 @@
</span><span class="cx">         $r = wp_parse_args( $args, $defaults );
</span><span class="cx">         extract( $r, EXTR_SKIP );
</span><span class="cx"> 
</span><del>-        if ( !BP_Activity_Activity::delete_by_item_id( $item_id, $component_name, $component_action, $user_id, $secondary_item_id ) )
</del><ins>+        if ( !$activity_ids_deleted = BP_Activity_Activity::delete_by_item_id( $item_id, $component_name, $component_action, $user_id, $secondary_item_id ) )
</ins><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">         do_action( 'bp_activity_delete_by_item_id', $item_id, $component_name, $component_action, $user_id, $secondary_item_id );
</span><ins>+        do_action( 'bp_activity_deleted_activities', $activity_ids_deleted );
</ins><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="cx"> }
</span><span class="lines">@@ -509,6 +529,7 @@
</span><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">         do_action( 'bp_activity_delete_by_activity_id', $activity_id );
</span><ins>+        do_action( 'bp_activity_deleted_activities', $activity_id );
</ins><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="cx"> }
</span><span class="lines">@@ -517,19 +538,21 @@
</span><span class="cx">         /* Insert the &quot;time-since&quot; placeholder to match the existing content in the DB */
</span><span class="cx">         $content = bp_activity_add_timesince_placeholder( $content );
</span><span class="cx"> 
</span><del>-        if ( !BP_Activity_Activity::delete_by_content( $user_id, $content, $component_name, $component_action ) )
</del><ins>+        if ( !$activity_ids_deleted = BP_Activity_Activity::delete_by_content( $user_id, $content, $component_name, $component_action ) )
</ins><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">         do_action( 'bp_activity_delete_by_content', $user_id, $content, $component_name, $component_action );
</span><ins>+        do_action( 'bp_activity_deleted_activities', $activity_ids_deleted );
</ins><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function bp_activity_delete_for_user_by_component( $user_id, $component_name ) {
</span><del>-        if ( !BP_Activity_Activity::delete_for_user_by_component( $user_id, $component_name ) )
</del><ins>+        if ( !$activity_ids_deleted = BP_Activity_Activity::delete_for_user_by_component( $user_id, $component_name ) )
</ins><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">         do_action( 'bp_activity_delete_for_user_by_component', $user_id, $component_name );
</span><ins>+        do_action( 'bp_activity_deleted_activities', $activity_ids_deleted );
</ins><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="cx"> }
</span><span class="lines">@@ -595,6 +618,70 @@
</span><span class="cx">         return apply_filters( 'bp_activity_get_action', $bp-&gt;activity-&gt;actions-&gt;{$component_id}-&gt;{$key}, $component_id, $key );
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function bp_activity_get_user_favorites( $user_id ) {
+        global $bp;
+
+        $my_favs = maybe_unserialize( get_usermeta( $user_id, 'bp_favorite_activities' ) );
+        $existing_favs = bp_activity_get_specific( array( 'activity_ids' =&gt; $my_favs ) );
+
+        foreach( (array)$existing_favs['activities'] as $fav )
+                $new_favs[] = $fav-&gt;id;
+
+        $new_favs = array_unique( (array)$new_favs );
+        update_usermeta( $user_id, 'bp_favorite_activities', $new_favs );
+
+        return apply_filters( 'bp_activity_get_user_favorites', $new_favs );
+}
+
+function bp_activity_add_user_favorite( $activity_id, $user_id = false ) {
+        global $bp;
+
+        if ( !$user_id )
+                $user_id = $bp-&gt;loggedin_user-&gt;id;
+
+        /* Update the user's personal favorites */
+        $my_favs = maybe_unserialize( get_usermeta( $bp-&gt;loggedin_user-&gt;id, 'bp_favorite_activities' ) );
+        $my_favs[] = $_POST['id'];
+
+        /* Update the total number of users who have favorited this activity */
+        $fav_count = bp_activity_get_meta( $_POST['id'], 'favorite_count' );
+
+        if ( !empty( $fav_count ) )
+                $fav_count = (int)$fav_count + 1;
+        else
+                $fav_count = 1;
+
+        update_usermeta( $bp-&gt;loggedin_user-&gt;id, 'bp_favorite_activities', $my_favs );
+        bp_activity_update_meta( $_POST['id'], 'favorite_count', $fav_count );
+
+        return true;
+}
+
+function bp_activity_remove_user_favorite( $activity_id, $user_id = false ) {
+        global $bp;
+
+        if ( !$user_id )
+                $user_id = $bp-&gt;loggedin_user-&gt;id;
+
+        /* Remove the fav from the user's favs */
+        $my_favs = maybe_unserialize( get_usermeta( $user_id, 'bp_favorite_activities' ) );
+        $my_favs = array_flip( (array) $my_favs );
+        unset( $my_favs[$_POST['id']] );
+        $my_favs = array_unique( array_flip( $my_favs ) );
+
+        /* Update the total number of users who have favorited this activity */
+        $fav_count = bp_activity_get_meta( $_POST['id'], 'favorite_count' );
+
+        if ( !empty( $fav_count ) ) {
+                $fav_count = (int)$fav_count - 1;
+                bp_activity_update_meta( $_POST['id'], 'favorite_count', $fav_count );
+        }
+
+        update_usermeta( $user_id, 'bp_favorite_activities', $my_favs );
+
+        return true;
+}
+
</ins><span class="cx"> function bp_activity_check_exists_by_content( $content ) {
</span><span class="cx">         /* Insert the &quot;time-since&quot; placeholder to match the existing content in the DB */
</span><span class="cx">         $content = bp_activity_add_timesince_placeholder( $content );
</span><span class="lines">@@ -615,6 +702,100 @@
</span><span class="cx">         return BP_Activity_Activity::total_favorite_count( $user_id );
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+/********************************************************************************
+ * Activity Meta Functions
+ *
+ * Meta functions allow you to store extra data for a particular item.
+ */
+
+function bp_activity_delete_meta( $activity_id, $meta_key = false, $meta_value = false ) {
+        global $wpdb, $bp;
+
+        if ( !is_numeric( $activity_id ) )
+                return false;
+
+        $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
+
+        if ( is_array( $meta_value ) || is_object( $meta_value ) )
+                $meta_value = serialize( $meta_value );
+
+        $meta_value = trim( $meta_value );
+
+        if ( !$meta_key ) {
+                $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name_meta} WHERE activity_id = %d&quot;, $activity_id ) );
+        } else if ( $meta_value ) {
+                $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name_meta} WHERE activity_id = %d AND meta_key = %s AND meta_value = %s&quot;, $activity_id, $meta_key, $meta_value ) );
+        } else {
+                $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;DELETE FROM {$bp-&gt;activity-&gt;table_name_meta} WHERE activity_id = %d AND meta_key = %s&quot;, $activity_id, $meta_key ) );
+        }
+
+        wp_cache_delete( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, 'bp' );
+
+        return true;
+}
+
+function bp_activity_get_meta( $activity_id, $meta_key = '' ) {
+        global $wpdb, $bp;
+
+        $activity_id = (int)$activity_id;
+
+        if ( !$activity_id )
+                return false;
+
+        if ( !empty($meta_key) ) {
+                $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
+
+                if ( !$metas = wp_cache_get( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, 'bp' ) ) {
+                        $metas = $wpdb-&gt;get_col( $wpdb-&gt;prepare(&quot;SELECT meta_value FROM {$bp-&gt;activity-&gt;table_name_meta} WHERE activity_id = %d AND meta_key = %s&quot;, $activity_id, $meta_key ) );
+                        wp_cache_set( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, $metas, 'bp' );
+                }
+        } else
+                $metas = $wpdb-&gt;get_col( $wpdb-&gt;prepare( &quot;SELECT meta_value FROM {$bp-&gt;activity-&gt;table_name_meta} WHERE activity_id = %d&quot;, $activity_id ) );
+
+        if ( empty($metas) )
+                return false;
+
+        $metas = array_map( 'maybe_unserialize', $metas );
+
+        if ( 1 == count($metas) )
+                return $metas[0];
+        else
+                return $metas;
+}
+
+function bp_activity_update_meta( $activity_id, $meta_key, $meta_value ) {
+        global $wpdb, $bp;
+
+        if ( !is_numeric( $activity_id ) )
+                return false;
+
+        $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
+
+        if ( is_string( $meta_value ) )
+                $meta_value = stripslashes( $wpdb-&gt;escape( $meta_value ) );
+
+        $meta_value = maybe_serialize( $meta_value );
+
+        if ( empty( $meta_value ) ) {
+                return bp_activity_delete_meta( $activity_id, $meta_key );
+        }
+
+        $cur = $wpdb-&gt;get_row( $wpdb-&gt;prepare( &quot;SELECT * FROM {$bp-&gt;activity-&gt;table_name_meta} WHERE activity_id = %d AND meta_key = %s&quot;, $activity_id, $meta_key ) );
+
+        if ( !$cur ) {
+                $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;INSERT INTO {$bp-&gt;activity-&gt;table_name_meta} ( activity_id, meta_key, meta_value ) VALUES ( %d, %s, %s )&quot;, $activity_id, $meta_key, $meta_value ) );
+        } else if ( $cur-&gt;meta_value != $meta_value ) {
+                $wpdb-&gt;query( $wpdb-&gt;prepare( &quot;UPDATE {$bp-&gt;activity-&gt;table_name_meta} SET meta_value = %s WHERE activity_id = %d AND meta_key = %s&quot;, $meta_value, $activity_id, $meta_key ) );
+        } else {
+                return false;
+        }
+
+        wp_cache_replace( 'bp_activity_meta_' . $meta_key . '_' . $activity_id, $meta_value, 'bp' );
+
+        return true;
+}
+
+
</ins><span class="cx"> /**
</span><span class="cx">  * bp_activity_filter_template_paths()
</span><span class="cx">  *
</span></span></pre></div>
<a id="trunkbpblogsphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-blogs.php (2230 => 2231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-blogs.php        2009-12-31 10:14:47 UTC (rev 2230)
+++ trunk/bp-blogs.php        2009-12-31 13:39:22 UTC (rev 2231)
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx"> function bp_blogs_check_installed() {
</span><span class="cx">         global $wpdb, $bp, $userdata;
</span><span class="cx"> 
</span><del>-        if ( is_site_admin() ) {
</del><ins>+        if ( is_site_admin() &amp;&amp; bp_core_is_multiblog_install() ) {
</ins><span class="cx">                 /* Need to check db tables exist, activate hook no-worky in mu-plugins folder. */
</span><span class="cx">                 if ( get_site_option('bp-blogs-db-version') &lt; BP_BLOGS_DB_VERSION )
</span><span class="cx">                         bp_blogs_install();
</span></span></pre></div>
<a id="trunkbpgroupsphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-groups.php (2230 => 2231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-groups.php        2009-12-31 10:14:47 UTC (rev 2230)
+++ trunk/bp-groups.php        2009-12-31 13:39:22 UTC (rev 2231)
</span><span class="lines">@@ -65,30 +65,6 @@
</span><span class="cx">         require_once(ABSPATH . 'wp-admin/upgrade-functions.php');
</span><span class="cx">         dbDelta($sql);
</span><span class="cx"> 
</span><del>-        /* On upgrade, handle moving of old group avatars */
-        $groups = groups_get_all();
-
-        foreach ( $groups as $group ) {
-                /* Don't fetch and move gravs, default images or empties */
-                if ( empty($group-&gt;avatar_thumb) || strpos( $group-&gt;avatar_thumb, 'gravatar.com' ) || strpos( $group-&gt;avatar_thumb, 'identicon' ) || strpos( $group-&gt;avatar_thumb, 'none-thumbnail' ) )
-                        continue;
-
-                $start = strpos( $group-&gt;avatar_thumb, 'blogs.dir' );
-
-                if ( false !== $start ) {
-                        $avatar_thumb = WP_CONTENT_DIR . '/' . substr( $group-&gt;avatar_thumb, $start, strlen( $group-&gt;avatar_thumb ) );
-                        $avatar_full = WP_CONTENT_DIR . '/' . substr( $group-&gt;avatar_full, $start, strlen( $group-&gt;avatar_full ) );
-
-                        if ( !file_exists( $avatar_thumb ) || !file_exists( $avatar_full ) )
-                                continue;
-
-                        $upload_dir = groups_avatar_upload_dir( $group-&gt;id );
-
-                        copy( $avatar_thumb, $upload_dir['path'] . '/' . basename($avatar_thumb) );
-                        copy( $avatar_full, $upload_dir['path'] . '/' . basename($avatar_full) );
-                }
-        }
-
</del><span class="cx">         if ( function_exists('bp_wire_install') )
</span><span class="cx">                 groups_wire_install();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkbploaderphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-loader.php (2230 => 2231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-loader.php        2009-12-31 10:14:47 UTC (rev 2230)
+++ trunk/bp-loader.php        2009-12-31 13:39:22 UTC (rev 2231)
</span><span class="lines">@@ -4,12 +4,12 @@
</span><span class="cx"> Plugin URI: http://buddypress.org/download/
</span><span class="cx"> Description: BuddyPress will add social networking features to a new or existing WordPress MU installation.
</span><span class="cx"> Author: The BuddyPress Community
</span><del>-Version: 1.2-bleeding
</del><ins>+Version: 1.2-rare
</ins><span class="cx"> Author URI: http://buddypress.org/developers/
</span><span class="cx"> Site Wide Only: true
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-define( 'BP_VERSION', '1.2-bleeding' );
</del><ins>+define( 'BP_VERSION', '1.2-rare' );
</ins><span class="cx"> 
</span><span class="cx"> /***
</span><span class="cx">  * This file will load in each BuddyPress component based on which
</span><span class="lines">@@ -17,36 +17,36 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> require_once( WP_PLUGIN_DIR . '/buddypress/bp-core.php' );
</span><del>-$deactivated = apply_filters( 'bp_deactivated_components', get_site_option( 'bp-deactivated-components' ) );
</del><ins>+$bp_deactivated = apply_filters( 'bp_deactivated_components', get_site_option( 'bp-deactivated-components' ) );
</ins><span class="cx"> 
</span><span class="cx"> do_action( 'bp_core_loaded' );
</span><span class="cx"> 
</span><span class="cx"> /* Activity Streams */
</span><del>-if ( !isset( $deactivated['bp-activity.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-activity.php') )
</del><ins>+if ( !isset( $bp_deactivated['bp-activity.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-activity.php') )
</ins><span class="cx">         include( BP_PLUGIN_DIR . '/bp-activity.php' );
</span><span class="cx"> 
</span><span class="cx"> /* Blog Tracking */
</span><del>-if ( !isset( $deactivated['bp-blogs.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-blogs.php') )
</del><ins>+if ( !isset( $bp_deactivated['bp-blogs.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-blogs.php') )
</ins><span class="cx">         include( BP_PLUGIN_DIR . '/bp-blogs.php' );
</span><span class="cx"> 
</span><span class="cx"> /* bbPress Forum Integration */
</span><del>-if ( !isset( $deactivated['bp-forums.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-forums.php') )
</del><ins>+if ( !isset( $bp_deactivated['bp-forums.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-forums.php') )
</ins><span class="cx">         include( BP_PLUGIN_DIR . '/bp-forums.php' );
</span><span class="cx"> 
</span><span class="cx"> /* Friend Connections */
</span><del>-if ( !isset( $deactivated['bp-friends.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-friends.php') )
</del><ins>+if ( !isset( $bp_deactivated['bp-friends.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-friends.php') )
</ins><span class="cx">         include( BP_PLUGIN_DIR . '/bp-friends.php' );
</span><span class="cx"> 
</span><span class="cx"> /* Groups Support */
</span><del>-if ( !isset( $deactivated['bp-groups.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-groups.php') )
</del><ins>+if ( !isset( $bp_deactivated['bp-groups.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-groups.php') )
</ins><span class="cx">         include( BP_PLUGIN_DIR . '/bp-groups.php' );
</span><span class="cx"> 
</span><span class="cx"> /* Private Messaging */
</span><del>-if ( !isset( $deactivated['bp-messages.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-messages.php') )
</del><ins>+if ( !isset( $bp_deactivated['bp-messages.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-messages.php') )
</ins><span class="cx">         include( BP_PLUGIN_DIR . '/bp-messages.php' );
</span><span class="cx"> 
</span><span class="cx"> /* Extended Profiles */
</span><del>-if ( !isset( $deactivated['bp-xprofile.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-xprofile.php') )
</del><ins>+if ( !isset( $bp_deactivated['bp-xprofile.php'] ) &amp;&amp; file_exists( BP_PLUGIN_DIR . '/bp-xprofile.php') )
</ins><span class="cx">         include( BP_PLUGIN_DIR . '/bp-xprofile.php' );
</span><span class="cx"> 
</span><span class="cx"> do_action( 'bp_init' );
</span><span class="lines">@@ -72,6 +72,7 @@
</span><span class="cx">         delete_site_option( 'bp-groups-db-version' );
</span><span class="cx">         delete_site_option( 'bp-messages-db-version' );
</span><span class="cx">         delete_site_option( 'bp-xprofile-db-version' );
</span><ins>+        delete_site_option( 'bp-deactivated-components' );
</ins><span class="cx"> 
</span><span class="cx">         do_action( 'bp_loader_deactivate' );
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkbpthemesbpdefault_incajaxphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-themes/bp-default/_inc/ajax.php (2230 => 2231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-themes/bp-default/_inc/ajax.php        2009-12-31 10:14:47 UTC (rev 2230)
+++ trunk/bp-themes/bp-default/_inc/ajax.php        2009-12-31 13:39:22 UTC (rev 2231)
</span><span class="lines">@@ -299,7 +299,12 @@
</span><span class="cx">                                         $query_string = 'object=groups&amp;primary_id=' . $group_ids;
</span><span class="cx">                                         break;
</span><span class="cx">                                 case 'favorites':
</span><del>-                                        $favorite_ids = implode( ',', (array)get_usermeta( $bp-&gt;loggedin_user-&gt;id, 'bp_favorite_activities' ) );
</del><ins>+                                        $favs = bp_activity_get_user_favorites( $bp-&gt;loggedin_user-&gt;id );
+
+                                        if ( empty( $favs ) )
+                                                $favorite_ids = false;
+
+                                        $favorite_ids = implode( ',', (array)$favs );
</ins><span class="cx">                                         $query_string = 'include=' . $favorite_ids;
</span><span class="cx">                                         break;
</span><span class="cx">                         }
</span><span class="lines">@@ -356,11 +361,7 @@
</span><span class="cx"> function bp_dtheme_mark_activity_favorite() {
</span><span class="cx">         global $bp;
</span><span class="cx"> 
</span><del>-        $my_favs = maybe_unserialize( get_usermeta( $bp-&gt;loggedin_user-&gt;id, 'bp_favorite_activities' ) );
-        $my_favs[] = $_POST['id'];
-
-        update_usermeta( $bp-&gt;loggedin_user-&gt;id, 'bp_favorite_activities', $my_favs );
-
</del><ins>+        bp_activity_add_user_favorite( $_POST['id'] );
</ins><span class="cx">         _e( 'Remove Favorite', 'buddypress' );
</span><span class="cx"> }
</span><span class="cx"> add_action( 'wp_ajax_activity_mark_fav', 'bp_dtheme_mark_activity_favorite' );
</span><span class="lines">@@ -368,16 +369,7 @@
</span><span class="cx"> function bp_dtheme_unmark_activity_favorite() {
</span><span class="cx">         global $bp;
</span><span class="cx"> 
</span><del>-        $my_favs = maybe_unserialize( get_usermeta( $bp-&gt;loggedin_user-&gt;id, 'bp_favorite_activities' ) );
-        $new_favs = array();
-
-        foreach( (array)$my_favs as $fav ) {
-                if ( $fav != $_POST['id'] )
-                        $new_favs[] = $fav;
-        }
-
-        update_usermeta( $bp-&gt;loggedin_user-&gt;id, 'bp_favorite_activities', $new_favs );
-
</del><ins>+        bp_activity_remove_user_favorite( $_POST['id'] );
</ins><span class="cx">         _e( 'Favorite', 'buddypress' );
</span><span class="cx"> }
</span><span class="cx"> add_action( 'wp_ajax_activity_mark_unfav', 'bp_dtheme_unmark_activity_favorite' );
</span></span></pre>
</div>
</div>

</body>
</html>