PluginProbe
bbPress / 2.6.4
bbPress v2.6.4
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.4, at bbpress.php

1,063 lines 38.0 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 7062 2020-01-30 12:32:42Z 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.4
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.4';
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 // Activity
794 register_meta( 'user', '_bbp_last_posted', array(
795 'type' => 'integer',
796 'description' => esc_html__( 'bbPress User Activity', 'bbpress' ),
797 'single' => true,
798 'show_in_rest' => true,
799 'sanitize_callback' => 'bbp_number_not_negative',
800 'auth_callback' => '__return_true'
801 ) );
802 }
803
804 /**
805 * Setup the currently logged-in user
806 *
807 * @since 2.0.0 bbPress (r2697)
808 */
809 public function setup_current_user() {
810 $this->current_user = wp_get_current_user();
811 }
812
813 /**
814 * Setup the user engagements strategy
815 *
816 * @since 2.6.0 bbPress (r6875)
817 */
818 public function setup_engagements() {
819
820 // Setup the class name
821 $strategy = ucwords( bbp_engagements_strategy() );
822 $class_name = "BBP_User_Engagements_{$strategy}";
823
824 // Setup the engagements interface
825 $this->engagements = new $class_name();
826 }
827
828 /**
829 * Initialize forum-specific roles
830 *
831 * @since 2.6.0
832 */
833 public function roles_init() {
834
835 // Get role IDs
836 $keymaster = bbp_get_keymaster_role();
837 $moderator = bbp_get_moderator_role();
838 $participant = bbp_get_participant_role();
839 $spectator = bbp_get_spectator_role();
840 $blocked = bbp_get_blocked_role();
841
842 // Build the roles into one useful array
843 $this->roles[ $keymaster ] = new WP_Role( 'Keymaster', bbp_get_caps_for_role( $keymaster ) );
844 $this->roles[ $moderator ] = new WP_Role( 'Moderator', bbp_get_caps_for_role( $moderator ) );
845 $this->roles[ $participant ] = new WP_Role( 'Participant', bbp_get_caps_for_role( $participant ) );
846 $this->roles[ $spectator ] = new WP_Role( 'Spectator', bbp_get_caps_for_role( $spectator ) );
847 $this->roles[ $blocked ] = new WP_Role( 'Blocked', bbp_get_caps_for_role( $blocked ) );
848 }
849
850 /** Custom Rewrite Rules **************************************************/
851
852 /**
853 * Add the bbPress-specific rewrite tags
854 *
855 * @since 2.0.0 bbPress (r2753)
856 */
857 public static function add_rewrite_tags() {
858 add_rewrite_tag( '%' . bbp_get_view_rewrite_id() . '%', '([^/]+)' ); // View Page tag
859 add_rewrite_tag( '%' . bbp_get_edit_rewrite_id() . '%', '([1]{1,})' ); // Edit Page tag
860 add_rewrite_tag( '%' . bbp_get_search_rewrite_id() . '%', '([^/]+)' ); // Search Results tag
861 add_rewrite_tag( '%' . bbp_get_user_rewrite_id() . '%', '([^/]+)' ); // User Profile tag
862 add_rewrite_tag( '%' . bbp_get_user_favorites_rewrite_id() . '%', '([1]{1,})' ); // User Favorites tag
863 add_rewrite_tag( '%' . bbp_get_user_subscriptions_rewrite_id() . '%', '([1]{1,})' ); // User Subscriptions tag
864 add_rewrite_tag( '%' . bbp_get_user_engagements_rewrite_id() . '%', '([1]{1,})' ); // User Engagements tag
865 add_rewrite_tag( '%' . bbp_get_user_topics_rewrite_id() . '%', '([1]{1,})' ); // User Topics Tag
866 add_rewrite_tag( '%' . bbp_get_user_replies_rewrite_id() . '%', '([1]{1,})' ); // User Replies Tag
867 }
868
869 /**
870 * Add bbPress-specific rewrite rules for uri's that are not
871 * setup for us by way of custom post types or taxonomies. This includes:
872 * - Front-end editing
873 * - Topic views
874 * - User profiles
875 *
876 * @since 2.0.0 bbPress (r2688)
877 *
878 * @todo Extract into an API
879 */
880 public static function add_rewrite_rules() {
881
882 /** Setup *************************************************************/
883
884 // Add rules to top or bottom?
885 $priority = 'top';
886
887 // Single Slugs
888 $forum_slug = bbp_get_forum_slug();
889 $topic_slug = bbp_get_topic_slug();
890 $reply_slug = bbp_get_reply_slug();
891 $ttag_slug = bbp_get_topic_tag_tax_slug();
892
893 // Archive Slugs
894 $user_slug = bbp_get_user_slug();
895 $view_slug = bbp_get_view_slug();
896 $search_slug = bbp_get_search_slug();
897 $topic_archive_slug = bbp_get_topic_archive_slug();
898 $reply_archive_slug = bbp_get_reply_archive_slug();
899
900 // Tertiary Slugs
901 $feed_slug = 'feed';
902 $edit_slug = bbp_get_edit_slug();
903 $paged_slug = bbp_get_paged_slug();
904 $user_favs_slug = bbp_get_user_favorites_slug();
905 $user_subs_slug = bbp_get_user_subscriptions_slug();
906 $user_engs_slug = bbp_get_user_engagements_slug();
907
908 // Unique rewrite ID's
909 $feed_id = 'feed';
910 $edit_id = bbp_get_edit_rewrite_id();
911 $view_id = bbp_get_view_rewrite_id();
912 $paged_id = bbp_get_paged_rewrite_id();
913 $search_id = bbp_get_search_rewrite_id();
914 $user_id = bbp_get_user_rewrite_id();
915 $user_favs_id = bbp_get_user_favorites_rewrite_id();
916 $user_subs_id = bbp_get_user_subscriptions_rewrite_id();
917 $user_tops_id = bbp_get_user_topics_rewrite_id();
918 $user_reps_id = bbp_get_user_replies_rewrite_id();
919 $user_engs_id = bbp_get_user_engagements_rewrite_id();
920
921 // Rewrite rule matches used repeatedly below
922 $root_rule = '/([^/]+)/?$';
923 $feed_rule = '/([^/]+)/' . $feed_slug . '/?$';
924 $edit_rule = '/([^/]+)/' . $edit_slug . '/?$';
925 $paged_rule = '/([^/]+)/' . $paged_slug . '/?([0-9]{1,})/?$';
926
927 // Search rules (without slug check)
928 $search_root_rule = '/?$';
929 $search_paged_rule = '/' . $paged_slug . '/?([0-9]{1,})/?$';
930
931 /** Add ***************************************************************/
932
933 // User profile rules
934 $tops_rule = '/([^/]+)/' . $topic_archive_slug . '/?$';
935 $reps_rule = '/([^/]+)/' . $reply_archive_slug . '/?$';
936 $favs_rule = '/([^/]+)/' . $user_favs_slug . '/?$';
937 $subs_rule = '/([^/]+)/' . $user_subs_slug . '/?$';
938 $engs_rule = '/([^/]+)/' . $user_engs_slug . '/?$';
939 $tops_paged_rule = '/([^/]+)/' . $topic_archive_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
940 $reps_paged_rule = '/([^/]+)/' . $reply_archive_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
941 $favs_paged_rule = '/([^/]+)/' . $user_favs_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
942 $subs_paged_rule = '/([^/]+)/' . $user_subs_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
943 $engs_paged_rule = '/([^/]+)/' . $user_engs_slug . '/' . $paged_slug . '/?([0-9]{1,})/?$';
944
945 // Edit Forum|Topic|Reply|Topic-tag
946 add_rewrite_rule( $forum_slug . $edit_rule, 'index.php?' . bbp_get_forum_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
947 add_rewrite_rule( $topic_slug . $edit_rule, 'index.php?' . bbp_get_topic_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
948 add_rewrite_rule( $reply_slug . $edit_rule, 'index.php?' . bbp_get_reply_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
949 add_rewrite_rule( $ttag_slug . $edit_rule, 'index.php?' . bbp_get_topic_tag_tax_id() . '=$matches[1]&' . $edit_id . '=1', $priority );
950
951 // User Pagination|Edit|View
952 add_rewrite_rule( $user_slug . $tops_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_tops_id . '=1&' . $paged_id . '=$matches[2]', $priority );
953 add_rewrite_rule( $user_slug . $reps_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_reps_id . '=1&' . $paged_id . '=$matches[2]', $priority );
954 add_rewrite_rule( $user_slug . $favs_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_favs_id . '=1&' . $paged_id . '=$matches[2]', $priority );
955 add_rewrite_rule( $user_slug . $subs_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_subs_id . '=1&' . $paged_id . '=$matches[2]', $priority );
956 add_rewrite_rule( $user_slug . $engs_paged_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_engs_id . '=1&' . $paged_id . '=$matches[2]', $priority );
957 add_rewrite_rule( $user_slug . $tops_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_tops_id . '=1', $priority );
958 add_rewrite_rule( $user_slug . $reps_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_reps_id . '=1', $priority );
959 add_rewrite_rule( $user_slug . $favs_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_favs_id . '=1', $priority );
960 add_rewrite_rule( $user_slug . $subs_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_subs_id . '=1', $priority );
961 add_rewrite_rule( $user_slug . $engs_rule, 'index.php?' . $user_id . '=$matches[1]&' . $user_engs_id . '=1', $priority );
962 add_rewrite_rule( $user_slug . $edit_rule, 'index.php?' . $user_id . '=$matches[1]&' . $edit_id . '=1', $priority );
963 add_rewrite_rule( $user_slug . $root_rule, 'index.php?' . $user_id . '=$matches[1]', $priority );
964
965 // Topic-View Pagination|Feed|View
966 add_rewrite_rule( $view_slug . $paged_rule, 'index.php?' . $view_id . '=$matches[1]&' . $paged_id . '=$matches[2]', $priority );
967 add_rewrite_rule( $view_slug . $feed_rule, 'index.php?' . $view_id . '=$matches[1]&' . $feed_id . '=$matches[2]', $priority );
968 add_rewrite_rule( $view_slug . $root_rule, 'index.php?' . $view_id . '=$matches[1]', $priority );
969
970 // Search All
971 add_rewrite_rule( $search_slug . $search_paged_rule, 'index.php?' . $paged_id .'=$matches[1]', $priority );
972 add_rewrite_rule( $search_slug . $search_root_rule, 'index.php?' . $search_id, $priority );
973 }
974
975 /**
976 * Add permalink structures for new archive-style destinations.
977 *
978 * - Users
979 * - Topic Views
980 * - Search
981 *
982 * @since 2.4.0 bbPress (r4930)
983 */
984 public static function add_permastructs() {
985
986 // Get unique ID's
987 $user_id = bbp_get_user_rewrite_id();
988 $view_id = bbp_get_view_rewrite_id();
989 $search_id = bbp_get_search_rewrite_id();
990
991 // Get root slugs
992 $user_slug = bbp_get_user_slug();
993 $view_slug = bbp_get_view_slug();
994 $search_slug = bbp_get_search_slug();
995
996 // User Permastruct
997 add_permastruct( $user_id, $user_slug . '/%' . $user_id . '%', array(
998 'with_front' => false,
999 'ep_mask' => EP_NONE,
1000 'paged' => false,
1001 'feed' => false,
1002 'forcomments' => false,
1003 'walk_dirs' => true,
1004 'endpoints' => false,
1005 ) );
1006
1007 // Topic View Permastruct
1008 add_permastruct( $view_id, $view_slug . '/%' . $view_id . '%', array(
1009 'with_front' => false,
1010 'ep_mask' => EP_NONE,
1011 'paged' => false,
1012 'feed' => false,
1013 'forcomments' => false,
1014 'walk_dirs' => true,
1015 'endpoints' => false,
1016 ) );
1017
1018 // Search Permastruct
1019 add_permastruct( $search_id, $search_slug . '/%' . $search_id . '%', array(
1020 'with_front' => false,
1021 'ep_mask' => EP_NONE,
1022 'paged' => true,
1023 'feed' => false,
1024 'forcomments' => false,
1025 'walk_dirs' => true,
1026 'endpoints' => false,
1027 ) );
1028 }
1029 }
1030
1031 /**
1032 * The main function responsible for returning the one true bbPress Instance
1033 * to functions everywhere.
1034 *
1035 * Use this function like you would a global variable, except without needing
1036 * to declare the global.
1037 *
1038 * Example: <?php $bbp = bbpress(); ?>
1039 *
1040 * @since 2.0.0 bbPress (r2464)
1041 *
1042 * @return bbPress The one true bbPress Instance
1043 */
1044 function bbpress() {
1045 return bbPress::instance();
1046 }
1047
1048 /**
1049 * Hook bbPress early onto the 'plugins_loaded' action.
1050 *
1051 * This gives all other plugins the chance to load before bbPress, to get their
1052 * actions, filters, and overrides setup without bbPress being in the way.
1053 */
1054 if ( defined( 'BBPRESS_LATE_LOAD' ) ) {
1055 add_action( 'plugins_loaded', 'bbpress', (int) BBPRESS_LATE_LOAD );
1056
1057 // "And now here's something we hope you'll really like!"
1058 } else {
1059 bbpress();
1060 }
1061
1062 endif; // class_exists check
1063