PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.4.1
Forumax – AI Powered Advanced Community Forum Plugin v2.4.1
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 / common / engagements.php

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