Professional Documents
Culture Documents
php
/**
* The bbPress Plugin
*
* bbPress is forum software with a twist from the creators of WordPress.
*
* $Id: bbpress.php 7228 2021-11-29 15:22:27Z johnjamesjacoby $
*
* @package bbPress
* @subpackage Main
*/
/**
* Plugin Name: bbPress
* Plugin URI: https://bbpress.org
* Description: bbPress is forum software with a twist from the creators of
WordPress.
* Author: The bbPress Contributors
* Author URI: https://bbpress.org
* Version: 2.6.9
* Text Domain: bbpress
* Domain Path: /languages/
* License: GPLv2 or later (license.txt)
* Requires PHP: 5.6.20
* Requires at least: 5.0
*/
if ( ! class_exists( 'bbPress' ) ) :
/**
* Main bbPress Class
*
* "Word hard. Stay bumble."
*
* @since 2.0.0 bbPress (r2464)
*/
final class bbPress {
/**
* bbPress uses many variables, several of which can be filtered to
* customize the way it operates. Most of these variables are stored in a
* private array that gets updated with the help of PHP magic methods.
*
* This is a precautionary measure, to avoid potential errors produced by
* unanticipated direct manipulation of run-time data.
*
* @see bbPress::setup_globals()
* @var array
*/
private $data;
/**
* @var mixed False when not logged in; WP_User object when logged in
*/
public $current_user = false;
/**
* @var stdClass Add-ons append to this (Akismet, BuddyPress, etc...)
*/
public $extend;
/**
* @var array Topic views
*/
public $views = array();
/**
* @var array Overloads get_option()
*/
public $options = array();
/**
* @var array Storage of options not in the database
*/
public $not_options = array();
/**
* @var array Overloads get_user_meta()
*/
public $user_options = array();
/**
* @var array Dynamically initialized user roles
*/
public $roles = array();
/**
* Main bbPress Instance
*
* bbPress is fun
* Please load it only one time
* For this, we thank you
*
* Insures that only one instance of bbPress exists in memory at any one
* time. Also prevents needing to define globals all over the place.
*
* @since 2.1.0 bbPress (r3757)
*
* @staticvar object $instance
* @see bbpress()
* @return bbPress The one true bbPress
*/
public static function instance() {
/**
* A dummy constructor to prevent bbPress from being loaded more than once.
*
* @since 2.0.0 bbPress (r2464)
*
* @see bbPress::instance()
* @see bbpress();
*/
private function __construct() { /* Do nothing here */ }
/**
* A dummy magic method to prevent bbPress from being cloned
*
* @since 2.0.0 bbPress (r2464)
*/
public function __clone() { _doing_it_wrong( __FUNCTION__,
__( 'Cheatin’ huh?', 'bbpress' ), '2.1' ); }
/**
* A dummy magic method to prevent bbPress from being unserialized
*
* @since 2.0.0 bbPress (r2464)
*/
public function __wakeup() { _doing_it_wrong( __FUNCTION__,
__( 'Cheatin’ huh?', 'bbpress' ), '2.1' ); }
/**
* Magic method for checking the existence of a certain custom field
*
* @since 2.1.0 bbPress (r3951)
*/
public function __isset( $key ) { return isset( $this->data[ $key ] ); }
/**
* Magic method for getting bbPress variables
*
* @since 2.1.0 bbPress (r3951)
*/
public function __get( $key ) { return isset( $this->data[ $key ] ) ? $this-
>data[ $key ] : null; }
/**
* Magic method for setting bbPress variables
*
* @since 2.1.0 bbPress (r3951)
*/
public function __set( $key , $value ) { $this->data[ $key ] = $value; }
/**
* Magic method for unsetting bbPress variables
*
* @since 2.3.0 bbPress (r4628)
*/
public function __unset( $key ) {
if ( isset( $this->data[ $key ] ) ) {
unset( $this->data[ $key ] );
}
}
/**
* Magic method to prevent notices and errors from invalid method calls
*
* @since 2.2.0 bbPress (r4252)
*/
public function __call( $name = '', $args = array() ) { unset( $name,
$args ); return null; }
/**
* Setup the environment variables to allow the rest of bbPress to function
* more easily.
*
* @since 2.0.0 bbPress (r2626)
*
* @access private
*/
private function setup_environment() {
/** Versions
**********************************************************/
$this->version = '2.6.9';
$this->db_version = '263';
/** Paths
*************************************************************/
// Includes
$this->includes_dir = apply_filters( 'bbp_includes_dir',
trailingslashit( $this->plugin_dir . 'includes' ) );
$this->includes_url = apply_filters( 'bbp_includes_url',
trailingslashit( $this->plugin_url . 'includes' ) );
// Languages
$this->lang_base = apply_filters( 'bbp_lang_base',
trailingslashit( $this->basepath . 'languages' ) );
$this->lang_dir = apply_filters( 'bbp_lang_dir',
trailingslashit( $this->plugin_dir . 'languages' ) );
// Templates
$this->themes_dir = apply_filters( 'bbp_themes_dir',
trailingslashit( $this->plugin_dir . 'templates' ) );
$this->themes_url = apply_filters( 'bbp_themes_url',
trailingslashit( $this->plugin_url . 'templates' ) );
}
/**
* Smart defaults to many bbPress specific class variables.
*
* @since 2.6.0 bbPress (r6330)
*/
private function setup_variables() {
/** Identifiers
*******************************************************/
// Status identifiers
$this->spam_status_id = apply_filters( 'bbp_spam_post_status',
'spam' );
$this->closed_status_id = apply_filters( 'bbp_closed_post_status',
'closed' );
$this->orphan_status_id = apply_filters( 'bbp_orphan_post_status',
'orphan' );
$this->public_status_id = apply_filters( 'bbp_public_post_status',
'publish' );
$this->pending_status_id = apply_filters( 'bbp_pending_post_status',
'pending' );
$this->private_status_id = apply_filters( 'bbp_private_post_status',
'private' );
$this->hidden_status_id = apply_filters( 'bbp_hidden_post_status',
'hidden' );
$this->trash_status_id = apply_filters( 'bbp_trash_post_status',
'trash' );
// Other identifiers
$this->user_id = apply_filters( 'bbp_user_id',
'bbp_user' );
$this->tops_id = apply_filters( 'bbp_tops_id',
'bbp_tops' );
$this->reps_id = apply_filters( 'bbp_reps_id',
'bbp_reps' );
$this->favs_id = apply_filters( 'bbp_favs_id',
'bbp_favs' );
$this->subs_id = apply_filters( 'bbp_subs_id',
'bbp_subs' );
$this->view_id = apply_filters( 'bbp_view_id',
'bbp_view' );
$this->edit_id = apply_filters( 'bbp_edit_id', 'edit'
);
$this->paged_id = apply_filters( 'bbp_paged_id', 'paged'
);
$this->search_id = apply_filters( 'bbp_search_id',
'bbp_search' );
$this->engagements_id = apply_filters( 'bbp_engagements_id',
'bbp_engagements' );
/** Queries
***********************************************************/
/** Users
*************************************************************/
/** Misc
**************************************************************/
/** Deprecated
********************************************************/
/** Core
**************************************************************/
/** Components
********************************************************/
// Common
require $this->includes_dir . 'common/ajax.php';
require $this->includes_dir . 'common/classes.php';
require $this->includes_dir . 'common/engagements.php';
require $this->includes_dir . 'common/functions.php';
require $this->includes_dir . 'common/formatting.php';
require $this->includes_dir . 'common/locale.php';
require $this->includes_dir . 'common/locks.php';
require $this->includes_dir . 'common/template.php';
require $this->includes_dir . 'common/widgets.php';
require $this->includes_dir . 'common/shortcodes.php';
// Forums
require $this->includes_dir . 'forums/capabilities.php';
require $this->includes_dir . 'forums/functions.php';
require $this->includes_dir . 'forums/template.php';
// Topics
require $this->includes_dir . 'topics/capabilities.php';
require $this->includes_dir . 'topics/functions.php';
require $this->includes_dir . 'topics/template.php';
// Replies
require $this->includes_dir . 'replies/capabilities.php';
require $this->includes_dir . 'replies/functions.php';
require $this->includes_dir . 'replies/template.php';
// Search
require $this->includes_dir . 'search/functions.php';
require $this->includes_dir . 'search/template.php';
// Users
require $this->includes_dir . 'users/capabilities.php';
require $this->includes_dir . 'users/engagements.php';
require $this->includes_dir . 'users/functions.php';
require $this->includes_dir . 'users/template.php';
require $this->includes_dir . 'users/options.php';
require $this->includes_dir . 'users/signups.php';
/** Hooks
*************************************************************/
/** Admin
*************************************************************/
/**
* Setup the default hooks and actions
*
* @since 2.0.0 bbPress (r2644)
*
* @access private
*/
private function setup_actions() {
/**
* Register bundled theme packages
*
* Note that since we currently have complete control over bbp-themes and
* the bbp-theme-compat folders, it's fine to hardcode these here. If at a
* later date we need to automate this, and API will need to be built.
*
* @since 2.1.0 bbPress (r3829)
*/
public function register_theme_packages() {
/**
* Setup the default bbPress theme compatibility location.
*
* @since 2.1.0 bbPress (r3778)
*/
public function setup_theme() {
bbp_setup_theme_compat( bbp_get_theme_package_id() );
}
/**
* Load the translation file for current language. Checks the deprecated
* languages folder inside the bbPress plugin first, and then the default
* WordPress languages folder.
*
* Note that custom translation files inside the bbPress plugin folder
* will be removed on bbPress updates. If you're creating custom
* translation files, please use the global language folder.
*
* @since 2.0.0 bbPress (r2596)
*/
public function load_textdomain() {
/**
* Setup the post types for forums, topics and replies
*
* @since 2.0.0 bbPress (r2597)
*/
public static function register_post_types() {
/** Forums
************************************************************/
/** Topics
************************************************************/
/** Replies
***********************************************************/
/**
* Register the post statuses used by bbPress
*
* We do some manipulation of the 'trash' status so trashed topics and
* replies can be viewed from within the theme.
*
* @since 2.0.0 bbPress (r2727)
*/
public static function register_post_statuses() {
// Closed
register_post_status(
bbp_get_closed_status_id(),
apply_filters( 'bbp_register_closed_post_status', array(
'label' => _x( 'Closed', 'post',
'bbpress' ),
'label_count' => _nx_noop( 'Closed <span
class="count">(%s)</span>', 'Closed <span class="count">(%s)</span>', 'post',
'bbpress' ),
'public' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'source' => 'bbpress'
) )
);
// Spam
register_post_status(
bbp_get_spam_status_id(),
apply_filters( 'bbp_register_spam_post_status', array(
'label' => _x( 'Spam', 'post',
'bbpress' ),
'label_count' => _nx_noop( 'Spam <span
class="count">(%s)</span>', 'Spam <span class="count">(%s)</span>', 'post',
'bbpress' ),
'protected' => true,
'exclude_from_search' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => false,
'source' => 'bbpress'
) )
);
// Orphan
register_post_status(
bbp_get_orphan_status_id(),
apply_filters( 'bbp_register_orphan_post_status', array(
'label' => _x( 'Orphan', 'post',
'bbpress' ),
'label_count' => _nx_noop( 'Orphan <span
class="count">(%s)</span>', 'Orphans <span class="count">(%s)</span>', 'post',
'bbpress' ),
'protected' => true,
'exclude_from_search' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => false,
'source' => 'bbpress'
) )
);
// Hidden
register_post_status(
bbp_get_hidden_status_id(),
apply_filters( 'bbp_register_hidden_post_status', array(
'label' => _x( 'Hidden', 'post',
'bbpress' ),
'label_count' => _nx_noop( 'Hidden <span
class="count">(%s)</span>', 'Hidden <span class="count">(%s)</span>', 'post',
'bbpress' ),
'private' => true,
'exclude_from_search' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'source' => 'bbpress'
) )
);
/**
* Trash fix
*
* We need to remove the internal arg and change that to
* protected so that the users with 'view_trash' cap can view
* single trashed topics/replies in the front-end as wp_query
* doesn't allow any hack for the trashed topics to be viewed.
*/
global $wp_post_statuses;
if ( ! empty( $wp_post_statuses['trash'] ) ) {
/**
* Register the topic tag and forum moderator taxonomies
*
* @since 2.0.0 bbPress (r2464) Added bbp_get_topic_tag_tax_id() taxonomy
*/
public static function register_taxonomies() {
/**
* Register the bbPress views
*
* @since 2.0.0 bbPress (r2789)
*/
public static function register_views() {
// Popular topics
bbp_register_view(
'popular',
esc_html__( 'Most popular topics', 'bbpress' ),
apply_filters( 'bbp_register_view_popular', array(
'meta_key' => '_bbp_reply_count',
'meta_type' => 'NUMERIC',
'max_num_pages' => 1,
'orderby' => 'meta_value_num',
'show_stickies' => false
)
) );
/**
* Register the bbPress shortcodes
*
* @since 2.0.0 bbPress (r3031)
*/
public function register_shortcodes() {
$this->shortcodes = new BBP_Shortcodes();
}
/**
* Register bbPress meta-data
*
* Counts added in 2.6.0 to avoid negative values
*
* @since 2.6.0 bbPress (r6300)
*/
public function register_meta() {
/** Post
**************************************************************/
// Counts
register_meta( 'post', '_bbp_topic_count', $count );
register_meta( 'post', '_bbp_reply_count', $count );
register_meta( 'post', '_bbp_total_topic_count', $count );
register_meta( 'post', '_bbp_total_reply_count', $count );
register_meta( 'post', '_bbp_voice_count', $count );
register_meta( 'post', '_bbp_anonymous_reply_count', $count );
register_meta( 'post', '_bbp_topic_count_hidden', $count );
register_meta( 'post', '_bbp_reply_count_hidden', $count );
register_meta( 'post', '_bbp_forum_subforum_count', $count );
/* User
***************************************************************/
// Counts
register_meta( 'user', '_bbp_topic_count', $count );
register_meta( 'user', '_bbp_reply_count', $count );
// Activity
register_meta( 'user', '_bbp_last_posted', array(
'type' => 'integer',
'description' => esc_html__( 'bbPress User Activity',
'bbpress' ),
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'bbp_number_not_negative',
'auth_callback' => '__return_true'
) );
}
/**
* Setup the currently logged-in user
*
* @since 2.0.0 bbPress (r2697)
*/
public function setup_current_user() {
$this->current_user = wp_get_current_user();
}
/**
* Setup the user engagements strategy
*
* @since 2.6.0 bbPress (r6875)
*/
public function setup_engagements() {
/**
* Initialize forum-specific roles
*
* @since 2.6.0
*/
public function roles_init() {
/**
* Add the bbPress-specific rewrite tags
*
* @since 2.0.0 bbPress (r2753)
*/
public static function add_rewrite_tags() {
add_rewrite_tag( '%' . bbp_get_view_rewrite_id() . '%',
'([^/]+)' ); // View Page tag
add_rewrite_tag( '%' . bbp_get_edit_rewrite_id() . '%',
'([1]{1,})' ); // Edit Page tag
add_rewrite_tag( '%' . bbp_get_search_rewrite_id() . '%',
'([^/]+)' ); // Search Results tag
add_rewrite_tag( '%' . bbp_get_user_rewrite_id() . '%',
'([^/]+)' ); // User Profile tag
add_rewrite_tag( '%' . bbp_get_user_favorites_rewrite_id() . '%',
'([1]{1,})' ); // User Favorites tag
add_rewrite_tag( '%' . bbp_get_user_subscriptions_rewrite_id() . '%',
'([1]{1,})' ); // User Subscriptions tag
add_rewrite_tag( '%' . bbp_get_user_engagements_rewrite_id() . '%',
'([1]{1,})' ); // User Engagements tag
add_rewrite_tag( '%' . bbp_get_user_topics_rewrite_id() . '%',
'([1]{1,})' ); // User Topics Tag
add_rewrite_tag( '%' . bbp_get_user_replies_rewrite_id() . '%',
'([1]{1,})' ); // User Replies Tag
}
/**
* Add bbPress-specific rewrite rules for uri's that are not
* setup for us by way of custom post types or taxonomies. This includes:
* - Front-end editing
* - Topic views
* - User profiles
*
* @since 2.0.0 bbPress (r2688)
*
* @todo Extract into an API
*/
public static function add_rewrite_rules() {
/** Setup
*************************************************************/
// Single Slugs
$forum_slug = bbp_get_forum_slug();
$topic_slug = bbp_get_topic_slug();
$reply_slug = bbp_get_reply_slug();
$ttag_slug = bbp_get_topic_tag_tax_slug();
// Archive Slugs
$user_slug = bbp_get_user_slug();
$view_slug = bbp_get_view_slug();
$search_slug = bbp_get_search_slug();
$topic_archive_slug = bbp_get_topic_archive_slug();
$reply_archive_slug = bbp_get_reply_archive_slug();
// Tertiary Slugs
$feed_slug = 'feed';
$edit_slug = bbp_get_edit_slug();
$paged_slug = bbp_get_paged_slug();
$user_favs_slug = bbp_get_user_favorites_slug();
$user_subs_slug = bbp_get_user_subscriptions_slug();
$user_engs_slug = bbp_get_user_engagements_slug();
/** Add
***************************************************************/
// Edit Forum|Topic|Reply|Topic-tag
add_rewrite_rule( $forum_slug . $edit_rule, 'index.php?' .
bbp_get_forum_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
add_rewrite_rule( $topic_slug . $edit_rule, 'index.php?' .
bbp_get_topic_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
add_rewrite_rule( $reply_slug . $edit_rule, 'index.php?' .
bbp_get_reply_post_type() . '=$matches[1]&' . $edit_id . '=1', $priority );
add_rewrite_rule( $ttag_slug . $edit_rule, 'index.php?' .
bbp_get_topic_tag_tax_id() . '=$matches[1]&' . $edit_id . '=1', $priority );
// User Pagination|Edit|View
add_rewrite_rule( $user_slug . $tops_paged_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_tops_id . '=1&' . $paged_id . '=$matches[2]',
$priority );
add_rewrite_rule( $user_slug . $reps_paged_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_reps_id . '=1&' . $paged_id . '=$matches[2]',
$priority );
add_rewrite_rule( $user_slug . $favs_paged_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_favs_id . '=1&' . $paged_id . '=$matches[2]',
$priority );
add_rewrite_rule( $user_slug . $subs_paged_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_subs_id . '=1&' . $paged_id . '=$matches[2]',
$priority );
add_rewrite_rule( $user_slug . $engs_paged_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_engs_id . '=1&' . $paged_id . '=$matches[2]',
$priority );
add_rewrite_rule( $user_slug . $tops_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_tops_id . '=1',
$priority );
add_rewrite_rule( $user_slug . $reps_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_reps_id . '=1',
$priority );
add_rewrite_rule( $user_slug . $favs_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_favs_id . '=1',
$priority );
add_rewrite_rule( $user_slug . $subs_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_subs_id . '=1',
$priority );
add_rewrite_rule( $user_slug . $engs_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $user_engs_id . '=1',
$priority );
add_rewrite_rule( $user_slug . $edit_rule, 'index.php?' .
$user_id . '=$matches[1]&' . $edit_id . '=1',
$priority );
add_rewrite_rule( $user_slug . $root_rule, 'index.php?' .
$user_id . '=$matches[1]',
$priority );
// Topic-View Pagination|Feed|View
add_rewrite_rule( $view_slug . $paged_rule, 'index.php?' . $view_id .
'=$matches[1]&' . $paged_id . '=$matches[2]', $priority );
add_rewrite_rule( $view_slug . $feed_rule, 'index.php?' . $view_id .
'=$matches[1]&' . $feed_id . '=$matches[2]', $priority );
add_rewrite_rule( $view_slug . $root_rule, 'index.php?' . $view_id .
'=$matches[1]', $priority );
// Search All
add_rewrite_rule( $search_slug . $search_paged_rule, 'index.php?' .
$paged_id .'=$matches[1]', $priority );
add_rewrite_rule( $search_slug . $search_root_rule, 'index.php?' .
$search_id, $priority );
}
/**
* Add permalink structures for new archive-style destinations.
*
* - Users
* - Topic Views
* - Search
*
* @since 2.4.0 bbPress (r4930)
*/
public static function add_permastructs() {
// User Permastruct
add_permastruct( $user_id, $user_slug . '/%' . $user_id . '%', array(
'with_front' => false,
'ep_mask' => EP_NONE,
'paged' => false,
'feed' => false,
'forcomments' => false,
'walk_dirs' => true,
'endpoints' => false,
) );
// Search Permastruct
add_permastruct( $search_id, $search_slug . '/%' . $search_id . '%',
array(
'with_front' => false,
'ep_mask' => EP_NONE,
'paged' => true,
'feed' => false,
'forcomments' => false,
'walk_dirs' => true,
'endpoints' => false,
) );
}
}
/**
* The main function responsible for returning the one true bbPress Instance
* to functions everywhere.
*
* Use this function like you would a global variable, except without needing
* to declare the global.
*
* Example: <?php $bbp = bbpress(); ?>
*
* @since 2.0.0 bbPress (r2464)
*
* @return bbPress The one true bbPress Instance
*/
function bbpress() {
return bbPress::instance();
}
/**
* Hook bbPress early onto the 'plugins_loaded' action.
*
* This gives all other plugins the chance to load before bbPress, to get their
* actions, filters, and overrides setup without bbPress being in the way.
*/
if ( defined( 'BBPRESS_LATE_LOAD' ) ) {
add_action( 'plugins_loaded', 'bbpress', (int) BBPRESS_LATE_LOAD );