Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
11/13/2009 01:01:37 AM (17 years ago)
Author:
apeatling
Message:

Initial support for threaded activity stream commenting. Some major performance improvements around fetching profile and group data.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-activity/bp-activity-classes.php

    r2077 r2088  
    2626                $activity = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) );
    2727
    28                 $this->id = $activity->id;
    29                 $this->item_id = $activity->item_id;
    30                 $this->secondary_item_id = $activity->secondary_item_id;
    31                 $this->user_id = $activity->user_id;
    32                 $this->content = $activity->content;
    33                 $this->primary_link = $activity->primary_link;
    34                 $this->component_name = $activity->component_name;
    35                 $this->component_action = $activity->component_action;
    36                 $this->date_recorded = $activity->date_recorded;
    37                 $this->hide_sitewide = $activity->hide_sitewide;
     28                if ( $activity ) {
     29                        $this->id = $activity->id;
     30                        $this->item_id = $activity->item_id;
     31                        $this->secondary_item_id = $activity->secondary_item_id;
     32                        $this->user_id = $activity->user_id;
     33                        $this->content = $activity->content;
     34                        $this->primary_link = $activity->primary_link;
     35                        $this->component_name = $activity->component_name;
     36                        $this->component_action = $activity->component_action;
     37                        $this->date_recorded = $activity->date_recorded;
     38                        $this->hide_sitewide = $activity->hide_sitewide;
     39                }
    3840        }
    3941
     
    6365                        $this->primary_link = $bp->loggedin_user->domain;
    6466
    65                 if ( $existing_activity_id = $this->exists() )
    66                         BP_Activity_Activity::delete_by_activity_id( $existing_activity_id );
    67 
    6867                /* If we have an existing ID, update the activity item, otherwise insert it. */
    69                 if ( $this->id ) {
    70                         if ( $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET user_id = %d, component_name = %s, component_action = %s, content = %s, primary_link = %s, date_recorded = FROM_UNIXTIME(%d), item_id = %s, secondary_item_id = %s, hide_sitewide = %d WHERE id = %d", $this->user_id, $this->component_name, $this->component_action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->id ) ) ) {
    71                                 do_action( 'bp_activity_after_save', $this );
    72                                 return true;
    73                         }
    74                 } else {
    75                         if ( $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name} ( user_id, component_name, component_action, content, primary_link, date_recorded, item_id, secondary_item_id, hide_sitewide ) VALUES ( %d, %s, %s, %s, %s, FROM_UNIXTIME(%d), %s, %s, %d )", $this->user_id, $this->component_name, $this->component_action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide ) ) ) {
    76                                 do_action( 'bp_activity_after_save', $this );
    77                                 return true;
    78                         }
    79                 }
    80 
    81                 return false;
    82         }
    83 
    84         function exists() {
    85                 global $wpdb, $bp;
    86 
    87                 /* This doesn't seem to be working correctly at the moment, so it is disabled [TODO] */
    88                 return false;
    89 
    90                 /* If we have an item id, try and match on that, if not do a content match */
    91                 if ( $this->item_id ) {
    92                         if ( $this->secondary_item_id )
    93                                 $secondary_sql = $wpdb->prepare( " AND secondary_item_id = %s", $secondary_item_id );
    94 
    95                         return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE user_id = %d AND item_id = %s{$secondary_sql} AND component_name = %s AND component_action = %s", $this->user_id, $this->item_id, $this->component_name, $this->component_action ) );
    96                 } else {
    97                         return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE user_id = %d AND content = %s AND component_name = %s AND component_action = %s", $this->user_id, $this->content, $this->component_name, $this->component_action ) );
    98                 }
     68                if ( $this->id )
     69                        $q = $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET user_id = %d, component_name = %s, component_action = %s, content = %s, primary_link = %s, date_recorded = FROM_UNIXTIME(%d), item_id = %s, secondary_item_id = %s, hide_sitewide = %d WHERE id = %d", $this->user_id, $this->component_name, $this->component_action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->id );
     70                else
     71                        $q = $wpdb->prepare( "INSERT INTO {$bp->activity->table_name} ( user_id, component_name, component_action, content, primary_link, date_recorded, item_id, secondary_item_id, hide_sitewide ) VALUES ( %d, %s, %s, %s, %s, FROM_UNIXTIME(%d), %s, %s, %d )", $this->user_id, $this->component_name, $this->component_action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide );
     72
     73                if ( !$wpdb->query( $q ) )
     74                        return false;
     75
     76                $this->id = $wpdb->insert_id;
     77
     78                do_action( 'bp_activity_after_save', $this );
     79                return true;
    9980        }
    10081
     
    144125        }
    145126
    146         function get_activity_for_user( $user_id, $max_items, $limit, $page, $filter ) {
    147                 global $wpdb, $bp;
     127        function get_activity_for_user( $user_id, $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $search_terms = false, $filter = false, $display_comments = false ) {
     128                global $wpdb, $bp;
     129
     130                if ( $limit && $page )
     131                        $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
     132
     133                if ( $max )
     134                        $max_sql = $wpdb->prepare( "LIMIT %d", $max );
     135
     136                /* Searching */
     137                if ( $search_terms ) {
     138                        $search_terms = $wpdb->escape( $search_terms );
     139                        $search_sql = "AND content LIKE '%%" . like_escape( $search_terms ) . "%%'";
     140                }
     141
     142                /* Filtering */
     143                if ( $filter )
     144                        $filter_sql = BP_Activity_Activity::get_filter_sql( $filter );
     145
     146                /* Sorting */
     147                if ( $sort != 'ASC' && $sort != 'DESC' )
     148                        $sort = 'DESC';
     149
     150                /* Alter the query based on whether we want to show activity item comments in the stream like normal comments or threaded below the activity */
     151                if ( !$display_comments || 'threaded' == $display_comments ) {
     152                        if ( $per_page && $page && $max )
     153                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d {$search_sql} {$filter_sql} AND component_action != 'activity_comment' ORDER BY date_recorded {$sort} {$pag_sql}", $user_id ) );
     154                        else
     155                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d {$search_sql} {$filter_sql} AND component_action != 'activity_comment' ORDER BY date_recorded {$sort} {$pag_sql} {$max_sql}", $user_id ) );
     156
     157                        $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE user_id = %d {$search_sql} {$filter_sql} AND component_action != 'activity_comment' ORDER BY date_recorded {$sort} {$max_sql}", $user_id ) );
     158
     159                        if ( $activities && $display_comments )
     160                                $activities = BP_Activity_Activity::append_comments( &$activities );
     161                } else {
     162                        if ( $per_page && $page && $max )
     163                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d {$search_sql} {$filter_sql} ORDER BY date_recorded {$sort} {$pag_sql}", $user_id ) );
     164                        else
     165                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d {$search_sql} {$filter_sql} ORDER BY date_recorded {$sort} {$pag_sql} {$max_sql}", $user_id ) );
     166
     167                        $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE user_id = %d {$search_sql} {$filter_sql} ORDER BY date_recorded {$sort} {$max_sql}", $user_id ) );
     168
     169                        if ( $activities )
     170                                $activities = BP_Activity_Activity::append_comments( &$activities );
     171                }
     172
     173                return array( 'activities' => $activities, 'total' => (int)$total_activities );
     174        }
     175
     176        function get_activity_for_friends( $user_id, $max_items, $max_items_per_friend, $limit, $page, $filter ) {
     177                global $wpdb, $bp;
     178
     179                // TODO: Max items per friend not yet implemented.
     180
     181                if ( !function_exists('friends_get_friend_user_ids') )
     182                        return false;
    148183
    149184                if ( $limit && $page )
     
    157192                        $filter_sql = BP_Activity_Activity::get_filter_sql( $filter );
    158193
    159                 if ( $limit && $page && $max_items )
    160                         $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d $filter_sql ORDER BY date_recorded DESC $pag_sql", $user_id ) );
    161                 else
    162                         $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE user_id = %d $filter_sql ORDER BY date_recorded DESC $pag_sql $max_sql", $user_id ) );
    163 
    164                 $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE user_id = %d $filter_sql ORDER BY date_recorded DESC $max_sql", $user_id ) );
    165 
    166                 return array( 'activities' => $activities, 'total' => (int)$total_activities );
    167         }
    168 
    169         function get_activity_for_friends( $user_id, $max_items, $max_items_per_friend, $limit, $page, $filter ) {
    170                 global $wpdb, $bp;
    171 
    172                 // TODO: Max items per friend not yet implemented.
    173 
    174                 if ( !function_exists('friends_get_friend_user_ids') )
    175                         return false;
    176 
    177                 if ( $limit && $page )
    178                         $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
    179 
    180                 if ( $max_items )
    181                         $max_sql = $wpdb->prepare( "LIMIT %d", $max_items );
    182 
    183                 /* Sort out filtering */
    184                 if ( $filter )
    185                         $filter_sql = BP_Activity_Activity::get_filter_sql( $filter );
    186 
    187194                $friend_ids = friends_get_friend_user_ids( $user_id );
    188195
     
    190197                        return false;
    191198
    192                 $friend_ids = implode( ',', $friend_ids );
     199                $friend_ids = $wpdb->escape( implode( ',', $friend_ids ) );
    193200
    194201                if ( $limit && $page && $max_items )
     
    202209        }
    203210
    204         function get_sitewide_activity( $max, $limit, $page, $filter ) {
    205                 global $wpdb, $bp;
    206 
    207                 if ( $limit && $page )
    208                         $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) );
     211        function get_sitewide_activity( $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $search_terms = false, $filter = false, $display_comments = false ) {
     212                global $wpdb, $bp;
     213
     214                if ( $per_page && $page )
     215                        $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $per_page ), intval( $per_page ) );
    209216
    210217                if ( $max )
    211218                        $max_sql = $wpdb->prepare( "LIMIT %d", $max );
    212219
    213                 /* Sort out filtering */
     220                /* Searching */
     221                if ( $search_terms ) {
     222                        $search_terms = $wpdb->escape( $search_terms );
     223                        $search_sql = "AND content LIKE '%%" . like_escape( $search_terms ) . "%%'";
     224                }
     225
     226                /* Filtering */
    214227                if ( $filter )
    215228                        $filter_sql = BP_Activity_Activity::get_filter_sql( $filter );
    216229
    217                 if ( $limit && $page && $max )
    218                         $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 $filter_sql ORDER BY date_recorded DESC $pag_sql" ) );
     230                /* Sorting */
     231                if ( $sort != 'ASC' && $sort != 'DESC' )
     232                        $sort = 'DESC';
     233
     234                /* Alter the query based on whether we want to show activity item comments in the stream like normal comments or threaded below the activity */
     235                if ( !$display_comments || 'threaded' == $display_comments ) {
     236                        if ( $per_page && $page && $max )
     237                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 {$search_sql} {$filter_sql} AND component_action != 'activity_comment' ORDER BY date_recorded {$sort} {$pag_sql}" ) );
     238                        else
     239                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 {$search_sql} {$filter_sql} AND component_action != 'activity_comment' ORDER BY date_recorded {$sort} {$pag_sql} {$max_sql}" ) );
     240
     241                        $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 {$search_sql} {$filter_sql} AND component_action != 'activity_comment' ORDER BY date_recorded {$sort} {$max_sql}" ) );
     242
     243                        if ( $activities && $display_comments )
     244                                $activities = BP_Activity_Activity::append_comments( &$activities );
     245                } else {
     246                        if ( $per_page && $page && $max )
     247                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 {$search_sql} {$filter_sql} ORDER BY date_recorded {$sort} {$pag_sql}" ) );
     248                        else
     249                                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 {$search_sql} {$filter_sql} ORDER BY date_recorded {$sort} {$pag_sql} {$max_sql}" ) );
     250
     251                        $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 {$search_sql} {$filter_sql} ORDER BY date_recorded {$sort} {$max_sql}" ) );
     252
     253                        if ( $activities )
     254                                $activities = BP_Activity_Activity::append_comments( &$activities );
     255                }
     256
     257                return array( 'activities' => $activities, 'total' => (int)$total_activities );
     258        }
     259
     260        function get_specific( $activity_ids, $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $display_comments = false ) {
     261                global $wpdb, $bp;
     262
     263                if ( is_array( $activity_ids ) )
     264                        $activity_ids = implode( ',', $activity_ids );
     265
     266                $activity_ids = $wpdb->escape( $activity_ids );
     267
     268                if ( $per_page && $page )
     269                        $pag_sql = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $per_page ), intval( $per_page ) );
     270
     271                if ( $max )
     272                        $max_sql = $wpdb->prepare( "LIMIT %d", $max );
     273
     274                if ( $sort != 'ASC' && $sort != 'DESC' )
     275                        $sort = 'DESC';
     276
     277                $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$activity_ids}) ORDER BY date_recorded {$sort} $pag_sql $max_sql" ) );
     278                $total_activities = $wpdb->get_results( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE id IN ({$activity_ids}) ORDER BY date_recorded {$sort}" ) );
     279
     280                if ( $display_comments )
     281                        $activities = BP_Activity_Activity::append_comments( $activities );
     282
     283                return array( 'activities' => $activities, 'total' => (int)$total_activities );
     284        }
     285
     286        function append_comments( $activities ) {
     287                global $bp, $wpdb;
     288
     289                /* Now fetch the activity comments and parse them into the correct position in the activities array. */
     290                foreach( $activities as $activity ) {
     291                        if ( 'activity_comment' != $activity->component_action )
     292                                $activity_comments[$activity->id] = BP_Activity_Activity::get_activity_comments( $activity->id, $activity->mptt_left, $activity->mptt_right );
     293                }
     294
     295                /* Merge the comments with the activity items */
     296                foreach( $activities as $key => $activity )
     297                        $activities[$key]->children = $activity_comments[$activity->id];
     298
     299                return $activities;
     300        }
     301
     302        function get_activity_comments( $activity_id, $left, $right ) {
     303                global $wpdb, $bp;
     304
     305                /* Start with an empty $stack */
     306                $stack = array();
     307
     308                /* Retrieve all descendants of the $root node */
     309                $descendants = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE component_action = 'activity_comment' AND item_id = %d AND mptt_left BETWEEN %d AND %d", $activity_id, $left, $right ) );
     310
     311                /* Loop descendants and build an assoc array */
     312                foreach ( $descendants as $d ) {
     313                    $d->children = array();
     314
     315                        /* We have a reference on its parent */
     316                    if ( isset( $ref[ $d->secondary_item_id ] ) ) {
     317                        $ref[ $d->secondary_item_id ]->children[ $d->id ] = $d;
     318                        $ref[ $d->id ] =& $ref[ $d->secondary_item_id ]->children[ $d->id ];
     319
     320                        /* We don't have a reference on its parent, put it a root level */
     321                    } else {
     322                        $menu[ $d->id ] = $d;
     323                        $ref[ $d->id ] =& $menu[ $d->id ];
     324                    }
     325                }
     326
     327                return $menu;
     328        }
     329
     330        function rebuild_activity_comment_tree( $parent_id, $left = 1 ) {
     331                global $wpdb, $bp;
     332
     333                /* The right value of this node is the left value + 1 */
     334                $right = $left + 1;
     335
     336                /* Get all descendants of this node */
     337                $descendants = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE component_action = 'activity_comment' AND secondary_item_id = %d", $parent_id ) );
     338
     339                /* Loop the descendants and recalculate the left and right values */
     340                foreach ( $descendants as $descendant )
     341                        $right = BP_Activity_Activity::rebuild_activity_comment_tree( $descendant->id, $right );
     342
     343                /* We've got the left value, and now that we've processed the children of this node we also know the right value */
     344                if ( 1 == $left )
     345                        $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE id = %d", $left, $right, $parent_id ) );
    219346                else
    220                         $activities = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 $filter_sql ORDER BY date_recorded DESC $pag_sql $max_sql" ) );
    221 
    222                 $total_activities = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$bp->activity->table_name} WHERE hide_sitewide = 0 $filter_sql ORDER BY date_recorded DESC $max_sql" ) );
    223 
    224                 return array( 'activities' => $activities, 'total' => (int)$total_activities );
     347                        $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE component_action = 'activity_comment' AND id = %d", $left, $right, $parent_id ) );
     348
     349                /* Return the right value of this node + 1 */
     350                return $right + 1;
    225351        }
    226352
     
    234360                global $wpdb, $bp;
    235361
    236                 $activities = bp_activity_get_sitewide_activity( $limit );
     362                $activities = bp_activity_get_sitewide( array( 'max' => $limit ) );
     363
    237364                for ( $i = 0; $i < count($activities); $i++ ) {
    238365                                $title = explode( '<span', $activities[$i]['content'] );
Note: See TracChangeset for help on using the changeset viewer.