PluginProbe
bbPress / 2.6.17
bbPress v2.6.17
2.6.17 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 All 72 releases
bbpress / includes / users / engagements.php

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

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