Skip to:
Content

BuddyPress.org

Changeset 10518


Ignore:
Timestamp:
02/05/2016 04:26:30 AM (5 years ago)
Author:
boonebgorges
Message:

Move bp-core classes to their own files.

See #6870.

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  
    1111defined( 'ABSPATH' ) || exit;
    1212
    13 require dirname( __FILE__ ) . '/classes/bp-walker-category-checklist.php';
     13require dirname( dirname( __FILE__ ) ) . '/classes/bp-walker-category-checklist.php';
  • trunk/src/bp-core/bp-core-admin.php

    r10497 r10518  
    1111defined( 'ABSPATH' ) || exit;
    1212
    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 &amp; 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&#8217;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 &rarr;</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 &rarr;', '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> &bullet; <a href="https://buddypress.org/support/"><?php _ex( 'Support', 'About screen, link to support site', 'buddypress' ); ?></a> &bullet; <a href="https://codex.buddypress.org/"><?php _ex( 'Documentation', 'About screen, link to documentation', 'buddypress' ); ?></a> &bullet; <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> &bullet; <a href="https://twitter.com/bptrac/"><?php _ex( 'Trac', '@bptrac twitter account name', 'buddypress' ); ?></a> &bullet; <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( '&#x1f31f;Recent Rockstars&#x1f31f;', '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( '&#x1f496;With our thanks to these Open Source projects&#x1f496;', '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&#8217;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&#8217;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.
     13require dirname( __FILE__ ) . '/classes/class-bp-admin.php';
    99614
    99715/**
  • trunk/src/bp-core/bp-core-component.php

    r10497 r10518  
    1111defined( 'ABSPATH' ) || exit;
    1212
    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.
     13require dirname( __FILE__ ) . '/classes/class-bp-core-component.php';
  • trunk/src/bp-core/bp-core-loader.php

    r10497 r10518  
    1313defined( 'ABSPATH' ) || exit;
    1414
    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 }
     15require dirname( __FILE__ ) . '/classes/class-bp-core.php';
    32216
    32317/**
  • trunk/src/bp-core/bp-core-theme-compatibility.php

    r10497 r10518  
    2525/** Base Class ****************************************************************/
    2626
    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 }
     27require dirname( __FILE__ ) . '/classes/class-bp-core-theme-compat.php';
    13528
    13629/** Functions *****************************************************************/
  • trunk/src/bp-core/bp-core-widgets.php

    r10497 r10518  
    1111defined( 'ABSPATH' ) || exit;
    1212
     13require dirname( __FILE__ ) . '/classes/class-bp-core-login-widget.php';
     14
    1315/**
    1416 * Register bp-core widgets.
     
    2022}
    2123add_action( 'bp_register_widgets', 'bp_core_register_widgets' );
    22 
    23 /**
    24  * BuddyPress Login Widget.
    25  *
    26  * @since 1.9.0
    27  */
    28 class BP_Core_Login_Widget extends WP_Widget {
    29 
    30     /**
    31      * Constructor method.
    32      *
    33      * @since 1.9.0
    34      */
    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.0
    50      *
    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.0
    63          * @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             <?php
    78             /**
    79              * Fires before the display of widget content if logged in.
    80              *
    81              * @since 1.9.0
    82              */
    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             <?php
    97 
    98             /**
    99              * Fires after the display of widget content if logged in.
    100              *
    101              * @since 1.9.0
    102              */
    103             do_action( 'bp_after_login_widget_loggedin' ); ?>
    104 
    105         <?php else : ?>
    106 
    107             <?php
    108 
    109             /**
    110              * Fires before the display of widget content if logged out.
    111              *
    112              * @since 1.9.0
    113              */
    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                 <?php
    134 
    135                 /**
    136                  * Fires inside the display of the login widget form.
    137                  *
    138                  * @since 2.4.0
    139                  */
    140                 do_action( 'bp_login_widget_form' ); ?>
    141 
    142             </form>
    143 
    144             <?php
    145 
    146             /**
    147              * Fires after the display of widget content if logged out.
    148              *
    149              * @since 1.9.0
    150              */
    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.0
    162      *
    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.0
    178      *
    179      * @param array $instance Settings for this widget.
    180      * @return void
    181      */
    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         <?php
    194     }
    195 }
  • trunk/src/bp-core/classes/class-bp-admin.php

    r10515 r10518  
    994994}
    995995endif; // End class_exists check.
    996 
    997 /**
    998  * Setup BuddyPress Admin.
    999  *
    1000  * @since 1.6.0
    1001  *
    1002  * @uses BP_Admin
    1003  */
    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  
    11<?php
    22/**
    3  * BuddyPress Core Component Widgets.
     3 * BuddyPress Core Login Widget.
    44 *
    55 * @package BuddyPress
    66 * @subpackage Core
    7  * @since 1.0.0
     7 * @since 1.9.0
    88 */
    99
    1010// Exit if accessed directly.
    1111defined( 'ABSPATH' ) || exit;
    12 
    13 /**
    14  * Register bp-core widgets.
    15  *
    16  * @since 1.0.0
    17  */
    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' );
    2212
    2313/**
  • trunk/src/bp-core/classes/class-bp-core-theme-compat.php

    r10515 r10518  
    11<?php
    22/**
    3  * BuddyPress Core Theme Compatibility.
     3 * BuddyPress Core Theme Compatibility Base Class.
    44 *
    55 * @package BuddyPress
     
    1010// Exit if accessed directly.
    1111defined( 'ABSPATH' ) || exit;
    12 
    13 /** Theme Compat **************************************************************/
    14 
    15 /**
    16  * What follows is an attempt at intercepting the natural page load process
    17  * to replace the_content() with the appropriate BuddyPress content.
    18  *
    19  * To do this, BuddyPress does several direct manipulations of global variables
    20  * 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 ****************************************************************/
    2612
    2713/**
     
    133119    }
    134120}
    135 
    136 /** Functions *****************************************************************/
    137 
    138 /**
    139  * Set up the default theme compat theme.
    140  *
    141  * @since 1.7.0
    142  *
    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 the
    161  * default and include their own BuddyPress compatibility layers for their themes.
    162  *
    163  * @since 1.7.0
    164  *
    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.0
    175      *
    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 the
    185  * default and include their own BuddyPress compatibility layers for their themes.
    186  *
    187  * @since 1.7.0
    188  *
    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.0
    199      *
    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 the
    209  * default and include their own BuddyPress compatibility layers for their themes.
    210  *
    211  * @since 1.7.0
    212  *
    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.0
    223      *
    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 include
    233  * their own BuddyPress compatibility layers for their themes.
    234  *
    235  * @since 1.7.0
    236  *
    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.0
    247      *
    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 override
    257  * the default and include their own BuddyPress compatibility layers for their
    258  * themes.
    259  *
    260  * @since 1.7.0
    261  *
    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.0
    272      *
    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, we
    282  * do so using bp_detect_theme_compat_with_current_theme().
    283  *
    284  * @since 1.9.0
    285  *
    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.0
    299      *
    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-default
    311  * 3) A legacy template is found at members/members-loop.php. This is a
    312  *    fallback check for themes that were derived from bp-default, and have
    313  *    not been updated for BP 1.7+; we make the assumption that any theme in
    314  *    this category will have the members-loop.php template, and so use its
    315  *    presence as an indicator that theme compatibility is not required
    316  *
    317  * @since 1.9.0
    318  *
    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.0
    356  *
    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.0
    373  *
    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 want
    387  * to override them, or see what files are being scanned for inclusion.
    388  *
    389  * @since 1.7.0
    390  *
    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 want
    404  * to override it, or see what file is being included.
    405  *
    406  * @since 1.7.0
    407  *
    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 checking
    421  * if BuddyPress was able to find a more appropriate template.
    422  *
    423  * @since 1.7.0
    424  *
    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 feature
    436  *
    437  * @since 2.4.0
    438  *
    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 feature
    496  *
    497  * @since 2.4.0
    498  *
    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 features
    518  *
    519  * Note: BP Legacy's buddypress-functions.php is not loaded in WP Administration
    520  * as it's loaded using bp_locate_template(). That's why this function is here.
    521  *
    522  * @since 2.4.0
    523  *
    524  * @global string $content_width the content width of the theme
    525  */
    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 smaller
    555      * than the width used by BuddyPress, so we need to manually set the
    556      * 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.0
    603  *
    604  * @param string $template The template name to check.
    605  * @return bool True if the value of $template is the same as the
    606  *              "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.0
    625  *
    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 the
    648     // 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 fakes
    658  * WordPress into thinking that there is content where, in fact, there is none
    659  * (at least, no WordPress post content). By providing dummy data, we ensure
    660  * that template functions - things like is_page() - don't throw errors.
    661  *
    662  * @since 1.7.0
    663  *
    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 properties
    668  *                    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 404
    767      *
    768      * @see https://bbpress.trac.wordpress.org/ticket/1973
    769      */
    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.0
    785  *
    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's
    818      * theme compatibility layer whether or not we're replacing the_content()
    819      * with some other template part.
    820      *
    821      * @since 1.7.0
    822      */
    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 load
    832      * the proper content, we need to intercept the_content, replace the
    833      * output, and display ours instead.
    834      *
    835      * To do this, we first remove all filters from 'the_content' and hook
    836      * our own function into it, which runs a series of checks to determine
    837      * the context, and then uses the built in shortcodes to output the
    838      * correct results from inside an output buffer.
    839      *
    840      * Uses bp_get_theme_compat_templates() to provide fall-backs that
    841      * should be coded without superfluous mark-up and logic (prev/next
    842      * navigation, comments, date/time, etc...)
    843      *
    844      * Hook into 'bp_get_buddypress_template' to override the array of
    845      * 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.0
    862      *
    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 would
    872  * normally be handled by BuddyPress, but proper single page templates do not
    873  * exist in the currently active theme.
    874  *
    875  * @since 1.7.0
    876  *
    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 to
    888     // 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.0
    895      *
    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.0
    921  *
    922  * @return bool True if the_content is currently in the process of being
    923  *              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 be
    935  * restored later.
    936  *
    937  * @since 1.7.0
    938  *
    939  * @global WP_filter $wp_filter
    940  * @global array $merged_filters
    941  *
    942  * @param string   $tag      The filter tag to remove filters from.
    943  * @param int|bool $priority Optional. If present, only those callbacks attached
    944  *                           at a given priority will be removed. Otherwise, all callbacks
    945  *                           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.0
    993  *
    994  * @global WP_filter $wp_filter
    995  * @global array $merged_filters
    996  *
    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 originally
    999  *                           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.0
    1048  *
    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.0
    1061      *
    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 via
    1073  * {@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' and
    1077  * 'is_single' flags to false since that function looks at these conditionals
    1078  * 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 any
    1081  * wonkiness.
    1082  *
    1083  * @since 1.9.2
    1084  *
    1085  * @param string $retval The current post content.
    1086  * @return string $retval
    1087  */
    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.2
    1104  *
    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  
    320320    }
    321321}
    322 
    323 /**
    324  * Set up the BuddyPress Core component.
    325  *
    326  * @since 1.6.0
    327  *
    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.