PluginProbe
bbPress / 2.1-beta-1
bbPress v2.1-beta-1
2.6.17 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 All 72 releases
bbpress / bbpress.php

bbpress.php in bbPress 2.1-beta-1, at bbpress.php

916 lines 33.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 3989 2012-06-18 16:09:43Z johnjamesjacoby $
9 *
10 * @package bbPress
11 * @subpackage Main
12 */
13
14 /**
15 * Plugin Name: bbPress
16 * Plugin URI: http://bbpress.org
17 * Description: bbPress is forum software with a twist from the creators of WordPress.
18 * Author: The bbPress Community
19 * Author URI: http://bbpress.org
20 * Version: 2.1-beta-1
21 * Text Domain: bbpress
22 * Domain Path: /bbp-languages/
23 */
24
25 // Exit if accessed directly
26 if ( !defined( 'ABSPATH' ) ) exit;
27
28 if ( !class_exists( 'bbPress' ) ) :
29 /**
30 * Main bbPress Class
31 *
32 * Tap tap tap... Is this thing on?
33 *
34 * @since bbPress (r2464)
35 */
36 final class bbPress {
37
38 /** Magic *****************************************************************/
39
40 /**
41 * bbPress uses many variables, most of which can be filtered to customize
42 * the way that it works. To prevent unauthorized access, these variables
43 * are stored in a private array that is magically updated using PHP 5.2+
44 * methods. This is to prevent third party plugins from tampering with
45 * essential information indirectly, which would cause issues later.
46 *
47 * @see bbPress::setup_globals()
48 * @var array
49 */
50 private $data;
51
52 /** Not Magic *************************************************************/
53
54 /**
55 * @var mixed False when not logged in; WP_User object when logged in
56 */
57 public $current_user = false;
58
59 /**
60 * @var obj Add-ons append to this (Akismet, BuddyPress, etc...)
61 */
62 public $extend;
63
64 /**
65 * @var array Topic views
66 */
67 public $views = array();
68
69 /**
70 * @var array Overloads get_option()
71 */
72 public $options = array();
73
74 /**
75 * @var array Overloads get_user_meta()
76 */
77 public $user_options = array();
78
79 /** Singleton *************************************************************/
80
81 /**
82 * @var bbPress The one true bbPress
83 */
84 private static $instance;
85
86 /**
87 * Main bbPress Instance
88 *
89 * bbPress is fun
90 * Please load it only one time
91 * For this, we thank you
92 *
93 * Insures that only one instance of bbPress exists in memory at any one
94 * time. Also prevents needing to define globals all over the place.
95 *
96 * @since bbPress (r3757)
97 * @staticvar array $instance
98 * @uses bbPress::setup_globals() Setup the globals needed
99 * @uses bbPress::includes() Include the required files
100 * @uses bbPress::setup_actions() Setup the hooks and actions
101 * @see bbpress()
102 * @return The one true bbPress
103 */
104 public static function instance() {
105 if ( ! isset( self::$instance ) ) {
106 self::$instance = new bbPress;
107 self::$instance->setup_globals();
108 self::$instance->includes();
109 self::$instance->setup_actions();
110 }
111 return self::$instance;
112 }
113
114 /** Magic Methods *********************************************************/
115
116 /**
117 * A dummy constructor to prevent bbPress from being loaded more than once.
118 *
119 * @since bbPress (r2464)
120 * @see bbPress::instance()
121 * @see bbpress();
122 */
123 private function __construct() { /* Do nothing here */ }
124
125 /**
126 * A dummy magic method to prevent bbPress from being cloned
127 *
128 * @since bbPress (r2464)
129 */
130 public function __clone() { wp_die( __( 'Cheatin&#8217; huh?', 'bbpress' ) ); }
131
132 /**
133 * A dummy magic method to prevent bbPress from being unserialized
134 *
135 * @since bbPress (r2464)
136 */
137 public function __wakeup() { wp_die( __( 'Cheatin&#8217; huh?', 'bbpress' ) ); }
138
139 /**
140 * Magic method for checking the existence of a certain custom field
141 *
142 * @since bbPress (r3951)
143 */
144 public function __isset( $key ) { return isset( $this->data[$key] ); }
145
146 /**
147 * Magic method for getting bbPress varibles
148 *
149 * @since bbPress (r3951)
150 */
151 public function __get( $key ) { return isset( $this->data[$key] ) ? $this->data[$key] : null; }
152
153 /**
154 * Magic method for setting bbPress varibles
155 *
156 * @since bbPress (r3951)
157 */
158 public function __set( $key, $value ) { $this->data[$key] = $value; }
159
160 /** Private Methods *******************************************************/
161
162 /**
163 * Set some smart defaults to class variables. Allow some of them to be
164 * filtered to allow for early overriding.
165 *
166 * @since bbPress (r2626)
167 * @access private
168 * @uses plugin_dir_path() To generate bbPress plugin path
169 * @uses plugin_dir_url() To generate bbPress plugin url
170 * @uses apply_filters() Calls various filters
171 */
172 private function setup_globals() {
173
174 /** Versions **********************************************************/
175
176 $this->version = '2.1-beta-1'; // bbPress version
177 $this->db_version = '201'; // bbPress DB version
178
179 /** Paths *************************************************************/
180
181 // Setup some base path and URL information
182 $this->file = __FILE__;
183 $this->basename = apply_filters( 'bbp_plugin_basenname', plugin_basename( $this->file ) );
184 $this->plugin_dir = apply_filters( 'bbp_plugin_dir_path', plugin_dir_path( $this->file ) );
185 $this->plugin_url = apply_filters( 'bbp_plugin_dir_url', plugin_dir_url ( $this->file ) );
186
187 // Themes
188 $this->themes_dir = apply_filters( 'bbp_themes_dir', trailingslashit( $this->plugin_dir . 'bbp-themes' ) );
189 $this->themes_url = apply_filters( 'bbp_themes_url', trailingslashit( $this->plugin_url . 'bbp-themes' ) );
190
191 // Languages
192 $this->lang_dir = apply_filters( 'bbp_lang_dir', trailingslashit( $this->plugin_dir . 'bbp-languages' ) );
193
194 /** Identifiers *******************************************************/
195
196 // Post type identifiers
197 $this->forum_post_type = apply_filters( 'bbp_forum_post_type', 'forum' );
198 $this->topic_post_type = apply_filters( 'bbp_topic_post_type', 'topic' );
199 $this->reply_post_type = apply_filters( 'bbp_reply_post_type', 'reply' );
200 $this->topic_tag_tax_id = apply_filters( 'bbp_topic_tag_tax_id', 'topic-tag' );
201
202 // Status identifiers
203 $this->spam_status_id = apply_filters( 'bbp_spam_post_status', 'spam' );
204 $this->closed_status_id = apply_filters( 'bbp_closed_post_status', 'closed' );
205 $this->orphan_status_id = apply_filters( 'bbp_orphan_post_status', 'orphan' );
206 $this->public_status_id = apply_filters( 'bbp_public_post_status', 'publish' );
207 $this->pending_status_id = apply_filters( 'bbp_pending_post_status', 'pending' );
208 $this->private_status_id = apply_filters( 'bbp_private_post_status', 'private' );
209 $this->hidden_status_id = apply_filters( 'bbp_hidden_post_status', 'hidden' );
210 $this->trash_status_id = apply_filters( 'bbp_trash_post_status', 'trash' );
211
212 // Other identifiers
213 $this->user_id = apply_filters( 'bbp_user_id', 'bbp_user' );
214 $this->view_id = apply_filters( 'bbp_view_id', 'bbp_view' );
215 $this->edit_id = apply_filters( 'bbp_edit_id', 'edit' );
216
217 /** Queries ***********************************************************/
218
219 $this->current_forum_id = 0; // Current forum id
220 $this->current_topic_id = 0; // Current topic id
221 $this->current_reply_id = 0; // Current reply id
222 $this->current_topic_tag_id = 0; // Current topic tag id
223
224 $this->forum_query = new stdClass; // Main forum query
225 $this->topic_query = new stdClass; // Main topic query
226 $this->reply_query = new stdClass; // Main reply query
227
228 /** Theme Compat ******************************************************/
229
230 $this->theme_compat = new stdClass(); // Base theme compatibility class
231 $this->filters = new stdClass(); // Used when adding/removing filters
232
233 /** Users *************************************************************/
234
235 $this->current_user = new stdClass(); // Currently logged in user
236 $this->displayed_user = new stdClass(); // Currently displayed user
237
238 /** Misc **************************************************************/
239
240 $this->extend = new stdClass(); // Plugins add data here
241 $this->errors = new WP_Error(); // Feedback
242 $this->tab_index = apply_filters( 'bbp_default_tab_index', 100 );
243
244 /** Cache *************************************************************/
245
246 // Add bbPress to global cache groups
247 wp_cache_add_global_groups( 'bbpress' );
248 }
249
250 /**
251 * Include required files
252 *
253 * @since bbPress (r2626)
254 * @access private
255 * @todo Be smarter about conditionally loading code
256 * @uses is_admin() If in WordPress admin, load additional file
257 */
258 private function includes() {
259
260 /** Core **************************************************************/
261
262 require( $this->plugin_dir . 'bbp-includes/bbp-core-actions.php' ); // All actions
263 require( $this->plugin_dir . 'bbp-includes/bbp-core-filters.php' ); // All filters
264 require( $this->plugin_dir . 'bbp-includes/bbp-core-functions.php' ); // Core functions
265 require( $this->plugin_dir . 'bbp-includes/bbp-core-options.php' ); // Configuration options
266 require( $this->plugin_dir . 'bbp-includes/bbp-core-caps.php' ); // Roles and capabilities
267 require( $this->plugin_dir . 'bbp-includes/bbp-core-classes.php' ); // Common classes
268 require( $this->plugin_dir . 'bbp-includes/bbp-core-widgets.php' ); // Sidebar widgets
269 require( $this->plugin_dir . 'bbp-includes/bbp-core-shortcodes.php' ); // Shortcodes for use with pages and posts
270 require( $this->plugin_dir . 'bbp-includes/bbp-core-update.php' ); // Database updater
271
272 /** Templates *********************************************************/
273
274 require( $this->plugin_dir . 'bbp-includes/bbp-template-functions.php' ); // Template functions
275 require( $this->plugin_dir . 'bbp-includes/bbp-template-loader.php' ); // Template loader
276 require( $this->plugin_dir . 'bbp-includes/bbp-theme-compatibility.php' ); // Theme compatibility for existing themes
277
278 /** Extensions ********************************************************/
279
280 require( $this->plugin_dir . 'bbp-includes/bbp-extend-akismet.php' ); // Spam prevention for topics and replies
281
282 /**
283 * BuddyPress extension is loaded in bbp-core-hooks.php
284 *
285 * @since bbPress (r3559)
286 */
287
288 /** Components ********************************************************/
289
290 require( $this->plugin_dir . 'bbp-includes/bbp-common-functions.php' ); // Common functions
291 require( $this->plugin_dir . 'bbp-includes/bbp-common-template.php' ); // Common template tags
292
293 require( $this->plugin_dir . 'bbp-includes/bbp-forum-functions.php' ); // Forum functions
294 require( $this->plugin_dir . 'bbp-includes/bbp-forum-template.php' ); // Forum template tags
295
296 require( $this->plugin_dir . 'bbp-includes/bbp-topic-functions.php' ); // Topic functions
297 require( $this->plugin_dir . 'bbp-includes/bbp-topic-template.php' ); // Topic template tags
298
299 require( $this->plugin_dir . 'bbp-includes/bbp-reply-functions.php' ); // Reply functions
300 require( $this->plugin_dir . 'bbp-includes/bbp-reply-template.php' ); // Reply template tags
301
302 require( $this->plugin_dir . 'bbp-includes/bbp-user-functions.php' ); // User functions
303 require( $this->plugin_dir . 'bbp-includes/bbp-user-template.php' ); // User template tags
304 require( $this->plugin_dir . 'bbp-includes/bbp-user-options.php' ); // User options
305
306 /** Admin *************************************************************/
307
308 // Quick admin check and load if needed
309 if ( is_admin() ) {
310 require( $this->plugin_dir . 'bbp-admin/bbp-admin.php' );
311 require( $this->plugin_dir . 'bbp-admin/bbp-actions.php' );
312 }
313 }
314
315 /**
316 * Setup the default hooks and actions
317 *
318 * @since bbPress (r2644)
319 * @access private
320 * @todo Not use bbp_is_deactivation()
321 * @uses register_activation_hook() To register the activation hook
322 * @uses register_deactivation_hook() To register the deactivation hook
323 * @uses add_action() To add various actions
324 */
325 private function setup_actions() {
326
327 // Add actions to plugin activation and deactivation hooks
328 add_action( 'activate_' . $this->basename, 'bbp_activation' );
329 add_action( 'deactivate_' . $this->basename, 'bbp_deactivation' );
330
331 // If bbPress is being deactivated, do not add any actions
332 if ( bbp_is_deactivation( $this->basename ) )
333 return;
334
335 // Array of bbPress core actions
336 $actions = array(
337 'setup_theme', // Setup the default theme compat
338 'setup_current_user', // Setup currently logged in user
339 'register_post_types', // Register post types (forum|topic|reply)
340 'register_post_statuses', // Register post statuses (closed|spam|orphan|hidden)
341 'register_taxonomies', // Register taxonomies (topic-tag)
342 'register_views', // Register the views (no-replies)
343 'register_theme_directory', // Register the theme directory (bbp-themes)
344 'register_theme_packages', // Register bundled theme packages (bbp-theme-compat/bbp-themes)
345 'load_textdomain', // Load textdomain (bbpress)
346 'add_rewrite_tags', // Add rewrite tags (view|user|edit)
347 'generate_rewrite_rules' // Generate rewrite rules (view|edit)
348 );
349
350 // Add the actions
351 foreach( $actions as $class_action )
352 add_action( 'bbp_' . $class_action, array( $this, $class_action ), 5 );
353
354 // All bbPress actions are setup (includes bbp-core-hooks.php)
355 do_action_ref_array( 'bbp_after_setup_actions', array( &$this ) );
356 }
357
358 /** Public Methods ********************************************************/
359
360 /**
361 * Register bundled theme packages
362 *
363 * Note that since we currently have complete control over bbp-themes and
364 * the bbp-theme-compat folders, it's fine to hardcode these here. If at a
365 * later date we need to automate this, and API will need to be built.
366 *
367 * @since bbPress (r3829)
368 */
369 public function register_theme_packages() {
370
371 /** Default Theme *****************************************************/
372
373 bbp_register_theme_package( array(
374 'id' => 'default',
375 'name' => __( 'bbPress Default', 'bbpress' ),
376 'version' => bbp_get_version(),
377 'dir' => trailingslashit( $this->plugin_dir . 'bbp-theme-compat' ),
378 'url' => trailingslashit( $this->plugin_url . 'bbp-theme-compat' )
379 ) );
380
381 /** Twenty Ten ********************************************************/
382
383 bbp_register_theme_package( array(
384 'id' => 'bbp-twentyten',
385 'name' => __( 'Twenty Ten (bbPress)', 'bbpress' ),
386 'version' => bbp_get_version(),
387 'dir' => trailingslashit( $this->themes_dir . 'bbp-twentyten' ),
388 'url' => trailingslashit( $this->themes_url . 'bbp-twentyten' )
389 ) );
390 }
391
392 /**
393 * Setup the default bbPress theme compatability location.
394 *
395 * @since bbPress (r3778)
396 */
397 public function setup_theme() {
398
399 // Bail if something already has this under control
400 if ( ! empty( $this->theme_compat->theme ) )
401 return;
402
403 // Setup the theme package to use for compatibility
404 bbp_setup_theme_compat( bbp_get_theme_package_id() );
405 }
406
407 /**
408 * Load the translation file for current language. Checks the languages
409 * folder inside the bbPress plugin first, and then the default WordPress
410 * languages folder.
411 *
412 * Note that custom translation files inside the bbPress plugin folder
413 * will be removed on bbPress updates. If you're creating custom
414 * translation files, please use the global language folder.
415 *
416 * @since bbPress (r2596)
417 *
418 * @uses apply_filters() Calls 'bbpress_locale' with the
419 * {@link get_locale()} value
420 * @uses load_textdomain() To load the textdomain
421 * @return bool True on success, false on failure
422 */
423 public function load_textdomain() {
424 $locale = get_locale(); // Default locale
425 $locale = apply_filters( 'plugin_locale', $locale, 'bbpress' ); // Traditional WordPress plugin locale filter
426 $locale = apply_filters( 'bbpress_locale', $locale ); // bbPress specific locale filter
427 $mofile = sprintf( 'bbpress-%s.mo', $locale ); // Get mo file name
428
429 // Setup paths to current locale file
430 $mofile_local = $this->lang_dir . $mofile;
431 $mofile_global = WP_LANG_DIR . '/bbpress/' . $mofile;
432
433 // Look in local /wp-content/plugins/bbpress/bbp-languages/ folder
434 if ( file_exists( $mofile_local ) ) {
435 return load_textdomain( 'bbpress', $mofile_local );
436
437 // Look in global /wp-content/languages/bbpress folder
438 } elseif ( file_exists( $mofile_global ) ) {
439 return load_textdomain( 'bbpress', $mofile_global );
440 }
441
442 // Nothing found
443 return false;
444 }
445
446 /**
447 * Sets up the bbPress theme directory to use in WordPress
448 *
449 * @since bbPress (r2507)
450 * @uses register_theme_directory() To register the theme directory
451 * @return bool True on success, false on failure
452 */
453 public function register_theme_directory() {
454 return register_theme_directory( $this->themes_dir );
455 }
456
457 /**
458 * Setup the post types for forums, topics and replies
459 *
460 * @since bbPress (r2597)
461 * @uses register_post_type() To register the post types
462 * @uses apply_filters() Calls various filters to modify the arguments
463 * sent to register_post_type()
464 */
465 public static function register_post_types() {
466
467 // Define local variable(s)
468 $post_type = array();
469
470 /** Forums ************************************************************/
471
472 // Forum labels
473 $post_type['labels'] = array(
474 'name' => __( 'Forums', 'bbpress' ),
475 'menu_name' => __( 'Forums', 'bbpress' ),
476 'singular_name' => __( 'Forum', 'bbpress' ),
477 'all_items' => __( 'All Forums', 'bbpress' ),
478 'add_new' => __( 'New Forum', 'bbpress' ),
479 'add_new_item' => __( 'Create New Forum', 'bbpress' ),
480 'edit' => __( 'Edit', 'bbpress' ),
481 'edit_item' => __( 'Edit Forum', 'bbpress' ),
482 'new_item' => __( 'New Forum', 'bbpress' ),
483 'view' => __( 'View Forum', 'bbpress' ),
484 'view_item' => __( 'View Forum', 'bbpress' ),
485 'search_items' => __( 'Search Forums', 'bbpress' ),
486 'not_found' => __( 'No forums found', 'bbpress' ),
487 'not_found_in_trash' => __( 'No forums found in Trash', 'bbpress' ),
488 'parent_item_colon' => __( 'Parent Forum:', 'bbpress' )
489 );
490
491 // Forum rewrite
492 $post_type['rewrite'] = array(
493 'slug' => bbp_get_forum_slug(),
494 'with_front' => false
495 );
496
497 // Forum supports
498 $post_type['supports'] = array(
499 'title',
500 'editor',
501 'revisions'
502 );
503
504 // Register Forum content type
505 register_post_type(
506 bbp_get_forum_post_type(),
507 apply_filters( 'bbp_register_forum_post_type', array(
508 'labels' => $post_type['labels'],
509 'rewrite' => $post_type['rewrite'],
510 'supports' => $post_type['supports'],
511 'description' => __( 'bbPress Forums', 'bbpress' ),
512 'capabilities' => bbp_get_forum_caps(),
513 'capability_type' => array( 'forum', 'forums' ),
514 'menu_position' => 56,
515 'has_archive' => bbp_get_root_slug(),
516 'exclude_from_search' => true,
517 'show_in_nav_menus' => true,
518 'public' => true,
519 'show_ui' => bbp_current_user_can_see( bbp_get_forum_post_type() ),
520 'can_export' => true,
521 'hierarchical' => true,
522 'query_var' => true,
523 'menu_icon' => ''
524 ) )
525 );
526
527 /** Topics ************************************************************/
528
529 // Topic labels
530 $post_type['labels'] = array(
531 'name' => __( 'Topics', 'bbpress' ),
532 'menu_name' => __( 'Topics', 'bbpress' ),
533 'singular_name' => __( 'Topic', 'bbpress' ),
534 'all_items' => __( 'All Topics', 'bbpress' ),
535 'add_new' => __( 'New Topic', 'bbpress' ),
536 'add_new_item' => __( 'Create New Topic', 'bbpress' ),
537 'edit' => __( 'Edit', 'bbpress' ),
538 'edit_item' => __( 'Edit Topic', 'bbpress' ),
539 'new_item' => __( 'New Topic', 'bbpress' ),
540 'view' => __( 'View Topic', 'bbpress' ),
541 'view_item' => __( 'View Topic', 'bbpress' ),
542 'search_items' => __( 'Search Topics', 'bbpress' ),
543 'not_found' => __( 'No topics found', 'bbpress' ),
544 'not_found_in_trash' => __( 'No topics found in Trash', 'bbpress' ),
545 'parent_item_colon' => __( 'Forum:', 'bbpress' )
546 );
547
548 // Topic rewrite
549 $post_type['rewrite'] = array(
550 'slug' => bbp_get_topic_slug(),
551 'with_front' => false
552 );
553
554 // Topic supports
555 $post_type['supports'] = array(
556 'title',
557 'editor',
558 'revisions'
559 );
560
561 // Register Topic content type
562 register_post_type(
563 bbp_get_topic_post_type(),
564 apply_filters( 'bbp_register_topic_post_type', array(
565 'labels' => $post_type['labels'],
566 'rewrite' => $post_type['rewrite'],
567 'supports' => $post_type['supports'],
568 'description' => __( 'bbPress Topics', 'bbpress' ),
569 'capabilities' => bbp_get_topic_caps(),
570 'capability_type' => array( 'topic', 'topics' ),
571 'menu_position' => 57,
572 'has_archive' => bbp_get_topic_archive_slug(),
573 'exclude_from_search' => true,
574 'show_in_nav_menus' => false,
575 'public' => true,
576 'show_ui' => bbp_current_user_can_see( bbp_get_topic_post_type() ),
577 'can_export' => true,
578 'hierarchical' => false,
579 'query_var' => true,
580 'menu_icon' => ''
581 )
582 ) );
583
584 /** Replies ***********************************************************/
585
586 // Reply labels
587 $post_type['labels'] = array(
588 'name' => __( 'Replies', 'bbpress' ),
589 'menu_name' => __( 'Replies', 'bbpress' ),
590 'singular_name' => __( 'Reply', 'bbpress' ),
591 'all_items' => __( 'All Replies', 'bbpress' ),
592 'add_new' => __( 'New Reply', 'bbpress' ),
593 'add_new_item' => __( 'Create New Reply', 'bbpress' ),
594 'edit' => __( 'Edit', 'bbpress' ),
595 'edit_item' => __( 'Edit Reply', 'bbpress' ),
596 'new_item' => __( 'New Reply', 'bbpress' ),
597 'view' => __( 'View Reply', 'bbpress' ),
598 'view_item' => __( 'View Reply', 'bbpress' ),
599 'search_items' => __( 'Search Replies', 'bbpress' ),
600 'not_found' => __( 'No replies found', 'bbpress' ),
601 'not_found_in_trash' => __( 'No replies found in Trash', 'bbpress' ),
602 'parent_item_colon' => __( 'Topic:', 'bbpress' )
603 );
604
605 // Reply rewrite
606 $post_type['rewrite'] = array(
607 'slug' => bbp_get_reply_slug(),
608 'with_front' => false
609 );
610
611 // Reply supports
612 $post_type['supports'] = array(
613 'title',
614 'editor',
615 'revisions'
616 );
617
618 // Register reply content type
619 register_post_type(
620 bbp_get_reply_post_type(),
621 apply_filters( 'bbp_register_reply_post_type', array(
622 'labels' => $post_type['labels'],
623 'rewrite' => $post_type['rewrite'],
624 'supports' => $post_type['supports'],
625 'description' => __( 'bbPress Replies', 'bbpress' ),
626 'capabilities' => bbp_get_reply_caps(),
627 'capability_type' => array( 'reply', 'replies' ),
628 'menu_position' => 58,
629 'exclude_from_search' => true,
630 'has_archive' => false,
631 'show_in_nav_menus' => false,
632 'public' => true,
633 'show_ui' => bbp_current_user_can_see( bbp_get_reply_post_type() ),
634 'can_export' => true,
635 'hierarchical' => false,
636 'query_var' => true,
637 'menu_icon' => ''
638 ) )
639 );
640 }
641
642 /**
643 * Register the post statuses used by bbPress
644 *
645 * We do some manipulation of the 'trash' status so trashed topics and
646 * replies can be viewed from within the theme.
647 *
648 * @since bbPress (r2727)
649 * @uses register_post_status() To register post statuses
650 * @uses $wp_post_statuses To modify trash and private statuses
651 * @uses current_user_can() To check if the current user is capable &
652 * modify $wp_post_statuses accordingly
653 */
654 public static function register_post_statuses() {
655
656 // Closed
657 register_post_status(
658 bbp_get_closed_status_id(),
659 apply_filters( 'bbp_register_closed_post_status', array(
660 'label' => _x( 'Closed', 'post', 'bbpress' ),
661 'label_count' => _nx_noop( 'Closed <span class="count">(%s)</span>', 'Closed <span class="count">(%s)</span>', 'bbpress' ),
662 'public' => true,
663 'show_in_admin_all' => true
664 ) )
665 );
666
667 // Spam
668 register_post_status(
669 bbp_get_spam_status_id(),
670 apply_filters( 'bbp_register_spam_post_status', array(
671 'label' => _x( 'Spam', 'post', 'bbpress' ),
672 'label_count' => _nx_noop( 'Spam <span class="count">(%s)</span>', 'Spam <span class="count">(%s)</span>', 'bbpress' ),
673 'protected' => true,
674 'exclude_from_search' => true,
675 'show_in_admin_status_list' => true,
676 'show_in_admin_all_list' => false
677 ) )
678 );
679
680 // Orphan
681 register_post_status(
682 bbp_get_orphan_status_id(),
683 apply_filters( 'bbp_register_orphan_post_status', array(
684 'label' => _x( 'Orphan', 'post', 'bbpress' ),
685 'label_count' => _nx_noop( 'Orphan <span class="count">(%s)</span>', 'Orphans <span class="count">(%s)</span>', 'bbpress' ),
686 'protected' => true,
687 'exclude_from_search' => true,
688 'show_in_admin_status_list' => true,
689 'show_in_admin_all_list' => false
690 ) )
691 );
692
693 // Hidden
694 register_post_status(
695 bbp_get_hidden_status_id(),
696 apply_filters( 'bbp_register_hidden_post_status', array(
697 'label' => _x( 'Hidden', 'post', 'bbpress' ),
698 'label_count' => _nx_noop( 'Hidden <span class="count">(%s)</span>', 'Hidden <span class="count">(%s)</span>', 'bbpress' ),
699 'private' => true,
700 'exclude_from_search' => true,
701 'show_in_admin_status_list' => true,
702 'show_in_admin_all_list' => true
703 ) )
704 );
705
706 /**
707 * Trash fix
708 *
709 * We need to remove the internal arg and change that to
710 * protected so that the users with 'view_trash' cap can view
711 * single trashed topics/replies in the front-end as wp_query
712 * doesn't allow any hack for the trashed topics to be viewed.
713 */
714 global $wp_post_statuses;
715
716 if ( !empty( $wp_post_statuses['trash'] ) ) {
717
718 // User can view trash so set internal to false
719 if ( current_user_can( 'view_trash' ) ) {
720 $wp_post_statuses['trash']->internal = false;
721 $wp_post_statuses['trash']->protected = true;
722
723 // User cannot view trash so set internal to true
724 } elseif ( !current_user_can( 'view_trash' ) ) {
725 $wp_post_statuses['trash']->internal = true;
726 }
727 }
728 }
729
730 /**
731 * Register the topic tag taxonomy
732 *
733 * @since bbPress (r2464)
734 * @uses register_taxonomy() To register the taxonomy
735 */
736 public static function register_taxonomies() {
737
738 // Define local variable(s)
739 $topic_tag = array();
740
741 // Topic tag labels
742 $topic_tag['labels'] = array(
743 'name' => __( 'Topic Tags', 'bbpress' ),
744 'singular_name' => __( 'Topic Tag', 'bbpress' ),
745 'search_items' => __( 'Search Tags', 'bbpress' ),
746 'popular_items' => __( 'Popular Tags', 'bbpress' ),
747 'all_items' => __( 'All Tags', 'bbpress' ),
748 'edit_item' => __( 'Edit Tag', 'bbpress' ),
749 'update_item' => __( 'Update Tag', 'bbpress' ),
750 'add_new_item' => __( 'Add New Tag', 'bbpress' ),
751 'new_item_name' => __( 'New Tag Name', 'bbpress' ),
752 'view_item' => __( 'View Topic Tag', 'bbpress' )
753 );
754
755 // Topic tag rewrite
756 $topic_tag['rewrite'] = array(
757 'slug' => bbp_get_topic_tag_tax_slug(),
758 'with_front' => false
759 );
760
761 // Register the topic tag taxonomy
762 register_taxonomy(
763 bbp_get_topic_tag_tax_id(),
764 bbp_get_topic_post_type(),
765 apply_filters( 'bbp_register_topic_taxonomy', array(
766 'labels' => $topic_tag['labels'],
767 'rewrite' => $topic_tag['rewrite'],
768 'capabilities' => bbp_get_topic_tag_caps(),
769 'update_count_callback' => '_update_post_term_count',
770 'query_var' => true,
771 'show_tagcloud' => true,
772 'hierarchical' => false,
773 'public' => true,
774 'show_ui' => bbp_current_user_can_see( bbp_get_topic_tag_tax_id() )
775 )
776 ) );
777 }
778
779 /**
780 * Register the bbPress views
781 *
782 * @since bbPress (r2789)
783 * @uses bbp_register_view() To register the views
784 */
785 public static function register_views() {
786
787 // Topics with no replies
788 bbp_register_view(
789 'no-replies',
790 __( 'Topics with no replies', 'bbpress' ),
791 apply_filters( 'bbp_register_view_no_replies', array(
792 'meta_key' => '_bbp_reply_count',
793 'meta_value' => 1,
794 'meta_compare' => '<',
795 'orderby' => ''
796 )
797 ) );
798 }
799
800 /**
801 * Setup the currently logged-in user
802 *
803 * Do not to call this prematurely, I.E. before the 'init' action has
804 * started. This function is naturally hooked into 'init' to ensure proper
805 * execution. get_currentuserinfo() is used to check for XMLRPC_REQUEST to
806 * avoid xmlrpc errors.
807 *
808 * @since bbPress (r2697)
809 * @uses wp_get_current_user()
810 */
811 public function setup_current_user() {
812 $this->current_user = &wp_get_current_user();
813 }
814
815 /** Custom Rewrite Rules **************************************************/
816
817 /**
818 * Add the bbPress-specific rewrite tags
819 *
820 * @since bbPress (r2753)
821 * @uses add_rewrite_tag() To add the rewrite tags
822 */
823 public static function add_rewrite_tags() {
824 add_rewrite_tag( '%%' . bbp_get_user_rewrite_id() . '%%', '([^/]+)' ); // User Profile tag
825 add_rewrite_tag( '%%' . bbp_get_view_rewrite_id() . '%%', '([^/]+)' ); // View Page tag
826 add_rewrite_tag( '%%' . bbp_get_edit_rewrite_id() . '%%', '([1]{1,})' ); // Edit Page tag
827 }
828
829 /**
830 * Register bbPress-specific rewrite rules for uri's that are not
831 * setup for us by way of custom post types or taxonomies. This includes:
832 * - Front-end editing
833 * - Topic views
834 * - User profiles
835 *
836 * @since bbPress (r2688)
837 * @param WP_Rewrite $wp_rewrite bbPress-sepecific rules are appended in
838 * $wp_rewrite->rules
839 */
840 public static function generate_rewrite_rules( $wp_rewrite ) {
841
842 // Slugs
843 $user_slug = bbp_get_user_slug();
844 $view_slug = bbp_get_view_slug();
845
846 // Unique rewrite ID's
847 $user_id = bbp_get_user_rewrite_id();
848 $view_id = bbp_get_view_rewrite_id();
849 $edit_id = bbp_get_edit_rewrite_id();
850
851 // Rewrite rule matches used repeatedly below
852 $root_rule = '/([^/]+)/?$';
853 $edit_rule = '/([^/]+)/edit/?$';
854 $feed_rule = '/([^/]+)/feed/?$';
855 $page_rule = '/([^/]+)/page/?([0-9]{1,})/?$';
856
857 // New bbPress specific rules to merge with existing that are not
858 // handled automatically by custom post types or taxonomy types
859 $bbp_rules = array(
860
861 // Edit Forum|Topic|Reply|Topic-tag
862 bbp_get_forum_slug() . $edit_rule => 'index.php?' . bbp_get_forum_post_type() . '=' . $wp_rewrite->preg_index( 1 ) . '&' . $edit_id . '=1',
863 bbp_get_topic_slug() . $edit_rule => 'index.php?' . bbp_get_topic_post_type() . '=' . $wp_rewrite->preg_index( 1 ) . '&' . $edit_id . '=1',
864 bbp_get_reply_slug() . $edit_rule => 'index.php?' . bbp_get_reply_post_type() . '=' . $wp_rewrite->preg_index( 1 ) . '&' . $edit_id . '=1',
865 bbp_get_topic_tag_tax_slug() . $edit_rule => 'index.php?' . bbp_get_topic_tag_tax_id() . '=' . $wp_rewrite->preg_index( 1 ) . '&' . $edit_id . '=1',
866
867 // User Pagination|Edit|View
868 $user_slug . $page_rule => 'index.php?' . $user_id . '=' . $wp_rewrite->preg_index( 1 ) . '&paged=' . $wp_rewrite->preg_index( 2 ),
869 $user_slug . $edit_rule => 'index.php?' . $user_id . '=' . $wp_rewrite->preg_index( 1 ) . '&' . $edit_id . '=1',
870 $user_slug . $root_rule => 'index.php?' . $user_id . '=' . $wp_rewrite->preg_index( 1 ),
871
872 // Topic-View Pagination|Feed|View
873 $view_slug . $page_rule => 'index.php?' . $view_id . '=' . $wp_rewrite->preg_index( 1 ) . '&paged=' . $wp_rewrite->preg_index( 2 ),
874 $view_slug . $feed_rule => 'index.php?' . $view_id . '=' . $wp_rewrite->preg_index( 1 ) . '&feed=' . $wp_rewrite->preg_index( 2 ),
875 $view_slug . $root_rule => 'index.php?' . $view_id . '=' . $wp_rewrite->preg_index( 1 ),
876 );
877
878 // Merge bbPress rules with existing
879 $wp_rewrite->rules = array_merge( $bbp_rules, $wp_rewrite->rules );
880
881 // Return merged rules
882 return $wp_rewrite;
883 }
884 }
885
886 /**
887 * The main function responsible for returning the one true bbPress Instance
888 * to functions everywhere.
889 *
890 * Use this function like you would a global variable, except without needing
891 * to declare the global.
892 *
893 * Example: <?php $bbp = bbpress(); ?>
894 *
895 * @return The one true bbPress Instance
896 */
897 function bbpress() {
898 return bbpress::instance();
899 }
900
901 /**
902 * Hook bbPress early onto the 'plugins_loaded' action.
903 *
904 * This gives all other plugins the chance to load before bbPress, to get their
905 * actions, filters, and overrides setup without bbPress being in the way.
906 */
907 if ( defined( 'BBPRESS_LATE_LOAD' ) ) {
908 add_action( 'plugins_loaded', 'bbpress', (int) BBPRESS_LATE_LOAD );
909
910 // "And now here's something we hope you'll really like!"
911 } else {
912 bbpress();
913 }
914
915 endif; // class_exists check
916