Skip to:
Content

BuddyPress.org

Ticket #4393: bp-activity-functions.php

File bp-activity-functions.php, 54.5 KB (added by rachelbaker, 14 years ago)

Initial code to create array in activity meta for activity favorites

Line 
1<?php
2
3/**
4 * BuddyPress Activity Functions
5 *
6 * Functions for the Activity Streams component
7 *
8 * @package BuddyPress
9 * @subpackage ActivityFunctions
10 */
11
12// Exit if accessed directly
13if ( !defined( 'ABSPATH' ) ) exit;
14
15/**
16 * Checks $bp pages global and looks for directory page
17 *
18 * @since BuddyPress (1.5)
19 *
20 * @global object $bp BuddyPress global settings
21 *
22 * @return bool True if set, False if empty
23 */
24function bp_activity_has_directory() {
25        global $bp;
26
27        return (bool) !empty( $bp->pages->activity->id );
28}
29
30/**
31 * Searches through the content of an activity item to locate usernames, designated by an @ sign
32 *
33 * @since BuddyPress (1.5)
34 *
35 * @param string $content The content of the activity, usually found in $activity->content
36 *
37 * @return bool|array $usernames Array of the found usernames that match existing users. False if no matches
38 */
39function bp_activity_find_mentions( $content ) {
40        $pattern = '/[@]+([A-Za-z0-9-_\.@]+)\b/';
41        preg_match_all( $pattern, $content, $usernames );
42
43        // Make sure there's only one instance of each username
44        if ( !$usernames = array_unique( $usernames[1] ) )
45                return false;
46
47        return $usernames;
48}
49
50/**
51 * Resets a user's unread mentions list and count
52 *
53 * @since BuddyPress (1.5)
54 *
55 * @param int $user_id The id of the user whose unread mentions are being reset
56 * @uses bp_delete_user_meta()
57 */
58function bp_activity_clear_new_mentions( $user_id ) {
59        bp_delete_user_meta( $user_id, 'bp_new_mention_count' );
60        bp_delete_user_meta( $user_id, 'bp_new_mentions' );
61}
62
63/**
64 * Adjusts new mention count for mentioned users when activity items are deleted or created
65 *
66 * @since BuddyPress (1.5)
67 *
68 * @param int $activity_id The unique id for the activity item
69 * @param string $action Can be 'delete' or 'add'. Defaults to 'add'
70 *
71 * @uses BP_Activity_Activity() {@link BP_Activity_Activity}
72 * @uses bp_activity_find_mentions()
73 * @uses bp_is_username_compatibility_mode()
74 * @uses bp_core_get_userid_from_nicename()
75 * @uses bp_get_user_meta()
76 * @uses bp_update_user_meta()
77 */
78function bp_activity_adjust_mention_count( $activity_id, $action = 'add' ) {
79        $activity = new BP_Activity_Activity( $activity_id );
80
81        if ( $usernames = bp_activity_find_mentions( strip_tags( $activity->content ) ) ) {
82                foreach( (array) $usernames as $username ) {
83                        if ( bp_is_username_compatibility_mode() )
84                                $user_id = username_exists( $username );
85                        else
86                                $user_id = bp_core_get_userid_from_nicename( $username );
87
88                        if ( empty( $user_id ) )
89                                continue;
90
91                        // Adjust the mention list and count for the member
92                        $new_mention_count = (int)bp_get_user_meta( $user_id, 'bp_new_mention_count', true );
93                        if ( !$new_mentions = bp_get_user_meta( $user_id, 'bp_new_mentions', true ) )
94                                $new_mentions = array();
95
96                        switch ( $action ) {
97                                case 'delete' :
98                                        $key = array_search( $activity_id, $new_mentions );
99                                        if ( $key !== false ) {
100                                                unset( $new_mentions[$key] );
101                                        }
102                                        break;
103
104                                case 'add' :
105                                default :
106                                        if ( !in_array( $activity_id, $new_mentions ) ) {
107                                                $new_mentions[] = (int) $activity_id;
108                                        }
109                                        break;
110                        }
111
112                        // Get an updated mention count
113                        $new_mention_count = count( $new_mentions );
114
115                        // Resave the user_meta
116                        bp_update_user_meta( $user_id, 'bp_new_mention_count', $new_mention_count );
117                        bp_update_user_meta( $user_id, 'bp_new_mentions', $new_mentions );
118                }
119        }
120}
121
122/**
123 * Formats notifications related to activity
124 *
125 * @since BuddyPress (1.5)
126 *
127 * @param string $action The type of activity item. Just 'new_at_mention' for now
128 * @param int $item_id The activity id
129 * @param int $secondary_item_id In the case of at-mentions, this is the mentioner's id
130 * @param int $total_items The total number of notifications to format
131 * @param string $format 'string' to get a BuddyBar-compatible notification, 'array' otherwise
132 *
133 * @uses bp_loggedin_user_domain()
134 * @uses bp_get_activity_slug()
135 * @uses bp_core_get_user_displayname()
136 * @uses apply_filters() To call the 'bp_activity_multiple_at_mentions_notification' hook
137 * @uses apply_filters() To call the 'bp_activity_single_at_mentions_notification' hook
138 * @uses do_action() To call 'activity_format_notifications' hook
139 *
140 * @return string $return Formatted @mention notification
141 */
142function bp_activity_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
143
144        switch ( $action ) {
145                case 'new_at_mention':
146                        $activity_id      = $item_id;
147                        $poster_user_id   = $secondary_item_id;
148                        $at_mention_link  = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
149                        $at_mention_title = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
150
151                        if ( (int) $total_items > 1 ) {
152                                $text = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
153                                $filter = 'bp_activity_multiple_at_mentions_notification';
154                        } else {
155                                $user_fullname = bp_core_get_user_displayname( $poster_user_id );
156                                $text =  sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
157                                $filter = 'bp_activity_single_at_mentions_notification';
158                        }
159                break;
160        }
161
162        if ( 'string' == $format ) {
163                $return = apply_filters( $filter, '<a href="' . $at_mention_link . '" title="' . $at_mention_title . '">' . $text . '</a>', $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
164        } else {
165                $return = apply_filters( $filter, array(
166                        'text' => $text,
167                        'link' => $at_mention_link
168                ), $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
169        }
170
171        do_action( 'activity_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
172
173        return $return;
174}
175
176/** Actions ******************************************************************/
177
178/**
179 * Sets the current action for a given activity stream location
180 *
181 * @since BuddyPress (1.1)
182 *
183 * @param string $component_id
184 * @param string $key
185 * @param string $value
186 *
187 * @global object $bp BuddyPress global settings
188 * @uses apply_filters() To call the 'bp_activity_set_action' hook
189 *
190 * @return bool False if any param is empty, otherwise true
191 */
192function bp_activity_set_action( $component_id, $key, $value ) {
193        global $bp;
194
195        // Return false if any of the above values are not set
196        if ( empty( $component_id ) || empty( $key ) || empty( $value ) )
197                return false;
198
199        // Set activity action
200        if ( !isset( $bp->activity->actions ) || !is_object( $bp->activity->actions ) ) {
201                $bp->activity->actions = new stdClass;
202        }
203
204        if ( !isset( $bp->activity->actions->{$component_id} ) || !is_object( $bp->activity->actions->{$component_id} ) ) {
205                $bp->activity->actions->{$component_id} = new stdClass;
206        }
207
208        $bp->activity->actions->{$component_id}->{$key} = apply_filters( 'bp_activity_set_action', array(
209                'key'   => $key,
210                'value' => $value
211        ), $component_id, $key, $value );
212
213        return true;
214}
215
216/**
217 * Retreives the current action from a component and key
218 *
219 * @since BuddyPress (1.1)
220 *
221 * @param string $component_id
222 * @param string $key
223 *
224 * @global object $bp BuddyPress global settings
225 * @uses apply_filters() To call the 'bp_activity_get_action' hook
226 *
227 * @return mixed False on error, action on success
228 */
229function bp_activity_get_action( $component_id, $key ) {
230        global $bp;
231
232        // Return false if any of the above values are not set
233        if ( empty( $component_id ) || empty( $key ) )
234                return false;
235
236        return apply_filters( 'bp_activity_get_action', $bp->activity->actions->{$component_id}->{$key}, $component_id, $key );
237}
238
239/** Favorites ****************************************************************/
240
241/**
242 * Get a users favorite activity stream items
243 *
244 * @since BuddyPress (1.2)
245 *
246 * @param int $user_id
247 *
248 * @uses bp_get_user_meta()
249 * @uses apply_filters() To call the 'bp_activity_get_user_favorites' hook
250 *
251 * @return array Array of users favorite activity stream ID's
252 */
253function bp_activity_get_user_favorites( $user_id = 0 ) {
254
255        // Fallback to logged in user if no user_id is passed
256        if ( empty( $user_id ) )
257                $user_id = bp_displayed_user_id();
258
259        // Get favorites for user
260        $favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
261
262        return apply_filters( 'bp_activity_get_user_favorites', $favs );
263}
264
265/**
266 * Add an activity stream item as a favorite for a user
267 *
268 * @since BuddyPress (1.2)
269 *
270 * @param int $activity_id
271 * @param int $user_id
272 *
273 * @uses is_user_logged_in()
274 * @uses bp_get_user_meta()
275 * @uses bp_activity_get_meta()
276 * @uses bp_update_user_meta()
277 * @uses bp_activity_update_meta()
278 * @uses do_action() To call the 'bp_activity_add_user_favorite' hook
279 * @uses do_action() To call the 'bp_activity_add_user_favorite_fail' hook
280 *
281 * @return bool True on success, false on failure
282 */
283function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
284
285        // Favorite activity stream items are for logged in users only
286        if ( !is_user_logged_in() )
287                return false;
288
289        // Fallback to logged in user if no user_id is passed
290        if ( empty( $user_id ) )
291                $user_id = bp_loggedin_user_id();
292
293        // Update the user's personal favorites
294        $my_favs   = bp_get_user_meta( bp_loggedin_user_id(), 'bp_favorite_activities', true );
295        $my_favs[] = $activity_id;
296
297        // Update the total number of users who have favorited this activity
298        $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' );
299        $fav_count = !empty( $fav_count ) ? (int) $fav_count + 1 : 1;
300
301        // Update user meta
302        bp_update_user_meta( bp_loggedin_user_id(), 'bp_favorite_activities', $my_favs );
303
304        // Update activity meta counts
305        if ( true === bp_activity_update_meta( $activity_id, 'favorite_count', $fav_count ) ) {
306
307            // Update the users that favorited this activity
308        $favorited_users = bp_activity_get_meta( $activity_id, 'activity_favorited_users');
309        $favorited_users[] = $user_id;
310        bp_activity_update_meta( $activity_id, 'activity_favorited_users', $favorited_users );
311
312                // Execute additional code
313                do_action( 'bp_activity_add_user_favorite', $activity_id, $user_id );
314
315                // Success
316                return true;
317
318        // Saving meta was unsuccessful for an unknown reason
319        } else {
320                // Execute additional code
321                do_action( 'bp_activity_add_user_favorite_fail', $activity_id, $user_id );
322
323                return false;
324        }
325}
326
327/**
328 * Remove an activity stream item as a favorite for a user
329 *
330 * @since BuddyPress (1.2)
331 *
332 * @param int $activity_id
333 * @param int $user_id
334 *
335 * @uses is_user_logged_in()
336 * @uses bp_get_user_meta()
337 * @uses bp_activity_get_meta()
338 * @uses bp_activity_update_meta()
339 * @uses bp_update_user_meta()
340 * @uses do_action() To call the 'bp_activity_remove_user_favorite' hook
341 *
342 * @return bool True on success, false on failure
343 */
344function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
345
346        // Favorite activity stream items are for logged in users only
347        if ( !is_user_logged_in() )
348                return false;
349
350        // Fallback to logged in user if no user_id is passed
351        if ( empty( $user_id ) )
352                $user_id = bp_loggedin_user_id();
353
354        // Remove the fav from the user's favs
355        $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
356        $my_favs = array_flip( (array) $my_favs );
357        unset( $my_favs[$activity_id] );
358        $my_favs = array_unique( array_flip( $my_favs ) );
359
360        // Update the total number of users who have favorited this activity
361        if ( $fav_count = bp_activity_get_meta( $activity_id, 'favorite_count' ) ) {
362
363                // Deduct from total favorites
364                if ( bp_activity_update_meta( $activity_id, 'favorite_count', (int) $fav_count - 1 ) ) {
365
366                        // Update users favorites
367                        if ( bp_update_user_meta( $user_id, 'bp_favorite_activities', $my_favs ) ) {
368
369                                // Execute additional code
370                                do_action( 'bp_activity_remove_user_favorite', $activity_id, $user_id );
371
372                                // Success
373                                return true;
374
375                        // Error updating
376                        } else {
377                                return false;
378                        }
379
380                // Error updating favorite count
381                } else {
382                        return false;
383                }
384
385        // Error getting favorite count
386        } else {
387                return false;
388        }
389}
390
391/**
392 * Check if activity exists by scanning content
393 *
394 * @since BuddyPress (1.1)
395 *
396 * @param string $content
397 *
398 * @uses BP_Activity_Activity::check_exists_by_content() {@link BP_Activity_Activity}
399 * @uses apply_filters() To call the 'bp_activity_check_exists_by_content' hook
400 *
401 * @return bool
402 */
403function bp_activity_check_exists_by_content( $content ) {
404        return apply_filters( 'bp_activity_check_exists_by_content', BP_Activity_Activity::check_exists_by_content( $content ) );
405}
406
407/**
408 * Retrieve the last time activity was updated
409 *
410 * @since BuddyPress (1.0)
411 *
412 * @uses BP_Activity_Activity::get_last_updated() {@link BP_Activity_Activity}
413 * @uses apply_filters() To call the 'bp_activity_get_last_updated' hook
414 *
415 * @return string Date last updated
416 */
417function bp_activity_get_last_updated() {
418        return apply_filters( 'bp_activity_get_last_updated', BP_Activity_Activity::get_last_updated() );
419}
420
421/**
422 * Retrieve the number of favorite activity stream items a user has
423 *
424 * @since BuddyPress (1.2)
425 *
426 * @param int $user_id
427 *
428 * @uses BP_Activity_Activity::total_favorite_count() {@link BP_Activity_Activity}
429 *
430 * @return int Total favorite count
431 */
432function bp_activity_total_favorites_for_user( $user_id = 0 ) {
433
434        // Fallback on displayed user, and then logged in user
435        if ( empty( $user_id ) )
436                $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
437
438        return BP_Activity_Activity::total_favorite_count( $user_id );
439}
440
441/** Meta *********************************************************************/
442
443/**
444 * Delete a meta entry from the DB for an activity stream item
445 *
446 * @since BuddyPress (1.2)
447 *
448 * @param int $activity_id
449 * @param string $meta_key
450 * @param string $meta_value
451 *
452 * @global object $wpdb
453 * @global object $bp BuddyPress global settings
454 * @uses wp_cache_delete()
455 * @uses is_wp_error()
456 *
457 * @return bool True on success, false on failure
458 */
459function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = '' ) {
460        global $wpdb, $bp;
461
462        // Return false if any of the above values are not set
463        if ( !is_numeric( $activity_id ) )
464                return false;
465
466        // Sanitize key
467        $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
468
469        if ( is_array( $meta_value ) || is_object( $meta_value ) )
470                $meta_value = serialize( $meta_value );
471
472        // Trim off whitespace
473        $meta_value = trim( $meta_value );
474
475        // Delete all for activity_id
476        if ( empty( $meta_key ) )
477                $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
478
479        // Delete only when all match
480        else if ( $meta_value )
481                $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s AND meta_value = %s", $activity_id, $meta_key, $meta_value ) );
482
483        // Delete only when activity_id and meta_key match
484        else
485                $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
486
487        // Delete cache entry
488        wp_cache_delete( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' );
489
490        // Success
491        if ( !is_wp_error( $retval ) )
492                return true;
493
494        // Fail
495        else
496                return false;
497}
498
499/**
500 * Get activity meta
501 *
502 * @since BuddyPress (1.2)
503 *
504 * @param int $activity_id
505 * @param string $meta_key
506 *
507 * @global object $wpdb
508 * @global object $bp BuddyPress global settings
509 * @uses wp_cache_get()
510 * @uses wp_cache_set()
511 * @uses apply_filters() To call the 'bp_activity_get_meta' hook
512 *
513 * @return bool
514 */
515function bp_activity_get_meta( $activity_id = 0, $meta_key = '' ) {
516        global $wpdb, $bp;
517
518        // Make sure activity_id is valid
519        if ( empty( $activity_id ) || !is_numeric( $activity_id ) )
520                return false;
521
522        // We have a key to look for
523        if ( !empty( $meta_key ) ) {
524
525                // Sanitize key
526                $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
527
528                // Check cache
529                if ( !$metas = wp_cache_get( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' ) ) {
530                        // No cache so hit the DB
531                        $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
532
533                        // Set cache
534                        wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $metas, 'bp' );
535                }
536
537        // No key so get all for activity_id
538        } else {
539                $metas = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
540                               
541                if ( !empty( $metas ) ) {
542                        $metas = array_map( 'maybe_unserialize', (array) $metas );
543                       
544                        foreach( $metas as $mkey => $mvalue ) {
545                                wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $mkey, $mvalue, 'bp' );
546                        }
547                }
548        }
549       
550        // No result so return false
551        if ( empty( $metas ) )
552                return false;
553
554        // Maybe, just maybe... unserialize
555        $metas = array_map( 'maybe_unserialize', (array) $metas );
556
557        // Return first item in array if only 1, else return all metas found
558        $retval = ( 1 == count( $metas ) ? $metas[0] : $metas );
559
560        // Filter result before returning
561        return apply_filters( 'bp_activity_get_meta', $retval, $activity_id, $meta_key );
562}
563
564/**
565 * Update activity meta
566 *
567 * @since BuddyPress (1.2)
568 *
569 * @param int $activity_id
570 * @param string $meta_key
571 * @param string $meta_value
572 *
573 * @global object $wpdb
574 * @global object $bp BuddyPress global settings
575 * @uses maybe_serialize()
576 * @uses bp_activity_delete_meta()
577 * @uses wp_cache_set()
578 *
579 * @return bool True on success, false on failure
580 */
581function bp_activity_update_meta( $activity_id, $meta_key, $meta_value ) {
582        global $wpdb, $bp;
583
584        // Make sure activity_id is valid
585        if ( !is_numeric( $activity_id ) )
586                return false;
587
588        // Sanitize key
589        $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
590
591        // Sanitize value
592        if ( is_string( $meta_value ) )
593                $meta_value = stripslashes( $wpdb->escape( $meta_value ) );
594
595        // Maybe, just maybe... serialize
596        $meta_value = maybe_serialize( $meta_value );
597
598        // If value is empty, delete the meta key
599        if ( empty( $meta_value ) )
600                return bp_activity_delete_meta( $activity_id, $meta_key );
601
602        // See if meta key exists for activity_id
603        $cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
604
605        // Meta key does not exist so INSERT
606        if ( empty( $cur ) )
607                $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_meta} ( activity_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $activity_id, $meta_key, $meta_value ) );
608
609        // Meta key exists, so UPDATE
610        else if ( $cur->meta_value != $meta_value )
611                $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name_meta} SET meta_value = %s WHERE activity_id = %d AND meta_key = %s", $meta_value, $activity_id, $meta_key ) );
612
613        // Weirdness, so return false
614        else
615                return false;
616
617        // Set cache
618        wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $meta_value, 'bp' );
619
620        // Victory is ours!
621        return true;
622}
623
624/** Clean up *****************************************************************/
625
626/**
627 * Completely remove a user's activity data
628 *
629 * @since BuddyPress (1.5)
630 *
631 * @param int $user_id
632 *
633 * @uses is_user_logged_in()
634 * @uses bp_activity_delete()
635 * @uses bp_delete_user_meta()
636 * @uses do_action() To call the 'bp_activity_remove_data' hook
637 * @uses do_action() To call the 'bp_activity_remove_all_user_data' hook
638 */
639function bp_activity_remove_all_user_data( $user_id = 0 ) {
640
641        // Do not delete user data unless a logged in user says so
642        if ( empty( $user_id ) || !is_user_logged_in() )
643                return false;
644
645        // Clear the user's activity from the sitewide stream and clear their activity tables
646        bp_activity_delete( array( 'user_id' => $user_id ) );
647
648        // Remove any usermeta
649        bp_delete_user_meta( $user_id, 'bp_latest_update' );
650        bp_delete_user_meta( $user_id, 'bp_favorite_activities' );
651
652        // Execute additional code
653        do_action( 'bp_activity_remove_data', $user_id ); // Deprecated! Do not use!
654
655        // Use this going forward
656        do_action( 'bp_activity_remove_all_user_data', $user_id );
657}
658add_action( 'wpmu_delete_user',  'bp_activity_remove_all_user_data' );
659add_action( 'delete_user',       'bp_activity_remove_all_user_data' );
660
661/**
662 * Mark all of the user's activity as spam
663 *
664 * @global object $wpdb
665 * @global object $bp BuddyPress global settings
666 * @param int $user_id
667 * @since 1.6
668 */
669function bp_activity_spam_all_user_data( $user_id = 0 ) {
670        global $bp, $wpdb;
671
672        // Do not delete user data unless a logged in user says so
673        if ( empty( $user_id ) || ! is_user_logged_in() )
674                return false;
675
676        // Get all the user's activities.
677        $activities = bp_activity_get( array( 'display_comments' => 'stream', 'filter' => array( 'user_id' => $user_id ), 'show_hidden' => true, ) );
678
679        // Mark each as spam
680        foreach ( (array) $activities['activities'] as $activity ) {
681
682                // Create an activity object
683                $activity_obj = new BP_Activity_Activity;
684                foreach ( $activity as $k => $v )
685                        $activity_obj->$k = $v;
686
687                // Mark as spam
688                bp_activity_mark_as_spam( $activity_obj );
689
690                /*
691                 * If Akismet is present, update the activity history meta.
692                 *
693                 * This is usually taken care of when BP_Activity_Activity::save() happens, but
694                 * as we're going to be updating all the activity statuses directly, for efficency,
695                 * we need to update manually.
696                 */
697                if ( ! empty( $bp->activity->akismet ) )
698                        $bp->activity->akismet->update_activity_spam_meta( $activity_obj );
699
700                // Tidy up
701                unset( $activity_obj );
702        }
703
704        // Mark all of this user's activities as spam
705        $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET is_spam = 1 WHERE user_id = %d", $user_id ) );
706
707        // Call an action for plugins to use
708        do_action( 'bp_activity_spam_all_user_data', $user_id, $activities['activities'] );
709}
710add_action( 'bp_make_spam_user', 'bp_activity_spam_all_user_data' );
711
712/**
713 * Mark all of the user's activity as ham (not spam)
714 *
715 * @global object $wpdb
716 * @global object $bp BuddyPress global settings
717 * @param int $user_id
718 * @since 1.6
719 */
720function bp_activity_ham_all_user_data( $user_id = 0 ) {
721        global $bp, $wpdb;
722
723        // Do not delete user data unless a logged in user says so
724        if ( empty( $user_id ) || ! is_user_logged_in() )
725                return false;
726
727        // Get all the user's activities.
728        $activities = bp_activity_get( array( 'display_comments' => 'stream', 'filter' => array( 'user_id' => $user_id ), 'show_hidden' => true, 'spam' => 'all', ) );
729
730        // Mark each as not spam
731        foreach ( (array) $activities['activities'] as $activity ) {
732
733                // Create an activity object
734                $activity_obj = new BP_Activity_Activity;
735                foreach ( $activity as $k => $v )
736                        $activity_obj->$k = $v;
737
738                // Mark as not spam     
739                bp_activity_mark_as_ham( $activity_obj );
740
741                /*
742                 * If Akismet is present, update the activity history meta.
743                 *
744                 * This is usually taken care of when BP_Activity_Activity::save() happens, but
745                 * as we're going to be updating all the activity statuses directly, for efficency,
746                 * we need to update manually.
747                 */
748                if ( ! empty( $bp->activity->akismet ) )
749                        $bp->activity->akismet->update_activity_ham_meta( $activity_obj );
750
751                // Tidy up
752                unset( $activity_obj );
753        }
754
755        // Mark all of this user's activities as spam
756        $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET is_spam = 0 WHERE user_id = %d", $user_id ) );
757
758        // Call an action for plugins to use
759        do_action( 'bp_activity_ham_all_user_data', $user_id, $activities['activities'] );
760}
761add_action( 'bp_make_ham_user', 'bp_activity_ham_all_user_data' );
762
763/**
764 * Register the activity stream actions for updates
765 *
766 * @global object $bp BuddyPress global settings
767 * @since 1.6
768 */
769function bp_activity_register_activity_actions() {
770        global $bp;
771
772        bp_activity_set_action( $bp->activity->id, 'activity_update', __( 'Posted a status update', 'buddypress' ) );
773        bp_activity_set_action( $bp->activity->id, 'activity_comment', __( 'Replied to a status update', 'buddypress' ) );
774
775        do_action( 'bp_activity_register_activity_actions' );
776
777        // Backpat. Don't use this.
778        do_action( 'updates_register_activity_actions' );
779}
780add_action( 'bp_register_activity_actions', 'bp_activity_register_activity_actions' );
781
782/******************************************************************************
783 * Business functions are where all the magic happens in BuddyPress. They will
784 * handle the actual saving or manipulation of information. Usually they will
785 * hand off to a database class for data access, then return
786 * true or false on success or failure.
787 */
788
789/**
790 * Retrieve an activity or activities
791 *
792 * @since BuddyPress (1.2)
793 *
794 * @param array $args
795 *
796 * @uses wp_parse_args()
797 * @uses wp_cache_get()
798 * @uses wp_cache_set()
799 * @uses BP_Activity_Activity::get() {@link BP_Activity_Activity}
800 * @uses apply_filters_ref_array() To call the 'bp_activity_get' hook
801 *
802 * @return object $activity The activity/activities object
803 */
804function bp_activity_get( $args = '' ) {
805        $defaults = array(
806                'max'              => false,        // Maximum number of results to return
807                'page'             => 1,            // page 1 without a per_page will result in no pagination.
808                'per_page'         => false,        // results per page
809                'sort'             => 'DESC',       // sort ASC or DESC
810                'display_comments' => false,        // false for no comments. 'stream' for within stream display, 'threaded' for below each activity item
811
812                'search_terms'     => false,        // Pass search terms as a string
813                'show_hidden'      => false,        // Show activity items that are hidden site-wide?
814                'exclude'          => false,        // Comma-separated list of activity IDs to exclude
815                'in'               => false,        // Comma-separated list or array of activity IDs to which you want to limit the query
816                'spam'             => 'ham_only',   // 'ham_only' (default), 'spam_only' or 'all'.
817
818                /**
819                 * Pass filters as an array -- all filter items can be multiple values comma separated:
820                 * array(
821                 *      'user_id'      => false, // user_id to filter on
822                 *      'object'       => false, // object to filter on e.g. groups, profile, status, friends
823                 *      'action'       => false, // action to filter on e.g. activity_update, profile_updated
824                 *      'primary_id'   => false, // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
825                 *      'secondary_id' => false, // secondary object ID to filter on e.g. a post_id
826                 * );
827                 */
828                'filter' => array()
829        );
830        $r = wp_parse_args( $args, $defaults );
831        extract( $r, EXTR_SKIP );
832
833        // Attempt to return a cached copy of the first page of sitewide activity.
834        if ( 1 == (int) $page && empty( $max ) && empty( $search_terms ) && empty( $filter ) && empty( $exclude ) && empty( $in ) && 'DESC' == $sort && empty( $exclude ) && 'ham_only' == $spam ) {
835                if ( !$activity = wp_cache_get( 'bp_activity_sitewide_front', 'bp' ) ) {
836                        $args = array(
837                                'page'             => $page,
838                                'per_page'         => $per_page,
839                                'max'              => $max,
840                                'sort'             => $sort,
841                                'search_terms'     => $search_terms,
842                                'filter'           => $filter,
843                                'display_comments' => $display_comments,
844                                'show_hidden'      => $show_hidden,
845                                'spam'             => $spam
846                        );
847                        $activity = BP_Activity_Activity::get( $args );
848                        wp_cache_set( 'bp_activity_sitewide_front', $activity, 'bp' );
849                }
850
851        } else {
852                $args = array(
853                        'page'             => $page,
854                        'per_page'         => $per_page,
855                        'max'              => $max,
856                        'sort'             => $sort,
857                        'search_terms'     => $search_terms,
858                        'filter'           => $filter,
859                        'display_comments' => $display_comments,
860                        'show_hidden'      => $show_hidden,
861                        'exclude'          => $exclude,
862                        'in'               => $in,
863                        'spam'             => $spam
864                );
865                $activity = BP_Activity_Activity::get( $args );
866        }
867
868        return apply_filters_ref_array( 'bp_activity_get', array( &$activity, &$r ) );
869}
870
871/**
872 * Fetch specific activity items
873 *
874 * @since BuddyPress (1.2)
875 *
876 * @param array $args See docs for $defaults for details
877 *
878 * @uses wp_parse_args()
879 * @uses apply_filters() To call the 'bp_activity_get_specific' hook
880 * @uses BP_Activity_Activity::get() {@link BP_Activity_Activity}
881 *
882 * @return array The array returned by BP_Activity_Activity::get()
883 */
884function bp_activity_get_specific( $args = '' ) {
885        $defaults = array(
886                'activity_ids'     => false,       // A single activity_id or array of IDs.
887                'display_comments' => false,       // true or false to display threaded comments for these specific activity items
888                'max'              => false,       // Maximum number of results to return
889                'page'             => 1,           // page 1 without a per_page will result in no pagination.
890                'per_page'         => false,       // results per page
891                'show_hidden'      => true,        // When fetching specific items, show all
892                'sort'             => 'DESC',      // sort ASC or DESC
893                'spam'             => 'ham_only',  // Retrieve items marked as spam
894        );
895        $r = wp_parse_args( $args, $defaults );
896        extract( $r, EXTR_SKIP );
897
898        $get_args = array(
899                'page'             => $page,
900                'per_page'         => $per_page,
901                'max'              => $max,
902                'sort'             => $sort,
903                'display_comments' => $display_comments,
904                'show_hidden'      => $show_hidden,
905                'in'               => $activity_ids,
906                'spam'             => $spam
907        );
908        return apply_filters( 'bp_activity_get_specific', BP_Activity_Activity::get( $get_args ), $args, $get_args );
909}
910
911/**
912 * Add an activity item
913 *
914 * @since BuddyPress (1.1)
915 *
916 * @param array $args See docs for $defaults for details
917 *
918 * @uses wp_parse_args()
919 * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
920 * @uses BP_Activity_Activity::rebuild_activity_comment_tree() {@link BP_Activity_Activity}
921 * @uses wp_cache_delete()
922 * @uses do_action() To call the 'bp_activity_add' hook
923 *
924 * @return int The activity id
925 */
926function bp_activity_add( $args = '' ) {
927
928        $defaults = array(
929                'id'                => false, // Pass an existing activity ID to update an existing entry.
930
931                'action'            => '',    // The activity action - e.g. "Jon Doe posted an update"
932                'content'           => '',    // Optional: The content of the activity item e.g. "BuddyPress is awesome guys!"
933
934                'component'         => false, // The name/ID of the component e.g. groups, profile, mycomponent
935                'type'              => false, // The activity type e.g. activity_update, profile_updated
936                'primary_link'      => '',    // Optional: The primary URL for this item in RSS feeds (defaults to activity permalink)
937
938                'user_id'           => bp_loggedin_user_id(), // Optional: The user to record the activity for, can be false if this activity is not for a user.
939                'item_id'           => false, // Optional: The ID of the specific item being recorded, e.g. a blog_id
940                'secondary_item_id' => false, // Optional: A second ID used to further filter e.g. a comment_id
941                'recorded_time'     => bp_core_current_time(), // The GMT time that this activity was recorded
942                'hide_sitewide'     => false, // Should this be hidden on the sitewide activity stream?
943                'is_spam'           => false, // Is this activity item to be marked as spam?
944        );
945        $params = wp_parse_args( $args, $defaults );
946        extract( $params, EXTR_SKIP );
947
948        // Make sure we are backwards compatible
949        if ( empty( $component ) && !empty( $component_name ) )
950                $component = $component_name;
951
952        if ( empty( $type ) && !empty( $component_action ) )
953                $type = $component_action;
954
955        // Setup activity to be added
956        $activity                    = new BP_Activity_Activity( $id );
957        $activity->user_id           = $user_id;
958        $activity->component         = $component;
959        $activity->type              = $type;
960        $activity->action            = $action;
961        $activity->content           = $content;
962        $activity->primary_link      = $primary_link;
963        $activity->item_id           = $item_id;
964        $activity->secondary_item_id = $secondary_item_id;
965        $activity->date_recorded     = $recorded_time;
966        $activity->hide_sitewide     = $hide_sitewide;
967        $activity->is_spam           = $is_spam;
968
969        if ( !$activity->save() )
970                return false;
971
972        // If this is an activity comment, rebuild the tree
973        if ( 'activity_comment' == $activity->type )
974                BP_Activity_Activity::rebuild_activity_comment_tree( $activity->item_id );
975
976        wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
977        do_action( 'bp_activity_add', $params );
978
979        return $activity->id;
980}
981
982/**
983 * Post an activity update
984 *
985 * @since BuddyPress (1.2)
986 *
987 * @param array $args See docs for $defaults for details
988 *
989 * @global object $bp BuddyPress global settings
990 * @uses wp_parse_args()
991 * @uses bp_is_user_inactive()
992 * @uses bp_core_get_userlink()
993 * @uses bp_activity_add()
994 * @uses apply_filters() To call the 'bp_activity_new_update_action' hook
995 * @uses apply_filters() To call the 'bp_activity_new_update_content' hook
996 * @uses apply_filters() To call the 'bp_activity_new_update_primary_link' hook
997 * @uses bp_update_user_meta()
998 * @uses wp_filter_kses()
999 * @uses do_action() To call the 'bp_activity_posted_update' hook
1000 *
1001 * @return int $activity_id The activity id
1002 */
1003function bp_activity_post_update( $args = '' ) {
1004        global $bp;
1005
1006        $defaults = array(
1007                'content' => false,
1008                'user_id' => bp_loggedin_user_id()
1009        );
1010        $r = wp_parse_args( $args, $defaults );
1011        extract( $r, EXTR_SKIP );
1012
1013        if ( empty( $content ) || !strlen( trim( $content ) ) )
1014                return false;
1015
1016        if ( bp_is_user_inactive( $user_id ) )
1017                return false;
1018
1019        // Record this on the user's profile
1020        $from_user_link   = bp_core_get_userlink( $user_id );
1021        $activity_action  = sprintf( __( '%s posted an update', 'buddypress' ), $from_user_link );
1022        $activity_content = $content;
1023        $primary_link     = bp_core_get_userlink( $user_id, false, true );
1024
1025        // Now write the values
1026        $activity_id = bp_activity_add( array(
1027                'user_id'      => $user_id,
1028                'action'       => apply_filters( 'bp_activity_new_update_action', $activity_action ),
1029                'content'      => apply_filters( 'bp_activity_new_update_content', $activity_content ),
1030                'primary_link' => apply_filters( 'bp_activity_new_update_primary_link', $primary_link ),
1031                'component'    => $bp->activity->id,
1032                'type'         => 'activity_update'
1033        ) );
1034
1035        $activity_content = apply_filters( 'bp_activity_latest_update_content', $content ); 
1036
1037        // Add this update to the "latest update" usermeta so it can be fetched anywhere.
1038        bp_update_user_meta( bp_loggedin_user_id(), 'bp_latest_update', array( 'id' => $activity_id, 'content' => $content ) );
1039
1040        do_action( 'bp_activity_posted_update', $content, $user_id, $activity_id );
1041
1042        return $activity_id;
1043}
1044
1045/**
1046 * Add an activity comment
1047 *
1048 * @since BuddyPress (1.2)
1049 *
1050 * @param array $args See docs for $defaults for details
1051 *
1052 * @global object $bp BuddyPress global settings
1053 * @uses wp_parse_args()
1054 * @uses bp_activity_add()
1055 * @uses apply_filters() To call the 'bp_activity_comment_action' hook
1056 * @uses apply_filters() To call the 'bp_activity_comment_content' hook
1057 * @uses bp_activity_new_comment_notification()
1058 * @uses wp_cache_delete()
1059 * @uses do_action() To call the 'bp_activity_comment_posted' hook
1060 *
1061 * @return int $comment_id The comment id
1062 */
1063function bp_activity_new_comment( $args = '' ) {
1064        global $bp;
1065
1066        $defaults = array(
1067                'id'          => false,
1068                'content'     => false,
1069                'user_id'     => bp_loggedin_user_id(),
1070                'activity_id' => false, // ID of the root activity item
1071                'parent_id'   => false  // ID of a parent comment (optional)
1072        );
1073
1074        $params = wp_parse_args( $args, $defaults );
1075        extract( $params, EXTR_SKIP );
1076
1077        if ( empty( $content ) || empty( $user_id ) || empty( $activity_id ) )
1078                return false;
1079
1080        if ( empty( $parent_id ) )
1081                $parent_id = $activity_id;
1082
1083        // Check to see if the parent activity is hidden, and if so, hide this comment publically.
1084        $activity = new BP_Activity_Activity( $activity_id );
1085        $is_hidden = ( (int) $activity->hide_sitewide ) ? 1 : 0;
1086
1087        // Insert the activity comment
1088        $comment_id = bp_activity_add( array(
1089                'id'                => $id,
1090                'action'            => apply_filters( 'bp_activity_comment_action', sprintf( __( '%s posted a new activity comment', 'buddypress' ), bp_core_get_userlink( $user_id ) ) ),
1091                'content'           => apply_filters( 'bp_activity_comment_content', $content ),
1092                'component'         => $bp->activity->id,
1093                'type'              => 'activity_comment',
1094                'user_id'           => $user_id,
1095                'item_id'           => $activity_id,
1096                'secondary_item_id' => $parent_id,
1097                'hide_sitewide'     => $is_hidden
1098        ) );
1099
1100        // Send an email notification if settings allow
1101        bp_activity_new_comment_notification( $comment_id, $user_id, $params );
1102
1103        // Clear the comment cache for this activity
1104        wp_cache_delete( 'bp_activity_comments_' . $parent_id );
1105
1106        do_action( 'bp_activity_comment_posted', $comment_id, $params );
1107
1108        return $comment_id;
1109}
1110
1111/**
1112 * Fetch the activity_id for an existing activity entry in the DB.
1113 *
1114 * @since BuddyPress (1.2)
1115 *
1116 * @param array $args See docs for $defaults for details
1117 *
1118 * @uses wp_parse_args()
1119 * @uses apply_filters() To call the 'bp_activity_get_activity_id' hook
1120 * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
1121 *
1122 * @return int $activity_id The activity id
1123 */
1124function bp_activity_get_activity_id( $args = '' ) {
1125        $defaults = array(
1126                'user_id'           => false,
1127                'component'         => false,
1128                'type'              => false,
1129                'item_id'           => false,
1130                'secondary_item_id' => false,
1131                'action'            => false,
1132                'content'           => false,
1133                'date_recorded'     => false,
1134        );
1135
1136        $r = wp_parse_args( $args, $defaults );
1137        extract( $r, EXTR_SKIP );
1138
1139        return apply_filters( 'bp_activity_get_activity_id', BP_Activity_Activity::get_id( $user_id, $component, $type, $item_id, $secondary_item_id, $action, $content, $date_recorded ) );
1140}
1141
1142/**
1143 * Deleting Activity
1144 *
1145 * If you're looking to hook into one action that provides the ID(s) of
1146 * the activity/activities deleted, then use:
1147 *
1148 * add_action( 'bp_activity_deleted_activities', 'my_function' );
1149 *
1150 * The action passes one parameter that is a single activity ID or an
1151 * array of activity IDs depending on the number deleted.
1152 *
1153 * If you are deleting an activity comment please use bp_activity_delete_comment();
1154 *
1155 * @since BuddyPress (1.0)
1156 *
1157 * @param array $args See docs for $defaults for details
1158 *
1159 * @uses wp_parse_args()
1160 * @uses bp_activity_adjust_mention_count()
1161 * @uses BP_Activity_Activity::delete() {@link BP_Activity_Activity}
1162 * @uses do_action() To call the 'bp_before_activity_delete' hook
1163 * @uses bp_get_user_meta()
1164 * @uses bp_delete_user_meta()
1165 * @uses do_action() To call the 'bp_activity_delete' hook
1166 * @uses do_action() To call the 'bp_activity_deleted_activities' hook
1167 * @uses wp_cache_delete()
1168 *
1169 * @return bool True on success, false on failure
1170 */
1171function bp_activity_delete( $args = '' ) {
1172
1173        // Pass one or more the of following variables to delete by those variables
1174        $defaults = array(
1175                'id'                => false,
1176                'action'            => false,
1177                'content'           => false,
1178                'component'         => false,
1179                'type'              => false,
1180                'primary_link'      => false,
1181                'user_id'           => false,
1182                'item_id'           => false,
1183                'secondary_item_id' => false,
1184                'date_recorded'     => false,
1185                'hide_sitewide'     => false
1186        );
1187
1188        $args = wp_parse_args( $args, $defaults );
1189
1190        // Adjust the new mention count of any mentioned member
1191        bp_activity_adjust_mention_count( $args['id'], 'delete' );
1192
1193        if ( !$activity_ids_deleted = BP_Activity_Activity::delete( $args ) )
1194                return false;
1195
1196        // Check if the user's latest update has been deleted
1197        if ( empty( $args['user_id'] ) )
1198                $user_id = bp_loggedin_user_id();
1199        else
1200                $user_id = $args['user_id'];
1201
1202        do_action( 'bp_before_activity_delete', $args );
1203
1204        $latest_update = bp_get_user_meta( $user_id, 'bp_latest_update', true );
1205        if ( !empty( $latest_update ) ) {
1206                if ( in_array( (int) $latest_update['id'], (array) $activity_ids_deleted ) ) {
1207                        bp_delete_user_meta( $user_id, 'bp_latest_update' );
1208                }
1209        }
1210
1211        do_action( 'bp_activity_delete', $args );
1212        do_action( 'bp_activity_deleted_activities', $activity_ids_deleted );
1213
1214        wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
1215
1216        return true;
1217}
1218
1219        /**
1220         * Delete an activity item by activity id
1221         *
1222         * You should use bp_activity_delete() instead
1223         *
1224         * @since BuddyPress (1.1)
1225         * @deprecated BuddyPress (1.2)
1226         *
1227         * @param array $args See docs for $defaults for details
1228         *
1229         * @uses wp_parse_args()
1230         * @uses bp_activity_delete()
1231         *
1232         * @return bool True on success, false on failure
1233         */
1234        function bp_activity_delete_by_item_id( $args = '' ) {
1235
1236                $defaults = array(
1237                        'item_id'           => false,
1238                        'component'         => false,
1239                        'type'              => false,
1240                        'user_id'           => false,
1241                        'secondary_item_id' => false
1242                );
1243                $r = wp_parse_args( $args, $defaults );
1244                extract( $r, EXTR_SKIP );
1245
1246                return bp_activity_delete( array( 'item_id' => $item_id, 'component' => $component, 'type' => $type, 'user_id' => $user_id, 'secondary_item_id' => $secondary_item_id ) );
1247        }
1248
1249        /**
1250         * Delete an activity item by activity id
1251         *
1252         * You should use bp_activity_delete() instead
1253         *
1254         * @since BuddyPress (1.1)
1255         * @deprecated BuddyPress (1.2)
1256         *
1257         * @param int $activity_id The activity id
1258         *
1259         * @uses bp_activity_delete()
1260         *
1261         * @return bool True on success, false on failure
1262         */
1263        function bp_activity_delete_by_activity_id( $activity_id ) {
1264                return bp_activity_delete( array( 'id' => $activity_id ) );
1265        }
1266
1267        /**
1268         * Delete an activity item by it's content
1269         *
1270         * You should use bp_activity_delete() instead
1271         *
1272         * @since BuddyPress (1.1)
1273         * @deprecated BuddyPress (1.2)
1274         *
1275         * @param int $user_id The user id
1276         * @param string $content The activity id
1277         * @param string $component The activity component
1278         * @param string $type The activity type
1279         *
1280         * @uses bp_activity_delete()
1281         *
1282         * @return bool True on success, false on failure
1283         */
1284        function bp_activity_delete_by_content( $user_id, $content, $component, $type ) {
1285                return bp_activity_delete( array( 'user_id' => $user_id, 'content' => $content, 'component' => $component, 'type' => $type ) );
1286        }
1287
1288        /**
1289         * Delete a user's activity for a component
1290         *
1291         * You should use bp_activity_delete() instead
1292         *
1293         * @since BuddyPress (1.1)
1294         * @deprecated BuddyPress (1.2)
1295         *
1296         * @param int $user_id The user id
1297         * @param string $component The activity component
1298         *
1299         * @uses bp_activity_delete()
1300         *
1301         * @return bool True on success, false on failure
1302         */
1303        function bp_activity_delete_for_user_by_component( $user_id, $component ) {
1304                return bp_activity_delete( array( 'user_id' => $user_id, 'component' => $component ) );
1305        }
1306
1307/**
1308 * Delete an activity comment
1309 *
1310 * @since BuddyPress (1.2)
1311 *
1312 * @param int $activity_id The activity id
1313 * @param int $comment_id The activity comment id
1314 *
1315 * @uses apply_filters() To call the 'bp_activity_delete_comment_pre' hook
1316 * @uses bp_activity_delete_children()
1317 * @uses bp_activity_delete()
1318 * @uses BP_Activity_Activity::rebuild_activity_comment_tree() {@link BP_Activity_Activity}
1319 * @uses do_action() To call the 'bp_activity_delete_comment' hook
1320 *
1321 * @return bool True on success, false on failure
1322 */
1323function bp_activity_delete_comment( $activity_id, $comment_id ) {
1324        /***
1325         * You may want to hook into this filter if you want to override this function and
1326         * handle the deletion of child comments differently. Make sure you return false.
1327         */
1328        if ( !apply_filters( 'bp_activity_delete_comment_pre', true, $activity_id, $comment_id ) )
1329                return false;
1330
1331        // Delete any children of this comment.
1332        bp_activity_delete_children( $activity_id, $comment_id );
1333
1334        // Delete the actual comment
1335        if ( !bp_activity_delete( array( 'id' => $comment_id, 'type' => 'activity_comment' ) ) )
1336                return false;
1337
1338        // Recalculate the comment tree
1339        BP_Activity_Activity::rebuild_activity_comment_tree( $activity_id );
1340
1341        do_action( 'bp_activity_delete_comment', $activity_id, $comment_id );
1342
1343        return true;
1344}
1345
1346        /**
1347         * Delete an activity comment's children
1348         *
1349         * @since BuddyPress (1.2)
1350         *
1351         * @param int $activity_id The activity id
1352         * @param int $comment_id The activity comment id
1353         *
1354         * @uses BP_Activity_Activity::get_child_comments() {@link BP_Activity_Activity}
1355         * @uses bp_activity_delete_children()
1356         * @uses bp_activity_delete()
1357         */
1358        function bp_activity_delete_children( $activity_id, $comment_id) {
1359                // Recursively delete all children of this comment.
1360                if ( $children = BP_Activity_Activity::get_child_comments( $comment_id ) ) {
1361                        foreach( (array) $children as $child ) {
1362                                bp_activity_delete_children( $activity_id, $child->id );
1363                        }
1364                }
1365                bp_activity_delete( array( 'secondary_item_id' => $comment_id, 'type' => 'activity_comment', 'item_id' => $activity_id ) );
1366        }
1367
1368/**
1369 * Get the permalink for a single activity item
1370 *
1371 * When only the $activity_id param is passed, BP has to instantiate a new BP_Activity_Activity
1372 * object. To save yourself some processing overhead, be sure to pass the full $activity_obj param
1373 * as well, if you already have it available.
1374 *
1375 * @since BuddyPress (1.2)
1376 *
1377 * @param int $activity_id The unique id of the activity object
1378 * @param object $activity_obj (optional) The activity object
1379 *
1380 * @uses bp_get_root_domain()
1381 * @uses bp_get_activity_root_slug()
1382 * @uses apply_filters_ref_array() To call the 'bp_activity_get_permalink' hook
1383 *
1384 * @return string $link Permalink for the activity item
1385 */
1386function bp_activity_get_permalink( $activity_id, $activity_obj = false ) {
1387
1388        if ( empty( $activity_obj ) )
1389                $activity_obj = new BP_Activity_Activity( $activity_id );
1390
1391        if ( isset( $activity_obj->current_comment ) ) {
1392                $activity_obj = $activity_obj->current_comment;
1393        }
1394
1395        if ( 'new_blog_post' == $activity_obj->type || 'new_blog_comment' == $activity_obj->type || 'new_forum_topic' == $activity_obj->type || 'new_forum_post' == $activity_obj->type ) {
1396                $link = $activity_obj->primary_link;
1397        } else {
1398                if ( 'activity_comment' == $activity_obj->type ) {
1399                        $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->item_id . '/';
1400                } else {
1401                        $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->id . '/';
1402                }
1403        }
1404
1405        return apply_filters_ref_array( 'bp_activity_get_permalink', array( $link, &$activity_obj ) );
1406}
1407
1408/**
1409 * Hide a user's activity
1410 *
1411 * @since BuddyPress (1.2)
1412 *
1413 * @param int $user_id The user id
1414 *
1415 * @uses BP_Activity_Activity::hide_all_for_user() {@link BP_Activity_Activity}
1416 *
1417 * @return bool True on success, false on failure
1418 */
1419function bp_activity_hide_user_activity( $user_id ) {
1420        return BP_Activity_Activity::hide_all_for_user( $user_id );
1421}
1422
1423/**
1424 * Take content, remove all images and replace them with one thumbnail image.
1425 *
1426 * @since BuddyPress (1.2)
1427 *
1428 * @param string $content The content to work with
1429 * @param string $link Optional. The URL that the image should link to
1430 *
1431 * @uses esc_attr()
1432 * @uses apply_filters() To call the 'bp_activity_thumbnail_content_images' hook
1433 *
1434 * @return string $content The content with images stripped and replaced with a single thumb.
1435 */
1436function bp_activity_thumbnail_content_images( $content, $link = false ) {
1437
1438        preg_match_all( '/<img[^>]*>/Ui', $content, $matches );
1439        $content = preg_replace('|(\[caption(.*?)\])?<img[^>]*>(\[/caption\])?|', '', $content );
1440       
1441        if ( !empty( $matches ) && !empty( $matches[0] ) ) {
1442                // Get the SRC value
1443                preg_match( '/<img.*?(src\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $src );
1444
1445                // Get the width and height
1446                preg_match( '/<img.*?(height\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i', $matches[0][0], $height );
1447                preg_match( '/<img.*?(width\=[\'|"]{0,1}.*?[\'|"]{0,1})[\s|>]{1}/i',  $matches[0][0], $width  );
1448
1449                if ( !empty( $src ) ) {
1450                        $src    = substr( substr( str_replace( 'src=', '', $src[1] ), 0, -1 ), 1 );
1451                        $height = substr( substr( str_replace( 'height=', '', $height[1] ), 0, -1 ), 1 );
1452                        $width  = substr( substr( str_replace( 'width=', '', $width[1] ), 0, -1 ), 1 );
1453
1454                        if ( empty( $width ) || empty( $height ) ) {
1455                                $width  = 100;
1456                                $height = 100;
1457                        }
1458
1459                        $ratio      = (int) $width / (int) $height;
1460                        $new_height = (int) $height >= 100 ? 100 : $height;
1461                        $new_width  = $new_height * $ratio;
1462
1463                        $image = '<img src="' . esc_attr( $src ) . '" width="' . $new_width . '" height="' . $new_height . '" alt="' . __( 'Thumbnail', 'buddypress' ) . '" class="align-left thumbnail" />';
1464
1465                        if ( !empty( $link ) ) {
1466                                $image = '<a href="' . $link . '">' . $image . '</a>';
1467                        }
1468
1469                        $content = $image . $content;
1470                }
1471        }
1472
1473        return apply_filters( 'bp_activity_thumbnail_content_images', $content, $matches );
1474}
1475
1476/**
1477 * Convenience function to control whether the current user is allowed to mark activity items as spam
1478 *
1479 * @return bool True if user is allowed to mark activity items as spam
1480 * @since 1.6
1481 * @static
1482 */
1483function bp_activity_user_can_mark_spam() {
1484        return apply_filters( 'bp_activity_user_can_mark_spam', bp_current_user_can( 'bp_moderate' ) );
1485}
1486
1487/**
1488 * Mark activity item as spam
1489 *
1490 * @global object $bp BuddyPress global settings
1491 * @param BP_Activity_Activity $activity
1492 * @param string $source Optional; default is "by_a_person" (e.g. a person has manually marked the activity as spam).
1493 * @since 1.6
1494 */
1495function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
1496        global $bp;
1497
1498        $activity->is_spam = 1;
1499
1500        // Clear the activity stream first page cache
1501        wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
1502
1503        // Clear the activity comment cache for this activity item
1504        wp_cache_delete( 'bp_activity_comments_' . $activity->id, 'bp' );
1505
1506        // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity
1507        if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
1508                remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4, 1 );
1509
1510                // Build data package for Akismet
1511                $activity_data = BP_Akismet::build_akismet_data_package( $activity );
1512
1513                // Tell Akismet this is spam
1514                $activity_data = $bp->activity->akismet->send_akismet_request( $activity_data, 'submit', 'spam' );
1515
1516                // Update meta
1517                add_action( 'bp_activity_after_save', array( $bp->activity->akismet, 'update_activity_spam_meta' ), 1, 1 );
1518        }
1519
1520        do_action( 'bp_activity_mark_as_spam', $activity, $source );
1521}
1522
1523/**
1524 * Mark activity item as ham
1525 *
1526 * @global object $bp BuddyPress global settings
1527 * @param BP_Activity_Activity $activity
1528 * @param string $source Optional; default is "by_a_person" (e.g. a person has manually marked the activity as spam).
1529 * @since 1.6
1530 */
1531function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
1532        global $bp;
1533
1534        $activity->is_spam = 0;
1535
1536        // Clear the activity stream first page cache
1537        wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
1538
1539        // Clear the activity comment cache for this activity item
1540        wp_cache_delete( 'bp_activity_comments_' . $activity->id, 'bp' );
1541
1542        // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity
1543        if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
1544                remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4, 1 );
1545
1546                // Build data package for Akismet
1547                $activity_data = BP_Akismet::build_akismet_data_package( $activity );
1548
1549                // Tell Akismet this is spam
1550                $activity_data = $bp->activity->akismet->send_akismet_request( $activity_data, 'submit', 'ham' );
1551
1552                // Update meta
1553                add_action( 'bp_activity_after_save', array( $bp->activity->akismet, 'update_activity_ham_meta' ), 1, 1 );
1554        }
1555
1556        do_action( 'bp_activity_mark_as_ham', $activity, $source );
1557} 
1558
1559
1560/** Embeds *******************************************************************/
1561
1562/**
1563 * Grabs the activity update ID and attempts to retrieve the oEmbed cache (if it exists)
1564 * during the activity loop.  If no cache and link is embeddable, cache it.
1565 *
1566 * This does not cover recursive activity comments, as they do not use a real loop.
1567 * For that, see {@link bp_activity_comment_embed()}.
1568 *
1569 * @since BuddyPress (1.5)
1570 *
1571 * @see BP_Embed
1572 * @see bp_embed_activity_cache()
1573 * @see bp_embed_activity_save_cache()
1574 *
1575 * @uses add_filter() To attach 'bp_get_activity_id' to 'embed_post_id'
1576 * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'
1577 * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'
1578 */
1579function bp_activity_embed() {
1580        add_filter( 'embed_post_id',         'bp_get_activity_id'                  );
1581        add_filter( 'bp_embed_get_cache',    'bp_embed_activity_cache',      10, 3 );
1582        add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
1583}
1584add_action( 'activity_loop_start', 'bp_activity_embed' );
1585
1586/**
1587 * Grabs the activity comment ID and attempts to retrieve the oEmbed cache (if it exists)
1588 * when BP is recursing through activity comments {@link bp_activity_recurse_comments()}.
1589 * If no cache and link is embeddable, cache it.
1590 *
1591 * @since BuddyPress (1.5)
1592 *
1593 * @see BP_Embed
1594 * @see bp_embed_activity_cache()
1595 * @see bp_embed_activity_save_cache()
1596 *
1597 * @uses add_filter() To attach 'bp_get_activity_comment_id' to 'embed_post_id'
1598 * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'
1599 * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'
1600 */
1601function bp_activity_comment_embed() {
1602        add_filter( 'embed_post_id',         'bp_get_activity_comment_id'          );
1603        add_filter( 'bp_embed_get_cache',    'bp_embed_activity_cache',      10, 3 );
1604        add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
1605}
1606add_action( 'bp_before_activity_comment', 'bp_activity_comment_embed' );
1607
1608/**
1609 * When a user clicks on a "Read More" item, make sure embeds are correctly parsed and shown for the expanded content.
1610 *
1611 * @since BuddyPress (1.5)
1612 *
1613 * @see BP_Embed
1614 *
1615 * @param object $activity The activity that is being expanded
1616 *
1617 * @global object $bp BuddyPress global settings
1618 * @uses add_filter() To attach create_function() to 'embed_post_id'
1619 * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'
1620 * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'
1621 */
1622function bp_dtheme_embed_read_more( $activity ) {
1623        global $bp;
1624
1625        $bp->activity->read_more_id = $activity->id;
1626
1627        add_filter( 'embed_post_id',            create_function( '', 'global $bp; return $bp->activity->read_more_id;' ) );
1628        add_filter( 'bp_embed_get_cache',       'bp_embed_activity_cache',      10, 3 );
1629        add_action( 'bp_embed_update_cache',    'bp_embed_activity_save_cache', 10, 3 );
1630}
1631add_action( 'bp_dtheme_get_single_activity_content', 'bp_dtheme_embed_read_more' );
1632
1633/**
1634 * Removes the 'embed_post_id' filter after {@link bp_activity_recurse_comments()}
1635 * is rendered to avoid conflict with the 'embed_post_id' filter in
1636 * {@link bp_activity_embed()} or any other component embeds.
1637 *
1638 * @since BuddyPress (1.5)
1639 *
1640 * @see bp_activity_comment_embed()
1641 *
1642 * @uses remove_filter() To remove 'bp_get_activity_comment_id' from 'embed_post_id'
1643 */
1644function bp_activity_comment_embed_after_recurse() {
1645        remove_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
1646}
1647add_action( 'bp_after_activity_comment', 'bp_activity_comment_embed_after_recurse' );
1648
1649/**
1650 * Wrapper function for {@link bp_activity_get_meta()}.
1651 * Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
1652 *
1653 * @since BuddyPress (1.5)
1654 *
1655 * @uses bp_activity_get_meta()
1656 *
1657 * @return mixed The activity meta
1658 */
1659function bp_embed_activity_cache( $cache, $id, $cachekey ) {
1660        return bp_activity_get_meta( $id, $cachekey );
1661}
1662
1663/**
1664 * Wrapper function for {@link bp_activity_update_meta()}.
1665 * Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
1666 *
1667 * @since BuddyPress (1.5)
1668 *
1669 * @uses bp_activity_update_meta()
1670 */
1671function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
1672        bp_activity_update_meta( $id, $cachekey, $cache );
1673}
1674
1675?>