PluginProbe
bbPress / 2.6.3
bbPress v2.6.3
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 / bbpress.php

bbpress.php in bbPress 2.6.3, at bbpress.php

1,053 lines 37.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The bbPress Plugin
5 *
6 * bbPress is forum software with a twist from the creators of WordPress.
7 *
8 * $Id: bbpress.php 7018 2019-12-10 20:13:58Z johnjamesjacoby $
9 *
10 * @package bbPress
11 * @subpackage Main
12 */
13
14 /**
15 * Plugin Name: bbPress
16 * Plugin URI: https://bbpress.org
17 * Description: bbPress is forum software with a twist from the creators of WordPress.
18 * Author: The bbPress Contributors
19 * Author URI: https://bbpress.org
20 * Version: 2.6.3
21 * Text Domain: bbpress
22 * Domain Path: /languages/
23 * License: GPLv2 or later (license.txt)
24 */
25
26 // Exit if accessed directly
27 defined( 'ABSPATH' ) || exit;
28
29 if ( ! class_exists( 'bbPress' ) ) :
30 /**
31 * Main bbPress Class
32 *
33 * "Word hard. Stay bumble."
34 *
35 * @since 2.0.0 bbPress (r2464)
36 */
37 final class bbPress {
38
39 /** Magic *****************************************************************/
40
41 /**
42 * bbPress uses many variables, several of which can be filtered to
43 * customize the way it operates. Most of these variables are stored in a
44 * private array that gets updated with the help of PHP magic methods.
45 *
46 * This is a precautionary measure, to avoid potential errors produced by
47 * unanticipated direct manipulation of run-time data.
48 *
49 * @see bbPress::setup_globals()
50 * @var array
51 */
52 private $data;
53
54 /** Not Magic *************************************************************/
55
56 /**
57 * @var mixed False when not logged in; WP_User object when logged in
58 */
59 public $current_user = false;
60
61 /**
62 * @var stdClass Add-ons append to this (Akismet, BuddyPress, etc...)
63 */
64 public $extend;
65
66 /**
67 * @var array Topic views
68 */
69 public $views = array();
70
71 /**
72 * @var array Overloads get_option()
73 */
74 public $options = array();
75
76 /**
77 * @var array Storage of options not in the database
78 */
79 public $not_options = array();
80
81 /**
82 * @var array Overloads get_user_meta()
83 */
84 public $user_options = array();
85
86 /**
87 * @var array Dynamically initialized user roles
88 */
89 public $roles = array();
90
91 /** Singleton *************************************************************/
92
93 /**
94 * Main bbPress Instance
95 *
96 * bbPress is fun
97 * Please load it only one time
98 * For this, we thank you
99 *
100 * Insures that only one instance of bbPress exists in memory at any one
101 * time. Also prevents needing to define globals all over the place.
102 *
103 * @since 2.1.0 bbPress (r3757)
104 *
105 * @staticvar object $instance
106 * @see bbpress()
107 * @return bbPress The one true bbPress
108 */
109 public static function instance() {
110
111 // Store the instance locally to avoid private static replication
112 static $instance = null;
113
114 // Only run these methods if they haven't been ran previously
115 if ( null === $instance ) {
116 $instance = new bbPress;
117 $instance->setup_environment();
118 $instance->includes();
119 $instance->setup_variables();
120 $instance->setup_actions();
121 }
122
123 // Always return the instance
124 return $instance;
125 }
126
127 /** Magic Methods *********************************************************/
128
129 /**
130 * A dummy constructor to prevent bbPress from being loaded more than once.
131 *
132 * @since 2.0.0 bbPress (r2464)
133 *
134 * @see bbPress::instance()
135 * @see bbpress();
136 */
137 private function __construct() { /* Do nothing here */ }
138
139 /**
140 * A dummy magic method to prevent bbPress from being cloned
141 *
142 * @since 2.0.0 bbPress (r2464)
143 */
144 public function __clone() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'bbpress' ), '2.1' ); }
145
146 /**
147 * A dummy magic method to prevent bbPress from being unserialized
148 *
149 * @since 2.0.0 bbPress (r2464)
150 */
151 public function __wakeup() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'bbpress' ), '2.1' ); }
152
153 /**
154 * Magic method for checking the existence of a certain custom field
155 *
156 * @since 2.1.0 bbPress (r3951)
157 */
158 public function __isset( $key ) { return isset( $this->data[ $key ] ); }
159
160 /**
161 * Magic method for getting bbPress variables
162 *
163 * @since 2.1.0 bbPress (r3951)
164 */
165 public function __get( $key ) { return isset( $this->data[ $key ] ) ? $this->data[ $key ] : null; }
166
167 /**
168 * Magic method for setting bbPress variables
169 *
170 * @since 2.1.0 bbPress (r3951)
171 */
172 public function __set( $key , $value ) { $this->data[ $key ] = $value; }
173
174 /**
175 * Magic method for unsetting bbPress variables
176 *
177 * @since 2.3.0 bbPress (r4628)
178 */
179 public function __unset( $key ) {
180 if ( isset( $this->data[ $key ] ) ) {
181 unset( $this->data[ $key ] );
182 }
183 }
184
185 /**
186 * Magic method to prevent notices and errors from invalid method calls
187 *
188 * @since 2.2.0 bbPress (r4252)
189 */
190 public function __call( $name = '', $args = array() ) { unset( $name, $args ); return null; }
191
192 /** Private Methods *******************************************************/
193
194 /**
195 * Setup the environment variables to allow the rest of bbPress to function
196 * more easily.
197 *
198 * @since 2.0.0 bbPress (r2626)
199 *
200 * @access private
201 */
202 private function setup_environment() {
203
204 /** Versions **********************************************************/
205
206 $this->version = '2.6.3';
207 $this->db_version = '263';
208
209 /** Paths *************************************************************/
210
211 // File & base
212 $this->file = __FILE__;
213 $this->basename = apply_filters( 'bbp_plugin_basename', str_replace( array( 'build/', 'src/' ), '', plugin_basename( $this->file ) ) );
214 $this->basepath = apply_filters( 'bbp_plugin_basepath', trailingslashit( dirname( $this->basename ) ) );
215
216 // Path and URL
217 $this->plugin_dir = apply_filters( 'bbp_plugin_dir_path', plugin_dir_path( $this->file ) );
218 $this->plugin_url = apply_filters( 'bbp_plugin_dir_url', plugin_dir_url ( $this->file ) );
219
220 // Includes
221 $this->includes_dir = apply_filters( 'bbp_includes_dir', trailingslashit( $this->plugin_dir . 'includes' ) );
222 $this->includes_url = apply_filters( 'bbp_includes_url', trailingslashit( $this->plugin_url . 'includes' ) );
223
224 // Languages
225 $this->lang_base = apply_filters( 'bbp_lang_base', trailingslashit( $this->basepath . 'languages' ) );
226 $this->lang_dir = apply_filters( 'bbp_lang_dir', trailingslashit( $this->plugin_dir . 'languages' ) );
227
228 // Templates
229 $this->themes_dir = apply_filters( 'bbp_themes_dir', trailingslashit( $this->plugin_dir . 'templates' ) );
230 $this->themes_url = apply_filters( 'bbp_themes_url', trailingslashit( $this->plugin_url . 'templates' ) );
231 }
232
233 /**
234 * Smart defaults to many bbPress specific class variables.
235 *
236 * @since 2.6.0 bbPress (r6330)
237 */
238 private function setup_variables() {
239
240 /** Identifiers *******************************************************/
241
242 // Post type identifiers
243 $this->forum_post_type = apply_filters( 'bbp_forum_post_type', 'forum' );
244 $this->topic_post_type = apply_filters( 'bbp_topic_post_type', 'topic' );
245 $this->topic_tag_tax_id = apply_filters( 'bbp_topic_tag_tax_id', 'topic-tag' );
246 $this->reply_post_type = apply_filters( 'bbp_reply_post_type', 'reply' );
247
248 // Status identifiers
249 $this->spam_status_id = apply_filters( 'bbp_spam_post_status', 'spam' );
250 $this->closed_status_id = apply_filters( 'bbp_closed_post_status', 'closed' );
251 $this->orphan_status_id = apply_filters( 'bbp_orphan_post_status', 'orphan' );
252 $this->public_status_id = apply_filters( 'bbp_public_post_status', 'publish' );
253 $this->pending_status_id = apply_filters( 'bbp_pending_post_status', 'pending' );
254 $this->private_status_id = apply_filters( 'bbp_private_post_status', 'private' );
255 $this->hidden_status_id = apply_filters( 'bbp_hidden_post_status', 'hidden' );
256 $this->trash_status_id = apply_filters( 'bbp_trash_post_status', 'trash' );
257
258 // Other identifiers
259 $this->user_id = apply_filters( 'bbp_user_id', 'bbp_user' );
260 $this->tops_id = apply_filters( 'bbp_tops_id', 'bbp_tops' );
261 $this->reps_id = apply_filters( 'bbp_reps_id', 'bbp_reps' );
262 $this->favs_id = apply_filters( 'bbp_favs_id', 'bbp_favs' );
263 $this->subs_id = apply_filters( 'bbp_subs_id', 'bbp_subs' );
264 $this->view_id = apply_filters( 'bbp_view_id', 'bbp_view' );
265 $this->edit_id = apply_filters( 'bbp_edit_id', 'edit' );
266 $this->paged_id = apply_filters( 'bbp_paged_id', 'paged' );
267 $this->search_id = apply_filters( 'bbp_search_id', 'bbp_search' );
268 $this->engagements_id = apply_filters( 'bbp_engagements_id', 'bbp_engagements' );
269
270 /** Queries ***********************************************************/
271
272 $this->current_view_id = 0; // Current view id
273 $this->current_forum_id = 0; // Current forum id
274 $this->current_topic_id = 0; // Current topic id
275 $this->current_reply_id = 0; // Current reply id
276 $this->current_topic_tag_id = 0; // Current topic tag id
277 $this->current_user_id = 0; // Current topic tag id
278
279 $this->forum_query = new WP_Query(); // Main forum query
280 $this->topic_query = new WP_Query(); // Main topic query
281 $this->reply_query = new WP_Query(); // Main reply query
282 $this->search_query = new WP_Query(); // Main search query
283 $this->user_query = new BBP_User_Query(); // Main user query
284
285 /** Theme Compat ******************************************************/
286
287 $this->theme_compat = new stdClass(); // Base theme compatibility class
288 $this->filters = new stdClass(); // Used when adding/removing filters
289
290 /** Users *************************************************************/
291
292 $this->current_user = new WP_User(); // Currently logged in user
293 $this->displayed_user = new WP_User(); // Currently displayed user
294
295 /** Misc **************************************************************/
296
297 $this->domain = 'bbpress'; // Unique identifier for retrieving translated strings
298 $this->extend = new stdClass(); // Plugins add data here
299 $this->errors = new WP_Error(); // Feedback
300
301 /** Deprecated ********************************************************/
302
303 $this->tab_index = apply_filters( 'bbp_default_tab_index', 100 );
304 }
305
306 /**
307 * Include required files
308 *
309 * @since 2.0.0 bbPress (r2626)
310 *
311 * @access private
312 */
313 private function includes() {
314
315 /** Core **************************************************************/
316
317 require $this->includes_dir . 'core/abstraction.php';
318 require $this->includes_dir . 'core/sub-actions.php';
319 require $this->includes_dir . 'core/functions.php';
320 require $this->includes_dir . 'core/cache.php';
321 require $this->includes_dir . 'core/options.php';
322 require $this->includes_dir . 'core/capabilities.php';
323 require $this->includes_dir . 'core/update.php';
324 require $this->includes_dir . 'core/template-functions.php';
325 require $this->includes_dir . 'core/template-loader.php';
326 require $this->includes_dir . 'core/theme-compat.php';
327
328 /** Components ********************************************************/
329
330 // Common
331 require $this->includes_dir . 'common/ajax.php';
332 require $this->includes_dir . 'common/classes.php';
333 require $this->includes_dir . 'common/engagements.php';
334 require $this->includes_dir . 'common/functions.php';
335 require $this->includes_dir . 'common/formatting.php';
336 require $this->includes_dir . 'common/locale.php';
337 require $this->includes_dir . 'common/locks.php';
338 require $this->includes_dir . 'common/template.php';
339 require $this->includes_dir . 'common/widgets.php';
340 require $this->includes_dir . 'common/shortcodes.php';
341
342 // Forums
343 require $this->includes_dir . 'forums/capabilities.php';
344 require $this->includes_dir . 'forums/functions.php';
345 require $this->includes_dir . 'forums/template.php';
346
347 // Topics
348 require $this->includes_dir . 'topics/capabilities.php';
349 require $this->includes_dir . 'topics/functions.php';
350 require $this->includes_dir . 'topics/template.php';
351
352 // Replies
353 require $this->includes_dir . 'replies/capabilities.php';
354 require $this->includes_dir . 'replies/functions.php';
355 require $this->includes_dir . 'replies/template.php';
356
357 // Search
358 require $this->includes_dir . 'search/functions.php';
359 require $this->includes_dir . 'search/template.php';
360
361 // Users
362 require $this->includes_dir . 'users/capabilities.php';
363 require $this->includes_dir . 'users/engagements.php';
364 require $this->includes_dir . 'users/functions.php';
365 require $this->includes_dir . 'users/template.php';
366 require $this->includes_dir . 'users/options.php';
367 require $this->includes_dir . 'users/signups.php';
368
369 /** Hooks *************************************************************/
370
371 require $this->includes_dir . 'core/extend.php';
372 require $this->includes_dir . 'core/actions.php';
373 require $this->includes_dir . 'core/filters.php';
374
375 /** Admin *************************************************************/
376
377 // Quick admin check and load if needed
378 if ( is_admin() ) {
379 require $this->includes_dir . 'admin/actions.php';
380 }
381 }
382
383 /**
384 * Setup the default hooks and actions
385 *
386 * @since 2.0.0 bbPress (r2644)
387 *
388 * @access private
389 */
390 private function setup_actions() {
391
392 // Add actions to plugin activation and deactivation hooks
393 add_action( 'activate_' . $this->basename, 'bbp_activation' );
394 add_action( 'deactivate_' . $this->basename, 'bbp_deactivation' );
395
396 // If bbPress is being deactivated, do not add any actions
397 if ( bbp_is_deactivation( $this->basename ) ) {
398 return;
399 }
400
401 // Array of bbPress core actions
402 $actions = array(
403 'setup_theme', // Setup the default theme compat
404 'setup_current_user', // Setup currently logged in user
405 'setup_engagements', // Setup user engagements strategy
406 'roles_init', // User roles init
407 'register_meta', // Register meta (forum|topic|reply|user)
408 'register_post_types', // Register post types (forum|topic|reply)
409 'register_post_statuses', // Register post statuses (closed|spam|orphan|hidden)
410 'register_taxonomies', // Register taxonomies (topic-tag)
411 'register_shortcodes', // Register shortcodes (bbp-login)
412 'register_views', // Register the views (no-replies)
413 'register_theme_packages', // Register bundled theme packages (bbp-theme-compat/bbp-themes)
414 'load_textdomain', // Load textdomain (bbpress)
415 'add_rewrite_tags', // Add rewrite tags (view|user|edit|search)
416 'add_rewrite_rules', // Generate rewrite rules (view|edit|paged|search)
417 'add_permastructs' // Add permalink structures (view|user|search)
418 );
419
420 // Add the actions
421 foreach ( $actions as $class_action ) {
422 add_action( 'bbp_' . $class_action, array( $this, $class_action ), 5 );
423 }
424
425 // All bbPress actions are setup (includes bbp-core-hooks.php)
426 do_action_ref_array( 'bbp_after_setup_actions', array( &$this ) );
427 }
428
429 /** Public Methods ********************************************************/
430
431 /**
432 * Register bundled theme packages
433 *
434 * Note that since we currently have complete control over bbp-themes and
435 * the bbp-theme-compat folders, it's fine to hardcode these here. If at a
436 * later date we need to automate this, and API will need to be built.
437 *
438 * @since 2.1.0 bbPress (r3829)
439 */
440 public function register_theme_packages() {
441
442 // Register the basic theme stack. This is really dope.
443 bbp_register_template_stack( 'get_stylesheet_directory', 6 );
444 bbp_register_template_stack( 'get_template_directory', 8 );
445
446 // Register the default theme compatibility package
447 bbp_register_theme_package( array(
448 'id' => 'default',
449 'name' => 'bbPress Default',
450 'version' => bbp_get_version(),
451 'dir' => trailingslashit( $this->themes_dir . 'default' ),
452 'url' => trailingslashit( $this->themes_url . 'default' )
453 ) );
454 }
455
456 /**
457 * Setup the default bbPress theme compatibility location.
458 *
459 * @since 2.1.0 bbPress (r3778)
460 */
461 public function setup_theme() {
462 bbp_setup_theme_compat( bbp_get_theme_package_id() );
463 }
464
465 /**
466 * Load the translation file for current language. Checks the deprecated
467 * languages folder inside the bbPress plugin first, and then the default
468 * WordPress languages folder.
469 *
470 * Note that custom translation files inside the bbPress plugin folder
471 * will be removed on bbPress updates. If you're creating custom
472 * translation files, please use the global language folder.
473 *
474 * @since 2.0.0 bbPress (r2596)
475 */
476 public function load_textdomain() {
477
478 // Define the old directory
479 $old_dir = WP_LANG_DIR . '/bbpress/';
480
481 // Old location, deprecated in 2.6.0
482 if ( is_dir( $old_dir ) ) {
483
484 // Get locale & file-name
485 $type = is_admin() ? get_user_locale() : get_locale();
486 $locale = apply_filters( 'plugin_locale', $type, $this->domain );
487 $mofile = sprintf( '%1$s-%2$s.mo', $this->domain, $locale );
488
489 // Look in global /wp-content/languages/bbpress/ folder
490 load_textdomain( $this->domain, $old_dir . $mofile );
491 }
492
493 // Look in global /wp-content/languages/plugins/
494 load_plugin_textdomain( $this->domain, false, $this->lang_base );
495 }
496
497 /**
498 * Setup the post types for forums, topics and replies
499 *
500 * @since 2.0.0 bbPress (r2597)
501 */
502 public static function register_post_types() {
503
504 /** Forums ************************************************************/
505
506 // Register Forum content type
507 register_post_type(
508 bbp_get_forum_post_type(),
509 apply_filters( 'bbp_register_forum_post_type', array(
510 'labels' => bbp_get_forum_post_type_labels(),
511 'rewrite' => bbp_get_forum_post_type_rewrite(),
512 'supports' => bbp_get_forum_post_type_supports(),
513 'description' => esc_html__( 'bbPress Forums', 'bbpress' ),
514 'capabilities' => bbp_get_forum_caps(),
515 'capability_type' => array( 'forum', 'forums' ),
516 'menu_position' => 555555,
517 'has_archive' => bbp_get_root_slug(),
518 'exclude_from_search' => true,
519 'show_in_nav_menus' => true,
520 'public' => true,
521 'show_ui' => current_user_can( 'bbp_forums_admin' ),
522 'can_export' => true,
523 'hierarchical' => true,
524 'query_var' => true,
525 'menu_icon' => '',
526 'source' => 'bbpress',
527 ) )
528 );
529
530 /** Topics ************************************************************/
531
532 // Register Topic content type
533 register_post_type(
534 bbp_get_topic_post_type(),
535 apply_filters( 'bbp_register_topic_post_type', array(
536 'labels' => bbp_get_topic_post_type_labels(),
537 'rewrite' => bbp_get_topic_post_type_rewrite(),
538 'supports' => bbp_get_topic_post_type_supports(),
539 'description' => esc_html__( 'bbPress Topics', 'bbpress' ),
540 'capabilities' => bbp_get_topic_caps(),
541 'capability_type' => array( 'topic', 'topics' ),
542 'menu_position' => 555555,
543 'has_archive' => ( 'forums' === bbp_show_on_root() ) ? bbp_get_topic_archive_slug() : false,
544 'exclude_from_search' => true,
545 'show_in_nav_menus' => false,
546 'public' => true,
547 'show_ui' => current_user_can( 'bbp_topics_admin' ),
548 'can_export' => true,
549 'hierarchical' => false,
550 'query_var' => true,
551 'menu_icon' => '',
552 'source' => 'bbpress',
553 )
554 ) );
555
556 /** Replies ***********************************************************/
557
558 // Register reply content type
559 register_post_type(
560 bbp_get_reply_post_type(),
561 apply_filters( 'bbp_register_reply_post_type', array(
562 'labels' => bbp_get_reply_post_type_labels(),
563 'rewrite' => bbp_get_reply_post_type_rewrite(),
564 'supports' => bbp_get_reply_post_type_supports(),
565 'description' => esc_html__( 'bbPress Replies', 'bbpress' ),
566 'capabilities' => bbp_get_reply_caps(),
567 'capability_type' => array( 'reply', 'replies' ),
568 'menu_position' => 555555,
569 'exclude_from_search' => true,
570 'has_archive' => false,
571 'show_in_nav_menus' => false,
572 'public' => true,
573 'show_ui' => current_user_can( 'bbp_replies_admin' ),
574 'can_export' => true,
575 'hierarchical' => false,
576 'query_var' => true,
577 'menu_icon' => '',
578 'source' => 'bbpress',
579 ) )
580 );
581 }
582
583 /**
584 * Register the post statuses used by bbPress
585 *
586 * We do some manipulation of the 'trash' status so trashed topics and
587 * replies can be viewed from within the theme.
588 *
589 * @since 2.0.0 bbPress (r2727)
590 */
591 public static function register_post_statuses() {
592
593 // Closed
594 register_post_status(
595 bbp_get_closed_status_id(),
596 apply_filters( 'bbp_register_closed_post_status', array(
597 'label' => _x( 'Closed', 'post', 'bbpress' ),
598 'label_count' => _nx_noop( 'Closed <span class="count">(%s)</span>', 'Closed <span class="count">(%s)</span>', 'post', 'bbpress' ),
599 'public' => true,
600 'show_in_admin_status_list' => true,
601 'show_in_admin_all_list' => true,
602 'source' => 'bbpress'
603 ) )
604 );
605
606 // Spam
607 register_post_status(
608 bbp_get_spam_status_id(),
609 apply_filters( 'bbp_register_spam_post_status', array(
610 'label' => _x( 'Spam', 'post', 'bbpress' ),
611 'label_count' => _nx_noop( 'Spam <span class="count">(%s)</span>', 'Spam <span class="count">(%s)</span>', 'post', 'bbpress' ),
612 'protected' => true,
613 'exclude_from_search' => true,
614 'show_in_admin_status_list' => true,
615 'show_in_admin_all_list' => false,
616 'source' => 'bbpress'
617 ) )
618 );
619
620 // Orphan
621 register_post_status(
622 bbp_get_orphan_status_id(),
623 apply_filters( 'bbp_register_orphan_post_status', array(
624 'label' => _x( 'Orphan', 'post', 'bbpress' ),
625 'label_count' => _nx_noop( 'Orphan <span class="count">(%s)</span>', 'Orphans <span class="count">(%s)</span>', 'post', 'bbpress' ),
626 'protected' => true,
627 'exclude_from_search' => true,
628 'show_in_admin_status_list' => true,
629 'show_in_admin_all_list' => false,
630 'source' => 'bbpress'
631 ) )
632 );
633
634 // Hidden
635 register_post_status(
636 bbp_get_hidden_status_id(),
637 apply_filters( 'bbp_register_hidden_post_status', array(
638 'label' => _x( 'Hidden', 'post', 'bbpress' ),
639 'label_count' => _nx_noop( 'Hidden <span class="count">(%s)</span>', 'Hidden <span class="count">(%s)</span>', 'post', 'bbpress' ),
640 'private' => true,
641 'exclude_from_search' => true,
642 'show_in_admin_status_list' => true,
643 'show_in_admin_all_list' => true,
644 'source' => 'bbpress'
645 ) )
646 );
647
648 /**
649 * Trash fix
650 *
651 * We need to remove the internal arg and change that to
652 * protected so that the users with 'view_trash' cap can view
653 * single trashed topics/replies in the front-end as wp_query
654 * doesn't allow any hack for the trashed topics to be viewed.
655 */
656 global $wp_post_statuses;
657
658 if ( ! empty( $wp_post_statuses['trash'] ) ) {
659
660 // User can view trash so set internal to false
661 if ( current_user_can( 'view_trash' ) ) {
662 $wp_post_statuses['trash']->internal = false;
663 $wp_post_statuses['trash']->protected = true;
664
665 // User cannot view trash so set internal to true
666 } else {
667 $wp_post_statuses['trash']->internal = true;
668 }
669 }
670 }
671
672 /**
673 * Register the topic tag and forum moderator taxonomies
674 *
675 * @since 2.0.0 bbPress (r2464) Added bbp_get_topic_tag_tax_id() taxonomy
676 */
677 public static function register_taxonomies() {
678
679 // Register the topic-tag taxonomy.
680 register_taxonomy(
681 bbp_get_topic_tag_tax_id(),
682 bbp_get_topic_post_type(),
683 apply_filters( 'bbp_register_topic_taxonomy', array(
684 'labels' => bbp_get_topic_tag_tax_labels(),
685 'rewrite' => bbp_get_topic_tag_tax_rewrite(),
686 'capabilities' => bbp_get_topic_tag_caps(),
687 'update_count_callback' => 'bbp_update_topic_tag_count',
688 'query_var' => true,
689 'show_tagcloud' => true,
690 'hierarchical' => false,
691 'show_in_nav_menus' => false,
692 'public' => true,
693 'show_ui' => bbp_allow_topic_tags() && current_user_can( 'bbp_topic_tags_admin' ),
694 'source' => 'bbpress'
695 )
696 ) );
697 }
698
699 /**
700 * Register the bbPress views
701 *
702 * @since 2.0.0 bbPress (r2789)
703 */
704 public static function register_views() {
705
706 // Popular topics
707 bbp_register_view(
708 'popular',
709 esc_html__( 'Most popular topics', 'bbpress' ),
710 apply_filters( 'bbp_register_view_popular', array(
711 'meta_key' => '_bbp_reply_count',
712 'meta_type' => 'NUMERIC',
713 'max_num_pages' => 1,
714 'orderby' => 'meta_value_num',
715 'show_stickies' => false
716 )
717 ) );
718
719 // Topics with no replies
720 bbp_register_view(
721 'no-replies',
722 esc_html__( 'Topics with no replies', 'bbpress' ),
723 apply_filters( 'bbp_register_view_no_replies', array(
724 'meta_key' => '_bbp_reply_count',
725 'meta_type' => 'NUMERIC',
726 'meta_value' => 1,
727 'meta_compare' => '<',
728 'orderby' => '',
729 'show_stickies' => false
730 )
731 ) );
732 }
733
734 /**
735 * Register the bbPress shortcodes
736 *
737 * @since 2.0.0 bbPress (r3031)
738 */
739 public function register_shortcodes() {
740 $this->shortcodes = new BBP_Shortcodes();
741 }
742
743 /**
744 * Register bbPress meta-data
745 *
746 * Counts added in 2.6.0 to avoid negative values
747 *
748 * @since 2.6.0 bbPress (r6300)
749 */
750 public function register_meta() {
751
752 // Define "count" meta-type array
753 $count = array(
754
755 // Counts are always integers
756 'type' => 'integer',
757
758 // Generic count description
759 'description' => esc_html__( 'bbPress Item Count', 'bbpress' ),
760
761 // Counts are single values
762 'single' => true,
763
764 // Counts should be made available in REST
765 'show_in_rest' => true,
766
767 // Never allow counts to go negative
768 'sanitize_callback' => 'bbp_number_not_negative',
769
770 // All users may update count meta data
771 'auth_callback' => '__return_true'
772 );
773
774 /** Post **************************************************************/
775
776 // Counts
777 register_meta( 'post', '_bbp_topic_count', $count );
778 register_meta( 'post', '_bbp_reply_count', $count );
779 register_meta( 'post', '_bbp_total_topic_count', $count );
780 register_meta( 'post', '_bbp_total_reply_count', $count );
781 register_meta( 'post', '_bbp_voice_count', $count );
782 register_meta( 'post', '_bbp_anonymous_reply_count', $count );
783 register_meta( 'post', '_bbp_topic_count_hidden', $count );
784 register_meta( 'post', '_bbp_reply_count_hidden', $count );
785 register_meta( 'post', '_bbp_forum_subforum_count', $count );
786
787 /* User ***************************************************************/
788
789 // Counts
790 register_meta( 'user', '_bbp_topic_count', $count );
791 register_meta( 'user', '_bbp_reply_count', $count );
792 }
793
794 /**
795 * Setup the currently logged-in user
796 *
797 * @since 2.0.0 bbPress (r2697)
798 */
799 public function setup_current_user() {
800 $this->current_user = wp_get_current_user();
801 }
802
803 /**
804 * Setup the user engagements strategy
805 *
806 * @since 2.6.0 bbPress (r6875)
807 */
808 public function setup_engagements() {
809
810 // Setup the class name
811 $strategy = ucwords( bbp_engagements_strategy() );
812 $class_name = "BBP_User_Engagements_{$strategy}";
813
814 // Setup the engagements interface
815 $this->engagements = new $class_name;
816 }
817
818 /**
819 * Initialize forum-specific roles
820 *
821 * @since 2.6.0
822 */
823 public function roles_init() {
824
825 // Get role IDs
826 $keymaster = bbp_get_keymaster_role();
827 $moderator = bbp_get_moderator_role();
828 $participant = bbp_get_participant_role();
829 $spectator = bbp_get_spectator_role();
830 $blocked = bbp_get_blocked_role();
831
832 // Build the roles into one useful array
833 $this->roles[ $keymaster ] = new WP_Role( 'Keymaster', bbp_get_caps_for_role( $keymaster ) );
834 $this->roles[ $moderator ] = new WP_Role( 'Moderator', bbp_get_caps_for_role( $moderator ) );
835 $this->roles[ $participant ] = new WP_Role( 'Participant', bbp_get_caps_for_role( $participant ) );
836 $this->roles[ $spectator ] = new WP_Role( 'Spectator', bbp_get_caps_for_role( $spectator ) );
837 $this->roles[ $blocked ] = new WP_Role( 'Blocked', bbp_get_caps_for_role( $blocked ) );
838 }
839
840 /** Custom Rewrite Rules **************************************************/
841
842 /**
843 * Add the bbPress-specific rewrite tags
844 *
845 * @since 2.0.0 bbPress (r2753)
846 */
847 public static function add_rewrite_tags() {
848 add_rewrite_tag( '%' . bbp_get_view_rewrite_id() . '%', '([^/]+)' ); // View Page tag
849 add_rewrite_tag( '%' . bbp_get_edit_rewrite_id() . '%', '([1]{1,})' ); // Edit Page tag
850 add_rewrite_tag( '%' . bbp_get_search_rewrite_id() . '%', '([^/]+)' ); // Search Results tag
851 add_rewrite_tag( '%' . bbp_get_user_rewrite_id() . '%', '([^/]+)' ); // User Profile tag
852 add_rewrite_tag( '%' . bbp_get_user_favorites_rewrite_id() . '%', '([1]{1,})' ); // User Favorites tag
853 add_rewrite_tag( '%' . bbp_get_user_subscriptions_rewrite_id() . '%', '([1]{1,})' ); // User Subscriptions tag
854 add_rewrite_tag( '%' . bbp_get_user_engagements_rewrite_id() . '%', '([1]{1,})' ); // User Engagements tag
855 add_rewrite_tag( '%' . bbp_get_user_topics_rewrite_id() . '%', '([1]{1,})' ); // User Topics Tag
856 add_rewrite_tag( '%' . bbp_get_user_replies_rewrite_id() . '%', '([1]{1,})' ); // User Replies Tag
857 }
858
859 /**
860 * Add bbPress-specific rewrite rules for uri's that are not
861 * setup for us by way of custom post types or taxonomies. This includes:
862 * - Front-end editing
863 * - Topic views
864 * - User profiles
865 *
866 * @since 2.0.0 bbPress (r2688)
867 *
868 * @todo Extract into an API
869 */
870 public static function add_rewrite_rules() {
871
872 /** Setup *************************************************************/
873
874 // Add rules to top or bottom?
875 $priority = 'top';
876
877 // Single Slugs
878 $forum_slug = bbp_get_forum_slug();
879 $topic_slug = bbp_get_topic_slug();
880 $reply_slug = bbp_get_reply_slug();
881 $ttag_slug = bbp_get_topic_tag_tax_slug();
882
883 // Archive Slugs
884 $user_slug = bbp_get_user_slug();
885 $view_slug = bbp_get_view_slug();
886 $search_slug = bbp_get_search_slug();
887 $topic_archive_slug = bbp_get_topic_archive_slug();
888 $reply_archive_slug = bbp_get_reply_archive_slug();
889
890 // Tertiary Slugs
891 $feed_slug = 'feed';
892 $edit_slug = bbp_get_edit_slug();
893 $paged_slug = bbp_get_paged_slug();
894 $user_favs_slug = bbp_get_user_favorites_slug();
895 $user_subs_slug = bbp_get_user_subscriptions_slug();
896 $user_engs_slug = bbp_get_user_engagements_slug();
897
898 // Unique rewrite ID's
899 $feed_id = 'feed';
900 $edit_id = bbp_get_edit_rewrite_id();
901 $view_id = bbp_get_view_rewrite_id();
902 $paged_id = bbp_get_paged_rewrite_id();
903 $search_id = bbp_get_search_rewrite_id();
904 $user_id = bbp_get_user_rewrite_id();
905 $user_favs_id = bbp_get_user_favorites_rewrite_id();
906 $user_subs_id = bbp_get_user_subscriptions_rewrite_id();
907 $user_tops_id = bbp_get_user_topics_rewrite_id();
908 $user_reps_id = bbp_get_user_replies_rewrite_id();
909 $user_engs_id = bbp_get_user_engagements_rewrite_id();
910
911 // Rewrite rule matches used repeatedly below
912 $root_rule = '/([^/]+)/?$';
913 $feed_rule = '/([^/]+)/' . $feed_slug . '/?$';
914 $edit_rule = '/([^/]+)/' . $edit_slug . '/?$';
915 $paged_rule = '/([^/]+)/' . $paged_slug . '/?([0-9]{1,})/?$';
916
917 // Search rules (without slug check)
918 $search_root_rule = '/?$';
919 $search_paged_rule = '/' . $paged_slug . '/?([0-9]{1,})/?$';
920
921 /** Add ***************************************************************/
922
923 // User profile rules
924 $tops_rule = '/([^/]+)/' . $topic_archive_slug . '/?$';
925 $reps_rule = '/([^/]+)/' . $reply_archive_slug . '/?$';
926 $favs_rule = '/([^/]+)/' . $user_favs_slug . '/?$';
927 $subs_rule = '/([^/]+)/' . $user_subs_slug . '/?$';
928 $engs_rule = '/([^/]+)/' . $user_engs_slug . '/?$';
929 $tops_paged_rule = '/([^/]+)/' . $topic_archive_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
930 $reps_paged_rule = '/([^/]+)/' . $reply_archive_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
931 $favs_paged_rule = '/([^/]+)/' . $user_favs_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
932 $subs_paged_rule = '/([^/]+)/' . $user_subs_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
933 $engs_paged_rule = '/([^/]+)/' . $user_engs_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
934
935 // Edit Forum|Topic|Reply|Topic-tag
936 add_rewrite_rule( $forum_slug . $edit_rule, 'index.php?' . bbp_get_forum_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
937 add_rewrite_rule( $topic_slug . $edit_rule, 'index.php?' . bbp_get_topic_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
938 add_rewrite_rule( $reply_slug . $edit_rule, 'index.php?' . bbp_get_reply_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
939 add_rewrite_rule( $ttag_slug . $edit_rule, 'index.php?' . bbp_get_topic_tag_tax_id() . '=$matches[1]&' . $edit_id . '=1', $priority );
940
941 // User Pagination|Edit|View
942 add_rewrite_rule( $user_slug . $tops_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_tops_id . '=1&' . $paged_id . '=$matches[2]', $priority );
943 add_rewrite_rule( $user_slug . $reps_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_reps_id . '=1&' . $paged_id . '=$matches[2]', $priority );
944 add_rewrite_rule( $user_slug . $favs_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_favs_id . '=1&' . $paged_id . '=$matches[2]', $priority );
945 add_rewrite_rule( $user_slug . $subs_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_subs_id . '=1&' . $paged_id . '=$matches[2]', $priority );
946 add_rewrite_rule( $user_slug . $engs_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_engs_id . '=1&' . $paged_id . '=$matches[2]', $priority );
947 add_rewrite_rule( $user_slug . $tops_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_tops_id . '=1', $priority );
948 add_rewrite_rule( $user_slug . $reps_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_reps_id . '=1', $priority );
949 add_rewrite_rule( $user_slug . $favs_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_favs_id . '=1', $priority );
950 add_rewrite_rule( $user_slug . $subs_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_subs_id . '=1', $priority );
951 add_rewrite_rule( $user_slug . $engs_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_engs_id . '=1', $priority );
952 add_rewrite_rule( $user_slug . $edit_rule, 'index.php?' . $user_id . '=$matches[1]&' . $edit_id . '=1', $priority );
953 add_rewrite_rule( $user_slug . $root_rule, 'index.php?' . $user_id . '=$matches[1]', $priority );
954
955 // Topic-View Pagination|Feed|View
956 add_rewrite_rule( $view_slug . $paged_rule, 'index.php?' . $view_id . '=$matches[1]&' . $paged_id . '=$matches[2]', $priority );
957 add_rewrite_rule( $view_slug . $feed_rule, 'index.php?' . $view_id . '=$matches[1]&' . $feed_id . '=$matches[2]', $priority );
958 add_rewrite_rule( $view_slug . $root_rule, 'index.php?' . $view_id . '=$matches[1]', $priority );
959
960 // Search All
961 add_rewrite_rule( $search_slug . $search_paged_rule, 'index.php?' . $paged_id .'=$matches[1]', $priority );
962 add_rewrite_rule( $search_slug . $search_root_rule, 'index.php?' . $search_id, $priority );
963 }
964
965 /**
966 * Add permalink structures for new archive-style destinations.
967 *
968 * - Users
969 * - Topic Views
970 * - Search
971 *
972 * @since 2.4.0 bbPress (r4930)
973 */
974 public static function add_permastructs() {
975
976 // Get unique ID's
977 $user_id = bbp_get_user_rewrite_id();
978 $view_id = bbp_get_view_rewrite_id();
979 $search_id = bbp_get_search_rewrite_id();
980
981 // Get root slugs
982 $user_slug = bbp_get_user_slug();
983 $view_slug = bbp_get_view_slug();
984 $search_slug = bbp_get_search_slug();
985
986 // User Permastruct
987 add_permastruct( $user_id, $user_slug . '/%' . $user_id . '%', array(
988 'with_front' => false,
989 'ep_mask' => EP_NONE,
990 'paged' => false,
991 'feed' => false,
992 'forcomments' => false,
993 'walk_dirs' => true,
994 'endpoints' => false,
995 ) );
996
997 // Topic View Permastruct
998 add_permastruct( $view_id, $view_slug . '/%' . $view_id . '%', array(
999 'with_front' => false,
1000 'ep_mask' => EP_NONE,
1001 'paged' => false,
1002 'feed' => false,
1003 'forcomments' => false,
1004 'walk_dirs' => true,
1005 'endpoints' => false,
1006 ) );
1007
1008 // Search Permastruct
1009 add_permastruct( $search_id, $search_slug . '/%' . $search_id . '%', array(
1010 'with_front' => false,
1011 'ep_mask' => EP_NONE,
1012 'paged' => true,
1013 'feed' => false,
1014 'forcomments' => false,
1015 'walk_dirs' => true,
1016 'endpoints' => false,
1017 ) );
1018 }
1019 }
1020
1021 /**
1022 * The main function responsible for returning the one true bbPress Instance
1023 * to functions everywhere.
1024 *
1025 * Use this function like you would a global variable, except without needing
1026 * to declare the global.
1027 *
1028 * Example: <?php $bbp = bbpress(); ?>
1029 *
1030 * @since 2.0.0 bbPress (r2464)
1031 *
1032 * @return bbPress The one true bbPress Instance
1033 */
1034 function bbpress() {
1035 return bbPress::instance();
1036 }
1037
1038 /**
1039 * Hook bbPress early onto the 'plugins_loaded' action.
1040 *
1041 * This gives all other plugins the chance to load before bbPress, to get their
1042 * actions, filters, and overrides setup without bbPress being in the way.
1043 */
1044 if ( defined( 'BBPRESS_LATE_LOAD' ) ) {
1045 add_action( 'plugins_loaded', 'bbpress', (int) BBPRESS_LATE_LOAD );
1046
1047 // "And now here's something we hope you'll really like!"
1048 } else {
1049 bbpress();
1050 }
1051
1052 endif; // class_exists check
1053