bp-activity-notifications.php 13.3 KB
Newer Older
root's avatar
root committed
1
<?php
root's avatar
root committed
2
/**
lechuck's avatar
lechuck committed
3
 * BuddyPress Activity Notifications.
root's avatar
root committed
4
5
6
 *
 * @package BuddyPress
 * @subpackage ActivityNotifications
lechuck's avatar
lechuck committed
7
 * @since 1.2.0
root's avatar
root committed
8
9
 */

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

lechuck's avatar
lechuck committed
13
14
15
/**
 * Format notifications related to activity.
 *
lechuck's avatar
lechuck committed
16
 * @since 1.5.0
lechuck's avatar
lechuck committed
17
 *
ale's avatar
ale committed
18
19
20
21
22
 * @param string $action            The type of activity item. Just 'new_at_mention' for now.
 * @param int    $item_id           The activity ID.
 * @param int    $secondary_item_id In the case of at-mentions, this is the mentioner's ID.
 * @param int    $total_items       The total number of notifications to format.
 * @param string $format            'string' to get a BuddyBar-compatible notification, 'array' otherwise.
lucha's avatar
lucha committed
23
 * @param int    $id                Optional. The notification ID.
lechuck's avatar
lechuck committed
24
25
 * @return string $return Formatted @mention notification.
 */
lucha's avatar
lucha committed
26
27
28
29
30
31
function bp_activity_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string', $id = 0 ) {
	$action_filter = $action;
	$return        = false;
	$activity_id   = $item_id;
	$user_id       = $secondary_item_id;
	$user_fullname = bp_core_get_user_displayname( $user_id );
lechuck's avatar
lechuck committed
32
33
34

	switch ( $action ) {
		case 'new_at_mention':
lucha's avatar
lucha committed
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
			$action_filter = 'at_mentions';
			$link          = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
			$title         = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
			$amount        = 'single';

			if ( (int) $total_items > 1 ) {
				$text   = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
				$amount = 'multiple';
			} else {
				$text = sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
			}
		break;

		case 'update_reply':
			$link   = bp_get_notifications_permalink();
			$title  = __( 'New Activity reply', 'buddypress' );
ale's avatar
ale committed
51
			$amount = 'single';
lechuck's avatar
lechuck committed
52
53

			if ( (int) $total_items > 1 ) {
lucha's avatar
lucha committed
54
55
				$link   = add_query_arg( 'type', $action, $link );
				$text   = sprintf( __( 'You have %1$d new replies', 'buddypress' ), (int) $total_items );
ale's avatar
ale committed
56
				$amount = 'multiple';
lechuck's avatar
lechuck committed
57
			} else {
lucha's avatar
lucha committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
				$link = add_query_arg( 'nid', (int) $id, bp_activity_get_permalink( $activity_id ) );
				$text = sprintf( __( '%1$s commented on one of your updates', 'buddypress' ), $user_fullname );
			}
		break;

		case 'comment_reply':
			$link   = bp_get_notifications_permalink();
			$title  = __( 'New Activity comment reply', 'buddypress' );
			$amount = 'single';

			if ( (int) $total_items > 1 ) {
				$link   = add_query_arg( 'type', $action, $link );
				$text   = sprintf( __( 'You have %1$d new comment replies', 'buddypress' ), (int) $total_items );
				$amount = 'multiple';
			} else {
				$link = add_query_arg( 'nid', (int) $id, bp_activity_get_permalink( $activity_id ) );
				$text = sprintf( __( '%1$s replied to one your activity comments', 'buddypress' ), $user_fullname );
lechuck's avatar
lechuck committed
75
76
77
78
79
			}
		break;
	}

	if ( 'string' == $format ) {
ale's avatar
ale committed
80
81

		/**
lucha's avatar
lucha committed
82
		 * Filters the activity notification for the string format.
ale's avatar
ale committed
83
84
85
86
87
		 *
		 * This is a variable filter that is dependent on how many items
		 * need notified about. The two possible hooks are bp_activity_single_at_mentions_notification
		 * or bp_activity_multiple_at_mentions_notification.
		 *
lechuck's avatar
lechuck committed
88
		 * @since 1.5.0
lucha's avatar
lucha committed
89
		 * @since 2.6.0 use the $action_filter as a new dynamic portion of the filter name.
ale's avatar
ale committed
90
		 *
lucha's avatar
lucha committed
91
92
		 * @param string $string          HTML anchor tag for the interaction.
		 * @param string $link            The permalink for the interaction.
ale's avatar
ale committed
93
94
		 * @param int    $total_items     How many items being notified about.
		 * @param int    $activity_id     ID of the activity item being formatted.
lucha's avatar
lucha committed
95
		 * @param int    $user_id         ID of the user who inited the interaction.
ale's avatar
ale committed
96
		 */
lucha's avatar
lucha committed
97
		$return = apply_filters( 'bp_activity_' . $amount . '_' . $action_filter . '_notification', '<a href="' . esc_url( $link ) . '" title="' . esc_attr( $title ) . '">' . esc_html( $text ) . '</a>', $link, (int) $total_items, $activity_id, $user_id );
lechuck's avatar
lechuck committed
98
	} else {
ale's avatar
ale committed
99
100

		/**
lucha's avatar
lucha committed
101
		 * Filters the activity notification for any non-string format.
ale's avatar
ale committed
102
103
104
105
106
		 *
		 * This is a variable filter that is dependent on how many items need notified about.
		 * The two possible hooks are bp_activity_single_at_mentions_notification
		 * or bp_activity_multiple_at_mentions_notification.
		 *
lechuck's avatar
lechuck committed
107
		 * @since 1.5.0
lucha's avatar
lucha committed
108
		 * @since 2.6.0 use the $action_filter as a new dynamic portion of the filter name.
ale's avatar
ale committed
109
		 *
lucha's avatar
lucha committed
110
111
		 * @param array  $array           Array holding the content and permalink for the interaction notification.
		 * @param string $link            The permalink for the interaction.
ale's avatar
ale committed
112
113
		 * @param int    $total_items     How many items being notified about.
		 * @param int    $activity_id     ID of the activity item being formatted.
lucha's avatar
lucha committed
114
		 * @param int    $user_id         ID of the user who inited the interaction.
ale's avatar
ale committed
115
		 */
lucha's avatar
lucha committed
116
		$return = apply_filters( 'bp_activity_' . $amount . '_' . $action_filter . '_notification', array(
lechuck's avatar
lechuck committed
117
			'text' => $text,
lucha's avatar
lucha committed
118
119
			'link' => $link
		), $link, (int) $total_items, $activity_id, $user_id );
lechuck's avatar
lechuck committed
120
121
	}

ale's avatar
ale committed
122
123
124
	/**
	 * Fires right before returning the formatted activity notifications.
	 *
lechuck's avatar
lechuck committed
125
	 * @since 1.2.0
ale's avatar
ale committed
126
127
128
	 *
	 * @param string $action            The type of activity item.
	 * @param int    $item_id           The activity ID.
lucha's avatar
lucha committed
129
	 * @param int    $secondary_item_id The user ID who inited the interaction.
ale's avatar
ale committed
130
131
	 * @param int    $total_items       Total amount of items to format.
	 */
lechuck's avatar
lechuck committed
132
133
134
135
136
137
138
139
140
141
142
143
144
	do_action( 'activity_format_notifications', $action, $item_id, $secondary_item_id, $total_items );

	return $return;
}

/**
 * Notify a member when their nicename is mentioned in an activity stream item.
 *
 * Hooked to the 'bp_activity_sent_mention_email' action, we piggy back off the
 * existing email code for now, since it does the heavy lifting for us. In the
 * future when we separate emails from Notifications, this will need its own
 * 'bp_activity_at_name_send_emails' equivalent helper function.
 *
lechuck's avatar
lechuck committed
145
 * @since 1.9.0
lechuck's avatar
lechuck committed
146
 *
lechuck's avatar
lechuck committed
147
148
149
150
151
 * @param object $activity           Activity object.
 * @param string $subject (not used) Notification subject.
 * @param string $message (not used) Notification message.
 * @param string $content (not used) Notification content.
 * @param int    $receiver_user_id   ID of user receiving notification.
lechuck's avatar
lechuck committed
152
153
 */
function bp_activity_at_mention_add_notification( $activity, $subject, $message, $content, $receiver_user_id ) {
lucha's avatar
lucha committed
154
	bp_notifications_add_notification( array(
lechuck's avatar
lechuck committed
155
156
157
158
159
160
161
			'user_id'           => $receiver_user_id,
			'item_id'           => $activity->id,
			'secondary_item_id' => $activity->user_id,
			'component_name'    => buddypress()->activity->id,
			'component_action'  => 'new_at_mention',
			'date_notified'     => bp_core_current_time(),
			'is_new'            => 1,
lucha's avatar
lucha committed
162
	) );
lechuck's avatar
lechuck committed
163
164
165
}
add_action( 'bp_activity_sent_mention_email', 'bp_activity_at_mention_add_notification', 10, 5 );

lucha's avatar
lucha committed
166
167
168
169
170
171
172
173
174
175
/**
 * Notify a member one of their activity received a reply.
 *
 * @since 2.6.0
 *
 * @param BP_Activity_Activity $activity     The original activity.
 * @param int                  $comment_id   ID for the newly received comment.
 * @param int                  $commenter_id ID of the user who made the comment.
 */
function bp_activity_update_reply_add_notification( $activity, $comment_id, $commenter_id ) {
lucha's avatar
lucha committed
176
177
178
179
180
181
182
183
184
	bp_notifications_add_notification( array(
		'user_id'           => $activity->user_id,
		'item_id'           => $comment_id,
		'secondary_item_id' => $commenter_id,
		'component_name'    => buddypress()->activity->id,
		'component_action'  => 'update_reply',
		'date_notified'     => bp_core_current_time(),
		'is_new'            => 1,
	) );
lucha's avatar
lucha committed
185
186
187
188
189
190
191
192
193
194
195
196
197
}
add_action( 'bp_activity_sent_reply_to_update_notification', 'bp_activity_update_reply_add_notification', 10, 3 );

/**
 * Notify a member one of their activity comment received a reply.
 *
 * @since 2.6.0
 *
 * @param BP_Activity_Activity $activity_comment The parent activity.
 * @param int                  $comment_id       ID for the newly received comment.
 * @param int                  $commenter_id     ID of the user who made the comment.
 */
function bp_activity_comment_reply_add_notification( $activity_comment, $comment_id, $commenter_id ) {
lucha's avatar
lucha committed
198
199
200
201
202
203
204
205
206
	bp_notifications_add_notification( array(
		'user_id'           => $activity_comment->user_id,
		'item_id'           => $comment_id,
		'secondary_item_id' => $commenter_id,
		'component_name'    => buddypress()->activity->id,
		'component_action'  => 'comment_reply',
		'date_notified'     => bp_core_current_time(),
		'is_new'            => 1,
	) );
lucha's avatar
lucha committed
207
208
209
}
add_action( 'bp_activity_sent_reply_to_reply_notification', 'bp_activity_comment_reply_add_notification', 10, 3 );

lechuck's avatar
lechuck committed
210
211
212
/**
 * Mark at-mention notifications as read when users visit their Mentions page.
 *
lechuck's avatar
lechuck committed
213
214
 * @since 1.5.0
 * @since 2.5.0 Add the $user_id parameter
lechuck's avatar
lechuck committed
215
 *
lechuck's avatar
lechuck committed
216
 * @param int $user_id The id of the user whose notifications are marked as read.
lechuck's avatar
lechuck committed
217
 */
lechuck's avatar
lechuck committed
218
219
220
function bp_activity_remove_screen_notifications( $user_id = 0 ) {
	// Only mark read if the current user is looking at his own mentions.
	if ( empty( $user_id ) || (int) $user_id !== (int) bp_loggedin_user_id() ) {
lechuck's avatar
lechuck committed
221
222
223
		return;
	}

lechuck's avatar
lechuck committed
224
	bp_notifications_mark_notifications_by_type( $user_id, buddypress()->activity->id, 'new_at_mention' );
lechuck's avatar
lechuck committed
225
}
lechuck's avatar
lechuck committed
226
add_action( 'bp_activity_clear_new_mentions', 'bp_activity_remove_screen_notifications', 10, 1 );
lechuck's avatar
lechuck committed
227
228
229
230

/**
 * Mark at-mention notification as read when user visits the activity with the mention.
 *
lechuck's avatar
lechuck committed
231
 * @since 2.0.0
ale's avatar
ale committed
232
 *
lechuck's avatar
lechuck committed
233
 * @param BP_Activity_Activity $activity Activity object.
lechuck's avatar
lechuck committed
234
235
236
237
238
239
 */
function bp_activity_remove_screen_notifications_single_activity_permalink( $activity ) {
	if ( ! is_user_logged_in() ) {
		return;
	}

lechuck's avatar
lechuck committed
240
	// Mark as read any notifications for the current user related to this activity item.
lechuck's avatar
lechuck committed
241
242
243
244
	bp_notifications_mark_notifications_by_item_id( bp_loggedin_user_id(), $activity->id, buddypress()->activity->id, 'new_at_mention' );
}
add_action( 'bp_activity_screen_single_activity_permalink', 'bp_activity_remove_screen_notifications_single_activity_permalink' );

lucha's avatar
lucha committed
245
246
247
248
249
250
251
252
253
/**
 * Mark non-mention notifications as read when user visits our read permalink.
 *
 * In particular, 'update_reply' and 'comment_reply' notifications are handled
 * here. See {@link bp_activity_format_notifications()} for more info.
 *
 * @since 2.6.0
 */
function bp_activity_remove_screen_notifications_for_non_mentions() {
lucha's avatar
lucha committed
254
	if ( false === is_singular() || false === is_user_logged_in() || empty( $_GET['nid'] ) ) {
lucha's avatar
lucha committed
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
		return;
	}

	// Mark notification as read.
	BP_Notifications_Notification::update(
		array(
			'is_new'  => false
		),
		array(
			'user_id' => bp_loggedin_user_id(),
			'id'      => (int) $_GET['nid']
		)
	);
}
add_action( 'bp_screens', 'bp_activity_remove_screen_notifications_for_non_mentions' );

lechuck's avatar
lechuck committed
271
272
273
/**
 * Delete at-mention notifications when the corresponding activity item is deleted.
 *
lechuck's avatar
lechuck committed
274
 * @since 2.0.0
lechuck's avatar
lechuck committed
275
276
277
278
279
 *
 * @param array $activity_ids_deleted IDs of deleted activity items.
 */
function bp_activity_at_mention_delete_notification( $activity_ids_deleted = array() ) {
	// Let's delete all without checking if content contains any mentions
lechuck's avatar
lechuck committed
280
	// to avoid a query to get the activity.
lucha's avatar
lucha committed
281
	if ( ! empty( $activity_ids_deleted ) ) {
lechuck's avatar
lechuck committed
282
283
284
285
286
287
		foreach ( $activity_ids_deleted as $activity_id ) {
			bp_notifications_delete_all_notifications_by_type( $activity_id, buddypress()->activity->id );
		}
	}
}
add_action( 'bp_activity_deleted_activities', 'bp_activity_at_mention_delete_notification', 10 );
lucha's avatar
lucha committed
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

/**
 * Add a notification for post comments to the post author or post commenter.
 *
 * Requires "activity stream commenting on blog and forum posts" to be enabled.
 *
 * @since 2.6.0
 *
 * @param int        $activity_id          The activity comment ID.
 * @param WP_Comment $post_type_comment    WP Comment object.
 * @param array      $activity_args        Activity comment arguments.
 * @param object     $activity_post_object The post type tracking args object.
 */
function bp_activity_add_notification_for_synced_blog_comment( $activity_id, $post_type_comment, $activity_args, $activity_post_object ) {
	// If activity comments are disabled for WP posts, stop now!
lucha's avatar
lucha committed
303
	if ( bp_disable_blogforum_comments() || empty( $activity_id ) ) {
lucha's avatar
lucha committed
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
		return;
	}

	// Send a notification to the blog post author.
	if ( (int) $post_type_comment->post->post_author !== (int) $activity_args['user_id'] ) {
		// Only add a notification if comment author is a registered user.
		// @todo Should we remove this restriction?
		if ( ! empty( $post_type_comment->user_id ) ) {
			bp_notifications_add_notification( array(
				'user_id'           => $post_type_comment->post->post_author,
				'item_id'           => $activity_id,
				'secondary_item_id' => $post_type_comment->user_id,
				'component_name'    => buddypress()->activity->id,
				'component_action'  => 'update_reply',
				'date_notified'     => $post_type_comment->comment_date_gmt,
				'is_new'            => 1,
			) );
		}
	}

	// Send a notification to the parent comment author for follow-up comments.
	if ( ! empty( $post_type_comment->comment_parent ) ) {
		$parent_comment = get_comment( $post_type_comment->comment_parent );

		if ( ! empty( $parent_comment->user_id ) && (int) $parent_comment->user_id !== (int) $activity_args['user_id'] ) {
			bp_notifications_add_notification( array(
				'user_id'           => $parent_comment->user_id,
				'item_id'           => $activity_id,
				'secondary_item_id' => $post_type_comment->user_id,
				'component_name'    => buddypress()->activity->id,
				'component_action'  => 'comment_reply',
				'date_notified'     => $post_type_comment->comment_date_gmt,
				'is_new'            => 1,
			) );
		}
	}
}
add_action( 'bp_blogs_comment_sync_activity_comment', 'bp_activity_add_notification_for_synced_blog_comment', 10, 4 );