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 / common / engagements.php

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

964 lines 26.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Common Engagements
5 *
6 * This file contains the common classes and functions for interacting with the
7 * bbPress engagements API. See `includes/users/engagements.php` for more.
8 *
9 * @package bbPress
10 * @subpackage Common
11 */
12
13 // Exit if accessed directly
14 defined( 'ABSPATH' ) || exit;
15
16 /**
17 * Return the strategy used for storing user engagements
18 *
19 * @since 2.6.0 bbPress (r6722)
20 *
21 * @param string $rel_key The key used to index this relationship
22 * @param string $rel_type The type of meta to look in
23 *
24 * @return string
25 */
26 function bbp_user_engagements_interface( $rel_key = '', $rel_type = 'post' ) {
27 return apply_filters( 'bbp_user_engagements_interface', bbpress()->engagements, $rel_key, $rel_type );
28 }
29
30 /**
31 * Base strategy class for interfacing with User Engagements, which other
32 * classes will extend.
33 *
34 * @since 2.6.0 bbPress (r6722)
35 */
36 class BBP_User_Engagements_Base {
37
38 /**
39 * Type of strategy being used.
40 *
41 * @since 2.6.0 bbPress (r6737)
42 *
43 * @var string
44 */
45 public $type = '';
46
47 /**
48 * Add a user id to an object
49 *
50 * @since 2.6.0 bbPress (r6722)
51 *
52 * @param int $object_id The object id
53 * @param int $user_id The user id
54 * @param string $meta_key The relationship key
55 * @param string $meta_type The relationship type (usually 'post')
56 * @param bool $unique Whether meta key should be unique to the object
57 *
58 * @return bool Returns true on success, false on failure
59 */
60 public function add_user_to_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post', $unique = false ) {
61
62 }
63
64 /**
65 * Remove a user id from an object
66 *
67 * @since 2.6.0 bbPress (r6722)
68 *
69 * @param int $object_id The object id
70 * @param int $user_id The user id
71 * @param string $meta_key The relationship key
72 * @param string $meta_type The relationship type (usually 'post')
73 *
74 * @return bool Returns true on success, false on failure
75 */
76 public function remove_user_from_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
77
78 }
79
80 /**
81 * Remove a user id from all objects
82 *
83 * @since 2.6.0 bbPress (r6722)
84 *
85 * @param int $user_id The user id
86 * @param string $meta_key The relationship key
87 * @param string $meta_type The relationship type (usually 'post')
88 *
89 * @return bool Returns true on success, false on failure
90 */
91 public function remove_user_from_all_objects( $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
92
93 }
94
95 /**
96 * Remove an object from all users
97 *
98 * @since 2.6.0 bbPress (r6722)
99 *
100 * @param int $object_id The object id
101 * @param int $user_id The user id
102 * @param string $meta_key The relationship key
103 * @param string $meta_type The relationship type (usually 'post')
104 *
105 * @return bool Returns true on success, false on failure
106 */
107 public function remove_object_from_all_users( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
108
109 }
110
111 /**
112 * Remove all users from all objects
113 *
114 * @since 2.6.0 bbPress (r6722)
115 *
116 * @param string $meta_key The relationship key
117 * @param string $meta_type The relationship type (usually 'post')
118 *
119 * @return bool Returns true on success, false on failure
120 */
121 public function remove_all_users_from_all_objects( $meta_key = '', $meta_type = 'post' ) {
122
123 }
124
125 /**
126 * Get users of an object
127 *
128 * @since 2.6.0 bbPress (r6722)
129 *
130 * @param int $object_id The object id
131 * @param string $meta_key The key used to index this relationship
132 * @param string $meta_type The type of meta to look in
133 *
134 * @return array Returns ids of users
135 */
136 public function get_users_for_object( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
137
138 }
139
140 /**
141 * Get the part of the query responsible for JOINing objects to relationships.
142 *
143 * @since 2.6.0 bbPress (r6737)
144 *
145 * @param array $args
146 * @param string $meta_key
147 * @param string $meta_type
148 *
149 * @return array
150 */
151 public function get_query( $args = array(), $context_key = '', $meta_key = '', $meta_type = 'post' ) {
152
153 }
154 }
155
156 /**
157 * Meta strategy for interfacing with User Engagements
158 *
159 * @since 2.6.0 bbPress (r6722)
160 */
161 class BBP_User_Engagements_Meta extends BBP_User_Engagements_Base {
162
163 /**
164 * Type of strategy being used.
165 *
166 * @since 2.6.0 bbPress (r6737)
167 *
168 * @var string
169 */
170 public $type = 'meta';
171
172 /**
173 * Add a user id to an object
174 *
175 * @since 2.6.0 bbPress (r6722)
176 *
177 * @param int $object_id The object id
178 * @param int $user_id The user id
179 * @param string $meta_key The relationship key
180 * @param string $meta_type The relationship type (usually 'post')
181 * @param bool $unique Whether meta key should be unique to the object
182 *
183 * @return bool Returns true on success, false on failure
184 */
185 public function add_user_to_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post', $unique = false ) {
186 return add_metadata( $meta_type, $object_id, $meta_key, $user_id, $unique );
187 }
188
189 /**
190 * Remove a user id from an object
191 *
192 * @since 2.6.0 bbPress (r6722)
193 *
194 * @param int $object_id The object id
195 * @param int $user_id The user id
196 * @param string $meta_key The relationship key
197 * @param string $meta_type The relationship type (usually 'post')
198 *
199 * @return bool Returns true on success, false on failure
200 */
201 public function remove_user_from_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
202 return delete_metadata( $meta_type, $object_id, $meta_key, $user_id, false );
203 }
204
205 /**
206 * Remove a user id from all objects
207 *
208 * @since 2.6.0 bbPress (r6722)
209 *
210 * @param int $user_id The user id
211 * @param string $meta_key The relationship key
212 * @param string $meta_type The relationship type (usually 'post')
213 *
214 * @return bool Returns true on success, false on failure
215 */
216 public function remove_user_from_all_objects( $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
217 return delete_metadata( $meta_type, null, $meta_key, $user_id, true );
218 }
219
220 /**
221 * Remove an object from all users
222 *
223 * @since 2.6.0 bbPress (r6722)
224 *
225 * @param int $object_id The object id
226 * @param int $user_id The user id
227 * @param string $meta_key The relationship key
228 * @param string $meta_type The relationship type (usually 'post')
229 *
230 * @return bool Returns true on success, false on failure
231 */
232 public function remove_object_from_all_users( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
233 return delete_metadata( $meta_type, $object_id, $meta_key, null, false );
234 }
235
236 /**
237 * Remove all users from all objects
238 *
239 * @since 2.6.0 bbPress (r6722)
240 *
241 * @param string $meta_key The relationship key
242 * @param string $meta_type The relationship type (usually 'post')
243 *
244 * @return bool Returns true on success, false on failure
245 */
246 public function remove_all_users_from_all_objects( $meta_key = '', $meta_type = 'post' ) {
247 return delete_metadata( $meta_type, null, $meta_key, null, true );
248 }
249
250 /**
251 * Get users of an object
252 *
253 * @since 2.6.0 bbPress (r6722)
254 *
255 * @param int $object_id The object id
256 * @param string $meta_key The key used to index this relationship
257 * @param string $meta_type The type of meta to look in
258 *
259 * @return array Returns ids of users
260 */
261 public function get_users_for_object( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
262 return wp_parse_id_list( get_metadata( $meta_type, $object_id, $meta_key, false ) );
263 }
264
265 /**
266 * Get the part of the query responsible for JOINing objects to relationships.
267 *
268 * @since 2.6.0 bbPress (r6737)
269 *
270 * @param array $args
271 * @param string $meta_key
272 * @param string $meta_type
273 *
274 * @return array
275 */
276 public function get_query( $args = array(), $context_key = '', $meta_key = '', $meta_type = 'post' ) {
277
278 // Backwards compat for pre-2.6.0
279 if ( is_numeric( $args ) ) {
280 $args = array(
281 'meta_query' => array( array(
282 'key' => $meta_key,
283 'value' => bbp_get_user_id( $args, false, false ),
284 'compare' => 'NUMERIC'
285 ) )
286 );
287 }
288
289 // Default arguments
290 $defaults = array(
291 'meta_query' => array( array(
292 'key' => $meta_key,
293 'value' => bbp_get_displayed_user_id(),
294 'compare' => 'NUMERIC'
295 ) )
296 );
297
298 // Parse arguments
299 return bbp_parse_args( $args, $defaults, $context_key );
300 }
301 }
302
303 /**
304 * Term strategy for interfacing with User Engagements
305 *
306 * @since 2.6.0 bbPress (r6737)
307 */
308 class BBP_User_Engagements_Term extends BBP_User_Engagements_Base {
309
310 /**
311 * Type of strategy being used.
312 *
313 * @since 2.6.0 bbPress (r6737)
314 *
315 * @var string
316 */
317 public $type = 'term';
318
319 /**
320 * Register an engagement taxonomy just-in-time for immediate use
321 *
322 * @since 2.6.0 bbPress (r6737)
323 *
324 * @param string $tax_key
325 * @param string $object_type
326 */
327 private function jit_taxonomy( $tax_key = '', $object_type = 'user' ) {
328
329 // Bail if taxonomy already exists
330 if ( taxonomy_exists( $tax_key ) ) {
331 return;
332 }
333
334 // Register the taxonomy
335 register_taxonomy( $tax_key, 'bbp_' . $object_type, array(
336 'labels' => array(),
337 'description' => '',
338 'public' => false,
339 'publicly_queryable' => false,
340 'hierarchical' => false,
341 'show_ui' => false,
342 'show_in_menu' => false,
343 'show_in_nav_menus' => false,
344 'show_tagcloud' => false,
345 'show_in_quick_edit' => false,
346 'show_admin_column' => false,
347 'meta_box_cb' => false,
348 'capabilities' => array(),
349 'rewrite' => false,
350 'query_var' => '',
351 'update_count_callback' => '',
352 'show_in_rest' => false,
353 'rest_base' => false,
354 'rest_controller_class' => false,
355 '_builtin' => false
356 ) );
357 }
358
359 /**
360 * Add a user id to an object
361 *
362 * @since 2.6.0 bbPress (r6737)
363 *
364 * @param int $object_id The object id
365 * @param int $user_id The user id
366 * @param string $meta_key The relationship key
367 * @param string $meta_type The relationship type (usually 'post')
368 * @param bool $unique Whether meta key should be unique to the object
369 *
370 * @return bool Returns true on success, false on failure
371 */
372 public function add_user_to_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post', $unique = false ) {
373 $user_key = "{$meta_key}_user_id_{$user_id}";
374 $tax_key = "{$meta_key}_{$meta_type}";
375 $this->jit_taxonomy( $tax_key );
376
377 return wp_add_object_terms( $object_id, $user_key, $tax_key );
378 }
379
380 /**
381 * Remove a user id from an object
382 *
383 * @since 2.6.0 bbPress (r6737)
384 *
385 * @param int $object_id The object id
386 * @param int $user_id The user id
387 * @param string $meta_key The relationship key
388 * @param string $meta_type The relationship type (usually 'post')
389 *
390 * @return bool Returns true on success, false on failure
391 */
392 public function remove_user_from_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
393 $user_key = "{$meta_key}_user_id_{$user_id}";
394 $tax_key = "{$meta_key}_{$meta_type}";
395 $this->jit_taxonomy( $tax_key );
396
397 return wp_remove_object_terms( $object_id, $user_key, $tax_key );
398 }
399
400 /**
401 * Remove a user id from all objects
402 *
403 * @since 2.6.0 bbPress (r6737)
404 *
405 * @param int $user_id The user id
406 * @param string $meta_key The relationship key
407 * @param string $meta_type The relationship type (usually 'post')
408 *
409 * @return bool Returns true on success, false on failure
410 */
411 public function remove_user_from_all_objects( $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
412 $user_key = "{$meta_key}_user_id_{$user_id}";
413 $tax_key = "{$meta_key}_{$meta_type}";
414 $this->jit_taxonomy( $tax_key );
415 $term = get_term_by( 'slug', $user_key, $tax_key );
416
417 return wp_delete_term( $term->term_id, $tax_key );
418 }
419
420 /**
421 * Remove an object from all users
422 *
423 * @since 2.6.0 bbPress (r6737)
424 *
425 * @param int $object_id The object id
426 * @param int $user_id The user id
427 * @param string $meta_key The relationship key
428 * @param string $meta_type The relationship type (usually 'post')
429 *
430 * @return bool Returns true on success, false on failure
431 */
432 public function remove_object_from_all_users( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
433 return wp_delete_object_term_relationships( $object_id, get_object_taxonomies( 'bbp_user' ) );
434 }
435
436 /**
437 * Remove all users from all objects
438 *
439 * @since 2.6.0 bbPress (r6737)
440 *
441 * @param string $meta_key The relationship key
442 * @param string $meta_type The relationship type (usually 'post')
443 *
444 * @return bool Returns true on success, false on failure
445 */
446 public function remove_all_users_from_all_objects( $meta_key = '', $meta_type = 'post' ) {
447 // TODO
448 }
449
450 /**
451 * Get users of an object
452 *
453 * @since 2.6.0 bbPress (r6737)
454 *
455 * @param int $object_id The object id
456 * @param string $meta_key The key used to index this relationship
457 * @param string $meta_type The type of meta to look in
458 *
459 * @return array Returns ids of users
460 */
461 public function get_users_for_object( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
462 $user_key = "{$meta_key}_user_id_";
463 $tax_key = "{$meta_key}_{$meta_type}";
464 $this->jit_taxonomy( $tax_key );
465
466 // Get terms
467 $terms = get_terms( array(
468 'object_ids' => $object_id,
469 'taxonomy' => $tax_key
470 ) );
471
472 // Slug part to replace
473 $user_ids = array();
474
475 // Loop through terms and get the user ID
476 foreach ( $terms as $term ) {
477 $user_ids[] = str_replace( $user_key, '', $term->slug );
478 }
479
480 // Parse & return
481 return wp_parse_id_list( $user_ids );
482 }
483
484 /**
485 * Get the part of the query responsible for JOINing objects to relationships.
486 *
487 * @since 2.6.0 bbPress (r6737)
488 *
489 * @param array $args
490 * @param string $meta_key
491 * @param string $meta_type
492 *
493 * @return array
494 */
495 public function get_query( $args = array(), $context_key = '', $meta_key = '', $meta_type = 'post' ) {
496 $tax_key = "{$meta_key}_{$meta_type}";
497 $user_key = "{$meta_key}_user_id_";
498
499 // Make sure the taxonomy is registered
500 $this->jit_taxonomy( $tax_key );
501
502 // Backwards compat for pre-2.6.0
503 if ( is_numeric( $args ) ) {
504 $args = array(
505 'tax_query' => array( array(
506 'taxonomy' => $tax_key,
507 'terms' => $user_key . bbp_get_user_id( $args, false, false ),
508 'field' => 'slug'
509 ) )
510 );
511 }
512
513 // Default arguments
514 $defaults = array(
515 'tax_query' => array( array(
516 'taxonomy' => $tax_key,
517 'terms' => $user_key . bbp_get_displayed_user_id(),
518 'field' => 'slug'
519 ) )
520 );
521
522 // Parse arguments
523 return bbp_parse_args( $args, $defaults, $context_key );
524 }
525 }
526
527 /**
528 * User strategy for interfacing with User Engagements
529 *
530 * This strategy largely exists for backwards compatibility with bbPress 2.5,
531 * or installations that have not upgraded their databases to 2.6 or above.
532 *
533 * Note: this strategy is going to be a bit less tidy than the others, because
534 * it needs to do weird things to maintain the 2.5 status-quo. Do not use this
535 * strategy as an example when building your own.
536 *
537 * @since 2.6.0 bbPress (r6844)
538 */
539 class BBP_User_Engagements_User extends BBP_User_Engagements_Base {
540
541 /**
542 * Type of strategy being used.
543 *
544 * @since 2.6.0 bbPress (r6844)
545 *
546 * @var string
547 */
548 public $type = 'user';
549
550 /**
551 * Private function to map 2.6 meta keys to 2.5 user-option keys.
552 *
553 * @since 2.6.0 bbPress (r6844)
554 *
555 * @param string $meta_key
556 * @param int $object_id
557 * @param bool $prefix
558 *
559 * @return string
560 */
561 private function get_user_option_key( $meta_key = '', $object_id = 0, $prefix = false ) {
562 switch ( $meta_key ) {
563
564 // Favorites
565 case '_bbp_favorite' :
566 $key = '_bbp_favorites';
567 break;
568
569 // Subscriptions
570 case '_bbp_subscription' :
571
572 // Maybe guess at post type
573 $post_type = ! empty( $object_id )
574 ? get_post_type( $object_id )
575 : bbp_get_topic_post_type();
576
577 // Forums & Topics used different keys :/
578 $key = ( bbp_get_forum_post_type() === $post_type )
579 ? '_bbp_forum_subscriptions'
580 : '_bbp_subscriptions';
581
582 break;
583
584 // Unknown, so pluralize
585 default :
586 $key = "{$meta_key}s";
587 break;
588 }
589
590 // Maybe prefix the key (for use in raw database queries)
591 if ( true === $prefix ) {
592 $key = bbp_db()->get_blog_prefix() . $key;
593 }
594
595 // Return the old (pluralized) user option key
596 return $key;
597 }
598
599 /**
600 * Private function to get a 2.5 compatible cache key.
601 *
602 * This method exists to provide backwards compatibility with bbPress 2.5,
603 * which had caching surrounding the FIND_IN_SET usermeta queries.
604 *
605 * @since 2.6.3 bbPress (r6991)
606 *
607 * @param string $meta_key
608 * @param int $object_id
609 *
610 * @return string
611 */
612 private function get_cache_key( $meta_key = '', $object_id = 0 ) {
613
614 // No negative numbers in cache keys (zero is weird, but not disallowed)
615 $object_id = absint( $object_id );
616
617 // Maybe guess at post type
618 $post_type = ! empty( $object_id )
619 ? get_post_type( $object_id )
620 : bbp_get_topic_post_type();
621
622 switch ( $meta_key ) {
623
624 // Favorites
625 case '_bbp_favorite' :
626 $key = 'bbp_get_topic_favoriters_';
627 break;
628
629 // Subscriptions
630 case '_bbp_subscription' :
631
632 // Forums & Topics used different keys :/
633 $key = ( bbp_get_forum_post_type() === $post_type )
634 ? 'bbp_get_forum_subscribers_'
635 : 'bbp_get_topic_subscribers_';
636
637 break;
638
639 // Unknown, so pluralize
640 default :
641 $nounize = rtrim( $meta_key, 'e' );
642 $key = "bbp_get_{$post_type}_{$nounize}ers_";
643 break;
644 }
645
646 // Return the old (pluralized) user option key with object ID appended
647 return "{$key}{$object_id}";
648 }
649
650 /**
651 * Get the user engagement cache for a given meta key and object ID.
652 *
653 * This method exists to provide backwards compatibility with bbPress 2.5,
654 * which had caching surrounding the FIND_IN_SET queries in usermeta.
655 *
656 * @since 2.6.3 bbPress (r6991)
657 *
658 * @param string $meta_key
659 * @param int $object_id
660 *
661 * @return mixed Results from cache get
662 */
663 private function cache_get( $meta_key = '', $object_id = 0 ) {
664 $cache_key = $this->get_cache_key( $meta_key, $object_id );
665
666 return wp_cache_get( $cache_key, 'bbpress_engagements' );
667 }
668
669 /**
670 * Set the user engagement cache for a given meta key and object ID.
671 *
672 * This method exists to provide backwards compatibility with bbPress 2.5,
673 * which had caching surrounding the FIND_IN_SET queries in usermeta.
674 *
675 * @since 2.6.3 bbPress (r6991)
676 *
677 * @param string $meta_key
678 * @param int $object_id
679 *
680 * @return mixed Results from cache set
681 */
682 private function cache_set( $meta_key = '', $object_id = 0, $user_ids = array() ) {
683 $cache_key = $this->get_cache_key( $meta_key, $object_id );
684 $user_ids = $this->parse_comma_list( $user_ids );
685
686 return wp_cache_set( $cache_key, $user_ids, 'bbpress_engagements' );
687 }
688
689 /**
690 * Delete the user engagement cache for a given meta key and object ID.
691 *
692 * This method exists to provide backwards compatibility with bbPress 2.5,
693 * which had caching surrounding the FIND_IN_SET queries in usermeta.
694 *
695 * @since 2.6.3 bbPress (r6991)
696 *
697 * @param string $meta_key
698 * @param int $object_id
699 *
700 * @return mixed Results from cache delete
701 */
702 private function cache_delete( $meta_key = '', $object_id = 0 ) {
703 $cache_key = $this->get_cache_key( $meta_key, $object_id );
704
705 return wp_cache_delete( $cache_key, 'bbpress_engagements' );
706 }
707
708 /**
709 * Turn a comma-separated string into an array of integers
710 *
711 * @since 2.6.0 bbPress (r6844)
712 *
713 * @param string $results
714 * @return array
715 */
716 private function parse_comma_list( $results = '' ) {
717 return array_filter( wp_parse_id_list( $results ) );
718 }
719
720 /**
721 * Add a user id to an object
722 *
723 * @since 2.6.0 bbPress (r6844)
724 *
725 * @param int $object_id The object id
726 * @param int $user_id The user id
727 * @param string $meta_key The relationship key
728 * @param string $meta_type The relationship type (usually 'post')
729 * @param bool $unique Whether meta key should be unique to the object
730 *
731 * @return bool Returns true on success, false on failure
732 */
733 public function add_user_to_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post', $unique = false ) {
734 $retval = false;
735 $option_key = $this->get_user_option_key( $meta_key, $object_id );
736 $object_ids = $this->parse_comma_list( get_user_option( $option_key, $user_id ) );
737 $exists = array_search( $object_id, $object_ids );
738
739 // Not already added, so add it
740 if ( false === $exists ) {
741 $object_ids[] = $object_id;
742 $object_ids = implode( ',', $this->parse_comma_list( $object_ids ) );
743 $retval = update_user_option( $user_id, $option_key, $object_ids );
744
745 // Delete cache if successful (accounts for int & true)
746 if ( false !== $retval ) {
747 $this->cache_delete( $meta_key, $object_id );
748 }
749 }
750
751 // Return true if added, or false if not
752 return $retval;
753 }
754
755 /**
756 * Remove a user id from an object
757 *
758 * @since 2.6.0 bbPress (r6844)
759 *
760 * @param int $object_id The object id
761 * @param int $user_id The user id
762 * @param string $meta_key The relationship key
763 * @param string $meta_type The relationship type (usually 'post')
764 *
765 * @return bool Returns true on success, false on failure
766 */
767 public function remove_user_from_object( $object_id = 0, $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
768 $retval = false;
769 $option_key = $this->get_user_option_key( $meta_key, $object_id );
770 $object_ids = $this->parse_comma_list( get_user_option( $option_key, $user_id ) );
771 $exists = array_search( $object_id, $object_ids );
772
773 // Exists, so remove it
774 if ( false !== $exists ) {
775 unset( $object_ids[ $exists ] );
776
777 $object_ids = implode( ',', $this->parse_comma_list( $object_ids ) );
778 $retval = ! empty( $object_ids )
779 ? update_user_option( $user_id, $option_key, $object_ids )
780 : delete_user_option( $user_id, $option_key );
781
782 // Delete cache if successful (accounts for int & true)
783 if ( false !== $retval ) {
784 $this->cache_delete( $meta_key, $object_id );
785 }
786 }
787
788 // Return true if removed, or false if not
789 return $retval;
790 }
791
792 /**
793 * Remove a user id from all objects
794 *
795 * @since 2.6.0 bbPress (r6844)
796 *
797 * @param int $user_id The user id
798 * @param string $meta_key The relationship key
799 * @param string $meta_type The relationship type (usually 'post')
800 *
801 * @return bool Returns true on success, false on failure
802 */
803 public function remove_user_from_all_objects( $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
804
805 // Get the key
806 $option_key = $this->get_user_option_key( $meta_key );
807
808 // Get the option
809 $object_ids = $this->parse_comma_list( get_user_option( $option_key, $user_id ) );
810
811 // Attempt to delete the user option
812 $retval = delete_user_option( $user_id, $option_key );
813
814 // Try to delete caches, but only if everything else succeeded
815 if ( ! empty( $retval ) && ! empty( $object_ids ) ) {
816 foreach ( $object_ids as $object_id ) {
817 $this->cache_delete( $meta_key, $object_id );
818 }
819 }
820
821 // Return true if user was removed, or false if not
822 return $retval;
823 }
824
825 /**
826 * Remove an object from all users
827 *
828 * @since 2.6.0 bbPress (r6844)
829 *
830 * @param int $object_id The object id
831 * @param int $user_id The user id
832 * @param string $meta_key The relationship key
833 * @param string $meta_type The relationship type (usually 'post')
834 *
835 * @return bool Returns true on success, false on failure
836 */
837 public function remove_object_from_all_users( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
838
839 // Query for users
840 $user_ids = $this->get_users_for_object( $object_id, $meta_key, $meta_type );
841 $u_count = count( $user_ids );
842
843 // Count number of removals
844 $removed = array();
845 $r_count = 0;
846
847 // Users have engaged, so remove them
848 if ( ! empty( $u_count ) ) {
849
850 // Loop through users and remove them from the object
851 foreach ( $user_ids as $user_id ) {
852 $removed[] = $this->remove_user_from_object( $object_id, $user_id, $meta_key, $meta_type );
853 }
854
855 // Count the removed users
856 $r_count = count( $removed );
857 }
858
859 // Return true if successfully removed from all users
860 return ( $r_count === $u_count );
861 }
862
863 /**
864 * Remove all users from all objects
865 *
866 * @since 2.6.0 bbPress (r6844)
867 *
868 * @param string $meta_key The relationship key
869 * @param string $meta_type The relationship type (usually 'post')
870 *
871 * @return bool Returns true on success, false on failure
872 */
873 public function remove_all_users_from_all_objects( $meta_key = '', $meta_type = 'post' ) {
874
875 // Query for users
876 $option_key = $this->get_user_option_key( $meta_key, 0, true );
877 $bbp_db = bbp_db();
878 $user_ids = $bbp_db->get_col( "SELECT user_id FROM {$bbp_db->usermeta} WHERE meta_key = '{$option_key}'" );
879 $u_count = count( $user_ids );
880
881 // Count number of removals
882 $removed = array();
883 $r_count = 0;
884
885 // Users have engaged, so remove them
886 if ( ! empty( $u_count ) ) {
887
888 // Loop through users and remove their user options
889 foreach ( $user_ids as $user_id ) {
890 $removed[] = $this->remove_user_from_all_objects( $user_id, $meta_key );
891 }
892
893 // Count the removed users
894 $r_count = count( $removed );
895 }
896
897 // Return true if successfully removed from all users
898 return ( $r_count === $u_count );
899 }
900
901 /**
902 * Get users of an object
903 *
904 * The database queries in this function were cached in bbPress versions
905 * older than 2.6, but no longer are to avoid cache pollution.
906 *
907 * @since 2.6.0 bbPress (r6844)
908 *
909 * @param int $object_id The object id
910 * @param string $meta_key The key used to index this relationship
911 * @param string $meta_type The type of meta to look in
912 *
913 * @return array Returns ids of users
914 */
915 public function get_users_for_object( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
916
917 // Try to get user IDs from cache
918 $user_ids = $this->cache_get( $meta_key, $object_id );
919
920 // Cache is empty, so hit the database
921 if ( false === $user_ids ) {
922 $option_key = $this->get_user_option_key( $meta_key, $object_id, true );
923 $bbp_db = bbp_db();
924 $user_ids = $bbp_db->get_col( "SELECT user_id FROM {$bbp_db->usermeta} WHERE meta_key = '{$option_key}' and FIND_IN_SET('{$object_id}', meta_value) > 0" );
925
926 // Always cache results (even if empty, to prevent multiple misses)
927 $this->cache_set( $meta_key, $object_id, $user_ids );
928 }
929
930 // Return parsed IDs
931 return $this->parse_comma_list( $user_ids );
932 }
933
934 /**
935 * Get the part of the query responsible for JOINing objects to relationships.
936 *
937 * @since 2.6.0 bbPress (r6844)
938 *
939 * @param array $args
940 * @param string $meta_key
941 * @param string $meta_type
942 *
943 * @return array
944 */
945 public function get_query( $args = array(), $context_key = '', $meta_key = '', $meta_type = 'post' ) {
946 $user_id = bbp_get_user_id( $args, true, true );
947 $option_key = $this->get_user_option_key( $meta_key );
948 $object_ids = $this->parse_comma_list( get_user_option( $option_key, $user_id ) );
949
950 // Maybe trick WP_Query into ".ID IN (0)" to return no results
951 if ( empty( $object_ids ) ) {
952 $object_ids = array( 0 );
953 }
954
955 // Maybe include these post IDs
956 $args = array(
957 'post__in' => $object_ids
958 );
959
960 // Parse arguments
961 return bbp_parse_args( $args, array(), $context_key );
962 }
963 }
964