PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / trunk
Forumax – AI Powered Advanced Community Forum Plugin vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 2.0.0 2.1.0 All 29 releases
bbp-core / lib / bbpress / includes / users / engagements.php

engagements.php in Forumax – AI Powered Advanced Community Forum Plugin trunk, at lib/bbpress/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