Changeset 10518
- Timestamp:
- 02/05/2016 04:26:30 AM (9 years ago)
- Location:
- trunk/src/bp-core
- Files:
-
- 1 deleted
- 6 edited
- 6 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bp-core/admin/bp-core-admin-classes.php
r10474 r10518 11 11 defined( 'ABSPATH' ) || exit; 12 12 13 require dirname( __FILE__) . '/classes/bp-walker-category-checklist.php';13 require dirname( dirname( __FILE__ ) ) . '/classes/bp-walker-category-checklist.php'; -
trunk/src/bp-core/bp-core-admin.php
r10497 r10518 11 11 defined( 'ABSPATH' ) || exit; 12 12 13 if ( !class_exists( 'BP_Admin' ) ) : 14 15 /** 16 * Load BuddyPress plugin admin area. 17 * 18 * @todo Break this apart into each applicable Component. 19 * 20 * @since 1.6.0 21 */ 22 class BP_Admin { 23 24 /** Directory *************************************************************/ 25 26 /** 27 * Path to the BuddyPress admin directory. 28 * 29 * @since 1.6.0 30 * @var string $admin_dir 31 */ 32 public $admin_dir = ''; 33 34 /** URLs ******************************************************************/ 35 36 /** 37 * URL to the BuddyPress admin directory. 38 * 39 * @since 1.6.0 40 * @var string $admin_url 41 */ 42 public $admin_url = ''; 43 44 /** 45 * URL to the BuddyPress images directory. 46 * 47 * @since 1.6.0 48 * @var string $images_url 49 */ 50 public $images_url = ''; 51 52 /** 53 * URL to the BuddyPress admin CSS directory. 54 * 55 * @since 1.6.0 56 * @var string $css_url 57 */ 58 public $css_url = ''; 59 60 /** 61 * URL to the BuddyPress admin JS directory. 62 * 63 * @since 1.6.0 64 * @var string 65 */ 66 public $js_url = ''; 67 68 /** Other *****************************************************************/ 69 70 /** 71 * Notices used for user feedback, like saving settings. 72 * 73 * @since 1.9.0 74 * @var array() 75 */ 76 public $notices = array(); 77 78 /** Methods ***************************************************************/ 79 80 /** 81 * The main BuddyPress admin loader. 82 * 83 * @since 1.6.0 84 * 85 * @uses BP_Admin::setup_globals() Setup the globals needed. 86 * @uses BP_Admin::includes() Include the required files. 87 * @uses BP_Admin::setup_actions() Setup the hooks and actions. 88 */ 89 public function __construct() { 90 $this->setup_globals(); 91 $this->includes(); 92 $this->setup_actions(); 93 } 94 95 /** 96 * Set admin-related globals. 97 * 98 * @since 1.6.0 99 */ 100 private function setup_globals() { 101 $bp = buddypress(); 102 103 // Paths and URLs 104 $this->admin_dir = trailingslashit( $bp->plugin_dir . 'bp-core/admin' ); // Admin path. 105 $this->admin_url = trailingslashit( $bp->plugin_url . 'bp-core/admin' ); // Admin url. 106 $this->images_url = trailingslashit( $this->admin_url . 'images' ); // Admin images URL. 107 $this->css_url = trailingslashit( $this->admin_url . 'css' ); // Admin css URL. 108 $this->js_url = trailingslashit( $this->admin_url . 'js' ); // Admin css URL. 109 110 // Main settings page. 111 $this->settings_page = bp_core_do_network_admin() ? 'settings.php' : 'options-general.php'; 112 113 // Main capability. 114 $this->capability = bp_core_do_network_admin() ? 'manage_network_options' : 'manage_options'; 115 } 116 117 /** 118 * Include required files. 119 * 120 * @since 1.6.0 121 */ 122 private function includes() { 123 require( $this->admin_dir . 'bp-core-admin-classes.php' ); 124 require( $this->admin_dir . 'bp-core-admin-actions.php' ); 125 require( $this->admin_dir . 'bp-core-admin-settings.php' ); 126 require( $this->admin_dir . 'bp-core-admin-functions.php' ); 127 require( $this->admin_dir . 'bp-core-admin-components.php' ); 128 require( $this->admin_dir . 'bp-core-admin-slugs.php' ); 129 require( $this->admin_dir . 'bp-core-admin-tools.php' ); 130 } 131 132 /** 133 * Set up the admin hooks, actions, and filters. 134 * 135 * @since 1.6.0 136 * 137 * @uses add_action() To add various actions. 138 * @uses add_filter() To add various filters. 139 */ 140 private function setup_actions() { 141 142 /* General Actions ***************************************************/ 143 144 // Add some page specific output to the <head>. 145 add_action( 'bp_admin_head', array( $this, 'admin_head' ), 999 ); 146 147 // Add menu item to settings menu. 148 add_action( bp_core_admin_hook(), array( $this, 'admin_menus' ), 5 ); 149 150 // Enqueue all admin JS and CSS. 151 add_action( 'bp_admin_enqueue_scripts', array( $this, 'admin_register_styles' ), 1 ); 152 add_action( 'bp_admin_enqueue_scripts', array( $this, 'admin_register_scripts' ), 1 ); 153 add_action( 'bp_admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 154 155 /* BuddyPress Actions ************************************************/ 156 157 // Load the BuddyPress metabox in the WP Nav Menu Admin UI. 158 add_action( 'load-nav-menus.php', 'bp_admin_wp_nav_menu_meta_box' ); 159 160 // Add settings. 161 add_action( 'bp_register_admin_settings', array( $this, 'register_admin_settings' ) ); 162 163 // Add a link to BuddyPress About page to the admin bar. 164 add_action( 'admin_bar_menu', array( $this, 'admin_bar_about_link' ), 15 ); 165 166 // Add a description of new BuddyPress tools in the available tools page. 167 add_action( 'tool_box', 'bp_core_admin_available_tools_intro' ); 168 add_action( 'bp_network_tool_box', 'bp_core_admin_available_tools_intro' ); 169 170 // On non-multisite, catch. 171 add_action( 'load-users.php', 'bp_core_admin_user_manage_spammers' ); 172 173 /* Filters ***********************************************************/ 174 175 // Add link to settings page. 176 add_filter( 'plugin_action_links', array( $this, 'modify_plugin_action_links' ), 10, 2 ); 177 add_filter( 'network_admin_plugin_action_links', array( $this, 'modify_plugin_action_links' ), 10, 2 ); 178 179 // Add "Mark as Spam" row actions on users.php. 180 add_filter( 'ms_user_row_actions', 'bp_core_admin_user_row_actions', 10, 2 ); 181 add_filter( 'user_row_actions', 'bp_core_admin_user_row_actions', 10, 2 ); 182 183 // Emails 184 add_filter( 'bp_admin_menu_order', array( $this, 'emails_admin_menu_order' ), 20 ); 185 } 186 187 /** 188 * Add the navigational menu elements. 189 * 190 * @since 1.6.0 191 * 192 * @uses add_management_page() To add the Recount page in Tools section. 193 * @uses add_options_page() To add the Forums settings page in Settings 194 * section. 195 */ 196 public function admin_menus() { 197 198 // Bail if user cannot moderate. 199 if ( ! bp_current_user_can( 'manage_options' ) ) { 200 return; 201 } 202 203 // About. 204 add_dashboard_page( 205 __( 'Welcome to BuddyPress', 'buddypress' ), 206 __( 'Welcome to BuddyPress', 'buddypress' ), 207 'manage_options', 208 'bp-about', 209 array( $this, 'about_screen' ) 210 ); 211 212 // Credits. 213 add_dashboard_page( 214 __( 'Welcome to BuddyPress', 'buddypress' ), 215 __( 'Welcome to BuddyPress', 'buddypress' ), 216 'manage_options', 217 'bp-credits', 218 array( $this, 'credits_screen' ) 219 ); 220 221 $hooks = array(); 222 223 // Changed in BP 1.6 . See bp_core_admin_backpat_menu(). 224 $hooks[] = add_menu_page( 225 __( 'BuddyPress', 'buddypress' ), 226 __( 'BuddyPress', 'buddypress' ), 227 $this->capability, 228 'bp-general-settings', 229 'bp_core_admin_backpat_menu', 230 'div' 231 ); 232 233 $hooks[] = add_submenu_page( 234 'bp-general-settings', 235 __( 'BuddyPress Help', 'buddypress' ), 236 __( 'Help', 'buddypress' ), 237 $this->capability, 238 'bp-general-settings', 239 'bp_core_admin_backpat_page' 240 ); 241 242 // Add the option pages. 243 $hooks[] = add_submenu_page( 244 $this->settings_page, 245 __( 'BuddyPress Components', 'buddypress' ), 246 __( 'BuddyPress', 'buddypress' ), 247 $this->capability, 248 'bp-components', 249 'bp_core_admin_components_settings' 250 ); 251 252 $hooks[] = add_submenu_page( 253 $this->settings_page, 254 __( 'BuddyPress Pages', 'buddypress' ), 255 __( 'BuddyPress Pages', 'buddypress' ), 256 $this->capability, 257 'bp-page-settings', 258 'bp_core_admin_slugs_settings' 259 ); 260 261 $hooks[] = add_submenu_page( 262 $this->settings_page, 263 __( 'BuddyPress Settings', 'buddypress' ), 264 __( 'BuddyPress Settings', 'buddypress' ), 265 $this->capability, 266 'bp-settings', 267 'bp_core_admin_settings' 268 ); 269 270 // For consistency with non-Multisite, we add a Tools menu in 271 // the Network Admin as a home for our Tools panel. 272 if ( is_multisite() && bp_core_do_network_admin() ) { 273 $tools_parent = 'network-tools'; 274 275 $hooks[] = add_menu_page( 276 __( 'Tools', 'buddypress' ), 277 __( 'Tools', 'buddypress' ), 278 $this->capability, 279 $tools_parent, 280 'bp_core_tools_top_level_item', 281 '', 282 24 // Just above Settings. 283 ); 284 285 $hooks[] = add_submenu_page( 286 $tools_parent, 287 __( 'Available Tools', 'buddypress' ), 288 __( 'Available Tools', 'buddypress' ), 289 $this->capability, 290 'available-tools', 291 'bp_core_admin_available_tools_page' 292 ); 293 } else { 294 $tools_parent = 'tools.php'; 295 } 296 297 $hooks[] = add_submenu_page( 298 $tools_parent, 299 __( 'BuddyPress Tools', 'buddypress' ), 300 __( 'BuddyPress', 'buddypress' ), 301 $this->capability, 302 'bp-tools', 303 'bp_core_admin_tools' 304 ); 305 306 $hooks[] = add_theme_page( 307 _x( 'Emails', 'screen heading', 'buddypress' ), 308 _x( 'Emails', 'screen heading', 'buddypress' ), 309 $this->capability, 310 'bp-emails-customizer-redirect', 311 'bp_email_redirect_to_customizer' 312 ); 313 314 foreach( $hooks as $hook ) { 315 add_action( "admin_head-$hook", 'bp_core_modify_admin_menu_highlight' ); 316 } 317 } 318 319 /** 320 * Register the settings. 321 * 322 * @since 1.6.0 323 * 324 * @uses add_settings_section() To add our own settings section. 325 * @uses add_settings_field() To add various settings fields. 326 * @uses register_setting() To register various settings. 327 */ 328 public function register_admin_settings() { 329 330 /* Main Section ******************************************************/ 331 332 // Add the main section. 333 add_settings_section( 'bp_main', __( 'Main Settings', 'buddypress' ), 'bp_admin_setting_callback_main_section', 'buddypress' ); 334 335 // Hide toolbar for logged out users setting. 336 add_settings_field( 'hide-loggedout-adminbar', __( 'Toolbar', 'buddypress' ), 'bp_admin_setting_callback_admin_bar', 'buddypress', 'bp_main' ); 337 register_setting( 'buddypress', 'hide-loggedout-adminbar', 'intval' ); 338 339 // Only show 'switch to Toolbar' option if the user chose to retain the BuddyBar during the 1.6 upgrade. 340 if ( (bool) bp_get_option( '_bp_force_buddybar', false ) ) { 341 add_settings_field( '_bp_force_buddybar', __( 'Toolbar', 'buddypress' ), 'bp_admin_setting_callback_force_buddybar', 'buddypress', 'bp_main' ); 342 register_setting( 'buddypress', '_bp_force_buddybar', 'bp_admin_sanitize_callback_force_buddybar' ); 343 } 344 345 // Allow account deletion. 346 add_settings_field( 'bp-disable-account-deletion', __( 'Account Deletion', 'buddypress' ), 'bp_admin_setting_callback_account_deletion', 'buddypress', 'bp_main' ); 347 register_setting( 'buddypress', 'bp-disable-account-deletion', 'intval' ); 348 349 /* XProfile Section **************************************************/ 350 351 if ( bp_is_active( 'xprofile' ) ) { 352 353 // Add the main section. 354 add_settings_section( 'bp_xprofile', _x( 'Profile Settings', 'BuddyPress setting tab', 'buddypress' ), 'bp_admin_setting_callback_xprofile_section', 'buddypress' ); 355 356 // Avatars. 357 add_settings_field( 'bp-disable-avatar-uploads', __( 'Profile Photo Uploads', 'buddypress' ), 'bp_admin_setting_callback_avatar_uploads', 'buddypress', 'bp_xprofile' ); 358 register_setting( 'buddypress', 'bp-disable-avatar-uploads', 'intval' ); 359 360 // Cover images. 361 if ( bp_is_active( 'xprofile', 'cover_image' ) ) { 362 add_settings_field( 'bp-disable-cover-image-uploads', __( 'Cover Image Uploads', 'buddypress' ), 'bp_admin_setting_callback_cover_image_uploads', 'buddypress', 'bp_xprofile' ); 363 register_setting( 'buddypress', 'bp-disable-cover-image-uploads', 'intval' ); 364 } 365 366 // Profile sync setting. 367 add_settings_field( 'bp-disable-profile-sync', __( 'Profile Syncing', 'buddypress' ), 'bp_admin_setting_callback_profile_sync', 'buddypress', 'bp_xprofile' ); 368 register_setting ( 'buddypress', 'bp-disable-profile-sync', 'intval' ); 369 } 370 371 /* Groups Section ****************************************************/ 372 373 if ( bp_is_active( 'groups' ) ) { 374 375 // Add the main section. 376 add_settings_section( 'bp_groups', __( 'Groups Settings', 'buddypress' ), 'bp_admin_setting_callback_groups_section', 'buddypress' ); 377 378 // Allow subscriptions setting. 379 add_settings_field( 'bp_restrict_group_creation', __( 'Group Creation', 'buddypress' ), 'bp_admin_setting_callback_group_creation', 'buddypress', 'bp_groups' ); 380 register_setting( 'buddypress', 'bp_restrict_group_creation', 'intval' ); 381 382 // Allow group avatars. 383 add_settings_field( 'bp-disable-group-avatar-uploads', __( 'Group Photo Uploads', 'buddypress' ), 'bp_admin_setting_callback_group_avatar_uploads', 'buddypress', 'bp_groups' ); 384 register_setting( 'buddypress', 'bp-disable-group-avatar-uploads', 'intval' ); 385 386 // Allow group cover images. 387 if ( bp_is_active( 'groups', 'cover_image' ) ) { 388 add_settings_field( 'bp-disable-group-cover-image-uploads', __( 'Group Cover Image Uploads', 'buddypress' ), 'bp_admin_setting_callback_group_cover_image_uploads', 'buddypress', 'bp_groups' ); 389 register_setting( 'buddypress', 'bp-disable-group-cover-image-uploads', 'intval' ); 390 } 391 } 392 393 /* Forums ************************************************************/ 394 395 if ( bp_is_active( 'forums' ) ) { 396 397 // Add the main section. 398 add_settings_section( 'bp_forums', __( 'Legacy Group Forums', 'buddypress' ), 'bp_admin_setting_callback_bbpress_section', 'buddypress' ); 399 400 // Allow subscriptions setting. 401 add_settings_field( 'bb-config-location', __( 'bbPress Configuration', 'buddypress' ), 'bp_admin_setting_callback_bbpress_configuration', 'buddypress', 'bp_forums' ); 402 register_setting( 'buddypress', 'bb-config-location', '' ); 403 } 404 405 /* Activity Section **************************************************/ 406 407 if ( bp_is_active( 'activity' ) ) { 408 409 // Add the main section. 410 add_settings_section( 'bp_activity', __( 'Activity Settings', 'buddypress' ), 'bp_admin_setting_callback_activity_section', 'buddypress' ); 411 412 // Activity commenting on blog and forum posts. 413 add_settings_field( 'bp-disable-blogforum-comments', __( 'Blog & Forum Comments', 'buddypress' ), 'bp_admin_setting_callback_blogforum_comments', 'buddypress', 'bp_activity' ); 414 register_setting( 'buddypress', 'bp-disable-blogforum-comments', 'bp_admin_sanitize_callback_blogforum_comments' ); 415 416 // Activity Heartbeat refresh. 417 add_settings_field( '_bp_enable_heartbeat_refresh', __( 'Activity auto-refresh', 'buddypress' ), 'bp_admin_setting_callback_heartbeat', 'buddypress', 'bp_activity' ); 418 register_setting( 'buddypress', '_bp_enable_heartbeat_refresh', 'intval' ); 419 420 // Allow activity akismet. 421 if ( is_plugin_active( 'akismet/akismet.php' ) && defined( 'AKISMET_VERSION' ) ) { 422 add_settings_field( '_bp_enable_akismet', __( 'Akismet', 'buddypress' ), 'bp_admin_setting_callback_activity_akismet', 'buddypress', 'bp_activity' ); 423 register_setting( 'buddypress', '_bp_enable_akismet', 'intval' ); 424 } 425 } 426 } 427 428 /** 429 * Add a link to BuddyPress About page to the admin bar. 430 * 431 * @since 1.9.0 432 * 433 * @param WP_Admin_Bar $wp_admin_bar As passed to 'admin_bar_menu'. 434 */ 435 public function admin_bar_about_link( $wp_admin_bar ) { 436 if ( is_user_logged_in() ) { 437 $wp_admin_bar->add_menu( array( 438 'parent' => 'wp-logo', 439 'id' => 'bp-about', 440 'title' => esc_html__( 'About BuddyPress', 'buddypress' ), 441 'href' => add_query_arg( array( 'page' => 'bp-about' ), bp_get_admin_url( 'index.php' ) ), 442 ) ); 443 } 444 } 445 446 /** 447 * Add Settings link to plugins area. 448 * 449 * @since 1.6.0 450 * 451 * @param array $links Links array in which we would prepend our link. 452 * @param string $file Current plugin basename. 453 * @return array Processed links. 454 */ 455 public function modify_plugin_action_links( $links, $file ) { 456 457 // Return normal links if not BuddyPress. 458 if ( plugin_basename( buddypress()->basename ) != $file ) { 459 return $links; 460 } 461 462 // Add a few links to the existing links array. 463 return array_merge( $links, array( 464 'settings' => '<a href="' . esc_url( add_query_arg( array( 'page' => 'bp-components' ), bp_get_admin_url( $this->settings_page ) ) ) . '">' . esc_html__( 'Settings', 'buddypress' ) . '</a>', 465 'about' => '<a href="' . esc_url( add_query_arg( array( 'page' => 'bp-about' ), bp_get_admin_url( 'index.php' ) ) ) . '">' . esc_html__( 'About', 'buddypress' ) . '</a>' 466 ) ); 467 } 468 469 /** 470 * Add some general styling to the admin area. 471 * 472 * @since 1.6.0 473 */ 474 public function admin_head() { 475 476 // Settings pages. 477 remove_submenu_page( $this->settings_page, 'bp-page-settings' ); 478 remove_submenu_page( $this->settings_page, 'bp-settings' ); 479 480 // Network Admin Tools. 481 remove_submenu_page( 'network-tools', 'network-tools' ); 482 483 // About and Credits pages. 484 remove_submenu_page( 'index.php', 'bp-about' ); 485 remove_submenu_page( 'index.php', 'bp-credits' ); 486 } 487 488 /** 489 * Add some general styling to the admin area. 490 * 491 * @since 1.6.0 492 */ 493 public function enqueue_scripts() { 494 wp_enqueue_style( 'bp-admin-common-css' ); 495 } 496 497 /** About *****************************************************************/ 498 499 /** 500 * Output the about screen. 501 * 502 * @since 1.7.0 503 */ 504 public function about_screen() { 505 ?> 506 507 <div class="wrap about-wrap"> 508 509 <?php self::welcome_text(); ?> 510 511 <?php self::tab_navigation( __METHOD__ ); ?> 512 513 <?php if ( self::is_new_install() ) : ?> 514 515 <div id="welcome-panel" class="welcome-panel"> 516 <div class="welcome-panel-content"> 517 <h3 style="margin:0"><?php _e( 'Getting Started with BuddyPress', 'buddypress' ); ?></h3> 518 <div class="welcome-panel-column-container"> 519 <div class="welcome-panel-column"> 520 <h4><?php _e( 'Configure BuddyPress', 'buddypress' ); ?></h4> 521 <ul> 522 <li><?php printf( 523 '<a href="%s" class="welcome-icon welcome-edit-page">' . __( 'Set Up Components', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) ) ) 524 ); ?></li> 525 <li><?php printf( 526 '<a href="%s" class="welcome-icon welcome-edit-page">' . __( 'Assign Components to Pages', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), $this->settings_page ) ) ) 527 ); ?></li> 528 <li><?php printf( 529 '<a href="%s" class="welcome-icon welcome-edit-page">' . __( 'Customize Settings', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), $this->settings_page ) ) ) 530 ); ?></li> 531 </ul> 532 <a class="button button-primary button-hero" style="margin-bottom:20px;margin-top:0;" href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), $this->settings_page ) ) ); ?>"><?php _e( 'Get Started', 'buddypress' ); ?></a> 533 </div> 534 <div class="welcome-panel-column"> 535 <h4><?php _e( 'Administration Tools', 'buddypress' ); ?></h4> 536 <ul> 537 <?php if ( bp_is_active( 'members' ) ) : ?> 538 <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Add User Profile Fields', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-profile-setup' ), 'users.php' ) ) ) ); ?></li> 539 <?php endif; ?> 540 <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Manage User Signups', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-signups' ), 'users.php' ) ) ) ); ?></li> 541 <?php if ( bp_is_active( 'activity' ) ) : ?> 542 <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Moderate Activity Streams', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-activity' ), 'admin.php' ) ) ) ); ?></li> 543 <?php endif; ?> 544 <?php if ( bp_is_active( 'groups' ) ) : ?> 545 <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Manage Groups', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-groups' ), 'admin.php' ) ) ) ); ?></li> 546 <?php endif; ?> 547 <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Repair Data', 'buddypress' ) . '</a>', esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-tools' ), 'tools.php' ) ) ) ); ?> 548 </li> 549 </ul> 550 </div> 551 <div class="welcome-panel-column welcome-panel-last"> 552 <h4><?php _e( 'Community and Support', 'buddypress' ); ?></h4> 553 <p class="welcome-icon welcome-learn-more" style="margin-right:10px"><?php _e( 'Looking for help? The <a href="https://codex.buddypress.org/">BuddyPress Codex</a> has you covered.', 'buddypress' ) ?></p> 554 <p class="welcome-icon welcome-learn-more" style="margin-right:10px"><?php _e( 'Can’t find what you need? Stop by <a href="https://buddypress.org/support/">our support forums</a>, where active BuddyPress users and developers are waiting to share tips and more.', 'buddypress' ) ?></p> 555 </div> 556 </div> 557 </div> 558 </div> 559 560 <?php endif; ?> 561 562 <div class="headline-feature"> 563 <h3><?php esc_html_e( 'Cover Images For Members And Groups', 'buddypress' ); ?></h3> 564 565 <div class="featured-image"> 566 <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/group-cover-image.png' ); ?>" alt="<?php esc_attr_e( 'Cover Images for Members and Groups', 'buddypress' ); ?>" width="843" height="377"> 567 </div> 568 <div> 569 <p><?php printf( __( 'Your community can now upload cover photos for their user profiles and groups. <a href="%s">Learn more →</a>', 'buddypress' ), esc_url( 'https://codex.buddypress.org/themes/buddypress-cover-images/' ) ); ?></p> 570 </div> 571 <div class="clear"></div> 572 573 </div> 574 575 <hr> 576 577 <div class="feature-section two-col"> 578 <div> 579 <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/member-type-field.png' ); ?>" alt="<?php esc_attr_e( 'Profile Field for Member Type', 'buddypress' ); ?>"> 580 <h3><?php esc_html_e( 'Profile Fields For Specific Member Types', 'buddypress' ); ?></h3> 581 <p><?php printf( __( 'You can create profile fields which are available to one or more <a href="%s">custom member types</a>.', 'buddypress' ), esc_url( 'https://codex.buddypress.org/developer/member-types/' ) ); ?></p> 582 </div> 583 <div class="last-feature"> 584 <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/theme-stylesheets.png' ); ?>" alt="<?php esc_attr_e( 'BuddyPress Companion Stylesheets', 'buddypress' ); ?>"> 585 <h3><?php esc_html_e( 'More Companion Stylesheets For Themes', 'buddypress' ); ?></h3> 586 <p><?php esc_html_e( 'BuddyPress looks and works better than ever with WordPress theme Twenty Thirteen, and the upcoming Twenty Sixteen.', 'buddypress' ); ?></p> 587 </div> 588 </div> 589 590 <div class="feature-section two-col"> 591 <div> 592 <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/group-home-page.png' ); ?>" alt="<?php esc_attr_e( 'Customize your group home page', 'buddypress' ); ?>"> 593 <h3><?php esc_html_e( 'Customizable Group Home Page', 'buddypress' ); ?></h3> 594 <p><?php esc_html_e( 'You can customize each and every Group\'s home page by using the new front page template hierarchy.', 'buddypress' ); ?> <a href="https://bpdevel.wordpress.com/2015/10/03/get-ready-2-4-0-will-introduce-important-changes-in-groups-homes/"><?php esc_html_e( 'Learn how →', 'buddypress' ); ?></a></p> 595 </div> 596 <div class="last-feature"> 597 <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/accessibility.gif' ); ?>" alt="<?php esc_attr_e( 'Accessibility Upgrades', 'buddypress' ); ?>"> 598 <h3><?php esc_html_e( 'Accessibility Upgrades', 'buddypress' ); ?></h3> 599 <p><?php _e( 'We\'re making BuddyPress more usable and accessible for everyone, from the frontend templates to the backend admin screens.', 'buddypress' ); ?></p> 600 </div> 601 602 </div> 603 604 <div class="changelog"> 605 <h3><?php esc_html_e( 'Under The Hood', 'buddypress' ); ?></h3> 606 607 <div class="feature-section col two-col"> 608 <div> 609 <h4><?php esc_html_e( 'User Experience', 'buddypress' ); ?></h4> 610 <p><?php esc_html_e( "Enhancements to the What's New form bring better user experience for your community, and make it easier for developers to add new features.", 'buddypress' ); ?></p> 611 612 <h4><?php esc_html_e( 'Cache Improvements', 'buddypress' ); ?></h4> 613 <p><?php esc_html_e( 'Continued object and query cache enhancements have been implemented across different components to improve performance.', 'buddypress' ); ?></p> 614 </div> 615 <div class="last-feature"> 616 <h4><?php esc_html_e( 'Developer Reference', 'buddypress' ); ?></h4> 617 <p><?php esc_html_e( 'Regular updates to inline code documentation make it easier for developers to understand how BuddyPress works.', 'buddypress' ); ?></p> 618 619 <h4><?php esc_html_e( 'Constant Refinements', 'buddypress' ); ?></h4> 620 <p><?php esc_html_e( 'The BuddyPress codebase is continuously tested and updated with the latest WordPress enhancements and features.', 'buddypress' ); ?></p> 621 </div> 622 </div> 623 </div> 624 625 <p><?php _ex( 'Learn more:', 'About screen, website links', 'buddypress' ); ?> <a href="https://buddypress.org/blog/"><?php _ex( 'News', 'About screen, link to project blog', 'buddypress' ); ?></a> • <a href="https://buddypress.org/support/"><?php _ex( 'Support', 'About screen, link to support site', 'buddypress' ); ?></a> • <a href="https://codex.buddypress.org/"><?php _ex( 'Documentation', 'About screen, link to documentation', 'buddypress' ); ?></a> • <a href="https://bpdevel.wordpress.com/"><?php _ex( 'Development Blog', 'About screen, link to development blog', 'buddypress' ); ?></a></p> 626 <p><?php _ex( 'Twitter:', 'official Twitter accounts:', 'buddypress' ); ?> <a href="https://twitter.com/buddypress/"><?php _ex( 'BuddyPress', '@buddypress twitter account name', 'buddypress' ); ?></a> • <a href="https://twitter.com/bptrac/"><?php _ex( 'Trac', '@bptrac twitter account name', 'buddypress' ); ?></a> • <a href="https://twitter.com/buddypressdev/"><?php _ex( 'Development', '@buddypressdev twitter account name', 'buddypress' ); ?></a></p> 627 628 </div> 629 630 <?php 631 } 632 633 /** 634 * Output the credits screen. 635 * 636 * Hardcoding this in here is pretty janky. It's fine for now, but we'll 637 * want to leverage api.wordpress.org eventually. 638 * 639 * @since 1.7.0 640 */ 641 public function credits_screen() { 642 ?> 643 644 <div class="wrap about-wrap"> 645 646 <?php self::welcome_text(); ?> 647 648 <?php self::tab_navigation( __METHOD__ ); ?> 649 650 <p class="about-description"><?php _e( 'BuddyPress is created by a worldwide network of friendly folks like these.', 'buddypress' ); ?></p> 651 652 <h3 class="wp-people-group"><?php _e( 'Project Leaders', 'buddypress' ); ?></h3> 653 <ul class="wp-people-group " id="wp-people-group-project-leaders"> 654 <li class="wp-person" id="wp-person-johnjamesjacoby"> 655 <a href="https://profiles.wordpress.org/johnjamesjacoby"><img src="//www.gravatar.com/avatar/81ec16063d89b162d55efe72165c105f?s=60" class="gravatar" alt="John James Jacoby" /></a> 656 <a class="web" href="https://profiles.wordpress.org/johnjamesjacoby">John James Jacoby</a> 657 <span class="title"><?php _e( 'Project Lead', 'buddypress' ); ?></span> 658 </li> 659 <li class="wp-person" id="wp-person-boonebgorges"> 660 <a href="https://profiles.wordpress.org/boonebgorges"><img src="//www.gravatar.com/avatar/9cf7c4541a582729a5fc7ae484786c0c?s=60" class="gravatar" alt="Boone B. Gorges" /></a> 661 <a class="web" href="https://profiles.wordpress.org/boonebgorges">Boone B. Gorges</a> 662 <span class="title"><?php _e( 'Lead Developer', 'buddypress' ); ?></span> 663 </li> 664 <li class="wp-person" id="wp-person-djpaul"> 665 <a href="https://profiles.wordpress.org/djpaul"><img src="//www.gravatar.com/avatar/3bc9ab796299d67ce83dceb9554f75df?s=60" class="gravatar" alt="Paul Gibbs" /></a> 666 <a class="web" href="https://profiles.wordpress.org/djpaul">Paul Gibbs</a> 667 <span class="title"><?php _e( 'Lead Developer', 'buddypress' ); ?></span> 668 </li> 669 </ul> 670 671 <h3 class="wp-people-group"><?php _e( 'Core Team', 'buddypress' ); ?></h3> 672 <ul class="wp-people-group " id="wp-people-group-core-team"> 673 <li class="wp-person" id="wp-person-r-a-y"> 674 <a href="https://profiles.wordpress.org/r-a-y"><img src="//www.gravatar.com/avatar/3bfa556a62b5bfac1012b6ba5f42ebfa?s=60" class="gravatar" alt="Ray" /></a> 675 <a class="web" href="https://profiles.wordpress.org/r-a-y">Ray</a> 676 <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span> 677 </li> 678 <li class="wp-person" id="wp-person-imath"> 679 <a href="https://profiles.wordpress.org/imath"><img src="//www.gravatar.com/avatar/8b208ca408dad63888253ee1800d6a03?s=60" class="gravatar" alt="Mathieu Viet" /></a> 680 <a class="web" href="https://profiles.wordpress.org/imath">Mathieu Viet</a> 681 <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span> 682 </li> 683 <li class="wp-person" id="wp-person-mercime"> 684 <a href="https://profiles.wordpress.org/mercime"><img src="//www.gravatar.com/avatar/fae451be6708241627983570a1a1817a?s=60" class="gravatar" alt="Mercime" /></a> 685 <a class="web" href="https://profiles.wordpress.org/mercime">Mercime</a> 686 <span class="title"><?php _e( 'Navigator', 'buddypress' ); ?></span> 687 </li> 688 <li class="wp-person" id="wp-person-dcavins"> 689 <a href="https://profiles.wordpress.org/dcavins"><img src="//www.gravatar.com/avatar/a5fa7e83d59cb45ebb616235a176595a?s=60" class="gravatar" alt="David Cavins" /></a> 690 <a class="web" href="https://profiles.wordpress.org/dcavins">David Cavins</a> 691 <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span> 692 </li> 693 <li class="wp-person" id="wp-person-tw2113"> 694 <a href="https://profiles.wordpress.org/tw2113"><img src="//www.gravatar.com/avatar/a5d7c934621fa1c025b83ee79bc62366?s=60" class="gravatar" alt="Michael Beckwith" /></a> 695 <a class="web" href="https://profiles.wordpress.org/tw2113">Michael Beckwith</a> 696 <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span> 697 </li> 698 <li class="wp-person" id="wp-person-hnla"> 699 <a href="https://profiles.wordpress.org/hnla"><img src="//www.gravatar.com/avatar/3860c955aa3f79f13b92826ae47d07fe?s=60" class="gravatar" alt="Hugo Ashmore" /></a> 700 <a class="web" href="https://profiles.wordpress.org/hnla">Hugo</a> 701 <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span> 702 </li> 703 </ul> 704 705 <h3 class="wp-people-group"><?php _e( '🌟Recent Rockstars🌟', 'buddypress' ); ?></h3> 706 <ul class="wp-people-group " id="wp-people-group-rockstars"> 707 <li class="wp-person" id="wp-person-henry-wright"> 708 <a href="https://profiles.wordpress.org/henry.wright"><img src="//www.gravatar.com/avatar/0da2f1a9340d6af196b870f6c107a248?s=60" class="gravatar" alt="Henry Wright" /></a> 709 <a class="web" href="https://profiles.wordpress.org/henry.wright">Henry Wright</a> 710 </li> 711 <li class="wp-person" id="wp-person-danbp"> 712 <a href="https://profiles.wordpress.org/danbp"><img src="//www.gravatar.com/avatar/0deae2e7003027fbf153500cd3fa5501?s=60" class="gravatar" alt="danbp" /></a> 713 <a class="web" href="https://profiles.wordpress.org/danbp">danbp</a> 714 </li> 715 <li class="wp-person" id="wp-person-shanebp"> 716 <a href="https://profiles.wordpress.org/shanebp"><img src="//www.gravatar.com/avatar/ffd294ab5833ba14aaf175f9acc71cc4?s=60" class="gravatar" alt="shanebp" /></a> 717 <a class="web" href="https://profiles.wordpress.org/shanebp">shanebp</a> 718 </li> 719 <li class="wp-person" id="wp-person-netweb"> 720 <a href="https://profiles.wordpress.org/netweb"><img src="//www.gravatar.com/avatar/97e1620b501da675315ba7cfb740e80f?s=60" class="gravatar" alt="Stephen Edgar" /></a> 721 <a class="web" href="https://profiles.wordpress.org/netweb">Stephen Edgar</a> 722 </li> 723 <li class="wp-person" id="wp-person-dimensionmedia"> 724 <a href="https://profiles.wordpress.org/dimensionmedia"><img src="//www.gravatar.com/avatar/7735aada1ec39d0c1118bd92ed4551f1?s=60" class="gravatar" alt="David Bisset" /></a> 725 <a class="web" href="https://profiles.wordpress.org/dimensionmedia">David Bisset</a> 726 </li> 727 728 </ul> 729 730 <h3 class="wp-people-group"><?php printf( esc_html__( 'Contributors to BuddyPress %s', 'buddypress' ), self::display_version() ); ?></h3> 731 <p class="wp-credits-list"> 732 <a href="https://profiles.wordpress.org/ankit-k-gupta/">Ankit K Gupta</a>, 733 <a href="https://profiles.wordpress.org/anthonyvalera/">anthonyvalera</a>, 734 <a href="https://profiles.wordpress.org/boonebgorges/">Boone B Gorges (boonebgorges)</a>, 735 <a href="https://profiles.wordpress.org/thebrandonallen/">Brandon Allen (thebrandonallen)</a>, 736 <a href="https://profiles.wordpress.org/BuddyBoss/">BuddyBoss</a>, 737 <a href="https://profiles.wordpress.org/needle/">Christian Wach (needle)</a>, 738 <a href="https://profiles.wordpress.org/damland/">damland</a>, 739 <a href="https://profiles.wordpress.org/danbp/">danbp</a>, 740 <a href="https://profiles.wordpress.org/daniluk4000/">daniluk4000</a>, 741 <a href="https://profiles.wordpress.org/davidtcarson/">David Carson (davidtcarson)</a>, 742 <a href="https://profiles.wordpress.org/dcavins/">David Cavins (dcavins)</a>, 743 <a href="https://profiles.wordpress.org/valendesigns/">Derek Herman (valendesigns)</a>, 744 <a href="https://profiles.wordpress.org/ganesh641/">ganesh641</a>, 745 <a href="https://profiles.wordpress.org/hnla/">Hugo (hnla)</a>, 746 <a href="https://profiles.wordpress.org/jdgrimes/">J.D. Grimes</a>, 747 <a href="https://profiles.wordpress.org/JeffMatson/">JeffMatson</a>, 748 <a href="https://profiles.wordpress.org/jmarx75/">jmarx75</a>, 749 <a href="https://profiles.wordpress.org/johnjamesjacoby/">John James Jacoby (johnjamesjacoby)</a>, 750 <a href="https://profiles.wordpress.org/kahless/">Jon Breitenbucher (kahless)</a>, 751 <a href="https://profiles.wordpress.org/jbrinley/">Jonathan Brinley (jbrinley)</a>, 752 <a href="https://profiles.wordpress.org/dunhakdis/">Joseph G. (dunhakdis)</a>, 753 <a href="https://profiles.wordpress.org/lakrisgubben/">lakrisgubben</a>, 754 <a href="https://profiles.wordpress.org/landwire/">landwire</a>, 755 <a href="https://profiles.wordpress.org/Offereins">Laurens Offereins (Offereins)</a> 756 <a href="https://profiles.wordpress.org/lenasterg/">lenasterg</a>, 757 <a href="https://profiles.wordpress.org/mrk-1/">m@rk</a>, 758 <a href="https://profiles.wordpress.org/mahype/">mahype</a>, 759 <a href="https://profiles.wordpress.org/imath/">Mathieu Viet (imath)</a>, 760 <a href="https://profiles.wordpress.org/mehulkaklotar/">mehulkaklotar</a>, 761 <a href="https://profiles.wordpress.org/mercime/">mercime</a>, 762 <a href="https://profiles.wordpress.org/tw2113/">Michael Beckwith (tw2113)</a>, 763 <a href="https://profiles.wordpress.org/modemlooper/">modemlooper</a>, 764 <a href="https://profiles.wordpress.org/pareshradadiya/">paresh.radadiya (pareshradadiya)</a>, 765 <a href="https://profiles.wordpress.org/DJPaul/">Paul Gibbs (DJPaul)</a>, 766 <a href="https://profiles.wordpress.org/r-a-y/">r-a-y</a>, 767 <a href="https://profiles.wordpress.org/ramiy/">Rami Yushuvaev (ramiy)</a>, 768 <a href="https://profiles.wordpress.org/ritteshpatel/">Ritesh Patel (ritteshpatel)</a>, 769 <a href="https://profiles.wordpress.org/SergeyBiryukov/">Sergey Biryukov (SergeyBiryukov)</a>, 770 <a href="https://profiles.wordpress.org/shanebp/">shanebp</a>, 771 <a href="https://profiles.wordpress.org/slaffik/">Slava UA (slaffik)</a>, 772 <a href="https://profiles.wordpress.org/netweb/">Stephen Edgar (netweb)</a>, 773 <a href="https://profiles.wordpress.org/svenl77/">svenl77</a>, 774 <a href="https://profiles.wordpress.org/tanner-m/">Tanner Moushey</a>, 775 <a href="https://profiles.wordpress.org/thomaslhotta/">thomaslhotta</a>, 776 <a href="https://profiles.wordpress.org/vnd/">vnd</a>, 777 <a href="https://profiles.wordpress.org/willgladstone/">willgladstone</a>. 778 </p> 779 780 <h3 class="wp-people-group"><?php _e( '💖With our thanks to these Open Source projects💖', 'buddypress' ); ?></h3> 781 <p class="wp-credits-list"> 782 <a href="https://github.com/ichord/At.js">At.js</a>, 783 <a href="https://bbpress.org">bbPress</a>, 784 <a href="https://github.com/ichord/Caret.js">Caret.js</a>, 785 <a href="http://tedgoas.github.io/Cerberus/">Cerberus</a>, 786 <a href="https://github.com/carhartl/jquery-cookie">jquery.cookie</a>, 787 <a href="https://www.mediawiki.org/wiki/MediaWiki">MediaWiki</a>, 788 <a href="https://wordpress.org">WordPress</a>. 789 </p> 790 791 </div> 792 793 <?php 794 } 795 796 /** 797 * Output welcome text and badge for What's New and Credits pages. 798 * 799 * @since 2.2.0 800 */ 801 public static function welcome_text() { 802 803 // Switch welcome text based on whether this is a new installation or not. 804 $welcome_text = ( self::is_new_install() ) 805 ? __( 'Thank you for installing BuddyPress! BuddyPress helps you build any type of community website using WordPress, with member profiles, activity streams, user groups, messaging, and more.', 'buddypress' ) 806 : __( 'BuddyPress %s comes with a bunch of great improvements we think you’re really going to like.', 'buddypress' ); 807 808 ?> 809 810 <h1><?php printf( esc_html__( 'Welcome to BuddyPress %s', 'buddypress' ), self::display_version() ); ?></h1> 811 812 <div class="about-text"> 813 <?php 814 if ( self::is_new_install() ) { 815 echo $welcome_text; 816 } else { 817 printf( $welcome_text, self::display_version() ); 818 } 819 ?> 820 </div> 821 822 <div class="bp-badge"></div> 823 824 <?php 825 } 826 827 /** 828 * Output tab navigation for `What's New` and `Credits` pages. 829 * 830 * @since 2.2.0 831 * 832 * @param string $tab Tab to highlight as active. 833 */ 834 public static function tab_navigation( $tab = 'whats_new' ) { 835 ?> 836 837 <h2 class="nav-tab-wrapper"> 838 <a class="nav-tab <?php if ( 'BP_Admin::about_screen' === $tab ) : ?>nav-tab-active<?php endif; ?>" href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-about' ), 'index.php' ) ) ); ?>"> 839 <?php esc_html_e( 'What’s New', 'buddypress' ); ?> 840 </a><a class="nav-tab <?php if ( 'BP_Admin::credits_screen' === $tab ) : ?>nav-tab-active<?php endif; ?>" href="<?php echo esc_url( bp_get_admin_url( add_query_arg( array( 'page' => 'bp-credits' ), 'index.php' ) ) ); ?>"> 841 <?php esc_html_e( 'Credits', 'buddypress' ); ?> 842 </a> 843 </h2> 844 845 <?php 846 } 847 848 /** Helpers ***************************************************************/ 849 850 /** 851 * Return true/false based on whether a query argument is set. 852 * 853 * @see bp_do_activation_redirect() 854 * 855 * @since 2.2.0 856 * 857 * @return bool 858 */ 859 public static function is_new_install() { 860 return (bool) isset( $_GET['is_new_install'] ); 861 } 862 863 /** 864 * Return a user-friendly version-number string, for use in translations. 865 * 866 * @since 2.2.0 867 * 868 * @return string 869 */ 870 public static function display_version() { 871 872 // Use static variable to prevent recalculations. 873 static $display = ''; 874 875 // Only calculate on first run. 876 if ( '' === $display ) { 877 878 // Get current version. 879 $version = bp_get_version(); 880 881 // Check for prerelease hyphen. 882 $pre = strpos( $version, '-' ); 883 884 // Strip prerelease suffix. 885 $display = ( false !== $pre ) 886 ? substr( $version, 0, $pre ) 887 : $version; 888 } 889 890 // Done! 891 return $display; 892 } 893 894 /** 895 * Add Emails menu item to custom menus array. 896 * 897 * Several BuddyPress components have top-level menu items in the Dashboard, 898 * which all appear together in the middle of the Dashboard menu. This function 899 * adds the Emails screen to the array of these menu items. 900 * 901 * @since 2.4.0 902 * 903 * @param array $custom_menus The list of top-level BP menu items. 904 * @return array $custom_menus List of top-level BP menu items, with Emails added. 905 */ 906 public function emails_admin_menu_order( $custom_menus = array() ) { 907 array_push( $custom_menus, 'edit.php?post_type=' . bp_get_email_post_type() ); 908 return $custom_menus; 909 } 910 911 /** 912 * Register styles commonly used by BuddyPress wp-admin screens. 913 * 914 * @since 2.5.0 915 */ 916 public function admin_register_styles() { 917 $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 918 $url = $this->css_url; 919 920 /** 921 * Filters the BuddyPress Core Admin CSS file path. 922 * 923 * @since 1.6.0 924 * 925 * @param string $file File path for the admin CSS. 926 */ 927 $common_css = apply_filters( 'bp_core_admin_common_css', "{$url}common{$min}.css" ); 928 929 /** 930 * Filters the BuddyPress admin stylesheet files to register. 931 * 932 * @since 2.5.0 933 * 934 * @param array $value Array of admin stylesheet file information to register. 935 */ 936 $styles = apply_filters( 'bp_core_admin_register_styles', array( 937 // Legacy. 938 'bp-admin-common-css' => array( 939 'file' => $common_css, 940 'dependencies' => array(), 941 ), 942 943 // 2.5 944 'bp-customizer-controls' => array( 945 'file' => "{$url}customizer-controls{$min}.css", 946 'dependencies' => array(), 947 ), 948 ) ); 949 950 951 $version = bp_get_version(); 952 953 foreach ( $styles as $id => $style ) { 954 wp_register_style( $id, $style['file'], $style['dependencies'], $version ); 955 wp_style_add_data( $id, 'rtl', true ); 956 957 if ( $min ) { 958 wp_style_add_data( $id, 'suffix', $min ); 959 } 960 } 961 } 962 963 /** 964 * Register JS commonly used by BuddyPress wp-admin screens. 965 * 966 * @since 2.5.0 967 */ 968 public function admin_register_scripts() { 969 $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 970 $url = $this->js_url; 971 972 /** 973 * Filters the BuddyPress admin JS files to register. 974 * 975 * @since 2.5.0 976 * 977 * @param array $value Array of admin JS file information to register. 978 */ 979 $scripts = apply_filters( 'bp_core_admin_register_scripts', array( 980 // 2.5 981 'bp-customizer-controls' => array( 982 'file' => "{$url}customizer-controls{$min}.js", 983 'dependencies' => array( 'jquery' ), 984 'footer' => true, 985 ), 986 ) ); 987 988 $version = bp_get_version(); 989 990 foreach ( $scripts as $id => $script ) { 991 wp_register_script( $id, $script['file'], $script['dependencies'], $version, $script['footer'] ); 992 } 993 } 994 } 995 endif; // End class_exists check. 13 require dirname( __FILE__ ) . '/classes/class-bp-admin.php'; 996 14 997 15 /** -
trunk/src/bp-core/bp-core-component.php
r10497 r10518 11 11 defined( 'ABSPATH' ) || exit; 12 12 13 if ( !class_exists( 'BP_Component' ) ) : 14 15 /** 16 * BuddyPress Component Class. 17 * 18 * The BuddyPress component class is responsible for simplifying the creation 19 * of components that share similar behaviors and routines. It is used 20 * internally by BuddyPress to create the bundled components, but can be 21 * extended to create other really neat things. 22 * 23 * @since 1.5.0 24 */ 25 class BP_Component { 26 27 /** Variables *************************************************************/ 28 29 /** 30 * Translatable name for the component. 31 * 32 * @internal 33 * @var string $name 34 */ 35 public $name = ''; 36 37 /** 38 * Unique ID for the component. 39 * 40 * @since 1.5.0 41 * @var string $id 42 */ 43 public $id = ''; 44 45 /** 46 * Unique slug for the component, for use in query strings and URLs. 47 * 48 * @since 1.5.0 49 * @var string $slug 50 */ 51 public $slug = ''; 52 53 /** 54 * Does the component need a top-level directory? 55 * 56 * @since 1.5.0 57 * @var bool $has_directory 58 */ 59 public $has_directory = false; 60 61 /** 62 * The path to the component's files. 63 * 64 * @since 1.5.0 65 * @var string $path 66 */ 67 public $path = ''; 68 69 /** 70 * The WP_Query loop for this component. 71 * 72 * @since 1.5.0 73 * @var WP_Query $query 74 */ 75 public $query = false; 76 77 /** 78 * The current ID of the queried object. 79 * 80 * @since 1.5.0 81 * @var string $current_id 82 */ 83 public $current_id = ''; 84 85 /** 86 * Callback for formatting notifications. 87 * 88 * @since 1.5.0 89 * @var callable $notification_callback 90 */ 91 public $notification_callback = ''; 92 93 /** 94 * WordPress Toolbar links. 95 * 96 * @since 1.5.0 97 * @var array $admin_menu 98 */ 99 public $admin_menu = ''; 100 101 /** 102 * Placeholder text for component directory search box. 103 * 104 * @since 1.6.0 105 * @var string $search_string 106 */ 107 public $search_string = ''; 108 109 /** 110 * Root slug for the component. 111 * 112 * @since 1.6.0 113 * @var string $root_slug 114 */ 115 public $root_slug = ''; 116 117 /** 118 * Metadata tables for the component (if applicable). 119 * 120 * @since 2.0.0 121 * 122 * @var array 123 */ 124 public $meta_tables = array(); 125 126 /** 127 * Global tables for the component (if applicable). 128 * 129 * @since 2.0.0 130 * 131 * @var array 132 */ 133 public $global_tables = array(); 134 135 /** 136 * Query argument for component search URLs. 137 * 138 * @since 2.4.0 139 * @var string 140 */ 141 public $search_query_arg = 's'; 142 143 /** Methods ***************************************************************/ 144 145 /** 146 * Component loader. 147 * 148 * @since 1.5.0 149 * @since 1.9.0 Added $params as a parameter. 150 * @since 2.3.0 Added $params['features'] as a configurable value. 151 * @since 2.4.0 Added $params['search_query_arg'] as a configurable value. 152 * 153 * @param string $id Unique ID. Letters, numbers, and underscores only. 154 * @param string $name Unique name. This should be a translatable name, eg. 155 * __( 'Groups', 'buddypress' ). 156 * @param string $path The file path for the component's files. Used by {@link BP_Component::includes()}. 157 * @param array $params { 158 * Additional parameters used by the component. 159 * @type int $adminbar_myaccount_order Set the position for our menu under the WP Toolbar's "My Account menu". 160 * @type array $features An array of feature names. This is used to load additional files from your 161 * component directory and for feature active checks. eg. array( 'awesome' ) 162 * would look for a file called "bp-{$this->id}-awesome.php" and you could use 163 * bp_is_active( $this->id, 'awesome' ) to determine if the feature is active. 164 * @type string $search_query_arg String to be used as the query argument in component search URLs. 165 * } 166 */ 167 public function start( $id = '', $name = '', $path = '', $params = array() ) { 168 169 // Internal identifier of component. 170 $this->id = $id; 171 172 // Internal component name. 173 $this->name = $name; 174 175 // Path for includes. 176 $this->path = $path; 177 178 // Miscellaneous component parameters that need to be set early on. 179 if ( ! empty( $params ) ) { 180 // Sets the position for our menu under the WP Toolbar's "My Account" menu. 181 if ( ! empty( $params['adminbar_myaccount_order'] ) ) { 182 $this->adminbar_myaccount_order = (int) $params['adminbar_myaccount_order']; 183 } 184 185 // Register features. 186 if ( ! empty( $params['features'] ) ) { 187 $this->features = array_map( 'sanitize_title', (array) $params['features'] ); 188 } 189 190 if ( ! empty( $params['search_query_arg'] ) ) { 191 $this->search_query_arg = sanitize_title( $params['search_query_arg'] ); 192 } 193 194 // Set defaults if not passed. 195 } else { 196 // New component menus are added before the settings menu if not set. 197 $this->adminbar_myaccount_order = 90; 198 } 199 200 // Move on to the next step. 201 $this->setup_actions(); 202 } 203 204 /** 205 * Set up component global variables. 206 * 207 * @since 1.5.0 208 * 209 * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_id'. 210 * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_slug'. 211 * 212 * @param array $args { 213 * All values are optional. 214 * @type string $slug The component slug. Used to construct certain URLs, such as 'friends' in 215 * http://example.com/members/joe/friends/. Default: the value of $this->id. 216 * @type string $root_slug The component root slug. Note that this value is generally unused if the 217 * component has a root directory (the slug will be overridden by the 218 * post_name of the directory page). Default: the slug of the directory page 219 * if one is found, otherwise an empty string. 220 * @type bool $has_directory Set to true if the component requires an associated WordPress page. 221 * @type callable $notification_callback Optional. The callable function that formats the component's notifications. 222 * @type string $search_term Optional. The placeholder text in the component directory search box. Eg, 223 * 'Search Groups...'. 224 * @type array $global_tables Optional. An array of database table names. 225 * @type array $meta_tables Optional. An array of metadata table names. 226 * } 227 */ 228 public function setup_globals( $args = array() ) { 229 230 /** Slugs ************************************************************ 231 */ 232 233 // If a WP directory page exists for the component, it should 234 // be the default value of 'root_slug'. 235 $default_root_slug = isset( buddypress()->pages->{$this->id}->slug ) ? buddypress()->pages->{$this->id}->slug : ''; 236 237 $r = wp_parse_args( $args, array( 238 'slug' => $this->id, 239 'root_slug' => $default_root_slug, 240 'has_directory' => false, 241 'directory_title' => '', 242 'notification_callback' => '', 243 'search_string' => '', 244 'global_tables' => '', 245 'meta_tables' => '', 246 ) ); 247 248 /** 249 * Filters the slug to be used for the permalink URI chunk after root. 250 * 251 * @since 1.5.0 252 * 253 * @param string $value Slug to use in permalink URI chunk. 254 */ 255 $this->slug = apply_filters( 'bp_' . $this->id . '_slug', $r['slug'] ); 256 257 /** 258 * Filters the slug used for root directory. 259 * 260 * @since 1.5.0 261 * 262 * @param string $value Root directory slug. 263 */ 264 $this->root_slug = apply_filters( 'bp_' . $this->id . '_root_slug', $r['root_slug'] ); 265 266 /** 267 * Filters the component's top-level directory if available. 268 * 269 * @since 1.5.0 270 * 271 * @param bool $value Whether or not there is a top-level directory. 272 */ 273 $this->has_directory = apply_filters( 'bp_' . $this->id . '_has_directory', $r['has_directory'] ); 274 275 /** 276 * Filters the component's directory title. 277 * 278 * @since 2.0.0 279 * 280 * @param string $value Title to use for the directory. 281 */ 282 $this->directory_title = apply_filters( 'bp_' . $this->id . '_directory_title', $r['directory_title'] ); 283 284 /** 285 * Filters the placeholder text for search inputs for component. 286 * 287 * @since 1.5.0 288 * 289 * @param string $value Name to use in search input placeholders. 290 */ 291 $this->search_string = apply_filters( 'bp_' . $this->id . '_search_string', $r['search_string'] ); 292 293 /** 294 * Filters the callable function that formats the component's notifications. 295 * 296 * @since 1.5.0 297 * 298 * @param string $value Function callback. 299 */ 300 $this->notification_callback = apply_filters( 'bp_' . $this->id . '_notification_callback', $r['notification_callback'] ); 301 302 // Set the global table names, if applicable. 303 if ( ! empty( $r['global_tables'] ) ) { 304 $this->register_global_tables( $r['global_tables'] ); 305 } 306 307 // Set the metadata table, if applicable. 308 if ( ! empty( $r['meta_tables'] ) ) { 309 $this->register_meta_tables( $r['meta_tables'] ); 310 } 311 312 /** BuddyPress ******************************************************* 313 */ 314 315 // Register this component in the loaded components array. 316 buddypress()->loaded_components[$this->slug] = $this->id; 317 318 /** 319 * Fires at the end of the setup_globals method inside BP_Component. 320 * 321 * This is a dynamic hook that is based on the component string ID. 322 * 323 * @since 1.5.0 324 */ 325 do_action( 'bp_' . $this->id . '_setup_globals' ); 326 } 327 328 /** 329 * Include required files. 330 * 331 * Please note that, by default, this method is fired on the bp_include 332 * hook, with priority 8. This is necessary so that core components are 333 * loaded in time to be available to third-party plugins. However, this 334 * load order means that third-party plugins whose main files are 335 * loaded at bp_include with priority 10 (as recommended), will not be 336 * loaded in time for their includes() method to fire automatically. 337 * 338 * For this reason, it is recommended that your plugin has its own 339 * method or function for requiring necessary files. If you must use 340 * this method, you will have to call it manually in your constructor 341 * class, ie 342 * $this->includes(); 343 * 344 * Note that when you pass an array value like 'actions' to includes, 345 * it looks for the following three files (assuming your component is 346 * called 'my_component'): 347 * - ./actions 348 * - ./bp-my_component/actions 349 * - ./bp-my_component/bp-my_component-actions.php 350 * 351 * @since 1.5.0 352 * 353 * @uses do_action() Calls 'bp_{@link bp_Component::name}includes'. 354 * 355 * @param array $includes An array of file names, or file name chunks, 356 * to be parsed and then included. 357 */ 358 public function includes( $includes = array() ) { 359 360 // Bail if no files to include. 361 if ( ! empty( $includes ) ) { 362 $slashed_path = trailingslashit( $this->path ); 363 364 // Loop through files to be included. 365 foreach ( (array) $includes as $file ) { 366 367 $paths = array( 368 369 // Passed with no extension. 370 'bp-' . $this->id . '/bp-' . $this->id . '-' . $file . '.php', 371 'bp-' . $this->id . '-' . $file . '.php', 372 'bp-' . $this->id . '/' . $file . '.php', 373 374 // Passed with extension. 375 $file, 376 'bp-' . $this->id . '-' . $file, 377 'bp-' . $this->id . '/' . $file, 378 ); 379 380 foreach ( $paths as $path ) { 381 if ( @is_file( $slashed_path . $path ) ) { 382 require( $slashed_path . $path ); 383 break; 384 } 385 } 386 } 387 } 388 389 /** 390 * Fires at the end of the includes method inside BP_Component. 391 * 392 * This is a dynamic hook that is based on the component string ID. 393 * 394 * @since 1.5.0 395 */ 396 do_action( 'bp_' . $this->id . '_includes' ); 397 } 398 399 /** 400 * Set up the actions. 401 * 402 * @since 1.5.0 403 * 404 * @uses add_action() To add various actions. 405 * @uses do_action() Calls 'bp_{@link BP_Component::name}setup_actions'. 406 */ 407 public function setup_actions() { 408 409 // Setup globals. 410 add_action( 'bp_setup_globals', array( $this, 'setup_globals' ), 10 ); 411 412 // Set up canonical stack. 413 add_action( 'bp_setup_canonical_stack', array( $this, 'setup_canonical_stack' ), 10 ); 414 415 // Include required files. Called early to ensure that BP core 416 // components are loaded before plugins that hook their loader functions 417 // to bp_include with the default priority of 10. This is for backwards 418 // compatibility; henceforth, plugins should register themselves by 419 // extending this base class. 420 add_action( 'bp_include', array( $this, 'includes' ), 8 ); 421 422 // Setup navigation. 423 add_action( 'bp_setup_nav', array( $this, 'setup_nav' ), 10 ); 424 425 // Setup WP Toolbar menus. 426 add_action( 'bp_setup_admin_bar', array( $this, 'setup_admin_bar' ), $this->adminbar_myaccount_order ); 427 428 // Setup component title. 429 add_action( 'bp_setup_title', array( $this, 'setup_title' ), 10 ); 430 431 // Setup cache groups. 432 add_action( 'bp_setup_cache_groups', array( $this, 'setup_cache_groups' ), 10 ); 433 434 // Register post types. 435 add_action( 'bp_register_post_types', array( $this, 'register_post_types' ), 10 ); 436 437 // Register taxonomies. 438 add_action( 'bp_register_taxonomies', array( $this, 'register_taxonomies' ), 10 ); 439 440 // Add the rewrite tags. 441 add_action( 'bp_add_rewrite_tags', array( $this, 'add_rewrite_tags' ), 10 ); 442 443 // Add the rewrite rules. 444 add_action( 'bp_add_rewrite_rules', array( $this, 'add_rewrite_rules' ), 10 ); 445 446 // Add the permalink structure. 447 add_action( 'bp_add_permastructs', array( $this, 'add_permastructs' ), 10 ); 448 449 // Allow components to parse the main query. 450 add_action( 'bp_parse_query', array( $this, 'parse_query' ), 10 ); 451 452 // Generate rewrite rules. 453 add_action( 'bp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10 ); 454 455 /** 456 * Fires at the end of the setup_actions method inside BP_Component. 457 * 458 * This is a dynamic hook that is based on the component string ID. 459 * 460 * @since 1.5.0 461 */ 462 do_action( 'bp_' . $this->id . '_setup_actions' ); 463 } 464 465 /** 466 * Set up the canonical URL stack for this component. 467 * 468 * @since 2.1.0 469 */ 470 public function setup_canonical_stack() {} 471 472 /** 473 * Set up component navigation. 474 * 475 * @since 1.5.0 476 * 477 * @see bp_core_new_nav_item() For a description of the $main_nav 478 * parameter formatting. 479 * @see bp_core_new_subnav_item() For a description of how each item 480 * in the $sub_nav parameter array should be formatted. 481 * 482 * @param array $main_nav Optional. Passed directly to bp_core_new_nav_item(). 483 * See that function for a description. 484 * @param array $sub_nav Optional. Multidimensional array, each item in 485 * which is passed to bp_core_new_subnav_item(). See that 486 * function for a description. 487 */ 488 public function setup_nav( $main_nav = array(), $sub_nav = array() ) { 489 490 // No sub nav items without a main nav item. 491 if ( !empty( $main_nav ) ) { 492 bp_core_new_nav_item( $main_nav ); 493 494 // Sub nav items are not required. 495 if ( !empty( $sub_nav ) ) { 496 foreach( (array) $sub_nav as $nav ) { 497 bp_core_new_subnav_item( $nav ); 498 } 499 } 500 } 501 502 /** 503 * Fires at the end of the setup_nav method inside BP_Component. 504 * 505 * This is a dynamic hook that is based on the component string ID. 506 * 507 * @since 1.5.0 508 */ 509 do_action( 'bp_' . $this->id . '_setup_nav' ); 510 } 511 512 /** 513 * Set up the component entries in the WordPress Admin Bar. 514 * 515 * @since 1.5.0 516 * 517 * @see WP_Admin_Bar::add_menu() for a description of the syntax 518 * required by each item in the $wp_admin_nav parameter array. 519 * @global object $wp_admin_bar 520 * 521 * @param array $wp_admin_nav An array of nav item arguments. Each item in this parameter 522 * array is passed to {@link WP_Admin_Bar::add_menu()}. 523 * See that method for a description of the required syntax for 524 * each item. 525 */ 526 public function setup_admin_bar( $wp_admin_nav = array() ) { 527 528 // Bail if this is an ajax request. 529 if ( defined( 'DOING_AJAX' ) ) { 530 return; 531 } 532 533 // Do not proceed if BP_USE_WP_ADMIN_BAR constant is not set or is false. 534 if ( ! bp_use_wp_admin_bar() ) { 535 return; 536 } 537 538 /** 539 * Filters the admin navigation passed into setup_admin_bar. 540 * 541 * This is a dynamic hook that is based on the component string ID. 542 * 543 * @since 1.9.0 544 * 545 * @param array $wp_admin_nav Array of navigation items to add. 546 */ 547 $wp_admin_nav = apply_filters( 'bp_' . $this->id . '_admin_nav', $wp_admin_nav ); 548 549 // Do we have Toolbar menus to add? 550 if ( !empty( $wp_admin_nav ) ) { 551 552 // Set this objects menus. 553 $this->admin_menu = $wp_admin_nav; 554 555 // Define the WordPress global. 556 global $wp_admin_bar; 557 558 // Add each admin menu. 559 foreach( $this->admin_menu as $admin_menu ) { 560 $wp_admin_bar->add_menu( $admin_menu ); 561 } 562 } 563 564 /** 565 * Fires at the end of the setup_admin_bar method inside BP_Component. 566 * 567 * This is a dynamic hook that is based on the component string ID. 568 * 569 * @since 1.5.0 570 */ 571 do_action( 'bp_' . $this->id . '_setup_admin_bar' ); 572 } 573 574 /** 575 * Set up the component title. 576 * 577 * @since 1.5.0 578 * 579 * @uses do_action() Calls 'bp_{@link bp_Component::name}_setup_title'. 580 */ 581 public function setup_title() { 582 583 /** 584 * Fires in the setup_title method inside BP_Component. 585 * 586 * This is a dynamic hook that is based on the component string ID. 587 * 588 * @since 1.5.0 589 */ 590 do_action( 'bp_' . $this->id . '_setup_title' ); 591 } 592 593 /** 594 * Setup component-specific cache groups. 595 * 596 * @since 2.2.0 597 * 598 * @uses do_action() Calls 'bp_setup_{@link bp_Component::name}_cache_groups'. 599 */ 600 public function setup_cache_groups() { 601 602 /** 603 * Fires in the setup_cache_groups method inside BP_Component. 604 * 605 * This is a dynamic hook that is based on the component string ID. 606 * 607 * @since 2.2.0 608 */ 609 do_action( 'bp_' . $this->id . '_setup_cache_groups' ); 610 } 611 612 /** 613 * Register global tables for the component, so that it may use WordPress's database API. 614 * 615 * @since 2.0.0 616 * 617 * @param array $tables Table names to register. 618 */ 619 public function register_global_tables( $tables = array() ) { 620 621 /** 622 * Filters the global tables for the component, so that it may use WordPress' database API. 623 * 624 * This is a dynamic hook that is based on the component string ID. 625 * It allows for component-specific filtering of table names. To filter 626 * *all* tables, use the 'bp_core_get_table_prefix' filter instead. 627 * 628 * @since 1.6.0 629 */ 630 $tables = apply_filters( 'bp_' . $this->id . '_global_tables', $tables ); 631 632 // Add to the BuddyPress global object. 633 if ( !empty( $tables ) && is_array( $tables ) ) { 634 foreach ( $tables as $global_name => $table_name ) { 635 $this->$global_name = $table_name; 636 } 637 638 // Keep a record of the metadata tables in the component. 639 $this->global_tables = $tables; 640 } 641 642 /** 643 * Fires at the end of the register_global_tables method inside BP_Component. 644 * 645 * This is a dynamic hook that is based on the component string ID. 646 * 647 * @since 2.0.0 648 */ 649 do_action( 'bp_' . $this->id . '_register_global_tables' ); 650 } 651 652 /** 653 * Register component metadata tables. 654 * 655 * Metadata tables are registered in the $wpdb global, for 656 * compatibility with the WordPress metadata API. 657 * 658 * @since 2.0.0 659 * 660 * @param array $tables Table names to register. 661 */ 662 public function register_meta_tables( $tables = array() ) { 663 global $wpdb; 664 665 /** 666 * Filters the global meta_tables for the component. 667 * 668 * This is a dynamic hook that is based on the component string ID. 669 * It allows for component-specific filtering of table names. To filter 670 * *all* tables, use the 'bp_core_get_table_prefix' filter instead. 671 * 672 * @since 2.0.0 673 */ 674 $tables = apply_filters( 'bp_' . $this->id . '_meta_tables', $tables ); 675 676 /** 677 * Add the name of each metadata table to WPDB to allow BuddyPress 678 * components to play nicely with the WordPress metadata API. 679 */ 680 if ( !empty( $tables ) && is_array( $tables ) ) { 681 foreach( $tables as $meta_prefix => $table_name ) { 682 $wpdb->{$meta_prefix . 'meta'} = $table_name; 683 } 684 685 // Keep a record of the metadata tables in the component. 686 $this->meta_tables = $tables; 687 } 688 689 /** 690 * Fires at the end of the register_meta_tables method inside BP_Component. 691 * 692 * This is a dynamic hook that is based on the component string ID. 693 * 694 * @since 2.0.0 695 */ 696 do_action( 'bp_' . $this->id . '_register_meta_tables' ); 697 } 698 699 /** 700 * Set up the component post types. 701 * 702 * @since 1.5.0 703 * 704 * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_post_types'. 705 */ 706 public function register_post_types() { 707 708 /** 709 * Fires in the register_post_types method inside BP_Component. 710 * 711 * This is a dynamic hook that is based on the component string ID. 712 * 713 * @since 1.5.0 714 */ 715 do_action( 'bp_' . $this->id . '_register_post_types' ); 716 } 717 718 /** 719 * Register component-specific taxonomies. 720 * 721 * @since 1.5.0 722 * 723 * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_taxonomies'. 724 */ 725 public function register_taxonomies() { 726 727 /** 728 * Fires in the register_taxonomies method inside BP_Component. 729 * 730 * This is a dynamic hook that is based on the component string ID. 731 * 732 * @since 1.5.0 733 */ 734 do_action( 'bp_' . $this->id . '_register_taxonomies' ); 735 } 736 737 /** 738 * Add any additional rewrite tags. 739 * 740 * @since 1.5.0 741 * 742 * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_rewrite_tags'. 743 */ 744 public function add_rewrite_tags() { 745 746 /** 747 * Fires in the add_rewrite_tags method inside BP_Component. 748 * 749 * This is a dynamic hook that is based on the component string ID. 750 * 751 * @since 1.5.0 752 */ 753 do_action( 'bp_' . $this->id . '_add_rewrite_tags' ); 754 } 755 756 /** 757 * Add any additional rewrite rules. 758 * 759 * @since 1.9.0 760 * 761 * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_rewrite_rules'. 762 */ 763 public function add_rewrite_rules() { 764 765 /** 766 * Fires in the add_rewrite_rules method inside BP_Component. 767 * 768 * This is a dynamic hook that is based on the component string ID. 769 * 770 * @since 1.9.0 771 */ 772 do_action( 'bp_' . $this->id . '_add_rewrite_rules' ); 773 } 774 775 /** 776 * Add any permalink structures. 777 * 778 * @since 1.9.0 779 * 780 * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_permastruct'. 781 */ 782 public function add_permastructs() { 783 784 /** 785 * Fires in the add_permastructs method inside BP_Component. 786 * 787 * This is a dynamic hook that is based on the component string ID. 788 * 789 * @since 1.9.0 790 */ 791 do_action( 'bp_' . $this->id . '_add_permastructs' ); 792 } 793 794 /** 795 * Allow components to parse the main query. 796 * 797 * @since 1.9.0 798 * 799 * @uses do_action() Calls 'bp_{@link bp_Component::name}_parse_query'. 800 * 801 * @param object $query The main WP_Query. 802 */ 803 public function parse_query( $query ) { 804 805 /** 806 * Fires in the parse_query method inside BP_Component. 807 * 808 * This is a dynamic hook that is based on the component string ID. 809 * 810 * @since 1.9.0 811 * 812 * @param object $query Main WP_Query object. Passed by reference. 813 */ 814 do_action_ref_array( 'bp_' . $this->id . '_parse_query', array( &$query ) ); 815 } 816 817 /** 818 * Generate any additional rewrite rules. 819 * 820 * @since 1.5.0 821 * 822 * @uses do_action() Calls 'bp_{@link bp_Component::name}_generate_rewrite_rules'. 823 */ 824 public function generate_rewrite_rules() { 825 826 /** 827 * Fires in the generate_rewrite_rules method inside BP_Component. 828 * 829 * This is a dynamic hook that is based on the component string ID. 830 * 831 * @since 1.5.0 832 */ 833 do_action( 'bp_' . $this->id . '_generate_rewrite_rules' ); 834 } 835 } 836 endif; // BP_Component. 13 require dirname( __FILE__ ) . '/classes/class-bp-core-component.php'; -
trunk/src/bp-core/bp-core-loader.php
r10497 r10518 13 13 defined( 'ABSPATH' ) || exit; 14 14 15 /** 16 * Creates the Core component. 17 * 18 * @since 1.5.0 19 */ 20 class BP_Core extends BP_Component { 21 22 /** 23 * Start the members component creation process. 24 * 25 * @since 1.5.0 26 * 27 * @uses BP_Core::bootstrap() 28 */ 29 public function __construct() { 30 parent::start( 31 'core', 32 __( 'BuddyPress Core', 'buddypress' ), 33 buddypress()->plugin_dir 34 ); 35 36 $this->bootstrap(); 37 } 38 39 /** 40 * Populate the global data needed before BuddyPress can continue. 41 * 42 * This involves figuring out the currently required, activated, deactivated, 43 * and optional components. 44 * 45 * @since 1.5.0 46 */ 47 private function bootstrap() { 48 $bp = buddypress(); 49 50 /** 51 * Fires before the loading of individual components and after BuddyPress Core. 52 * 53 * Allows plugins to run code ahead of the other components. 54 * 55 * @since 1.2.0 56 */ 57 do_action( 'bp_core_loaded' ); 58 59 /** Components ******************************************************* 60 */ 61 62 /** 63 * Filters the included and optional components. 64 * 65 * @since 1.5.0 66 * 67 * @param array $value Array of included and optional components. 68 */ 69 $bp->optional_components = apply_filters( 'bp_optional_components', array( 'activity', 'blogs', 'forums', 'friends', 'groups', 'messages', 'notifications', 'settings', 'xprofile' ) ); 70 71 /** 72 * Filters the required components. 73 * 74 * @since 1.5.0 75 * 76 * @param array $value Array of required components. 77 */ 78 $bp->required_components = apply_filters( 'bp_required_components', array( 'members' ) ); 79 80 // Get a list of activated components. 81 if ( $active_components = bp_get_option( 'bp-active-components' ) ) { 82 83 /** This filter is documented in bp-core/admin/bp-core-admin-components.php */ 84 $bp->active_components = apply_filters( 'bp_active_components', $active_components ); 85 86 /** 87 * Filters the deactivated components. 88 * 89 * @since 1.0.0 90 * 91 * @param array $value Array of deactivated components. 92 */ 93 $bp->deactivated_components = apply_filters( 'bp_deactivated_components', array_values( array_diff( array_values( array_merge( $bp->optional_components, $bp->required_components ) ), array_keys( $bp->active_components ) ) ) ); 94 95 // Pre 1.5 Backwards compatibility. 96 } elseif ( $deactivated_components = bp_get_option( 'bp-deactivated-components' ) ) { 97 98 // Trim off namespace and filename. 99 foreach ( array_keys( (array) $deactivated_components ) as $component ) { 100 $trimmed[] = str_replace( '.php', '', str_replace( 'bp-', '', $component ) ); 101 } 102 103 /** This filter is documented in bp-core/bp-core-loader.php */ 104 $bp->deactivated_components = apply_filters( 'bp_deactivated_components', $trimmed ); 105 106 // Setup the active components. 107 $active_components = array_fill_keys( array_diff( array_values( array_merge( $bp->optional_components, $bp->required_components ) ), array_values( $bp->deactivated_components ) ), '1' ); 108 109 /** This filter is documented in bp-core/admin/bp-core-admin-components.php */ 110 $bp->active_components = apply_filters( 'bp_active_components', $bp->active_components ); 111 112 // Default to all components active. 113 } else { 114 115 // Set globals. 116 $bp->deactivated_components = array(); 117 118 // Setup the active components. 119 $active_components = array_fill_keys( array_values( array_merge( $bp->optional_components, $bp->required_components ) ), '1' ); 120 121 /** This filter is documented in bp-core/admin/bp-core-admin-components.php */ 122 $bp->active_components = apply_filters( 'bp_active_components', $bp->active_components ); 123 } 124 125 // Loop through optional components. 126 foreach( $bp->optional_components as $component ) { 127 if ( bp_is_active( $component ) && file_exists( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' ) ) { 128 include( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' ); 129 } 130 } 131 132 // Loop through required components. 133 foreach( $bp->required_components as $component ) { 134 if ( file_exists( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' ) ) { 135 include( $bp->plugin_dir . '/bp-' . $component . '/bp-' . $component . '-loader.php' ); 136 } 137 } 138 139 // Add Core to required components. 140 $bp->required_components[] = 'core'; 141 142 /** 143 * Fires after the loading of individual components. 144 * 145 * @since 2.0.0 146 */ 147 do_action( 'bp_core_components_included' ); 148 } 149 150 /** 151 * Include bp-core files. 152 * 153 * @since 1.6.0 154 * 155 * @see BP_Component::includes() for description of parameters. 156 * 157 * @param array $includes See {@link BP_Component::includes()}. 158 */ 159 public function includes( $includes = array() ) { 160 161 if ( ! is_admin() ) { 162 return; 163 } 164 165 $includes = array( 166 'admin' 167 ); 168 169 parent::includes( $includes ); 170 } 171 172 /** 173 * Set up bp-core global settings. 174 * 175 * Sets up a majority of the BuddyPress globals that require a minimal 176 * amount of processing, meaning they cannot be set in the BuddyPress class. 177 * 178 * @since 1.5.0 179 * 180 * @see BP_Component::setup_globals() for description of parameters. 181 * 182 * @param array $args See {@link BP_Component::setup_globals()}. 183 */ 184 public function setup_globals( $args = array() ) { 185 $bp = buddypress(); 186 187 /** Database ********************************************************* 188 */ 189 190 // Get the base database prefix. 191 if ( empty( $bp->table_prefix ) ) { 192 $bp->table_prefix = bp_core_get_table_prefix(); 193 } 194 195 // The domain for the root of the site where the main blog resides. 196 if ( empty( $bp->root_domain ) ) { 197 $bp->root_domain = bp_core_get_root_domain(); 198 } 199 200 // Fetches all of the core BuddyPress settings in one fell swoop. 201 if ( empty( $bp->site_options ) ) { 202 $bp->site_options = bp_core_get_root_options(); 203 } 204 205 // The names of the core WordPress pages used to display BuddyPress content. 206 if ( empty( $bp->pages ) ) { 207 $bp->pages = bp_core_get_directory_pages(); 208 } 209 210 /** Basic current user data ****************************************** 211 */ 212 213 // Logged in user is the 'current_user'. 214 $current_user = wp_get_current_user(); 215 216 // The user ID of the user who is currently logged in. 217 $bp->loggedin_user = new stdClass; 218 $bp->loggedin_user->id = isset( $current_user->ID ) ? $current_user->ID : 0; 219 220 /** Avatars ********************************************************** 221 */ 222 223 // Fetches the default Gravatar image to use if the user/group/blog has no avatar or gravatar. 224 $bp->grav_default = new stdClass; 225 226 /** 227 * Filters the default user Gravatar. 228 * 229 * @since 1.1.0 230 * 231 * @param string $value Default user Gravatar. 232 */ 233 $bp->grav_default->user = apply_filters( 'bp_user_gravatar_default', $bp->site_options['avatar_default'] ); 234 235 /** 236 * Filters the default group Gravatar. 237 * 238 * @since 1.1.0 239 * 240 * @param string $value Default group Gravatar. 241 */ 242 $bp->grav_default->group = apply_filters( 'bp_group_gravatar_default', $bp->grav_default->user ); 243 244 /** 245 * Filters the default blog Gravatar. 246 * 247 * @since 1.1.0 248 * 249 * @param string $value Default blog Gravatar. 250 */ 251 $bp->grav_default->blog = apply_filters( 'bp_blog_gravatar_default', $bp->grav_default->user ); 252 253 // Notifications table. Included here for legacy purposes. Use 254 // bp-notifications instead. 255 $bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications'; 256 257 /** 258 * Used to determine if user has admin rights on current content. If the 259 * logged in user is viewing their own profile and wants to delete 260 * something, is_item_admin is used. This is a generic variable so it 261 * can be used by other components. It can also be modified, so when 262 * viewing a group 'is_item_admin' would be 'true' if they are a group 263 * admin, and 'false' if they are not. 264 */ 265 bp_update_is_item_admin( bp_user_has_access(), 'core' ); 266 267 // Is the logged in user is a mod for the current item? 268 bp_update_is_item_mod( false, 'core' ); 269 270 /** 271 * Fires at the end of the setup of bp-core globals setting. 272 * 273 * @since 1.1.0 274 */ 275 do_action( 'bp_core_setup_globals' ); 276 } 277 278 /** 279 * Setup cache groups 280 * 281 * @since 2.2.0 282 */ 283 public function setup_cache_groups() { 284 285 // Global groups. 286 wp_cache_add_global_groups( array( 287 'bp' 288 ) ); 289 290 parent::setup_cache_groups(); 291 } 292 293 /** 294 * Set up post types. 295 * 296 * @since BuddyPress (2.4.0) 297 */ 298 public function register_post_types() { 299 300 // Emails 301 if ( bp_is_root_blog() ) { 302 register_post_type( 303 bp_get_email_post_type(), 304 apply_filters( 'bp_register_email_post_type', array( 305 'description' => _x( 'BuddyPress emails', 'email post type description', 'buddypress' ), 306 'labels' => bp_get_email_post_type_labels(), 307 'menu_icon' => 'dashicons-email', 308 'public' => false, 309 'publicly_queryable' => bp_current_user_can( 'bp_moderate' ), 310 'query_var' => false, 311 'rewrite' => false, 312 'show_in_admin_bar' => false, 313 'show_ui' => bp_current_user_can( 'bp_moderate' ), 314 'supports' => bp_get_email_post_type_supports(), 315 ) ) 316 ); 317 } 318 319 parent::register_post_types(); 320 } 321 } 15 require dirname( __FILE__ ) . '/classes/class-bp-core.php'; 322 16 323 17 /** -
trunk/src/bp-core/bp-core-theme-compatibility.php
r10497 r10518 25 25 /** Base Class ****************************************************************/ 26 26 27 /** 28 * Theme Compatibility base class. 29 * 30 * This is only intended to be extended, and is included here as a basic guide 31 * for future Theme Packs to use. {@link BP_Legacy} is a good example of 32 * extending this class. 33 * 34 * @since 1.7.0 35 * 36 * @todo We should probably do something similar to BP_Component::start(). 37 * @todo If this is only intended to be extended, it should be abstract. 38 * 39 * @param array $properties { 40 * An array of properties describing the theme compat package. 41 * @type string $id ID of the package. Must be unique. 42 * @type string $name Name of the theme. This should match the name given 43 * in style.css. 44 * @type string $version Theme version. Used for busting script and style 45 * browser caches. 46 * @type string $dir Filesystem path of the theme. 47 * @type string $url Base URL of the theme. 48 * } 49 */ 50 class BP_Theme_Compat { 51 52 /** 53 * Template package properties, as passed to the constructor. 54 * 55 * @since 1.7.0 56 * @var array 57 */ 58 protected $_data = array(); 59 60 /** 61 * Pass the $properties to the object on creation. 62 * 63 * @since 1.7.0 64 * 65 * @param array $properties Array of properties for BP_Theme_Compat. 66 */ 67 public function __construct( Array $properties = array() ) { 68 $this->_data = $properties; 69 } 70 71 /** 72 * Set up the BuddyPress-specific theme compat methods. 73 * 74 * Themes should use this method in their constructor. 75 * 76 * @since 1.7.0 77 */ 78 protected function start() { 79 // Sanity check. 80 if ( ! bp_use_theme_compat_with_current_theme() ) { 81 return; 82 } 83 84 // Setup methods. 85 $this->setup_globals(); 86 $this->setup_actions(); 87 } 88 89 /** 90 * Set up global data for your template package. 91 * 92 * Meant to be overridden in your class. See 93 * {@link BP_Legacy::setup_globals()} for an example. 94 * 95 * @since 1.7.0 96 */ 97 protected function setup_globals() {} 98 99 /** 100 * Set up theme hooks for your template package. 101 * 102 * Meant to be overridden in your class. See 103 * {@link BP_Legacy::setup_actions()} for an example. 104 * 105 * @since 1.7.0 106 */ 107 protected function setup_actions() {} 108 109 /** 110 * Set a theme's property. 111 * 112 * @since 1.7.0 113 * 114 * @param string $property Property name. 115 * @param mixed $value Property value. 116 * @return bool True on success, false on failure. 117 */ 118 public function __set( $property, $value ) { 119 return $this->_data[$property] = $value; 120 } 121 122 /** 123 * Get a theme's property. 124 * 125 * @since 1.7.0 126 * 127 * @param string $property Property name. 128 * @return mixed The value of the property if it exists, otherwise an 129 * empty string. 130 */ 131 public function __get( $property ) { 132 return array_key_exists( $property, $this->_data ) ? $this->_data[$property] : ''; 133 } 134 } 27 require dirname( __FILE__ ) . '/classes/class-bp-core-theme-compat.php'; 135 28 136 29 /** Functions *****************************************************************/ -
trunk/src/bp-core/bp-core-widgets.php
r10497 r10518 11 11 defined( 'ABSPATH' ) || exit; 12 12 13 require dirname( __FILE__ ) . '/classes/class-bp-core-login-widget.php'; 14 13 15 /** 14 16 * Register bp-core widgets. … … 20 22 } 21 23 add_action( 'bp_register_widgets', 'bp_core_register_widgets' ); 22 23 /**24 * BuddyPress Login Widget.25 *26 * @since 1.9.027 */28 class BP_Core_Login_Widget extends WP_Widget {29 30 /**31 * Constructor method.32 *33 * @since 1.9.034 */35 public function __construct() {36 parent::__construct(37 false,38 _x( '(BuddyPress) Log In', 'Title of the login widget', 'buddypress' ),39 array(40 'description' => __( 'Show a Log In form to logged-out visitors, and a Log Out link to those who are logged in.', 'buddypress' ),41 'classname' => 'widget_bp_core_login_widget buddypress widget',42 )43 );44 }45 46 /**47 * Display the login widget.48 *49 * @since 1.9.050 *51 * @see WP_Widget::widget() for description of parameters.52 *53 * @param array $args Widget arguments.54 * @param array $instance Widget settings, as saved by the user.55 */56 public function widget( $args, $instance ) {57 $title = isset( $instance['title'] ) ? $instance['title'] : '';58 59 /**60 * Filters the title of the Login widget.61 *62 * @since 1.9.063 * @since 2.3.0 Added 'instance' and 'id_base' to arguments passed to filter.64 *65 * @param string $title The widget title.66 * @param array $instance The settings for the particular instance of the widget.67 * @param string $id_base Root ID for all widgets of this type.68 */69 $title = apply_filters( 'widget_title', $title, $instance, $this->id_base );70 71 echo $args['before_widget'];72 73 echo $args['before_title'] . esc_html( $title ) . $args['after_title']; ?>74 75 <?php if ( is_user_logged_in() ) : ?>76 77 <?php78 /**79 * Fires before the display of widget content if logged in.80 *81 * @since 1.9.082 */83 do_action( 'bp_before_login_widget_loggedin' ); ?>84 85 <div class="bp-login-widget-user-avatar">86 <a href="<?php echo bp_loggedin_user_domain(); ?>">87 <?php bp_loggedin_user_avatar( 'type=thumb&width=50&height=50' ); ?>88 </a>89 </div>90 91 <div class="bp-login-widget-user-links">92 <div class="bp-login-widget-user-link"><?php echo bp_core_get_userlink( bp_loggedin_user_id() ); ?></div>93 <div class="bp-login-widget-user-logout"><a class="logout" href="<?php echo wp_logout_url( bp_get_requested_url() ); ?>"><?php _e( 'Log Out', 'buddypress' ); ?></a></div>94 </div>95 96 <?php97 98 /**99 * Fires after the display of widget content if logged in.100 *101 * @since 1.9.0102 */103 do_action( 'bp_after_login_widget_loggedin' ); ?>104 105 <?php else : ?>106 107 <?php108 109 /**110 * Fires before the display of widget content if logged out.111 *112 * @since 1.9.0113 */114 do_action( 'bp_before_login_widget_loggedout' ); ?>115 116 <form name="bp-login-form" id="bp-login-widget-form" class="standard-form" action="<?php echo esc_url( site_url( 'wp-login.php', 'login_post' ) ); ?>" method="post">117 <label for="bp-login-widget-user-login"><?php _e( 'Username', 'buddypress' ); ?></label>118 <input type="text" name="log" id="bp-login-widget-user-login" class="input" value="" />119 120 <label for="bp-login-widget-user-pass"><?php _e( 'Password', 'buddypress' ); ?></label>121 <input type="password" name="pwd" id="bp-login-widget-user-pass" class="input" value="" <?php bp_form_field_attributes( 'password' ) ?> />122 123 <div class="forgetmenot"><label for="bp-login-widget-rememberme"><input name="rememberme" type="checkbox" id="bp-login-widget-rememberme" value="forever" /> <?php _e( 'Remember Me', 'buddypress' ); ?></label></div>124 125 <input type="submit" name="wp-submit" id="bp-login-widget-submit" value="<?php esc_attr_e( 'Log In', 'buddypress' ); ?>" />126 127 <?php if ( bp_get_signup_allowed() ) : ?>128 129 <span class="bp-login-widget-register-link"><?php printf( __( '<a href="%s" title="Register for a new account">Register</a>', 'buddypress' ), bp_get_signup_page() ); ?></span>130 131 <?php endif; ?>132 133 <?php134 135 /**136 * Fires inside the display of the login widget form.137 *138 * @since 2.4.0139 */140 do_action( 'bp_login_widget_form' ); ?>141 142 </form>143 144 <?php145 146 /**147 * Fires after the display of widget content if logged out.148 *149 * @since 1.9.0150 */151 do_action( 'bp_after_login_widget_loggedout' ); ?>152 153 <?php endif;154 155 echo $args['after_widget'];156 }157 158 /**159 * Update the login widget options.160 *161 * @since 1.9.0162 *163 * @param array $new_instance The new instance options.164 * @param array $old_instance The old instance options.165 * @return array $instance The parsed options to be saved.166 */167 public function update( $new_instance, $old_instance ) {168 $instance = $old_instance;169 $instance['title'] = isset( $new_instance['title'] ) ? strip_tags( $new_instance['title'] ) : '';170 171 return $instance;172 }173 174 /**175 * Output the login widget options form.176 *177 * @since 1.9.0178 *179 * @param array $instance Settings for this widget.180 * @return void181 */182 public function form( $instance = array() ) {183 184 $settings = wp_parse_args( $instance, array(185 'title' => '',186 ) ); ?>187 188 <p>189 <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'buddypress' ); ?>190 <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $settings['title'] ); ?>" /></label>191 </p>192 193 <?php194 }195 } -
trunk/src/bp-core/classes/class-bp-admin.php
r10515 r10518 994 994 } 995 995 endif; // End class_exists check. 996 997 /**998 * Setup BuddyPress Admin.999 *1000 * @since 1.6.01001 *1002 * @uses BP_Admin1003 */1004 function bp_admin() {1005 buddypress()->admin = new BP_Admin();1006 return;1007 1008 1009 // These are strings we may use to describe maintenance/security releases, where we aim for no new strings.1010 _n_noop( 'Maintenance Release', 'Maintenance Releases', 'buddypress' );1011 _n_noop( 'Security Release', 'Security Releases', 'buddypress' );1012 _n_noop( 'Maintenance and Security Release', 'Maintenance and Security Releases', 'buddypress' );1013 1014 /* translators: 1: WordPress version number. */1015 _n_noop( '<strong>Version %1$s</strong> addressed a security issue.',1016 '<strong>Version %1$s</strong> addressed some security issues.',1017 'buddypress' );1018 1019 /* translators: 1: WordPress version number, 2: plural number of bugs. */1020 _n_noop( '<strong>Version %1$s</strong> addressed %2$s bug.',1021 '<strong>Version %1$s</strong> addressed %2$s bugs.',1022 'buddypress' );1023 1024 /* translators: 1: WordPress version number, 2: plural number of bugs. Singular security issue. */1025 _n_noop( '<strong>Version %1$s</strong> addressed a security issue and fixed %2$s bug.',1026 '<strong>Version %1$s</strong> addressed a security issue and fixed %2$s bugs.',1027 'buddypress' );1028 1029 /* translators: 1: WordPress version number, 2: plural number of bugs. More than one security issue. */1030 _n_noop( '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bug.',1031 '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bugs.',1032 'buddypress' );1033 1034 __( 'For more information, see <a href="%s">the release notes</a>.', 'buddypress' );1035 } -
trunk/src/bp-core/classes/class-bp-core-login-widget.php
r10515 r10518 1 1 <?php 2 2 /** 3 * BuddyPress Core Component Widgets.3 * BuddyPress Core Login Widget. 4 4 * 5 5 * @package BuddyPress 6 6 * @subpackage Core 7 * @since 1. 0.07 * @since 1.9.0 8 8 */ 9 9 10 10 // Exit if accessed directly. 11 11 defined( 'ABSPATH' ) || exit; 12 13 /**14 * Register bp-core widgets.15 *16 * @since 1.0.017 */18 function bp_core_register_widgets() {19 add_action('widgets_init', create_function('', 'return register_widget("BP_Core_Login_Widget");') );20 }21 add_action( 'bp_register_widgets', 'bp_core_register_widgets' );22 12 23 13 /** -
trunk/src/bp-core/classes/class-bp-core-theme-compat.php
r10515 r10518 1 1 <?php 2 2 /** 3 * BuddyPress Core Theme Compatibility .3 * BuddyPress Core Theme Compatibility Base Class. 4 4 * 5 5 * @package BuddyPress … … 10 10 // Exit if accessed directly. 11 11 defined( 'ABSPATH' ) || exit; 12 13 /** Theme Compat **************************************************************/14 15 /**16 * What follows is an attempt at intercepting the natural page load process17 * to replace the_content() with the appropriate BuddyPress content.18 *19 * To do this, BuddyPress does several direct manipulations of global variables20 * and forces them to do what they are not supposed to be doing.21 *22 * Don't try anything you're about to witness here, at home. Ever.23 */24 25 /** Base Class ****************************************************************/26 12 27 13 /** … … 133 119 } 134 120 } 135 136 /** Functions *****************************************************************/137 138 /**139 * Set up the default theme compat theme.140 *141 * @since 1.7.0142 *143 * @param string $theme Optional. The unique ID identifier of a theme package.144 */145 function bp_setup_theme_compat( $theme = '' ) {146 $bp = buddypress();147 148 // Make sure theme package is available, set to default if not.149 if ( ! isset( $bp->theme_compat->packages[$theme] ) || ! is_a( $bp->theme_compat->packages[$theme], 'BP_Theme_Compat' ) ) {150 $theme = 'legacy';151 }152 153 // Set the active theme compat theme.154 $bp->theme_compat->theme = $bp->theme_compat->packages[$theme];155 }156 157 /**158 * Get the ID of the theme package being used.159 *160 * This can be filtered or set manually. Tricky theme authors can override the161 * default and include their own BuddyPress compatibility layers for their themes.162 *163 * @since 1.7.0164 *165 * @uses apply_filters()166 *167 * @return string ID of the theme package in use.168 */169 function bp_get_theme_compat_id() {170 171 /**172 * Filters the ID of the theme package being used.173 *174 * @since 1.7.0175 *176 * @param string $id ID of the theme package in use.177 */178 return apply_filters( 'bp_get_theme_compat_id', buddypress()->theme_compat->theme->id );179 }180 181 /**182 * Get the name of the theme package being used.183 *184 * This can be filtered or set manually. Tricky theme authors can override the185 * default and include their own BuddyPress compatibility layers for their themes.186 *187 * @since 1.7.0188 *189 * @uses apply_filters()190 *191 * @return string Name of the theme package currently in use.192 */193 function bp_get_theme_compat_name() {194 195 /**196 * Filters the name of the theme package being used.197 *198 * @since 1.7.0199 *200 * @param string $name Name of the theme package in use.201 */202 return apply_filters( 'bp_get_theme_compat_name', buddypress()->theme_compat->theme->name );203 }204 205 /**206 * Get the version of the theme package being used.207 *208 * This can be filtered or set manually. Tricky theme authors can override the209 * default and include their own BuddyPress compatibility layers for their themes.210 *211 * @since 1.7.0212 *213 * @uses apply_filters()214 *215 * @return string The version string of the theme package currently in use.216 */217 function bp_get_theme_compat_version() {218 219 /**220 * Filters the version of the theme package being used.221 *222 * @since 1.7.0223 *224 * @param string $version The version string of the theme package in use.225 */226 return apply_filters( 'bp_get_theme_compat_version', buddypress()->theme_compat->theme->version );227 }228 229 /**230 * Get the absolute path of the theme package being used.231 *232 * Or set manually. Tricky theme authors can override the default and include233 * their own BuddyPress compatibility layers for their themes.234 *235 * @since 1.7.0236 *237 * @uses apply_filters()238 *239 * @return string The absolute path of the theme package currently in use.240 */241 function bp_get_theme_compat_dir() {242 243 /**244 * Filters the absolute path of the theme package being used.245 *246 * @since 1.7.0247 *248 * @param string $dir The absolute path of the theme package in use.249 */250 return apply_filters( 'bp_get_theme_compat_dir', buddypress()->theme_compat->theme->dir );251 }252 253 /**254 * Get the URL of the theme package being used.255 *256 * This can be filtered, or set manually. Tricky theme authors can override257 * the default and include their own BuddyPress compatibility layers for their258 * themes.259 *260 * @since 1.7.0261 *262 * @uses apply_filters()263 *264 * @return string URL of the theme package currently in use.265 */266 function bp_get_theme_compat_url() {267 268 /**269 * Filters the URL of the theme package being used.270 *271 * @since 1.7.0272 *273 * @param string $url URL of the theme package in use.274 */275 return apply_filters( 'bp_get_theme_compat_url', buddypress()->theme_compat->theme->url );276 }277 278 /**279 * Should we use theme compat for this theme?280 *281 * If the current theme's need for theme compat hasn't yet been detected, we282 * do so using bp_detect_theme_compat_with_current_theme().283 *284 * @since 1.9.0285 *286 * @uses bp_detect_theme_compat_with_current_theme()287 *288 * @return bool True if the current theme needs theme compatibility.289 */290 function bp_use_theme_compat_with_current_theme() {291 if ( ! isset( buddypress()->theme_compat->use_with_current_theme ) ) {292 bp_detect_theme_compat_with_current_theme();293 }294 295 /**296 * Filters whether or not to use theme compat for the active theme.297 *298 * @since 1.9.0299 *300 * @param bool $use_with_current_theme True if the current theme needs theme compatibility.301 */302 return apply_filters( 'bp_use_theme_compat_with_current_theme', buddypress()->theme_compat->use_with_current_theme );303 }304 305 /**306 * Set our flag to determine whether theme compat should be enabled.307 *308 * Theme compat is disabled when a theme meets one of the following criteria:309 * 1) It declares BP support with add_theme_support( 'buddypress' )310 * 2) It is bp-default, or a child theme of bp-default311 * 3) A legacy template is found at members/members-loop.php. This is a312 * fallback check for themes that were derived from bp-default, and have313 * not been updated for BP 1.7+; we make the assumption that any theme in314 * this category will have the members-loop.php template, and so use its315 * presence as an indicator that theme compatibility is not required316 *317 * @since 1.9.0318 *319 * @return bool True if the current theme needs theme compatibility.320 */321 function bp_detect_theme_compat_with_current_theme() {322 if ( isset( buddypress()->theme_compat->use_with_current_theme ) ) {323 return buddypress()->theme_compat->use_with_current_theme;324 }325 326 // Theme compat enabled by default.327 $theme_compat = true;328 329 // If the theme supports 'buddypress', bail.330 if ( current_theme_supports( 'buddypress' ) ) {331 $theme_compat = false;332 333 // If the theme doesn't support BP, do some additional checks.334 } else {335 // Bail if theme is a derivative of bp-default.336 if ( in_array( 'bp-default', array( get_template(), get_stylesheet() ) ) ) {337 $theme_compat = false;338 339 // Brute-force check for a BP template.340 // Examples are clones of bp-default.341 } elseif ( locate_template( 'members/members-loop.php', false, false ) ) {342 $theme_compat = false;343 }344 }345 346 // Set a flag in the buddypress() singleton so we don't have to run this again.347 buddypress()->theme_compat->use_with_current_theme = $theme_compat;348 349 return $theme_compat;350 }351 352 /**353 * Is the current page using theme compatibility?354 *355 * @since 1.7.0356 *357 * @return bool True if the current page uses theme compatibility.358 */359 function bp_is_theme_compat_active() {360 $bp = buddypress();361 362 if ( empty( $bp->theme_compat->active ) ) {363 return false;364 }365 366 return $bp->theme_compat->active;367 }368 369 /**370 * Set the flag that tells whether the current page is using theme compatibility.371 *372 * @since 1.7.0373 *374 * @param bool $set True to set the flag to true, false to set it to false.375 * @return bool Returns the value of $set.376 */377 function bp_set_theme_compat_active( $set = true ) {378 buddypress()->theme_compat->active = $set;379 380 return (bool) buddypress()->theme_compat->active;381 }382 383 /**384 * Set the theme compat templates global.385 *386 * Stash possible template files for the current query. Useful if plugins want387 * to override them, or see what files are being scanned for inclusion.388 *389 * @since 1.7.0390 *391 * @param array $templates The template stack.392 * @return array The template stack (value of $templates).393 */394 function bp_set_theme_compat_templates( $templates = array() ) {395 buddypress()->theme_compat->templates = $templates;396 397 return buddypress()->theme_compat->templates;398 }399 400 /**401 * Set the theme compat template global.402 *403 * Stash the template file for the current query. Useful if plugins want404 * to override it, or see what file is being included.405 *406 * @since 1.7.0407 *408 * @param string $template The template currently in use.409 * @return string The template currently in use (value of $template).410 */411 function bp_set_theme_compat_template( $template = '' ) {412 buddypress()->theme_compat->template = $template;413 414 return buddypress()->theme_compat->template;415 }416 417 /**418 * Set the theme compat original_template global.419 *420 * Stash the original template file for the current query. Useful for checking421 * if BuddyPress was able to find a more appropriate template.422 *423 * @since 1.7.0424 *425 * @param string $template The template originally selected by WP.426 * @return string The template originally selected by WP (value of $template).427 */428 function bp_set_theme_compat_original_template( $template = '' ) {429 buddypress()->theme_compat->original_template = $template;430 431 return buddypress()->theme_compat->original_template;432 }433 434 /**435 * Set a theme compat feature436 *437 * @since 2.4.0438 *439 * @param string $theme_id The theme id (eg: legacy).440 * @param array $feature An associative array (eg: array( name => 'feature_name', 'settings' => array() )).441 */442 function bp_set_theme_compat_feature( $theme_id, $feature = array() ) {443 if ( empty( $theme_id ) || empty( $feature['name'] ) ) {444 return;445 }446 447 // Get BuddyPress instance.448 $bp = buddypress();449 450 // Get current theme compat theme.451 $theme_compat_theme = $bp->theme_compat->theme;452 453 // Bail if the Theme Compat theme is not in use.454 if ( $theme_id !== bp_get_theme_compat_id() ) {455 return;456 }457 458 $features = $theme_compat_theme->__get( 'features' );459 if ( empty( $features ) ) {460 $features = array();461 }462 463 // Bail if the feature is already registered or no settings were provided.464 if ( isset( $features[ $feature['name'] ] ) || empty( $feature['settings'] ) ) {465 return;466 }467 468 // Add the feature.469 $features[ $feature['name'] ] = (object) $feature['settings'];470 471 // The feature is attached to components.472 if ( isset( $features[ $feature['name'] ]->components ) ) {473 // Set the feature for each concerned component.474 foreach ( (array) $features[ $feature['name'] ]->components as $component ) {475 // The xProfile component is specific.476 if ( 'xprofile' === $component ) {477 $component = 'profile';478 }479 480 if ( isset( $bp->{$component} ) ) {481 if ( isset( $bp->{$component}->features ) ) {482 $bp->{$component}->features[] = $feature['name'];483 } else {484 $bp->{$component}->features = array( $feature['name'] );485 }486 }487 }488 }489 490 // Finally update the theme compat features.491 $theme_compat_theme->__set( 'features', $features );492 }493 494 /**495 * Get a theme compat feature496 *497 * @since 2.4.0498 *499 * @param string $feature The feature (eg: cover_image).500 * @return object The feature settings.501 */502 function bp_get_theme_compat_feature( $feature = '' ) {503 // Get current theme compat theme.504 $theme_compat_theme = buddypress()->theme_compat->theme;505 506 // Get features.507 $features = $theme_compat_theme->__get( 'features' );508 509 if ( ! isset( $features[ $feature ] ) ) {510 return false;511 }512 513 return $features[ $feature ];514 }515 516 /**517 * Setup the theme's features518 *519 * Note: BP Legacy's buddypress-functions.php is not loaded in WP Administration520 * as it's loaded using bp_locate_template(). That's why this function is here.521 *522 * @since 2.4.0523 *524 * @global string $content_width the content width of the theme525 */526 function bp_register_theme_compat_default_features() {527 global $content_width;528 529 // Do not set up default features on deactivation.530 if ( bp_is_deactivation() ) {531 return;532 }533 534 // If the current theme doesn't need theme compat, bail at this point.535 if ( ! bp_use_theme_compat_with_current_theme() ) {536 return;537 }538 539 // Make sure BP Legacy is the Theme Compat in use.540 if ( 'legacy' !== bp_get_theme_compat_id() ) {541 return;542 }543 544 // Get the theme.545 $current_theme = wp_get_theme();546 $theme_handle = $current_theme->get_stylesheet();547 $parent = $current_theme->parent();548 549 if ( $parent ) {550 $theme_handle = $parent->get_stylesheet();551 }552 553 /**554 * Since Companion stylesheets, the $content_width is smaller555 * than the width used by BuddyPress, so we need to manually set the556 * content width for the concerned themes.557 *558 * Example: array( stylesheet => content width used by BuddyPress )559 */560 $bp_content_widths = array(561 'twentyfifteen' => 1300,562 'twentyfourteen' => 955,563 'twentythirteen' => 890,564 );565 566 // Default values.567 $bp_content_width = (int) $content_width;568 $bp_handle = 'bp-legacy-css';569 570 // Specific to themes having companion stylesheets.571 if ( isset( $bp_content_widths[ $theme_handle ] ) ) {572 $bp_content_width = $bp_content_widths[ $theme_handle ];573 $bp_handle = 'bp-' . $theme_handle;574 }575 576 if ( is_rtl() ) {577 $bp_handle .= '-rtl';578 }579 580 $top_offset = 150;581 $avatar_height = apply_filters( 'bp_core_avatar_full_height', $top_offset );582 583 if ( $avatar_height > $top_offset ) {584 $top_offset = $avatar_height;585 }586 587 bp_set_theme_compat_feature( 'legacy', array(588 'name' => 'cover_image',589 'settings' => array(590 'components' => array( 'xprofile', 'groups' ),591 'width' => $bp_content_width,592 'height' => $top_offset + round( $avatar_height / 2 ),593 'callback' => 'bp_legacy_theme_cover_image',594 'theme_handle' => $bp_handle,595 ),596 ) );597 }598 599 /**600 * Check whether a given template is the one that WP originally selected to display current page.601 *602 * @since 1.7.0603 *604 * @param string $template The template name to check.605 * @return bool True if the value of $template is the same as the606 * "original_template" originally selected by WP. Otherwise false.607 */608 function bp_is_theme_compat_original_template( $template = '' ) {609 $bp = buddypress();610 611 if ( empty( $bp->theme_compat->original_template ) ) {612 return false;613 }614 615 return (bool) ( $bp->theme_compat->original_template == $template );616 }617 618 /**619 * Register a new BuddyPress theme package in the active theme packages array.620 *621 * For an example of how this function is used, see:622 * {@link BuddyPress::register_theme_packages()}.623 *624 * @since 1.7.0625 *626 * @see BP_Theme_Compat for a description of the $theme parameter arguments.627 *628 * @param array $theme See {@link BP_Theme_Compat}.629 * @param bool $override If true, overrides whatever package is currently set.630 * Default: true.631 */632 function bp_register_theme_package( $theme = array(), $override = true ) {633 634 // Create new BP_Theme_Compat object from the $theme array.635 if ( is_array( $theme ) ) {636 $theme = new BP_Theme_Compat( $theme );637 }638 639 // Bail if $theme isn't a proper object.640 if ( ! is_a( $theme, 'BP_Theme_Compat' ) ) {641 return;642 }643 644 // Load up BuddyPress.645 $bp = buddypress();646 647 // Only set if the theme package was not previously registered or if the648 // override flag is set.649 if ( empty( $bp->theme_compat->packages[$theme->id] ) || ( true === $override ) ) {650 $bp->theme_compat->packages[$theme->id] = $theme;651 }652 }653 654 /**655 * Populate various WordPress globals with dummy data to prevent errors.656 *657 * This dummy data is necessary because theme compatibility essentially fakes658 * WordPress into thinking that there is content where, in fact, there is none659 * (at least, no WordPress post content). By providing dummy data, we ensure660 * that template functions - things like is_page() - don't throw errors.661 *662 * @since 1.7.0663 *664 * @global WP_Query $wp_query WordPress database access object.665 * @global object $post Current post object.666 *667 * @param array $args Array of optional arguments. Arguments parallel the properties668 * of {@link WP_Post}; see that class for more details.669 */670 function bp_theme_compat_reset_post( $args = array() ) {671 global $wp_query, $post;672 673 // Switch defaults if post is set.674 if ( isset( $wp_query->post ) ) {675 $dummy = wp_parse_args( $args, array(676 'ID' => $wp_query->post->ID,677 'post_status' => $wp_query->post->post_status,678 'post_author' => $wp_query->post->post_author,679 'post_parent' => $wp_query->post->post_parent,680 'post_type' => $wp_query->post->post_type,681 'post_date' => $wp_query->post->post_date,682 'post_date_gmt' => $wp_query->post->post_date_gmt,683 'post_modified' => $wp_query->post->post_modified,684 'post_modified_gmt' => $wp_query->post->post_modified_gmt,685 'post_content' => $wp_query->post->post_content,686 'post_title' => $wp_query->post->post_title,687 'post_excerpt' => $wp_query->post->post_excerpt,688 'post_content_filtered' => $wp_query->post->post_content_filtered,689 'post_mime_type' => $wp_query->post->post_mime_type,690 'post_password' => $wp_query->post->post_password,691 'post_name' => $wp_query->post->post_name,692 'guid' => $wp_query->post->guid,693 'menu_order' => $wp_query->post->menu_order,694 'pinged' => $wp_query->post->pinged,695 'to_ping' => $wp_query->post->to_ping,696 'ping_status' => $wp_query->post->ping_status,697 'comment_status' => $wp_query->post->comment_status,698 'comment_count' => $wp_query->post->comment_count,699 'filter' => $wp_query->post->filter,700 701 'is_404' => false,702 'is_page' => false,703 'is_single' => false,704 'is_archive' => false,705 'is_tax' => false,706 ) );707 } else {708 $dummy = wp_parse_args( $args, array(709 'ID' => -9999,710 'post_status' => 'public',711 'post_author' => 0,712 'post_parent' => 0,713 'post_type' => 'page',714 'post_date' => 0,715 'post_date_gmt' => 0,716 'post_modified' => 0,717 'post_modified_gmt' => 0,718 'post_content' => '',719 'post_title' => '',720 'post_excerpt' => '',721 'post_content_filtered' => '',722 'post_mime_type' => '',723 'post_password' => '',724 'post_name' => '',725 'guid' => '',726 'menu_order' => 0,727 'pinged' => '',728 'to_ping' => '',729 'ping_status' => '',730 'comment_status' => 'closed',731 'comment_count' => 0,732 'filter' => 'raw',733 734 'is_404' => false,735 'is_page' => false,736 'is_single' => false,737 'is_archive' => false,738 'is_tax' => false,739 ) );740 }741 742 // Bail if dummy post is empty.743 if ( empty( $dummy ) ) {744 return;745 }746 747 // Set the $post global.748 $post = new WP_Post( (object) $dummy );749 750 // Copy the new post global into the main $wp_query.751 $wp_query->post = $post;752 $wp_query->posts = array( $post );753 754 // Prevent comments form from appearing.755 $wp_query->post_count = 1;756 $wp_query->is_404 = $dummy['is_404'];757 $wp_query->is_page = $dummy['is_page'];758 $wp_query->is_single = $dummy['is_single'];759 $wp_query->is_archive = $dummy['is_archive'];760 $wp_query->is_tax = $dummy['is_tax'];761 762 // Clean up the dummy post.763 unset( $dummy );764 765 /**766 * Force the header back to 200 status if not a deliberate 404767 *768 * @see https://bbpress.trac.wordpress.org/ticket/1973769 */770 if ( ! $wp_query->is_404() ) {771 status_header( 200 );772 }773 774 // If we are resetting a post, we are in theme compat.775 bp_set_theme_compat_active( true );776 777 // If we are in theme compat, we don't need the 'Edit' post link.778 add_filter( 'get_edit_post_link', 'bp_core_filter_edit_post_link', 10, 2 );779 }780 781 /**782 * Reset main query vars and filter 'the_content' to output a BuddyPress template part as needed.783 *784 * @since 1.7.0785 *786 * @uses bp_is_single_user() To check if page is single user.787 * @uses bp_get_single_user_template() To get user template.788 * @uses bp_is_single_user_edit() To check if page is single user edit.789 * @uses bp_get_single_user_edit_template() To get user edit template.790 * @uses bp_is_single_view() To check if page is single view.791 * @uses bp_get_single_view_template() To get view template.792 * @uses bp_is_forum_edit() To check if page is forum edit.793 * @uses bp_get_forum_edit_template() To get forum edit template.794 * @uses bp_is_topic_merge() To check if page is topic merge.795 * @uses bp_get_topic_merge_template() To get topic merge template.796 * @uses bp_is_topic_split() To check if page is topic split.797 * @uses bp_get_topic_split_template() To get topic split template.798 * @uses bp_is_topic_edit() To check if page is topic edit.799 * @uses bp_get_topic_edit_template() To get topic edit template.800 * @uses bp_is_reply_edit() To check if page is reply edit.801 * @uses bp_get_reply_edit_template() To get reply edit template.802 * @uses bp_set_theme_compat_template() To set the global theme compat template.803 *804 * @param string $template Template name.805 * @return string $template Template name.806 */807 function bp_template_include_theme_compat( $template = '' ) {808 809 // If the current theme doesn't need theme compat, bail at this point.810 if ( ! bp_use_theme_compat_with_current_theme() ) {811 return $template;812 }813 814 /**815 * Fires when resetting main query vars and filtering 'the_content' to output BuddyPress template parts.816 *817 * Use this action to execute code that will communicate to BuddyPress's818 * theme compatibility layer whether or not we're replacing the_content()819 * with some other template part.820 *821 * @since 1.7.0822 */823 do_action( 'bp_template_include_reset_dummy_post_data' );824 825 // Bail if the template already matches a BuddyPress template.826 if ( ! empty( buddypress()->theme_compat->found_template ) ) {827 return $template;828 }829 830 /**831 * If we are relying on BuddyPress's built in theme compatibility to load832 * the proper content, we need to intercept the_content, replace the833 * output, and display ours instead.834 *835 * To do this, we first remove all filters from 'the_content' and hook836 * our own function into it, which runs a series of checks to determine837 * the context, and then uses the built in shortcodes to output the838 * correct results from inside an output buffer.839 *840 * Uses bp_get_theme_compat_templates() to provide fall-backs that841 * should be coded without superfluous mark-up and logic (prev/next842 * navigation, comments, date/time, etc...)843 *844 * Hook into 'bp_get_buddypress_template' to override the array of845 * possible templates, or 'bp_buddypress_template' to override the result.846 */847 if ( bp_is_theme_compat_active() ) {848 $template = bp_get_theme_compat_templates();849 850 add_filter( 'the_content', 'bp_replace_the_content' );851 852 // Add BuddyPress's head action to wp_head.853 if ( ! has_action( 'wp_head', 'bp_head' ) ) {854 add_action( 'wp_head', 'bp_head' );855 }856 }857 858 /**859 * Filters the template name to include.860 *861 * @since 1.7.0862 *863 * @param string $template Template name.864 */865 return apply_filters( 'bp_template_include_theme_compat', $template );866 }867 868 /**869 * Conditionally replace 'the_content'.870 *871 * Replaces the_content() if the post_type being displayed is one that would872 * normally be handled by BuddyPress, but proper single page templates do not873 * exist in the currently active theme.874 *875 * @since 1.7.0876 *877 * @param string $content Original post content.878 * @return string $content Post content, potentially modified.879 */880 function bp_replace_the_content( $content = '' ) {881 882 // Bail if not the main loop where theme compat is happening.883 if ( ! bp_do_theme_compat() ) {884 return $content;885 }886 887 // Set theme compat to false early, to avoid recursion from nested calls to888 // the_content() that execute before theme compat has unhooked itself.889 bp_set_theme_compat_active( false );890 891 /**892 * Filters the content to replace in the post.893 *894 * @since 1.7.0895 *896 * @param string $content Original post content.897 */898 $new_content = apply_filters( 'bp_replace_the_content', $content );899 900 // Juggle the content around and try to prevent unsightly comments.901 if ( ! empty( $new_content ) && ( $new_content !== $content ) ) {902 903 // Set the content to be the new content.904 $content = $new_content;905 906 // Clean up after ourselves.907 unset( $new_content );908 909 // Reset the $post global.910 wp_reset_postdata();911 }912 913 // Return possibly hi-jacked content.914 return $content;915 }916 917 /**918 * Are we currently replacing the_content?919 *920 * @since 1.8.0921 *922 * @return bool True if the_content is currently in the process of being923 * filtered and replaced.924 */925 function bp_do_theme_compat() {926 return (bool) ( ! bp_is_template_included() && in_the_loop() && bp_is_theme_compat_active() );927 }928 929 /** Filters *******************************************************************/930 931 /**932 * Remove all filters from a WordPress filter hook.933 *934 * Removed filters are stashed in the $bp global, in case they need to be935 * restored later.936 *937 * @since 1.7.0938 *939 * @global WP_filter $wp_filter940 * @global array $merged_filters941 *942 * @param string $tag The filter tag to remove filters from.943 * @param int|bool $priority Optional. If present, only those callbacks attached944 * at a given priority will be removed. Otherwise, all callbacks945 * attached to the tag will be removed, regardless of priority.946 * @return bool True on success.947 */948 function bp_remove_all_filters( $tag, $priority = false ) {949 global $wp_filter, $merged_filters;950 951 $bp = buddypress();952 953 // Filters exist.954 if ( isset( $wp_filter[$tag] ) ) {955 956 // Filters exist in this priority.957 if ( ! empty( $priority ) && isset( $wp_filter[$tag][$priority] ) ) {958 959 // Store filters in a backup.960 $bp->filters->wp_filter[$tag][$priority] = $wp_filter[$tag][$priority];961 962 // Unset the filters.963 unset( $wp_filter[$tag][$priority] );964 965 // Priority is empty.966 } else {967 968 // Store filters in a backup.969 $bp->filters->wp_filter[$tag] = $wp_filter[$tag];970 971 // Unset the filters.972 unset( $wp_filter[$tag] );973 }974 }975 976 // Check merged filters.977 if ( isset( $merged_filters[$tag] ) ) {978 979 // Store filters in a backup.980 $bp->filters->merged_filters[$tag] = $merged_filters[$tag];981 982 // Unset the filters.983 unset( $merged_filters[$tag] );984 }985 986 return true;987 }988 989 /**990 * Restore filters that were removed using bp_remove_all_filters().991 *992 * @since 1.7.0993 *994 * @global WP_filter $wp_filter995 * @global array $merged_filters996 *997 * @param string $tag The tag to which filters should be restored.998 * @param int|bool $priority Optional. If present, only those filters that were originally999 * attached to the tag with $priority will be restored. Otherwise,1000 * all available filters will be restored, regardless of priority.1001 * @return bool True on success.1002 */1003 function bp_restore_all_filters( $tag, $priority = false ) {1004 global $wp_filter, $merged_filters;1005 1006 $bp = buddypress();1007 1008 // Filters exist.1009 if ( isset( $bp->filters->wp_filter[$tag] ) ) {1010 1011 // Filters exist in this priority.1012 if ( ! empty( $priority ) && isset( $bp->filters->wp_filter[$tag][$priority] ) ) {1013 1014 // Store filters in a backup.1015 $wp_filter[$tag][$priority] = $bp->filters->wp_filter[$tag][$priority];1016 1017 // Unset the filters.1018 unset( $bp->filters->wp_filter[$tag][$priority] );1019 1020 // Priority is empty.1021 } else {1022 1023 // Store filters in a backup.1024 $wp_filter[$tag] = $bp->filters->wp_filter[$tag];1025 1026 // Unset the filters.1027 unset( $bp->filters->wp_filter[$tag] );1028 }1029 }1030 1031 // Check merged filters.1032 if ( isset( $bp->filters->merged_filters[$tag] ) ) {1033 1034 // Store filters in a backup.1035 $merged_filters[$tag] = $bp->filters->merged_filters[$tag];1036 1037 // Unset the filters.1038 unset( $bp->filters->merged_filters[$tag] );1039 }1040 1041 return true;1042 }1043 1044 /**1045 * Force comments_status to 'closed' for BuddyPress post types.1046 *1047 * @since 1.7.01048 *1049 * @param bool $open True if open, false if closed.1050 * @param int $post_id ID of the post to check.1051 * @return bool True if open, false if closed.1052 */1053 function bp_comments_open( $open, $post_id = 0 ) {1054 1055 $retval = is_buddypress() ? false : $open;1056 1057 /**1058 * Filters whether or not to force comments_status to closed for BuddyPress post types.1059 *1060 * @since 1.7.01061 *1062 * @param bool $retval Whether or not we are on a BuddyPress post type.1063 * @param bool $open True if comments open, false if closed.1064 * @param int $post_id Post ID for the checked post.1065 */1066 return apply_filters( 'bp_force_comment_status', $retval, $open, $post_id );1067 }1068 1069 /**1070 * Do not allow {@link comments_template()} to render during theme compatibility.1071 *1072 * When theme compatibility sets the 'is_page' flag to true via1073 * {@link bp_theme_compat_reset_post()}, themes that use comments_template()1074 * in their page template will run.1075 *1076 * To prevent comments_template() from rendering, we set the 'is_page' and1077 * 'is_single' flags to false since that function looks at these conditionals1078 * before querying the database for comments and loading the comments template.1079 *1080 * This is done during the output buffer as late as possible to prevent any1081 * wonkiness.1082 *1083 * @since 1.9.21084 *1085 * @param string $retval The current post content.1086 * @return string $retval1087 */1088 function bp_theme_compat_toggle_is_page( $retval = '' ) {1089 global $wp_query;1090 1091 $wp_query->is_page = false;1092 1093 // Set a switch so we know that we've toggled these WP_Query properties.1094 buddypress()->theme_compat->is_page_toggled = true;1095 1096 return $retval;1097 }1098 add_filter( 'bp_replace_the_content', 'bp_theme_compat_toggle_is_page', 9999 );1099 1100 /**1101 * Restores the 'is_single' and 'is_page' flags if toggled by BuddyPress.1102 *1103 * @since 1.9.21104 *1105 * @see bp_theme_compat_toggle_is_page()1106 * @param object $query The WP_Query object.1107 */1108 function bp_theme_compat_loop_end( $query ) {1109 1110 // Get BuddyPress.1111 $bp = buddypress();1112 1113 // Bail if page is not toggled.1114 if ( ! isset( $bp->theme_compat->is_page_toggled ) ) {1115 return;1116 }1117 1118 // Revert our toggled WP_Query properties.1119 $query->is_page = true;1120 1121 // Unset our switch.1122 unset( $bp->theme_compat->is_page_toggled );1123 }1124 add_action( 'loop_end', 'bp_theme_compat_loop_end' ); -
trunk/src/bp-core/classes/class-bp-core.php
r10515 r10518 320 320 } 321 321 } 322 323 /**324 * Set up the BuddyPress Core component.325 *326 * @since 1.6.0327 *328 * @global BuddyPress $bp BuddyPress global settings object.329 */330 function bp_setup_core() {331 buddypress()->core = new BP_Core();332 }333 add_action( 'bp_loaded', 'bp_setup_core', 0 );
Note: See TracChangeset
for help on using the changeset viewer.