PluginProbe
bbPress / 2.6.15
bbPress v2.6.15
trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.2.2 All 71 releases
bbpress / includes / users / engagements.php

engagements.php in bbPress 2.6.15, at includes/users/engagements.php

1,230 lines 35.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress User Engagement Functions
5 *
6 * @package bbPress
7 * @subpackage Engagements
8 */
9
10 // Exit if accessed directly
11 defined( 'ABSPATH' ) || exit;
12
13 /** User Relationships ********************************************************/
14
15 /**
16 * Add a user id to an object
17 *
18 * @since 2.6.0 bbPress (r6109)
19 *
20 * @param int $object_id The object id
21 * @param int $user_id The user id
22 * @param string $rel_key The relationship key
23 * @param string $rel_type The relationship type (usually 'post')
24 * @param bool $unique Whether meta key should be unique to the object
25 *
26 * @return bool Returns true on success, false on failure
27 */
28 function bbp_add_user_to_object( $object_id = 0, $user_id = 0, $rel_key = '', $rel_type = 'post', $unique = false ) {
29 $object_id = absint( $object_id );
30 $user_id = absint( $user_id );
31 $retval = bbp_user_engagements_interface( $rel_key, $rel_type )->add_user_to_object( $object_id, $user_id, $rel_key, $rel_type, $unique );
32
33 // Filter & return
34 return (bool) apply_filters( 'bbp_add_user_to_object', $retval, $object_id, $user_id, $rel_key, $rel_type, $unique );
35 }
36
37 /**
38 * Remove a user id from an object
39 *
40 * @since 2.6.0 bbPress (r6109)
41 *
42 * @param int $object_id The object id
43 * @param int $user_id The user id
44 * @param string $rel_key The relationship key
45 * @param string $rel_type The relationship type (usually 'post')
46 *
47 * @return bool Returns true on success, false on failure
48 */
49 function bbp_remove_user_from_object( $object_id = 0, $user_id = 0, $rel_key = '', $rel_type = 'post' ) {
50 $retval = bbp_user_engagements_interface( $rel_key, $rel_type )->remove_user_from_object( $object_id, $user_id, $rel_key, $rel_type );
51
52 // Filter & return
53 return (bool) apply_filters( 'bbp_remove_user_from_object', $retval, $object_id, $user_id, $rel_key, $rel_type );
54 }
55
56 /**
57 * Remove a user id from all objects
58 *
59 * @since 2.6.0 bbPress (r6109)
60 *
61 * @param int $user_id The user id
62 * @param string $rel_key The relationship key
63 * @param string $rel_type The relationship type (usually 'post')
64 *
65 * @return bool Returns true on success, false on failure
66 */
67 function bbp_remove_user_from_all_objects( $user_id = 0, $rel_key = '', $rel_type = 'post' ) {
68 $user_id = absint( $user_id );
69 $retval = bbp_user_engagements_interface( $rel_key, $rel_type )->remove_user_from_all_objects( $user_id, $rel_key, $rel_type );
70
71 // Filter & return
72 return (bool) apply_filters( 'bbp_remove_user_from_all_objects', $retval, $user_id, $rel_key, $rel_type );
73 }
74
75 /**
76 * Remove an object from all users
77 *
78 * @since 2.6.0 bbPress (r6109)
79 *
80 * @param int $object_id The object id
81 * @param int $user_id The user id
82 * @param string $rel_key The relationship key
83 * @param string $rel_type The relationship type (usually 'post')
84 *
85 * @return bool Returns true on success, false on failure
86 */
87 function bbp_remove_object_from_all_users( $object_id = 0, $rel_key = '', $rel_type = 'post' ) {
88 $object_id = absint( $object_id );
89 $retval = bbp_user_engagements_interface( $rel_key, $rel_type )->remove_object_from_all_users( $object_id, $rel_key, $rel_type );
90
91 // Filter & return
92 return (bool) apply_filters( 'bbp_remove_object_from_all_users', $retval, $object_id, $rel_key, $rel_type );
93 }
94
95 /**
96 * Remove all users from all objects
97 *
98 * @since 2.6.0 bbPress (r6109)
99 *
100 * @param string $rel_key The relationship key
101 * @param string $rel_type The relationship type (usually 'post')
102 *
103 * @return bool Returns true on success, false on failure
104 */
105 function bbp_remove_all_users_from_all_objects( $rel_key = '', $rel_type = 'post' ) {
106 $retval = bbp_user_engagements_interface( $rel_key, $rel_type )->remove_all_users_from_all_objects( $rel_key, $rel_type );
107
108 // Filter & return
109 return (bool) apply_filters( 'bbp_remove_all_users_from_all_objects', $retval, $rel_key, $rel_type );
110 }
111
112 /**
113 * Get users of an object
114 *
115 * @since 2.6.0 bbPress (r6109)
116 *
117 * @param int $object_id The object id
118 * @param string $rel_key The key used to index this relationship
119 * @param string $rel_type The type of meta to look in
120 *
121 * @return array Returns ids of users
122 */
123 function bbp_get_users_for_object( $object_id = 0, $rel_key = '', $rel_type = 'post' ) {
124 $object_id = absint( $object_id );
125 $retval = bbp_user_engagements_interface( $rel_key, $rel_type )->get_users_for_object( $object_id, $rel_key, $rel_type );
126
127 // Filter & return
128 return (array) apply_filters( 'bbp_get_users_for_object', $retval, $object_id, $rel_key, $rel_type );
129 }
130
131 /**
132 * Check if an object has a specific user
133 *
134 * @since 2.6.0 bbPress (r6109)
135 *
136 * @param int $object_id The object id
137 * @param int $user_id The user id
138 * @param string $rel_key The relationship key
139 * @param string $rel_type The relationship type (usually 'post')
140 *
141 * @return bool Returns true if object has a user, false if not
142 */
143 function bbp_is_object_of_user( $object_id = 0, $user_id = 0, $rel_key = '', $rel_type = 'post' ) {
144 $object_id = absint( $object_id );
145 $user_id = absint( $user_id );
146 $user_ids = bbp_get_users_for_object( $object_id, $rel_key, $rel_type );
147 $retval = is_numeric( array_search( $user_id, $user_ids, true ) );
148
149 // Filter & return
150 return (bool) apply_filters( 'bbp_is_object_of_user', $retval, $object_id, $user_id, $rel_key, $rel_type );
151 }
152
153 /**
154 * Get the query part responsible for JOINing objects to user IDs
155 *
156 * @since 2.6.0 bbPress (r6747)
157 *
158 * @param array $args Default query arguments
159 * @param string $context Additional context
160 * @param string $rel_key The relationship key
161 * @param string $rel_type The relationship type (usually 'post')
162 *
163 * @return array
164 */
165 function bbp_get_user_object_query( $args = array(), $context = '', $rel_key = '', $rel_type = 'post' ) {
166 $retval = bbp_user_engagements_interface( $rel_key, $rel_type )->get_query( $args, "get_user_{$context}", $rel_key, $rel_type );
167
168 // Filter & return
169 return (array) apply_filters( 'bbp_get_user_object_query', $retval, $args, $context, $rel_key, $rel_type );
170 }
171
172 /** Engagements ***************************************************************/
173
174 /**
175 * Get the users who have engaged in a topic
176 *
177 * @since 2.6.0 bbPress (r6320)
178 *
179 * @param int $topic_id Optional. Topic id
180 *
181 * @return array|bool Results if the topic has any engagements, otherwise false
182 */
183 function bbp_get_topic_engagements( $topic_id = 0 ) {
184 $topic_id = bbp_get_topic_id( $topic_id );
185 $users = bbp_get_users_for_object( $topic_id, '_bbp_engagement' );
186
187 // Filter & return
188 return (array) apply_filters( 'bbp_get_topic_engagements', $users, $topic_id );
189 }
190
191 /**
192 * Return the users who have engaged in a topic, directly with a database query
193 *
194 * See: https://bbpress.trac.wordpress.org/ticket/3083
195 *
196 * @since 2.6.0 bbPress (r6522)
197 *
198 * @param int $topic_id
199 *
200 * @return array
201 */
202 function bbp_get_topic_engagements_raw( $topic_id = 0 ) {
203
204 // Default variables
205 $topic_id = bbp_get_topic_id( $topic_id );
206 $bbp_db = bbp_db();
207 $statii = "'" . implode( "', '", bbp_get_public_topic_statuses() ) . "'";
208
209 // A cool UNION query!
210 $sql = "
211 SELECT DISTINCT( post_author ) FROM (
212 SELECT post_author FROM {$bbp_db->posts}
213 WHERE ( ID = %d AND post_status IN ({$statii}) AND post_type = %s )
214 UNION
215 SELECT post_author FROM {$bbp_db->posts}
216 WHERE ( post_parent = %d AND post_status = %s AND post_type = %s )
217 ) as u1";
218
219 // Prepare & get results
220 $query = $bbp_db->prepare( $sql, $topic_id, bbp_get_topic_post_type(), $topic_id, bbp_get_public_status_id(), bbp_get_reply_post_type() );
221 $results = $bbp_db->get_col( $query );
222
223 // Parse results into voices
224 $engagements = ! is_wp_error( $results )
225 ? wp_parse_id_list( array_filter( $results ) )
226 : array();
227
228 // Filter & return
229 return (array) apply_filters( 'bbp_get_topic_engagements_raw', $engagements, $topic_id );
230 }
231
232 /**
233 * Get a user's topic engagements
234 *
235 * @since 2.6.0 bbPress (r6320)
236 * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
237 *
238 * @param array $args Optional. Arguments to pass into bbp_has_replies()
239 *
240 * @return bool True if user has engaged, otherwise false
241 */
242 function bbp_get_user_engagements( $args = array() ) {
243 $r = bbp_get_user_object_query( $args, 'engagements', '_bbp_engagement' );
244 $query = bbp_has_topics( $r );
245
246 // Filter & return
247 return apply_filters( 'bbp_get_user_engagements', $query, 0, $r, $args );
248 }
249
250 /**
251 * Check if a user is engaged in a topic or not
252 *
253 * @since 2.6.0 bbPress (r6320)
254 *
255 * @param int $user_id Optional. User id
256 * @param int $topic_id Optional. Topic id
257 *
258 * @return bool True if the topic is in user's engagements, otherwise false
259 */
260 function bbp_is_user_engaged( $user_id = 0, $topic_id = 0 ) {
261 $user_id = bbp_get_user_id( $user_id, true, true );
262 $topic_id = bbp_get_topic_id( $topic_id );
263 $retval = bbp_is_object_of_user( $topic_id, $user_id, '_bbp_engagement' );
264
265 // Filter & return
266 return (bool) apply_filters( 'bbp_is_user_engaged', $retval, $user_id, $topic_id );
267 }
268
269 /**
270 * Add a topic to user's engagements
271 *
272 * Note that both the User and Topic should be verified to exist before using
273 * this function. Originally both were validated, but because this function is
274 * frequently used within a loop, those verifications were moved upstream to
275 * improve performance on topics with many engaged users.
276 *
277 * @since 2.6.0 bbPress (r6320)
278 *
279 * @param int $user_id Optional. User id
280 * @param int $topic_id Optional. Topic id
281 *
282 * @return bool Always true
283 */
284 function bbp_add_user_engagement( $user_id = 0, $topic_id = 0 ) {
285
286 // Bail if not enough info
287 if ( empty( $user_id ) || empty( $topic_id ) ) {
288 return false;
289 }
290
291 // Bail if already a engaged
292 if ( bbp_is_user_engaged( $user_id, $topic_id ) ) {
293 return false;
294 }
295
296 // Bail if add fails
297 if ( ! bbp_add_user_to_object( $topic_id, $user_id, '_bbp_engagement' ) ) {
298 return false;
299 }
300
301 do_action( 'bbp_add_user_engagement', $user_id, $topic_id );
302
303 return true;
304 }
305
306 /**
307 * Remove a topic from user's engagements
308 *
309 * @since 2.6.0 bbPress (r6320)
310 *
311 * @param int $user_id Optional. User id
312 * @param int $topic_id Optional. Topic id
313 *
314 * @return bool True if the topic was removed from user's engagements, otherwise
315 * false
316 */
317 function bbp_remove_user_engagement( $user_id = 0, $topic_id = 0 ) {
318
319 // Bail if not enough info
320 if ( empty( $user_id ) || empty( $topic_id ) ) {
321 return false;
322 }
323
324 // Bail if not already engaged
325 if ( ! bbp_is_user_engaged( $user_id, $topic_id ) ) {
326 return false;
327 }
328
329 // Bail if remove fails
330 if ( ! bbp_remove_user_from_object( $topic_id, $user_id, '_bbp_engagement' ) ) {
331 return false;
332 }
333
334 do_action( 'bbp_remove_user_engagement', $user_id, $topic_id );
335
336 return true;
337 }
338
339 /**
340 * Recalculate all of the users who have engaged in a topic.
341 *
342 * This happens when permanently deleting a reply, because that reply author may
343 * have authored other replies to that same topic, or the topic itself.
344 *
345 * You may need to do this manually on heavily active forums where engagement
346 * count accuracy is important.
347 *
348 * @since 2.6.0 bbPress (r6522)
349 *
350 * @param int $topic_id
351 * @param bool $force
352 *
353 * @return boolean True if any engagements are added, false otherwise
354 */
355 function bbp_recalculate_topic_engagements( $topic_id = 0, $force = false ) {
356
357 // Default return value
358 $retval = false;
359
360 // Check post type
361 $topic_id = bbp_is_reply( $topic_id )
362 ? bbp_get_reply_topic_id( $topic_id )
363 : bbp_get_topic_id( $topic_id );
364
365 // Bail if no topic ID
366 if ( empty( $topic_id ) ) {
367 return $retval;
368 }
369
370 // Query for engagements
371 $old_engagements = bbp_get_topic_engagements( $topic_id );
372 $new_engagements = bbp_get_topic_engagements_raw( $topic_id );
373
374 // Sort arrays
375 sort( $old_engagements, SORT_NUMERIC );
376 sort( $new_engagements, SORT_NUMERIC );
377
378 // Only recalculate on change
379 if ( ( true === $force ) || ( $old_engagements !== $new_engagements ) ) {
380
381 // Delete all engagements
382 bbp_remove_object_from_all_users( $topic_id, '_bbp_engagement' );
383
384 // Update the voice count for this topic id
385 foreach ( $new_engagements as $user_id ) {
386 $retval = bbp_add_user_engagement( $user_id, $topic_id );
387 }
388 }
389
390 // Filter & return
391 return (bool) apply_filters( 'bbp_recalculate_user_engagements', $retval, $topic_id );
392 }
393
394 /**
395 * Update the engagements of a topic.
396 *
397 * Hooked to 'bbp_new_topic' and 'bbp_new_reply', this gets the post author and
398 * if not anonymous, passes it into bbp_add_user_engagement().
399 *
400 * @since 2.6.0 bbPress (r6526)
401 *
402 * @param int $topic_id
403 */
404 function bbp_update_topic_engagements( $topic_id = 0 ) {
405
406 // Is a reply
407 if ( bbp_is_reply( $topic_id ) ) {
408
409 // Bail if reply isn't published
410 if ( ! bbp_is_reply_published( $topic_id ) ) {
411 return;
412 }
413
414 $author_id = bbp_get_reply_author_id( $topic_id );
415 $topic_id = bbp_get_reply_topic_id( $topic_id );
416
417 // Is a topic
418 } elseif ( bbp_is_topic( $topic_id ) ) {
419
420 // Bail if topic isn't published
421 if ( ! bbp_is_topic_published( $topic_id ) ) {
422 return;
423 }
424
425 $author_id = bbp_get_topic_author_id( $topic_id );
426 $topic_id = bbp_get_topic_id( $topic_id );
427
428 // Is unknown
429 } else {
430 return;
431 }
432
433 // Bail if topic is not public
434 if ( ! bbp_is_topic_public( $topic_id ) ) {
435 return;
436 }
437
438 // Return whether engagement was added
439 return bbp_add_user_engagement( $author_id, $topic_id );
440 }
441
442 /** Favorites *****************************************************************/
443
444 /**
445 * Get the users who have made the topic favorite
446 *
447 * @since 2.0.0 bbPress (r2658)
448 *
449 * @param int $topic_id Optional. Topic id
450 *
451 * @return array|bool Results if the topic has any favoriters, otherwise false
452 */
453 function bbp_get_topic_favoriters( $topic_id = 0 ) {
454 $topic_id = bbp_get_topic_id( $topic_id );
455 $users = bbp_get_users_for_object( $topic_id, '_bbp_favorite' );
456
457 // Filter & return
458 return (array) apply_filters( 'bbp_get_topic_favoriters', $users, $topic_id );
459 }
460
461 /**
462 * Get a user's favorite topics
463 *
464 * @since 2.0.0 bbPress (r2652)
465 * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
466 *
467 * @param array $args Optional. Arguments to pass into bbp_has_topics()
468 *
469 * @return array Array of topics if user has favorites, otherwise empty array
470 */
471 function bbp_get_user_favorites( $args = array() ) {
472 $r = bbp_get_user_object_query( $args, 'favorites', '_bbp_favorite' );
473 $query = ! empty( $r )
474 ? bbp_has_topics( $r )
475 : array();
476
477 // Filter & return
478 return apply_filters( 'bbp_get_user_favorites', $query, 0, $r, $args );
479 }
480
481 /**
482 * Check if a topic is in user's favorites or not
483 *
484 * @since 2.0.0 bbPress (r2652)
485 *
486 * @param int $user_id Optional. User id
487 * @param int $topic_id Optional. Topic id
488 *
489 * @return bool True if the topic is in user's favorites, otherwise false
490 */
491 function bbp_is_user_favorite( $user_id = 0, $topic_id = 0 ) {
492 $retval = bbp_is_object_of_user( $topic_id, $user_id, '_bbp_favorite' );
493
494 // Filter & return
495 return (bool) apply_filters( 'bbp_is_user_favorite', $retval, $user_id, $topic_id );
496 }
497
498 /**
499 * Add a topic to user's favorites
500 *
501 * Note that both the User and Topic should be verified to exist before using
502 * this function. Originally both were validated, but because this function is
503 * frequently used within a loop, those verifications were moved upstream to
504 * improve performance on topics with many engaged users.
505 *
506 * @since 2.0.0 bbPress (r2652)
507 *
508 * @param int $user_id Optional. User id
509 * @param int $topic_id Optional. Topic id
510 *
511 * @return bool True if the topic was added to user's favorites, otherwise false
512 */
513 function bbp_add_user_favorite( $user_id = 0, $topic_id = 0 ) {
514 $user_id = bbp_get_user_id( $user_id, false, false );
515 $topic_id = bbp_get_topic_id( $topic_id );
516
517 // Bail if not enough info
518 if ( empty( $user_id ) || empty( $topic_id ) ) {
519 return false;
520 }
521
522 // Bail if already a favorite
523 if ( bbp_is_user_favorite( $user_id, $topic_id ) ) {
524 return false;
525 }
526
527 // Bail if add fails
528 if ( ! bbp_add_user_to_object( $topic_id, $user_id, '_bbp_favorite' ) ) {
529 return false;
530 }
531
532 do_action( 'bbp_add_user_favorite', $user_id, $topic_id );
533
534 return true;
535 }
536
537 /**
538 * Remove a topic from user's favorites
539 *
540 * @since 2.0.0 bbPress (r2652)
541 *
542 * @param int $user_id Optional. User id
543 * @param int $topic_id Optional. Topic id
544 *
545 * @return bool True if the topic was removed from user's favorites, otherwise false
546 */
547 function bbp_remove_user_favorite( $user_id, $topic_id ) {
548 $user_id = bbp_get_user_id( $user_id, false, false );
549 $topic_id = bbp_get_topic_id( $topic_id );
550
551 // Bail if not enough info
552 if ( empty( $user_id ) || empty( $topic_id ) ) {
553 return false;
554 }
555
556 // Bail if not already a favorite
557 if ( ! bbp_is_user_favorite( $user_id, $topic_id ) ) {
558 return false;
559 }
560
561 // Bail if remove fails
562 if ( ! bbp_remove_user_from_object( $topic_id, $user_id, '_bbp_favorite' ) ) {
563 return false;
564 }
565
566 do_action( 'bbp_remove_user_favorite', $user_id, $topic_id );
567
568 return true;
569 }
570
571 /**
572 * Handles the front end adding and removing of favorite topics
573 *
574 * @param string $action The requested action to compare this function to
575 */
576 function bbp_favorites_handler( $action = '' ) {
577
578 // Default
579 $success = false;
580
581 // Bail if favorites not active
582 if ( ! bbp_is_favorites_active() ) {
583 return $success;
584 }
585
586 // Bail if no topic ID is passed
587 if ( empty( $_GET['object_id'] ) ) {
588 return $success;
589 }
590
591 // Setup possible get actions
592 $possible_actions = array(
593 'bbp_favorite_add',
594 'bbp_favorite_remove',
595 );
596
597 // Bail if actions aren't meant for this function
598 if ( ! in_array( $action, $possible_actions, true ) ) {
599 return $success;
600 }
601
602 // What action is taking place?
603 $topic_id = bbp_get_topic_id( $_GET['object_id'] );
604 $user_id = bbp_get_user_id( 0, true, true );
605
606 // Check for empty topic
607 if ( empty( $topic_id ) ) {
608 bbp_add_error( 'bbp_favorite_topic_id', __( '<strong>Error</strong>: No topic was found. Which topic are you marking/unmarking as favorite?', 'bbpress' ) );
609
610 // Check nonce
611 } elseif ( ! bbp_verify_nonce_request( 'toggle-favorite_' . $topic_id ) ) {
612 bbp_add_error( 'bbp_favorite_nonce', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
613
614 // Check current user's ability to edit the user
615 } elseif ( ! current_user_can( 'edit_user', $user_id ) ) {
616 bbp_add_error( 'bbp_favorite_permission', __( '<strong>Error</strong>: You do not have permission to edit favorites for that user.', 'bbpress' ) );
617 }
618
619 // Bail if errors
620 if ( bbp_has_errors() ) {
621 return $success;
622 }
623
624 /** No errors *************************************************************/
625
626 if ( 'bbp_favorite_remove' === $action ) {
627 $success = bbp_remove_user_favorite( $user_id, $topic_id );
628 } elseif ( 'bbp_favorite_add' === $action ) {
629 $success = bbp_add_user_favorite( $user_id, $topic_id );
630 }
631
632 // Do additional favorites actions
633 do_action( 'bbp_favorites_handler', $success, $user_id, $topic_id, $action );
634
635 // Success!
636 if ( true === $success ) {
637
638 // Redirect back from whence we came
639 if ( ! empty( $_REQUEST['redirect_to'] ) ) {
640 $redirect = $_REQUEST['redirect_to']; // Validated later
641 } elseif ( bbp_is_favorites() ) {
642 $redirect = bbp_get_favorites_permalink( $user_id, true );
643 } elseif ( bbp_is_single_user() ) {
644 $redirect = bbp_get_user_profile_url();
645 } elseif ( is_singular( bbp_get_topic_post_type() ) ) {
646 $redirect = bbp_get_topic_permalink( $topic_id );
647 } elseif ( is_single() || is_page() ) {
648 $redirect = get_permalink();
649 } else {
650 $redirect = get_permalink( $topic_id );
651 }
652
653 bbp_redirect( $redirect );
654
655 // Fail! Handle errors
656 } elseif ( 'bbp_favorite_remove' === $action ) {
657 bbp_add_error( 'bbp_favorite_remove', __( '<strong>Error</strong>: There was a problem removing that topic from favorites.', 'bbpress' ) );
658 } elseif ( 'bbp_favorite_add' === $action ) {
659 bbp_add_error( 'bbp_favorite_add', __( '<strong>Error</strong>: There was a problem favoriting that topic.', 'bbpress' ) );
660 }
661
662 return (bool) $success;
663 }
664
665 /** Subscriptions *************************************************************/
666
667 /**
668 * Get the users who have subscribed
669 *
670 * @since 2.6.0 bbPress (r5156)
671 *
672 * @param int $object_id Optional. ID of object (forum, topic, or something else)
673 */
674 function bbp_get_subscribers( $object_id = 0, $type = 'post' ) {
675 $users = bbp_get_users_for_object( $object_id, '_bbp_subscription', $type );
676
677 // Filter & return
678 return (array) apply_filters( 'bbp_get_subscribers', $users, $object_id, $type );
679 }
680
681 /**
682 * Get a user's subscribed topics
683 *
684 * @since 2.0.0 bbPress (r2668)
685 * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
686 *
687 * @param array $args Optional. Arguments to pass into bbp_has_topics()
688 *
689 * @return array Array of topics if user has topic subscriptions, otherwise empty array
690 */
691 function bbp_get_user_topic_subscriptions( $args = array() ) {
692 $r = bbp_get_user_object_query( $args, 'topic_subscriptions', '_bbp_subscription' );
693 $query = ! empty( $r )
694 ? bbp_has_topics( $r )
695 : array();
696
697 // Filter & return
698 return apply_filters( 'bbp_get_user_topic_subscriptions', $query, 0, $r, $args );
699 }
700
701 /**
702 * Get a user's subscribed forums
703 *
704 * @since 2.5.0 bbPress (r5156)
705 * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
706 *
707 * @param array $args Optional. Arguments to pass into bbp_has_forums()
708 *
709 * @return array Array of forums if user has forum subscriptions, otherwise empty array
710 */
711 function bbp_get_user_forum_subscriptions( $args = array() ) {
712 $r = bbp_get_user_object_query( $args, 'forum_subscriptions', '_bbp_subscription' );
713 $query = ! empty( $r )
714 ? bbp_has_forums( $r )
715 : array();
716
717 // Filter & return
718 return apply_filters( 'bbp_get_user_forum_subscriptions', $query, 0, $r, $args );
719 }
720
721 /**
722 * Check if an object (forum or topic) is in user's subscription list or not
723 *
724 * @since 2.5.0 bbPress (r5156)
725 *
726 * @param int $user_id Optional. User id
727 * @param int $object_id Optional. Object id
728 *
729 * @return bool True if the object (forum or topic) is in user's subscriptions, otherwise false
730 */
731 function bbp_is_user_subscribed( $user_id = 0, $object_id = 0, $type = 'post' ) {
732 $retval = bbp_is_object_of_user( $object_id, $user_id, '_bbp_subscription', $type );
733
734 // Filter & return
735 return (bool) apply_filters( 'bbp_is_user_subscribed', $retval, $user_id, $object_id, $type );
736 }
737
738 /**
739 * Add a user subscription
740 *
741 * @since 2.5.0 bbPress (r5156)
742 * @since 2.6.0 bbPress (r6544) Added $type parameter
743 *
744 * @param int $user_id Optional. User id
745 * @param int $object_id Optional. Object id
746 * @param string $type Optional. Type of object being subscribed to
747 *
748 * @return bool True if the object was added to user subscriptions, otherwise false
749 */
750 function bbp_add_user_subscription( $user_id = 0, $object_id = 0, $type = 'post' ) {
751
752 // Bail if not enough info
753 if ( empty( $user_id ) || empty( $object_id ) ) {
754 return false;
755 }
756
757 // Bail if already subscribed
758 if ( bbp_is_user_subscribed( $user_id, $object_id, $type ) ) {
759 return false;
760 }
761
762 // Bail if add fails
763 if ( ! bbp_add_user_to_object( $object_id, $user_id, '_bbp_subscription', $type ) ) {
764 return false;
765 }
766
767 do_action( 'bbp_add_user_subscription', $user_id, $object_id, $type );
768
769 return true;
770 }
771
772 /**
773 * Remove a user subscription
774 *
775 * @since 2.5.0 bbPress (r5156)
776 * @since 2.6.0 bbPress (r6544) Added $type parameter
777 *
778 * @param int $user_id Optional. User id
779 * @param int $object_id Optional. Object id
780 * @param string $type Optional. Type of object being subscribed to
781 *
782 * @return bool True if the object was removed from user subscriptions, otherwise false
783 */
784 function bbp_remove_user_subscription( $user_id = 0, $object_id = 0, $type = 'post' ) {
785
786 // Bail if not enough info
787 if ( empty( $user_id ) || empty( $object_id ) ) {
788 return false;
789 }
790
791 // Bail if not subscribed
792 if ( ! bbp_is_user_subscribed( $user_id, $object_id, $type ) ) {
793 return false;
794 }
795
796 // Bail if remove fails
797 if ( ! bbp_remove_user_from_object( $object_id, $user_id, '_bbp_subscription', $type ) ) {
798 return false;
799 }
800
801 do_action( 'bbp_remove_user_subscription', $user_id, $object_id, $type );
802
803 return true;
804 }
805
806 /**
807 * Handles the front end toggling of user subscriptions
808 *
809 * @since 2.0.0 bbPress (r2790)
810 * @since 2.6.l bbPress (r6543)
811 *
812 * @param string $action The requested action to compare this function to
813 */
814 function bbp_subscriptions_handler( $action = '' ) {
815
816 // Default
817 $success = false;
818
819 // Bail if subscriptions not active
820 if ( ! bbp_is_subscriptions_active() ) {
821 return $success;
822 }
823
824 // Bail if no object ID is passed
825 if ( empty( $_GET['object_id'] ) ) {
826 return $success;
827 }
828
829 // Setup possible get actions
830 $possible_actions = array(
831 'bbp_subscribe',
832 'bbp_unsubscribe'
833 );
834
835 // Bail if actions aren't meant for this function
836 if ( ! in_array( $action, $possible_actions, true ) ) {
837 return $success;
838 }
839
840 // Get required data
841 $user_id = bbp_get_current_user_id();
842 $object_id = absint( $_GET['object_id'] );
843 $object_type = ! empty( $_GET['object_type'] )
844 ? sanitize_key( $_GET['object_type'] )
845 : 'post';
846
847 // Check for empty topic
848 if ( empty( $object_id ) ) {
849 bbp_add_error( 'bbp_subscription_object_id', __( '<strong>Error</strong>: Not found. What are you subscribing/unsubscribing to?', 'bbpress' ) );
850
851 // Check nonce
852 } elseif ( ! bbp_verify_nonce_request( 'toggle-subscription_' . $object_id ) ) {
853 bbp_add_error( 'bbp_subscription_object_id', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
854
855 // Check current user's ability to edit the user
856 } elseif ( ! current_user_can( 'edit_user', $user_id ) ) {
857 bbp_add_error( 'bbp_subscription_permission', __( '<strong>Error</strong>: You do not have permission to edit subscriptions of that user.', 'bbpress' ) );
858 }
859
860 // Bail if we have errors
861 if ( bbp_has_errors() ) {
862 return $success;
863 }
864
865 /** No errors *************************************************************/
866
867 if ( 'bbp_unsubscribe' === $action ) {
868 $success = bbp_remove_user_subscription( $user_id, $object_id, $object_type );
869 } elseif ( 'bbp_subscribe' === $action ) {
870 $success = bbp_add_user_subscription( $user_id, $object_id, $object_type );
871 }
872
873 // Do additional subscriptions actions
874 do_action( 'bbp_subscriptions_handler', $success, $user_id, $object_id, $action, $object_type );
875
876 // Success!
877 if ( true === $success ) {
878
879 // Redirect back from whence we came
880 if ( ! empty( $_REQUEST['redirect_to'] ) ) {
881 $redirect = $_REQUEST['redirect_to']; // Validated later
882 } elseif ( bbp_is_subscriptions() ) {
883 $redirect = bbp_get_subscriptions_permalink( $user_id );
884 } elseif ( bbp_is_single_user() ) {
885 $redirect = bbp_get_user_profile_url();
886 } elseif ( is_singular( bbp_get_topic_post_type() ) ) {
887 $redirect = bbp_get_topic_permalink( $object_id );
888 } elseif ( is_singular( bbp_get_forum_post_type() ) ) {
889 $redirect = bbp_get_forum_permalink( $object_id );
890 } elseif ( is_single() || is_page() ) {
891 $redirect = get_permalink();
892 } else {
893 $redirect = get_permalink( $object_id );
894 }
895
896 bbp_redirect( $redirect );
897
898 // Fail! Handle errors
899 } elseif ( 'bbp_unsubscribe' === $action ) {
900 bbp_add_error( 'bbp_unsubscribe', __( '<strong>Error</strong>: There was a problem unsubscribing.', 'bbpress' ) );
901 } elseif ( 'bbp_subscribe' === $action ) {
902 bbp_add_error( 'bbp_subscribe', __( '<strong>Error</strong>: There was a problem subscribing.', 'bbpress' ) );
903 }
904
905 return (bool) $success;
906 }
907
908 /** Query Helpers *************************************************************/
909
910 /**
911 * These functions are no longer used in bbPress due to general performance
912 * concerns on large installations. They are provided here for convenience and
913 * backwards compatibility only.
914 */
915
916 /**
917 * Get a user's object IDs
918 *
919 * For the most part, you should not need to use this function, and may even
920 * want to come up with a more efficient way to get IDs on your own. Nevertheless,
921 * it is available here for your convenience, using the most efficient query
922 * parameters available inside of the various query APIs.
923 *
924 * @since 2.6.0 bbPress (r6606)
925 *
926 * @param int $user_id The user id
927 * @param string $rel_key The relationship key
928 * @param string $rel_type The relationship type (usually 'post')
929 * @param array $args The arguments to override defaults
930 *
931 * @return array|bool Results if user has objects, otherwise null
932 */
933 function bbp_get_user_object_ids( $args = array() ) {
934 $object_ids = $defaults = array();
935
936 // Parse arguments
937 $r = bbp_parse_args( $args, array(
938 'user_id' => 0,
939 'object_type' => bbp_get_topic_post_type(),
940 'rel_key' => '',
941 'rel_type' => 'post',
942 'filter' => 'user_object_ids',
943 'args' => array()
944 ), 'get_user_object_ids' );
945
946 // Sanitize arguments
947 $r['user_id'] = bbp_get_user_id( $r['user_id'] );
948 $r['rel_key'] = sanitize_key( $r['rel_key'] );
949 $r['rel_type'] = sanitize_key( $r['rel_type'] );
950 $r['object_type'] = sanitize_key( $r['object_type'] );
951 $r['filter'] = sanitize_key( $r['filter'] );
952
953 // Defaults
954 if ( 'post' === $r['rel_type'] ) {
955 $defaults = array(
956 'fields' => 'ids',
957 'post_type' => $r['object_type'],
958 'posts_per_page' => -1,
959 'meta_query' => array( array(
960 'key' => $r['rel_key'],
961 'value' => $r['user_id'],
962 'compare' => 'NUMERIC'
963 ),
964
965 // Performance
966 'nopaging' => true,
967 'suppress_filters' => true,
968 'update_post_term_cache' => false,
969 'update_post_meta_cache' => false,
970 'ignore_sticky_posts' => true,
971 'no_found_rows' => true
972 ) );
973 }
974
975 // Parse arguments
976 $query_args = bbp_parse_args( $r['args'], $defaults, "get_{$r['filter']}_args" );
977
978 // Queries
979 if ( 'post' === $r['rel_type'] ) {
980 $query = new WP_Query( $query_args );
981 $object_ids = $query->posts;
982 }
983
984 // Filter & return
985 return (array) apply_filters( "bbp_get_{$r['filter']}", $object_ids, $r, $args );
986 }
987
988 /**
989 * Get array of forum IDs that a user can moderate
990 *
991 * @since 2.6.0 bbPress (r5834)
992 *
993 * @param int $user_id User id.
994 *
995 * @return array Return array of forum ids, or empty array
996 */
997 function bbp_get_moderator_forum_ids( $user_id = 0 ) {
998 return bbp_get_user_object_ids( array(
999 'user_id' => $user_id,
1000 'rel_key' => '_bbp_moderator_id',
1001 'object_type' => bbp_get_forum_post_type(),
1002 'filter' => 'moderator_forum_ids'
1003 ) );
1004 }
1005
1006 /**
1007 * Get a user's engaged topic ids
1008 *
1009 * @since 2.6.0 bbPress (r6320)
1010 *
1011 * @param int $user_id Optional. User id
1012 *
1013 * @return array Return array of topic ids, or empty array
1014 */
1015 function bbp_get_user_engaged_topic_ids( $user_id = 0 ) {
1016 return bbp_get_user_object_ids( array(
1017 'user_id' => $user_id,
1018 'rel_key' => '_bbp_engagement',
1019 'filter' => 'user_engaged_topic_ids'
1020 ) );
1021 }
1022
1023 /**
1024 * Get a user's favorite topic ids
1025 *
1026 * @since 2.0.0 bbPress (r2652)
1027 *
1028 * @param int $user_id Optional. User id
1029 *
1030 * @return array Return array of favorite topic ids, or empty array
1031 */
1032 function bbp_get_user_favorites_topic_ids( $user_id = 0 ) {
1033 return bbp_get_user_object_ids( array(
1034 'user_id' => $user_id,
1035 'rel_key' => '_bbp_favorite',
1036 'filter' => 'user_favorites_topic_ids'
1037 ) );
1038 }
1039
1040 /**
1041 * Get a user's subscribed forum ids
1042 *
1043 * @since 2.5.0 bbPress (r5156)
1044 *
1045 * @param int $user_id Optional. User id
1046 *
1047 * @return array Return array of subscribed forum ids, or empty array
1048 */
1049 function bbp_get_user_subscribed_forum_ids( $user_id = 0 ) {
1050 return bbp_get_user_object_ids( array(
1051 'user_id' => $user_id,
1052 'rel_key' => '_bbp_subscription',
1053 'object_type' => bbp_get_forum_post_type(),
1054 'filter' => 'user_subscribed_forum_ids'
1055 ) );
1056 }
1057
1058 /**
1059 * Get a user's subscribed topic ids
1060 *
1061 * @since 2.0.0 bbPress (r2668)
1062 *
1063 * @param int $user_id Optional. User id
1064 *
1065 * @return array Return array of subscribed topic ids, or empty array
1066 */
1067 function bbp_get_user_subscribed_topic_ids( $user_id = 0 ) {
1068 return bbp_get_user_object_ids( array(
1069 'user_id' => $user_id,
1070 'rel_key' => '_bbp_subscription',
1071 'filter' => 'user_subscribed_topic_ids'
1072 ) );
1073 }
1074
1075 /** Deprecated ****************************************************************/
1076
1077 /**
1078 * Get a user's subscribed topics
1079 *
1080 * @since 2.0.0 bbPress (r2668)
1081 * @deprecated 2.5.0 bbPress (r5156)
1082 *
1083 * @param int $user_id Optional. User id
1084 *
1085 * @return array|bool Results if user has subscriptions, otherwise false
1086 */
1087 function bbp_get_user_subscriptions( $user_id = 0 ) {
1088 _deprecated_function( __FUNCTION__, '2.5', 'bbp_get_user_topic_subscriptions()' );
1089 $query = bbp_get_user_topic_subscriptions( $user_id );
1090
1091 // Filter & return
1092 return apply_filters( 'bbp_get_user_subscriptions', $query, $user_id );
1093 }
1094
1095 /**
1096 * Get the users who have subscribed to the forum
1097 *
1098 * @since 2.5.0 bbPress (r5156)
1099 * @deprecated 2.6.0 bbPress (r6543)
1100 *
1101 * @param int $forum_id Optional. forum id
1102 *
1103 * @return array|bool Results if the forum has any subscribers, otherwise false
1104 */
1105 function bbp_get_forum_subscribers( $forum_id = 0 ) {
1106 $users = bbp_get_users_for_object( $forum_id, '_bbp_subscription' );
1107
1108 // Filter & return
1109 return (array) apply_filters( 'bbp_get_forum_subscribers', $users, $forum_id );
1110 }
1111
1112 /**
1113 * Get the users who have subscribed to the topic
1114 *
1115 * @since 2.0.0 bbPress (r2668)
1116 * @deprecated 2.6.0 bbPress (r6543)
1117 *
1118 * @param int $topic_id Optional. Topic id
1119 *
1120 * @return array|bool Results if the topic has any subscribers, otherwise false
1121 */
1122 function bbp_get_topic_subscribers( $topic_id = 0 ) {
1123 $users = bbp_get_users_for_object( $topic_id, '_bbp_subscription' );
1124
1125 // Filter & return
1126 return (array) apply_filters( 'bbp_get_topic_subscribers', $users, $topic_id );
1127 }
1128
1129 /**
1130 * Check if a forum is in user's subscription list or not
1131 *
1132 * @since 2.5.0 bbPress (r5156)
1133 * @deprecated 2.6.0 bbPress (r6543)
1134 *
1135 * @param int $user_id Optional. User id
1136 * @param int $forum_id Optional. Forum id
1137 *
1138 * @return bool True if the forum is in user's subscriptions, otherwise false
1139 */
1140 function bbp_is_user_subscribed_to_forum( $user_id = 0, $forum_id = 0 ) {
1141 return bbp_is_user_subscribed( $user_id, $forum_id );
1142 }
1143
1144 /**
1145 * Check if a topic is in user's subscription list or not
1146 *
1147 * @since 2.5.0 bbPress (r5156)
1148 * @deprecated 2.6.0 bbPress (r6543) Use bbp_is_user_subscribed()
1149 *
1150 * @param int $user_id Optional. User id
1151 * @param int $topic_id Optional. Topic id
1152 * @return bool True if the topic is in user's subscriptions, otherwise false
1153 */
1154 function bbp_is_user_subscribed_to_topic( $user_id = 0, $topic_id = 0 ) {
1155 return bbp_is_user_subscribed( $user_id, $topic_id );
1156 }
1157
1158 /**
1159 * Remove a forum from user's subscriptions
1160 *
1161 * @since 2.5.0 bbPress (r5156)
1162 * @deprecated 2.6.0 bbPress (r6543)
1163 *
1164 * @param int $user_id Optional. User id
1165 * @param int $forum_id Optional. forum id
1166 * @return bool True if the forum was removed from user's subscriptions,
1167 * otherwise false
1168 */
1169 function bbp_remove_user_forum_subscription( $user_id = 0, $forum_id = 0 ) {
1170 return bbp_remove_user_subscription( $user_id, $forum_id );
1171 }
1172
1173 /**
1174 * Remove a topic from user's subscriptions
1175 *
1176 * @since 2.5.0 bbPress (r5156)
1177 * @deprecated 2.6.0 bbPress (r6543)
1178 *
1179 * @param int $user_id Optional. User id
1180 * @param int $topic_id Optional. Topic id
1181 * @return bool True if the topic was removed from user's subscriptions,
1182 * otherwise false
1183 */
1184 function bbp_remove_user_topic_subscription( $user_id = 0, $topic_id = 0 ) {
1185 return bbp_remove_user_subscription( $user_id, $topic_id );
1186 }
1187
1188 /**
1189 * Add a forum to user's subscriptions
1190 *
1191 * @since 2.5.0 bbPress (r5156)
1192 * @deprecated 2.6.0 bbPress (r6543)
1193 *
1194 * @param int $user_id Optional. User id
1195 * @param int $forum_id Optional. forum id
1196 * @return bool Always true
1197 */
1198 function bbp_add_user_forum_subscription( $user_id = 0, $forum_id = 0 ) {
1199 return bbp_add_user_subscription( $user_id, $forum_id );
1200 }
1201
1202 /**
1203 * Add a topic to user's subscriptions
1204 *
1205 * Note that both the User and Topic should be verified to exist before using
1206 * this function. Originally both were validated, but because this function is
1207 * frequently used within a loop, those verifications were moved upstream to
1208 * improve performance on topics with many engaged users.
1209 *
1210 * @since 2.0.0 bbPress (r2668)
1211 * @deprecated 2.6.0 bbPress (r6543)
1212 *
1213 * @param int $user_id Optional. User id
1214 * @param int $topic_id Optional. Topic id
1215 * @return bool Always true
1216 */
1217 function bbp_add_user_topic_subscription( $user_id = 0, $topic_id = 0 ) {
1218 return bbp_add_user_subscription( $user_id, $topic_id );
1219 }
1220
1221 /**
1222 * Handles the front end toggling of forum subscriptions
1223 *
1224 * @since 2.5.0 bbPress (r5156)
1225 * @deprecated 2.6.0 bbPress (r6543)
1226 */
1227 function bbp_forum_subscriptions_handler( $action = '' ) {
1228 return bbp_subscriptions_handler( $action );
1229 }
1230