bp-activity-actions.php 28.1 KB
Newer Older
root's avatar
root committed
1
2
3
4
5
6
7
8
<?php
/**
 * Action functions are exactly the same as screen functions, however they do
 * not have a template screen associated with them. Usually they will send the
 * user back to the default screen after execution.
 *
 * @package BuddyPress
 * @subpackage ActivityActions
lechuck's avatar
lechuck committed
9
 * @since 1.5.0
root's avatar
root committed
10
11
 */

lechuck's avatar
lechuck committed
12
// Exit if accessed directly.
ale's avatar
ale committed
13
defined( 'ABSPATH' ) || exit;
root's avatar
root committed
14
15

/**
lechuck's avatar
lechuck committed
16
 * Allow core components and dependent plugins to register activity actions.
root's avatar
root committed
17
 *
lechuck's avatar
lechuck committed
18
 * @since 1.2.0
root's avatar
root committed
19
20
21
 *
 */
function bp_register_activity_actions() {
ale's avatar
ale committed
22
23
24
25

	/**
	 * Fires on bp_init to allow core components and dependent plugins to register activity actions.
	 *
lechuck's avatar
lechuck committed
26
	 * @since 1.2.0
ale's avatar
ale committed
27
	 */
root's avatar
root committed
28
29
30
31
32
	do_action( 'bp_register_activity_actions' );
}
add_action( 'bp_init', 'bp_register_activity_actions', 8 );

/**
lechuck's avatar
lechuck committed
33
 * Catch and route requests for single activity item permalinks.
root's avatar
root committed
34
 *
lechuck's avatar
lechuck committed
35
 * @since 1.2.0
root's avatar
root committed
36
 *
lechuck's avatar
lechuck committed
37
 * @return bool False on failure.
root's avatar
root committed
38
39
40
 */
function bp_activity_action_permalink_router() {

lechuck's avatar
lechuck committed
41
	// Not viewing activity.
lechuck's avatar
lechuck committed
42
	if ( ! bp_is_activity_component() || ! bp_is_current_action( 'p' ) )
root's avatar
root committed
43
44
		return false;

lechuck's avatar
lechuck committed
45
	// No activity to display.
lechuck's avatar
lechuck committed
46
	if ( ! bp_action_variable( 0 ) || ! is_numeric( bp_action_variable( 0 ) ) )
root's avatar
root committed
47
48
		return false;

lechuck's avatar
lechuck committed
49
	// Get the activity details.
root's avatar
root committed
50
51
52
53
54
55
56
57
58
59
	$activity = bp_activity_get_specific( array( 'activity_ids' => bp_action_variable( 0 ), 'show_hidden' => true ) );

	// 404 if activity does not exist
	if ( empty( $activity['activities'][0] ) ) {
		bp_do_404();
		return;
	} else {
		$activity = $activity['activities'][0];
	}

lechuck's avatar
lechuck committed
60
	// Do not redirect at default.
root's avatar
root committed
61
62
	$redirect = false;

lechuck's avatar
lechuck committed
63
	// Redirect based on the type of activity.
lechuck's avatar
lechuck committed
64
	if ( bp_is_active( 'groups' ) && $activity->component == buddypress()->groups->id ) {
root's avatar
root committed
65

lechuck's avatar
lechuck committed
66
		// Activity is a user update.
lechuck's avatar
lechuck committed
67
		if ( ! empty( $activity->user_id ) ) {
root's avatar
root committed
68
69
			$redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/';

lechuck's avatar
lechuck committed
70
		// Activity is something else.
root's avatar
root committed
71
72
		} else {

lechuck's avatar
lechuck committed
73
			// Set redirect to group activity stream.
root's avatar
root committed
74
75
76
77
78
			if ( $group = groups_get_group( array( 'group_id' => $activity->item_id ) ) ) {
				$redirect = bp_get_group_permalink( $group ) . bp_get_activity_slug() . '/' . $activity->id . '/';
			}
		}

lechuck's avatar
lechuck committed
79
	// Set redirect to users' activity stream.
ale's avatar
ale committed
80
	} elseif ( ! empty( $activity->user_id ) ) {
lechuck's avatar
lechuck committed
81
82
83
		$redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/';
	}

lechuck's avatar
lechuck committed
84
	// If set, add the original query string back onto the redirect URL.
lechuck's avatar
lechuck committed
85
	if ( ! empty( $_SERVER['QUERY_STRING'] ) ) {
lechuck's avatar
lechuck committed
86
87
88
		$query_frags = array();
		wp_parse_str( $_SERVER['QUERY_STRING'], $query_frags );
		$redirect = add_query_arg( urlencode_deep( $query_frags ), $redirect );
root's avatar
root committed
89
90
	}

ale's avatar
ale committed
91
92
93
	/**
	 * Filter the intended redirect url before the redirect occurs for the single activity item.
	 *
lechuck's avatar
lechuck committed
94
	 * @since 1.2.2
ale's avatar
ale committed
95
	 *
lechuck's avatar
lechuck committed
96
	 * @param array $value Array with url to redirect to and activity related to the redirect.
ale's avatar
ale committed
97
	 */
lechuck's avatar
lechuck committed
98
	if ( ! $redirect = apply_filters_ref_array( 'bp_activity_permalink_redirect_url', array( $redirect, &$activity ) ) ) {
root's avatar
root committed
99
		bp_core_redirect( bp_get_root_domain() );
lechuck's avatar
lechuck committed
100
	}
root's avatar
root committed
101

lechuck's avatar
lechuck committed
102
	// Redirect to the actual activity permalink page.
root's avatar
root committed
103
104
105
106
107
108
109
	bp_core_redirect( $redirect );
}
add_action( 'bp_actions', 'bp_activity_action_permalink_router' );

/**
 * Delete specific activity item and redirect to previous page.
 *
lechuck's avatar
lechuck committed
110
 * @since 1.1.0
root's avatar
root committed
111
 *
lechuck's avatar
lechuck committed
112
 * @param int $activity_id Activity id to be deleted. Defaults to 0.
lechuck's avatar
lechuck committed
113
 * @return bool False on failure.
root's avatar
root committed
114
115
116
 */
function bp_activity_action_delete_activity( $activity_id = 0 ) {

lechuck's avatar
lechuck committed
117
	// Not viewing activity or action is not delete.
root's avatar
root committed
118
119
120
121
122
123
	if ( !bp_is_activity_component() || !bp_is_current_action( 'delete' ) )
		return false;

	if ( empty( $activity_id ) && bp_action_variable( 0 ) )
		$activity_id = (int) bp_action_variable( 0 );

lechuck's avatar
lechuck committed
124
	// Not viewing a specific activity item.
root's avatar
root committed
125
126
127
	if ( empty( $activity_id ) )
		return false;

lechuck's avatar
lechuck committed
128
	// Check the nonce.
root's avatar
root committed
129
130
	check_admin_referer( 'bp_activity_delete_link' );

lechuck's avatar
lechuck committed
131
	// Load up the activity item.
root's avatar
root committed
132
133
	$activity = new BP_Activity_Activity( $activity_id );

lechuck's avatar
lechuck committed
134
	// Check access.
lechuck's avatar
lechuck committed
135
	if ( ! bp_activity_user_can_delete( $activity ) )
root's avatar
root committed
136
137
		return false;

ale's avatar
ale committed
138
139
140
	/**
	 * Fires before the deletion so plugins can still fetch information about it.
	 *
lechuck's avatar
lechuck committed
141
	 * @since 1.5.0
ale's avatar
ale committed
142
143
144
145
	 *
	 * @param int $activity_id The activity ID.
	 * @param int $user_id     The user associated with the activity.
	 */
root's avatar
root committed
146
147
	do_action( 'bp_activity_before_action_delete_activity', $activity_id, $activity->user_id );

lechuck's avatar
lechuck committed
148
	// Delete the activity item and provide user feedback.
root's avatar
root committed
149
150
151
152
153
	if ( bp_activity_delete( array( 'id' => $activity_id, 'user_id' => $activity->user_id ) ) )
		bp_core_add_message( __( 'Activity deleted successfully', 'buddypress' ) );
	else
		bp_core_add_message( __( 'There was an error when deleting that activity', 'buddypress' ), 'error' );

ale's avatar
ale committed
154
155
156
	/**
	 * Fires after the deletion so plugins can act afterwards based on the activity.
	 *
lechuck's avatar
lechuck committed
157
	 * @since 1.1.0
ale's avatar
ale committed
158
159
160
161
	 *
	 * @param int $activity_id The activity ID.
	 * @param int $user_id     The user associated with the activity.
	 */
root's avatar
root committed
162
163
	do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id );

lechuck's avatar
lechuck committed
164
165
	// Check for the redirect query arg, otherwise let WP handle things.
	if ( !empty( $_GET['redirect_to'] ) )
root's avatar
root committed
166
167
168
169
170
171
		bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
	else
		bp_core_redirect( wp_get_referer() );
}
add_action( 'bp_actions', 'bp_activity_action_delete_activity' );

lechuck's avatar
lechuck committed
172
/**
lechuck's avatar
lechuck committed
173
174
 * Mark specific activity item as spam and redirect to previous page.
 *
lechuck's avatar
lechuck committed
175
 * @since 1.6.0
lechuck's avatar
lechuck committed
176
177
 *
 * @param int $activity_id Activity id to be deleted. Defaults to 0.
lechuck's avatar
lechuck committed
178
 * @return bool False on failure.
lechuck's avatar
lechuck committed
179
180
 */
function bp_activity_action_spam_activity( $activity_id = 0 ) {
ale's avatar
ale committed
181
	$bp = buddypress();
lechuck's avatar
lechuck committed
182

lechuck's avatar
lechuck committed
183
	// Not viewing activity, or action is not spam, or Akismet isn't present.
lechuck's avatar
lechuck committed
184
185
186
187
188
189
	if ( !bp_is_activity_component() || !bp_is_current_action( 'spam' ) || empty( $bp->activity->akismet ) )
		return false;

	if ( empty( $activity_id ) && bp_action_variable( 0 ) )
		$activity_id = (int) bp_action_variable( 0 );

lechuck's avatar
lechuck committed
190
	// Not viewing a specific activity item.
lechuck's avatar
lechuck committed
191
192
193
194
195
196
197
	if ( empty( $activity_id ) )
		return false;

	// Is the current user allowed to spam items?
	if ( !bp_activity_user_can_mark_spam() )
		return false;

lechuck's avatar
lechuck committed
198
	// Load up the activity item.
lechuck's avatar
lechuck committed
199
200
201
202
	$activity = new BP_Activity_Activity( $activity_id );
	if ( empty( $activity->id ) )
		return false;

lechuck's avatar
lechuck committed
203
	// Check nonce.
lechuck's avatar
lechuck committed
204
205
	check_admin_referer( 'bp_activity_akismet_spam_' . $activity->id );

ale's avatar
ale committed
206
207
208
	/**
	 * Fires before the marking activity as spam so plugins can modify things if they want to.
	 *
lechuck's avatar
lechuck committed
209
	 * @since 1.6.0
ale's avatar
ale committed
210
211
212
213
	 *
	 * @param int    $activity_id Activity ID to be marked as spam.
	 * @param object $activity    Activity object for the ID to be marked as spam.
	 */
lechuck's avatar
lechuck committed
214
215
	do_action( 'bp_activity_before_action_spam_activity', $activity->id, $activity );

lechuck's avatar
lechuck committed
216
	// Mark as spam.
lechuck's avatar
lechuck committed
217
218
219
	bp_activity_mark_as_spam( $activity );
	$activity->save();

lechuck's avatar
lechuck committed
220
	// Tell the user the spamming has been successful.
lechuck's avatar
lechuck committed
221
222
	bp_core_add_message( __( 'The activity item has been marked as spam and is no longer visible.', 'buddypress' ) );

ale's avatar
ale committed
223
224
225
	/**
	 * Fires after the marking activity as spam so plugins can act afterwards based on the activity.
	 *
lechuck's avatar
lechuck committed
226
	 * @since 1.6.0
ale's avatar
ale committed
227
228
229
230
	 *
	 * @param int $activity_id Activity ID that was marked as spam.
	 * @param int $user_id     User ID associated with activity.
	 */
lechuck's avatar
lechuck committed
231
232
	do_action( 'bp_activity_action_spam_activity', $activity_id, $activity->user_id );

lechuck's avatar
lechuck committed
233
234
	// Check for the redirect query arg, otherwise let WP handle things.
	if ( !empty( $_GET['redirect_to'] ) )
lechuck's avatar
lechuck committed
235
236
237
238
239
240
		bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
	else
		bp_core_redirect( wp_get_referer() );
}
add_action( 'bp_actions', 'bp_activity_action_spam_activity' );

root's avatar
root committed
241
242
243
/**
 * Post user/group activity update.
 *
lechuck's avatar
lechuck committed
244
 * @since 1.2.0
root's avatar
root committed
245
 *
lechuck's avatar
lechuck committed
246
 * @return bool False on failure.
root's avatar
root committed
247
248
249
 */
function bp_activity_action_post_update() {

lechuck's avatar
lechuck committed
250
	// Do not proceed if user is not logged in, not viewing activity, or not posting.
root's avatar
root committed
251
252
253
	if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'post' ) )
		return false;

lechuck's avatar
lechuck committed
254
	// Check the nonce.
root's avatar
root committed
255
256
	check_admin_referer( 'post_update', '_wpnonce_post_update' );

ale's avatar
ale committed
257
258
259
	/**
	 * Filters the content provided in the activity input field.
	 *
lechuck's avatar
lechuck committed
260
	 * @since 1.2.0
ale's avatar
ale committed
261
262
263
	 *
	 * @param string $value Activity message being posted.
	 */
lechuck's avatar
lechuck committed
264
265
266
	$content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new'] );

	if ( ! empty( $_POST['whats-new-post-object'] ) ) {
ale's avatar
ale committed
267
268
269
270

		/**
		 * Filters the item type that the activity update should be associated with.
		 *
lechuck's avatar
lechuck committed
271
		 * @since 1.2.0
ale's avatar
ale committed
272
273
274
		 *
		 * @param string $value Item type to associate with.
		 */
lechuck's avatar
lechuck committed
275
276
277
278
		$object = apply_filters( 'bp_activity_post_update_object', $_POST['whats-new-post-object'] );
	}

	if ( ! empty( $_POST['whats-new-post-in'] ) ) {
ale's avatar
ale committed
279
280
281
282

		/**
		 * Filters what component the activity is being to.
		 *
lechuck's avatar
lechuck committed
283
		 * @since 1.2.0
ale's avatar
ale committed
284
285
286
		 *
		 * @param string $value Chosen component to post activity to.
		 */
lechuck's avatar
lechuck committed
287
288
		$item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in'] );
	}
root's avatar
root committed
289

lechuck's avatar
lechuck committed
290
	// No activity content so provide feedback and redirect.
root's avatar
root committed
291
292
293
294
295
	if ( empty( $content ) ) {
		bp_core_add_message( __( 'Please enter some content to post.', 'buddypress' ), 'error' );
		bp_core_redirect( wp_get_referer() );
	}

lechuck's avatar
lechuck committed
296
	// No existing item_id.
root's avatar
root committed
297
298
299
	if ( empty( $item_id ) ) {
		$activity_id = bp_activity_post_update( array( 'content' => $content ) );

lechuck's avatar
lechuck committed
300
	// Post to groups object.
ale's avatar
ale committed
301
	} elseif ( 'groups' == $object && bp_is_active( 'groups' ) ) {
lechuck's avatar
lechuck committed
302
		if ( (int) $item_id ) {
root's avatar
root committed
303
304
305
306
			$activity_id = groups_post_update( array( 'content' => $content, 'group_id' => $item_id ) );
		}

	} else {
ale's avatar
ale committed
307
308
309
310

		/**
		 * Filters activity object for BuddyPress core and plugin authors before posting activity update.
		 *
lechuck's avatar
lechuck committed
311
		 * @since 1.2.0
ale's avatar
ale committed
312
313
314
315
316
		 *
		 * @param string $object  Activity item being associated to.
		 * @param string $item_id Component ID being posted to.
		 * @param string $content Activity content being posted.
		 */
root's avatar
root committed
317
318
319
		$activity_id = apply_filters( 'bp_activity_custom_update', $object, $item_id, $content );
	}

lechuck's avatar
lechuck committed
320
	// Provide user feedback.
root's avatar
root committed
321
322
323
	if ( !empty( $activity_id ) )
		bp_core_add_message( __( 'Update Posted!', 'buddypress' ) );
	else
ale's avatar
ale committed
324
		bp_core_add_message( __( 'There was an error when posting your update. Please try again.', 'buddypress' ), 'error' );
root's avatar
root committed
325

lechuck's avatar
lechuck committed
326
	// Redirect.
root's avatar
root committed
327
328
329
330
331
332
333
	bp_core_redirect( wp_get_referer() );
}
add_action( 'bp_actions', 'bp_activity_action_post_update' );

/**
 * Post new activity comment.
 *
lechuck's avatar
lechuck committed
334
 * @since 1.2.0
root's avatar
root committed
335
 *
lechuck's avatar
lechuck committed
336
 * @return bool False on failure.
root's avatar
root committed
337
338
339
 */
function bp_activity_action_post_comment() {

lechuck's avatar
lechuck committed
340
	if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'reply' ) )
root's avatar
root committed
341
342
		return false;

lechuck's avatar
lechuck committed
343
	// Check the nonce.
root's avatar
root committed
344
345
	check_admin_referer( 'new_activity_comment', '_wpnonce_new_activity_comment' );

ale's avatar
ale committed
346
347
348
	/**
	 * Filters the activity ID a comment will be in reply to.
	 *
lechuck's avatar
lechuck committed
349
	 * @since 1.2.0
ale's avatar
ale committed
350
351
352
	 *
	 * @param string $value ID of the activity being replied to.
	 */
root's avatar
root committed
353
	$activity_id = apply_filters( 'bp_activity_post_comment_activity_id', $_POST['comment_form_id'] );
ale's avatar
ale committed
354
355
356
357

	/**
	 * Filters the comment content for a comment reply.
	 *
lechuck's avatar
lechuck committed
358
	 * @since 1.2.0
ale's avatar
ale committed
359
360
361
	 *
	 * @param string $value Comment content being posted.
	 */
root's avatar
root committed
362
363
364
365
366
367
368
369
	$content = apply_filters( 'bp_activity_post_comment_content', $_POST['ac_input_' . $activity_id] );

	if ( empty( $content ) ) {
		bp_core_add_message( __( 'Please do not leave the comment area blank.', 'buddypress' ), 'error' );
		bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
	}

	$comment_id = bp_activity_new_comment( array(
lechuck's avatar
lechuck committed
370
		'content'     => $content,
root's avatar
root committed
371
		'activity_id' => $activity_id,
lechuck's avatar
lechuck committed
372
		'parent_id'   => false
root's avatar
root committed
373
374
375
376
377
	));

	if ( !empty( $comment_id ) )
		bp_core_add_message( __( 'Reply Posted!', 'buddypress' ) );
	else
ale's avatar
ale committed
378
		bp_core_add_message( __( 'There was an error posting that reply. Please try again.', 'buddypress' ), 'error' );
root's avatar
root committed
379
380
381
382
383
384
385
386

	bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
}
add_action( 'bp_actions', 'bp_activity_action_post_comment' );

/**
 * Mark activity as favorite.
 *
lechuck's avatar
lechuck committed
387
 * @since 1.2.0
root's avatar
root committed
388
 *
lechuck's avatar
lechuck committed
389
 * @return bool False on failure.
root's avatar
root committed
390
391
392
 */
function bp_activity_action_mark_favorite() {

lechuck's avatar
lechuck committed
393
	if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'favorite' ) )
root's avatar
root committed
394
395
		return false;

lechuck's avatar
lechuck committed
396
	// Check the nonce.
root's avatar
root committed
397
398
399
400
401
	check_admin_referer( 'mark_favorite' );

	if ( bp_activity_add_user_favorite( bp_action_variable( 0 ) ) )
		bp_core_add_message( __( 'Activity marked as favorite.', 'buddypress' ) );
	else
ale's avatar
ale committed
402
		bp_core_add_message( __( 'There was an error marking that activity as a favorite. Please try again.', 'buddypress' ), 'error' );
root's avatar
root committed
403
404
405
406
407
408
409
410

	bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
}
add_action( 'bp_actions', 'bp_activity_action_mark_favorite' );

/**
 * Remove activity from favorites.
 *
lechuck's avatar
lechuck committed
411
 * @since 1.2.0
root's avatar
root committed
412
 *
lechuck's avatar
lechuck committed
413
 * @return bool False on failure.
root's avatar
root committed
414
415
416
 */
function bp_activity_action_remove_favorite() {

lechuck's avatar
lechuck committed
417
	if ( ! is_user_logged_in() || ! bp_is_activity_component() || ! bp_is_current_action( 'unfavorite' ) )
root's avatar
root committed
418
419
		return false;

lechuck's avatar
lechuck committed
420
	// Check the nonce.
root's avatar
root committed
421
422
423
424
425
	check_admin_referer( 'unmark_favorite' );

	if ( bp_activity_remove_user_favorite( bp_action_variable( 0 ) ) )
		bp_core_add_message( __( 'Activity removed as favorite.', 'buddypress' ) );
	else
ale's avatar
ale committed
426
		bp_core_add_message( __( 'There was an error removing that activity as a favorite. Please try again.', 'buddypress' ), 'error' );
root's avatar
root committed
427
428
429
430
431
432

	bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
}
add_action( 'bp_actions', 'bp_activity_action_remove_favorite' );

/**
lechuck's avatar
lechuck committed
433
 * Load the sitewide activity feed.
root's avatar
root committed
434
 *
lechuck's avatar
lechuck committed
435
 * @since 1.0.0
root's avatar
root committed
436
 *
lechuck's avatar
lechuck committed
437
 * @return bool False on failure.
root's avatar
root committed
438
439
 */
function bp_activity_action_sitewide_feed() {
ale's avatar
ale committed
440
	$bp = buddypress();
root's avatar
root committed
441

lechuck's avatar
lechuck committed
442
	if ( ! bp_is_activity_component() || ! bp_is_current_action( 'feed' ) || bp_is_user() || ! empty( $bp->groups->current_group ) )
root's avatar
root committed
443
444
		return false;

lechuck's avatar
lechuck committed
445
	// Setup the feed.
lechuck's avatar
lechuck committed
446
447
448
449
	buddypress()->activity->feed = new BP_Activity_Feed( array(
		'id'            => 'sitewide',

		/* translators: Sitewide activity RSS title - "[Site Name] | Site Wide Activity" */
lucha's avatar
lucha committed
450
		'title'         => sprintf( __( '%s | Site-Wide Activity', 'buddypress' ), bp_get_site_name() ),
root's avatar
root committed
451

lechuck's avatar
lechuck committed
452
453
454
455
		'link'          => bp_get_activity_directory_permalink(),
		'description'   => __( 'Activity feed for the entire site.', 'buddypress' ),
		'activity_args' => 'display_comments=threaded'
	) );
root's avatar
root committed
456
457
458
459
}
add_action( 'bp_actions', 'bp_activity_action_sitewide_feed' );

/**
lechuck's avatar
lechuck committed
460
 * Load a user's personal activity feed.
root's avatar
root committed
461
 *
lechuck's avatar
lechuck committed
462
 * @since 1.0.0
root's avatar
root committed
463
 *
lechuck's avatar
lechuck committed
464
 * @return bool False on failure.
root's avatar
root committed
465
466
 */
function bp_activity_action_personal_feed() {
lechuck's avatar
lechuck committed
467
	if ( ! bp_is_user_activity() || ! bp_is_current_action( 'feed' ) ) {
root's avatar
root committed
468
		return false;
lechuck's avatar
lechuck committed
469
470
	}

lechuck's avatar
lechuck committed
471
	// Setup the feed.
lechuck's avatar
lechuck committed
472
473
	buddypress()->activity->feed = new BP_Activity_Feed( array(
		'id'            => 'personal',
root's avatar
root committed
474

lechuck's avatar
lechuck committed
475
476
		/* translators: Personal activity RSS title - "[Site Name] | [User Display Name] | Activity" */
		'title'         => sprintf( __( '%1$s | %2$s | Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
root's avatar
root committed
477

lechuck's avatar
lechuck committed
478
479
480
481
		'link'          => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() ),
		'description'   => sprintf( __( 'Activity feed for %s.', 'buddypress' ), bp_get_displayed_user_fullname() ),
		'activity_args' => 'user_id=' . bp_displayed_user_id()
	) );
root's avatar
root committed
482
483
484
485
}
add_action( 'bp_actions', 'bp_activity_action_personal_feed' );

/**
lechuck's avatar
lechuck committed
486
 * Load a user's friends' activity feed.
root's avatar
root committed
487
 *
lechuck's avatar
lechuck committed
488
 * @since 1.0.0
root's avatar
root committed
489
 *
lechuck's avatar
lechuck committed
490
 * @return bool False on failure.
root's avatar
root committed
491
492
 */
function bp_activity_action_friends_feed() {
lechuck's avatar
lechuck committed
493
	if ( ! bp_is_active( 'friends' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_friends_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) {
root's avatar
root committed
494
		return false;
lechuck's avatar
lechuck committed
495
496
	}

lechuck's avatar
lechuck committed
497
	// Setup the feed.
lechuck's avatar
lechuck committed
498
499
	buddypress()->activity->feed = new BP_Activity_Feed( array(
		'id'            => 'friends',
root's avatar
root committed
500

lechuck's avatar
lechuck committed
501
502
		/* translators: Friends activity RSS title - "[Site Name] | [User Display Name] | Friends Activity" */
		'title'         => sprintf( __( '%1$s | %2$s | Friends Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
root's avatar
root committed
503

lechuck's avatar
lechuck committed
504
505
506
507
		'link'          => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() ),
		'description'   => sprintf( __( "Activity feed for %s's friends.", 'buddypress' ), bp_get_displayed_user_fullname() ),
		'activity_args' => 'scope=friends'
	) );
root's avatar
root committed
508
509
510
511
}
add_action( 'bp_actions', 'bp_activity_action_friends_feed' );

/**
lechuck's avatar
lechuck committed
512
 * Load the activity feed for a user's groups.
root's avatar
root committed
513
 *
lechuck's avatar
lechuck committed
514
 * @since 1.2.0
root's avatar
root committed
515
 *
lechuck's avatar
lechuck committed
516
 * @return bool False on failure.
root's avatar
root committed
517
518
 */
function bp_activity_action_my_groups_feed() {
lechuck's avatar
lechuck committed
519
	if ( ! bp_is_active( 'groups' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_groups_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) {
root's avatar
root committed
520
		return false;
lechuck's avatar
lechuck committed
521
	}
root's avatar
root committed
522

lechuck's avatar
lechuck committed
523
	// Get displayed user's group IDs.
lechuck's avatar
lechuck committed
524
525
526
	$groups    = groups_get_user_groups();
	$group_ids = implode( ',', $groups['groups'] );

lechuck's avatar
lechuck committed
527
	// Setup the feed.
lechuck's avatar
lechuck committed
528
529
530
531
532
533
534
	buddypress()->activity->feed = new BP_Activity_Feed( array(
		'id'            => 'mygroups',

		/* translators: Member groups activity RSS title - "[Site Name] | [User Display Name] | Groups Activity" */
		'title'         => sprintf( __( '%1$s | %2$s | Group Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),

		'link'          => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() ),
lucha's avatar
lucha committed
535
		'description'   => sprintf( __( "Public group activity feed of which %s is a member.", 'buddypress' ), bp_get_displayed_user_fullname() ),
lechuck's avatar
lechuck committed
536
537
538
539
540
541
		'activity_args' => array(
			'object'           => buddypress()->groups->id,
			'primary_id'       => $group_ids,
			'display_comments' => 'threaded'
		)
	) );
root's avatar
root committed
542
543
544
545
546
547
}
add_action( 'bp_actions', 'bp_activity_action_my_groups_feed' );

/**
 * Load a user's @mentions feed.
 *
lechuck's avatar
lechuck committed
548
 * @since 1.2.0
root's avatar
root committed
549
 *
lechuck's avatar
lechuck committed
550
 * @return bool False on failure.
root's avatar
root committed
551
552
 */
function bp_activity_action_mentions_feed() {
lechuck's avatar
lechuck committed
553
554
555
	if ( ! bp_activity_do_mentions() ) {
		return false;
	}
root's avatar
root committed
556

lechuck's avatar
lechuck committed
557
	if ( !bp_is_user_activity() || ! bp_is_current_action( 'mentions' ) || ! bp_is_action_variable( 'feed', 0 ) ) {
root's avatar
root committed
558
		return false;
lechuck's avatar
lechuck committed
559
	}
root's avatar
root committed
560

lechuck's avatar
lechuck committed
561
	// Setup the feed.
lechuck's avatar
lechuck committed
562
563
	buddypress()->activity->feed = new BP_Activity_Feed( array(
		'id'            => 'mentions',
root's avatar
root committed
564

lechuck's avatar
lechuck committed
565
566
567
568
569
570
571
572
573
		/* translators: User mentions activity RSS title - "[Site Name] | [User Display Name] | Mentions" */
		'title'         => sprintf( __( '%1$s | %2$s | Mentions', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),

		'link'          => bp_displayed_user_domain() . bp_get_activity_slug() . '/mentions/',
		'description'   => sprintf( __( "Activity feed mentioning %s.", 'buddypress' ), bp_get_displayed_user_fullname() ),
		'activity_args' => array(
			'search_terms' => '@' . bp_core_get_username( bp_displayed_user_id() )
		)
	) );
root's avatar
root committed
574
575
576
577
578
579
}
add_action( 'bp_actions', 'bp_activity_action_mentions_feed' );

/**
 * Load a user's favorites feed.
 *
lechuck's avatar
lechuck committed
580
 * @since 1.2.0
root's avatar
root committed
581
 *
lechuck's avatar
lechuck committed
582
 * @return bool False on failure.
root's avatar
root committed
583
584
 */
function bp_activity_action_favorites_feed() {
lechuck's avatar
lechuck committed
585
	if ( ! bp_is_user_activity() || ! bp_is_current_action( 'favorites' ) || ! bp_is_action_variable( 'feed', 0 ) ) {
root's avatar
root committed
586
		return false;
lechuck's avatar
lechuck committed
587
588
	}

lechuck's avatar
lechuck committed
589
	// Get displayed user's favorite activity IDs.
lechuck's avatar
lechuck committed
590
591
592
	$favs = bp_activity_get_user_favorites( bp_displayed_user_id() );
	$fav_ids = implode( ',', (array) $favs );

lechuck's avatar
lechuck committed
593
	// Setup the feed.
lechuck's avatar
lechuck committed
594
595
	buddypress()->activity->feed = new BP_Activity_Feed( array(
		'id'            => 'favorites',
root's avatar
root committed
596

lechuck's avatar
lechuck committed
597
598
		/* translators: User activity favorites RSS title - "[Site Name] | [User Display Name] | Favorites" */
		'title'         => sprintf( __( '%1$s | %2$s | Favorites', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
root's avatar
root committed
599

lechuck's avatar
lechuck committed
600
601
602
603
		'link'          => bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/',
		'description'   => sprintf( __( "Activity feed of %s's favorites.", 'buddypress' ), bp_get_displayed_user_fullname() ),
		'activity_args' => 'include=' . $fav_ids
	) );
root's avatar
root committed
604
605
606
}
add_action( 'bp_actions', 'bp_activity_action_favorites_feed' );

lechuck's avatar
lechuck committed
607
/**
lechuck's avatar
lechuck committed
608
 * Loads Akismet filtering for activity.
lechuck's avatar
lechuck committed
609
 *
lechuck's avatar
lechuck committed
610
611
 * @since 1.6.0
 * @since 2.3.0 We only support Akismet 3+.
lechuck's avatar
lechuck committed
612
613
 */
function bp_activity_setup_akismet() {
ale's avatar
ale committed
614
	$bp = buddypress();
lechuck's avatar
lechuck committed
615

lechuck's avatar
lechuck committed
616
	// Bail if Akismet is not active.
ale's avatar
ale committed
617
618
619
620
	if ( ! defined( 'AKISMET_VERSION' ) ) {
		return;
	}

lechuck's avatar
lechuck committed
621
	// Bail if older version of Akismet.
ale's avatar
ale committed
622
	if ( ! class_exists( 'Akismet' ) ) {
lechuck's avatar
lechuck committed
623
		return;
ale's avatar
ale committed
624
	}
lechuck's avatar
lechuck committed
625

lechuck's avatar
lechuck committed
626
	// Bail if no Akismet key is set.
ale's avatar
ale committed
627
	if ( ! bp_get_option( 'wordpress_api_key' ) && ! defined( 'WPCOM_API_KEY' ) ) {
lechuck's avatar
lechuck committed
628
		return;
ale's avatar
ale committed
629
	}
lechuck's avatar
lechuck committed
630

ale's avatar
ale committed
631
632
633
	/**
	 * Filters if BuddyPress Activity Akismet support has been disabled by another plugin.
	 *
lechuck's avatar
lechuck committed
634
	 * @since 1.6.0
ale's avatar
ale committed
635
636
637
638
	 *
	 * @param bool $value Return value of bp_is_akismet_active boolean function.
	 */
	if ( ! apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
lechuck's avatar
lechuck committed
639
		return;
ale's avatar
ale committed
640
	}
lechuck's avatar
lechuck committed
641

lechuck's avatar
lechuck committed
642
	// Instantiate Akismet for BuddyPress.
lechuck's avatar
lechuck committed
643
644
	$bp->activity->akismet = new BP_Akismet();
}
lucha's avatar
lucha committed
645
646
647
648

/**
 * AJAX endpoint for Suggestions API lookups.
 *
lechuck's avatar
lechuck committed
649
 * @since 2.1.0
lucha's avatar
lucha committed
650
651
652
653
654
655
656
 */
function bp_ajax_get_suggestions() {
	if ( ! bp_is_user_active() || empty( $_GET['term'] ) || empty( $_GET['type'] ) ) {
		wp_send_json_error( 'missing_parameter' );
		exit;
	}

ale's avatar
ale committed
657
	$args = array(
lucha's avatar
lucha committed
658
659
		'term' => sanitize_text_field( $_GET['term'] ),
		'type' => sanitize_text_field( $_GET['type'] ),
ale's avatar
ale committed
660
661
662
663
664
665
666
667
	);

	// Support per-Group suggestions.
	if ( ! empty( $_GET['group-id'] ) ) {
		$args['group_id'] = absint( $_GET['group-id'] );
	}

	$results = bp_core_get_suggestions( $args );
lucha's avatar
lucha committed
668
669
670
671
672
673
674
675
676

	if ( is_wp_error( $results ) ) {
		wp_send_json_error( $results->get_error_message() );
		exit;
	}

	wp_send_json_success( $results );
}
add_action( 'wp_ajax_bp_get_suggestions', 'bp_ajax_get_suggestions' );
ale's avatar
ale committed
677
678
679
680

/**
 * Detect a change in post type status, and initiate an activity update if necessary.
 *
lechuck's avatar
lechuck committed
681
 * @since 2.2.0
ale's avatar
ale committed
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
 *
 * @todo Support untrashing better.
 *
 * @param string $new_status New status for the post.
 * @param string $old_status Old status for the post.
 * @param object $post       Post data.
 */
function bp_activity_catch_transition_post_type_status( $new_status, $old_status, $post ) {
	if ( ! post_type_supports( $post->post_type, 'buddypress-activity' ) ) {
		return;
	}

	// This is an edit.
	if ( $new_status === $old_status ) {
		// An edit of an existing post should update the existing activity item.
		if ( $new_status == 'publish' ) {
lechuck's avatar
lechuck committed
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
			$edit = bp_activity_post_type_update( $post );

			// Post was never recorded into activity stream, so record it now!
			if ( null === $edit ) {
				bp_activity_post_type_publish( $post->ID, $post );
			}

		// Allow plugins to eventually deal with other post statuses.
		} else {
			/**
			 * Fires when editing the post and the new status is not 'publish'.
			 *
			 * This is a variable filter that is dependent on the post type
			 * being untrashed.
			 *
			 * @since 2.5.0
			 *
			 * @param WP_Post $post Post data.
			 * @param string $new_status New status for the post.
			 * @param string $old_status Old status for the post.
			 */
			do_action( 'bp_activity_post_type_edit_' . $post->post_type, $post, $new_status, $old_status );
ale's avatar
ale committed
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
		}

		return;
	}

	// Publishing a previously unpublished post.
	if ( 'publish' === $new_status ) {
		// Untrashing the post type - nothing here yet.
		if ( 'trash' == $old_status ) {

			/**
			 * Fires if untrashing post in a post type.
			 *
			 * This is a variable filter that is dependent on the post type
			 * being untrashed.
			 *
lechuck's avatar
lechuck committed
736
			 * @since 2.2.0
ale's avatar
ale committed
737
738
739
740
741
742
743
744
745
746
747
			 *
			 * @param WP_Post $post Post data.
			 */
			do_action( 'bp_activity_post_type_untrash_' . $post->post_type, $post );
		} else {
			// Record the post.
			bp_activity_post_type_publish( $post->ID, $post );
		}

	// Unpublishing a previously published post.
	} elseif ( 'publish' === $old_status ) {
lechuck's avatar
lechuck committed
748
		// Some form of pending status - only remove the activity entry.
ale's avatar
ale committed
749
		bp_activity_post_type_unpublish( $post->ID, $post );
lechuck's avatar
lechuck committed
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

	// For any other cases, allow plugins to eventually deal with it.
	} else {
		/**
		 * Fires when the old and the new post status are not 'publish'.
		 *
		 * This is a variable filter that is dependent on the post type
		 * being untrashed.
		 *
		 * @since 2.5.0
		 *
		 * @param WP_Post $post Post data.
		 * @param string $new_status New status for the post.
		 * @param string $old_status Old status for the post.
		 */
		do_action( 'bp_activity_post_type_transition_status_' . $post->post_type, $post, $new_status, $old_status );
ale's avatar
ale committed
766
767
768
	}
}
add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 );
lechuck's avatar
lechuck committed
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889

/**
 * When a post type comment status transition occurs, update the relevant activity's status.
 *
 * @since 2.5.0
 *
 * @param string     $new_status New comment status.
 * @param string     $old_status Previous comment status.
 * @param WP_Comment $comment Comment data.
 */
function bp_activity_transition_post_type_comment_status( $new_status, $old_status, $comment ) {
	$post_type = get_post_type( $comment->comment_post_ID );
	if ( ! $post_type ) {
		return;
	}

	// Get the post type tracking args.
	$activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );

	// Bail if the activity type does not exist
	if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
		return false;

	// Set the $activity_comment_object
	} else {
		$activity_comment_object = $activity_post_object->comments_tracking;
	}

	// Init an empty activity ID
	$activity_id = 0;

	/**
	 * Activity currently doesn't have any concept of a trash, or an unapproved/approved state.
	 *
	 * If a blog comment transitions to a "delete" or "hold" status, delete the activity item.
	 * If a blog comment transitions to trashed, or spammed, mark the activity as spam.
	 * If a blog comment transitions to approved (and the activity exists), mark the activity as ham.
	 * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam.
	 * Otherwise, record the comment into the activity stream.
	 */

	// This clause handles delete/hold.
	if ( in_array( $new_status, array( 'delete', 'hold' ) ) ) {
		return bp_activity_post_type_remove_comment( $comment->comment_ID, $activity_post_object );

	// These clauses handle trash, spam, and un-spams.
	} elseif ( in_array( $new_status, array( 'trash', 'spam', 'unapproved' ) ) ) {
		$action = 'spam_activity';
	} elseif ( 'approved' == $new_status ) {
		$action = 'ham_activity';
	}

	// Get the activity
	if ( bp_disable_blogforum_comments() ) {
		$activity_id = bp_activity_get_activity_id( array(
			'component'         => $activity_comment_object->component_id,
			'item_id'           => get_current_blog_id(),
			'secondary_item_id' => $comment->comment_ID,
			'type'              => $activity_comment_object->action_id,
		) );
	} else {
		$activity_id = get_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', true );
	}

	/**
	 * Leave a chance to plugins to manage activity comments differently.
	 *
	 * @since  2.5.0
	 *
	 * @param bool        $value       True to override BuddyPress management.
	 * @param string      $post_type   The post type name.
	 * @param int         $activity_id The post type activity (0 if not found).
	 * @param string      $new_status  The new status of the post type comment.
	 * @param string      $old_status  The old status of the post type comment.
	 * @param WP_Comment  $comment Comment data.
	 */
	if ( true === apply_filters( 'bp_activity_pre_transition_post_type_comment_status', false, $post_type, $activity_id, $new_status, $old_status, $comment ) ) {
		return false;
	}

	// Check activity item exists
	if ( empty( $activity_id ) ) {
		// If no activity exists, but the comment has been approved, record it into the activity table.
		if ( 'approved' == $new_status ) {
			return bp_activity_post_type_comment( $comment->comment_ID, true, $activity_post_object );
		}

		return;
	}

	// Create an activity object
	$activity = new BP_Activity_Activity( $activity_id );
	if ( empty( $activity->component ) ) {
		return;
	}

	// Spam/ham the activity if it's not already in that state
	if ( 'spam_activity' === $action && ! $activity->is_spam ) {
		bp_activity_mark_as_spam( $activity );
	} elseif ( 'ham_activity' == $action) {
		bp_activity_mark_as_ham( $activity );
	}

	// Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated
	$post_type_comment_action = $activity_comment_object->action_id;
	$comment_akismet_history = create_function( '$t', '$t[] = $post_type_comment_action; return $t;' );
	add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );

	// Make sure the activity change won't edit the comment if sync is on
	remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );

	// Save the updated activity
	$activity->save();

	// Restore the action
	add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );

	// Remove the "new_blog_comment" activity type whitelist so we don't break anything
	remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
}
add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );