[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/admin/ -> bp-core-admin-functions.php (source)

   1  <?php
   2  /**
   3   * BuddyPress Common Admin Functions.
   4   *
   5   * @package BuddyPress
   6   * @subpackage CoreAdministration
   7   * @since 2.3.0
   8   */
   9  
  10  // Exit if accessed directly.
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  /** Menu **********************************************************************/
  14  
  15  /**
  16   * Initializes the wp-admin area "BuddyPress" menus and sub menus.
  17   */
  18  function bp_core_admin_menu_init() {
  19      add_action( bp_core_admin_hook(), 'bp_core_add_admin_menu', 9 );
  20  }
  21  
  22  /**
  23   * In BP 1.6, the top-level admin menu was removed. For backpat, this function
  24   * keeps the top-level menu if a plugin has registered a menu into the old
  25   * 'bp-general-settings' menu.
  26   *
  27   * The old "bp-general-settings" page was renamed "bp-components".
  28   *
  29   * @global array $_parent_pages
  30   * @global array $_registered_pages
  31   * @global array $submenu
  32   *
  33   * @since 1.6.0
  34   */
  35  function bp_core_admin_backpat_menu() {
  36      global $_parent_pages, $_registered_pages, $submenu;
  37  
  38      // If there's no bp-general-settings menu (perhaps because the current
  39      // user is not an Administrator), there's nothing to do here.
  40      if ( ! isset( $submenu['bp-general-settings'] ) ) {
  41          return;
  42      }
  43  
  44      /**
  45       * By default, only the core "Help" submenu is added under the top-level BuddyPress menu.
  46       * This means that if no third-party plugins have registered their admin pages into the
  47       * 'bp-general-settings' menu, it will only contain one item. Kill it.
  48       */
  49      if ( 1 != count( $submenu['bp-general-settings'] ) ) {
  50          return;
  51      }
  52  
  53      // This removes the top-level menu.
  54      remove_submenu_page( 'bp-general-settings', 'bp-general-settings' );
  55      remove_menu_page( 'bp-general-settings' );
  56  
  57      // These stop people accessing the URL directly.
  58      unset( $_parent_pages['bp-general-settings'] );
  59      unset( $_registered_pages['toplevel_page_bp-general-settings'] );
  60  }
  61  add_action( bp_core_admin_hook(), 'bp_core_admin_backpat_menu', 999 );
  62  
  63  /**
  64   * This tells WP to highlight the Settings > BuddyPress menu item,
  65   * regardless of which actual BuddyPress admin screen we are on.
  66   *
  67   * The conditional prevents the behavior when the user is viewing the
  68   * backpat "Help" page, the Activity page, or any third-party plugins.
  69   *
  70   * @global string $plugin_page
  71   * @global array $submenu
  72   *
  73   * @since 1.6.0
  74   */
  75  function bp_core_modify_admin_menu_highlight() {
  76      global $plugin_page, $submenu_file;
  77  
  78      // This tweaks the Settings subnav menu to show only one BuddyPress menu item.
  79      if ( ! in_array( $plugin_page, array( 'bp-activity', 'bp-general-settings' ) ) ) {
  80          $submenu_file = 'bp-components';
  81      }
  82  
  83      // Network Admin > Tools.
  84      if ( in_array( $plugin_page, array( 'bp-tools', 'available-tools' ) ) ) {
  85          $submenu_file = $plugin_page;
  86      }
  87  }
  88  
  89  /**
  90   * Generates markup for a fallback top-level BuddyPress menu page, if the site is running
  91   * a legacy plugin which hasn't been updated. If the site is up to date, this page
  92   * will never appear.
  93   *
  94   * @see bp_core_admin_backpat_menu()
  95   *
  96   * @since 1.6.0
  97   *
  98   * @todo Add convenience links into the markup once new positions are finalized.
  99   */
 100  function bp_core_admin_backpat_page() {
 101      $url          = bp_core_do_network_admin() ? network_admin_url( 'settings.php' ) : admin_url( 'options-general.php' );
 102      $settings_url = add_query_arg( 'page', 'bp-components', $url ); ?>
 103  
 104      <div class="wrap">
 105          <h2><?php _e( 'Why have all my BuddyPress menus disappeared?', 'buddypress' ); ?></h2>
 106  
 107          <p><?php _e( "Don't worry! We've moved the BuddyPress options into more convenient and easier to find locations. You're seeing this page because you are running a legacy BuddyPress plugin which has not been updated.", 'buddypress' ); ?></p>
 108          <p>
 109              <?php
 110              printf(
 111                  // Translators: 1: is the url to the BP Components settings screen. 2: is the url to the xProfile administration screen.
 112                  __( 'Components, Pages, Settings, and Forums, have been moved to <a href="%1$s">Settings &gt; BuddyPress</a>. Profile Fields has been moved into the <a href="%2$s">Users</a> menu.', 'buddypress' ),
 113                  esc_url( $settings_url ),
 114                  bp_get_admin_url( 'users.php?page=bp-profile-setup' )
 115              );
 116              ?>
 117          </p>
 118      </div>
 119  
 120      <?php
 121  }
 122  
 123  /** Notices *******************************************************************/
 124  
 125  /**
 126   * Print admin messages to admin_notices or network_admin_notices.
 127   *
 128   * BuddyPress combines all its messages into a single notice, to avoid a preponderance of yellow
 129   * boxes.
 130   *
 131   * @since 1.5.0
 132   */
 133  function bp_core_print_admin_notices() {
 134  
 135      // Only the super admin should see messages.
 136      if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 137          return;
 138      }
 139  
 140      // On multisite installs, don't show on a non-root blog, unless
 141      // 'do_network_admin' is overridden.
 142      if ( is_multisite() && bp_core_do_network_admin() && ! bp_is_root_blog() ) {
 143          return;
 144      }
 145  
 146      $notice_types = array();
 147      foreach ( buddypress()->admin->notices as $notice ) {
 148          $notice_types[] = $notice['type'];
 149      }
 150      $notice_types = array_unique( $notice_types );
 151  
 152      foreach ( $notice_types as $type ) {
 153          $notices = wp_list_filter( buddypress()->admin->notices, array( 'type' => $type ) );
 154          printf( '<div id="message" class="fade %s notice is-dismissible">', sanitize_html_class( $type ) );
 155  
 156          foreach ( $notices as $notice ) {
 157              printf( '<p>%s</p>', $notice['message'] );
 158          }
 159  
 160          printf( '</div>' );
 161      }
 162  }
 163  add_action( 'admin_notices', 'bp_core_print_admin_notices' );
 164  add_action( 'network_admin_notices', 'bp_core_print_admin_notices' );
 165  
 166  /**
 167   * Add an admin notice to the BP queue.
 168   *
 169   * Messages added with this function are displayed in BuddyPress's general purpose admin notices
 170   * box. It is recommended that you hook this function to admin_init, so that your messages are
 171   * loaded in time.
 172   *
 173   * @since 1.5.0
 174   *
 175   * @param string $notice The notice you are adding to the queue.
 176   * @param string $type   The notice type; optional. Usually either "updated" or "error".
 177   */
 178  function bp_core_add_admin_notice( $notice = '', $type = 'updated' ) {
 179  
 180      // Do not add if the notice is empty.
 181      if ( empty( $notice ) ) {
 182          return;
 183      }
 184  
 185      // Double check the object before referencing it.
 186      if ( ! isset( buddypress()->admin->notices ) ) {
 187          buddypress()->admin->notices = array();
 188      }
 189  
 190      // Add the notice.
 191      buddypress()->admin->notices[] = array(
 192          'message' => $notice,
 193          'type'    => $type,
 194      );
 195  }
 196  
 197  /**
 198   * Verify that some BP prerequisites are set up properly, and notify the admin if not.
 199   *
 200   * On every Dashboard page, this function checks the following:
 201   *   - that pretty permalinks are enabled.
 202   *   - that every BP component that needs a WP page for a directory has one.
 203   *   - that no WP page has multiple BP components associated with it.
 204   * The administrator will be shown a notice for each check that fails.
 205   *
 206   * @global WPDB $wpdb WordPress DB object
 207   * @global WP_Rewrite $wp_rewrite
 208   *
 209   * @since 1.2.0
 210   */
 211  function bp_core_activation_notice() {
 212      global $wp_rewrite, $wpdb;
 213  
 214      // Only the super admin gets warnings.
 215      if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 216          return;
 217      }
 218  
 219      // Bail in user admin.
 220      if ( is_user_admin() ) {
 221          return;
 222      }
 223  
 224      // On multisite installs, don't load on a non-root blog, unless do_network_admin is overridden.
 225      if ( is_multisite() && bp_core_do_network_admin() && ! bp_is_root_blog() ) {
 226          return;
 227      }
 228  
 229      // Bail if in network admin, and BuddyPress is not network activated.
 230      if ( is_network_admin() && ! bp_is_network_activated() ) {
 231          return;
 232      }
 233  
 234      /**
 235       * Check to make sure that the blog setup routine has run. This can't
 236       * happen during the wizard because of the order which the components
 237       * are loaded.
 238       */
 239      if ( bp_is_active( 'blogs' ) ) {
 240          $bp    = buddypress();
 241          $count = $wpdb->get_var( "SELECT COUNT(*) FROM {$bp->blogs->table_name}" );
 242  
 243          if ( empty( $count ) ) {
 244              bp_blogs_record_existing_blogs();
 245          }
 246      }
 247  
 248      // Add notice if no rewrite rules are enabled.
 249      if ( empty( $wp_rewrite->permalink_structure ) ) {
 250          bp_core_add_admin_notice(
 251              sprintf(
 252                  // Translators: %s is the url to the permalink settings.
 253                  __( '<strong>BuddyPress is almost ready</strong>. You must <a href="%s">update your permalink structure</a> to something other than the default for it to work.', 'buddypress' ),
 254                  admin_url( 'options-permalink.php' )
 255              ),
 256              'error'
 257          );
 258      }
 259  
 260      // Get BuddyPress instance.
 261      $bp = buddypress();
 262  
 263      /**
 264       * Check for orphaned BP components (BP component is enabled, no WP page exists).
 265       */
 266      $orphaned_components = array();
 267      $wp_page_components  = array();
 268  
 269      // Only components with 'has_directory' require a WP page to function.
 270      foreach ( array_keys( $bp->loaded_components ) as $component_id ) {
 271          if ( ! empty( $bp->{$component_id}->has_directory ) ) {
 272              $wp_page_components[] = array(
 273                  'id'   => $component_id,
 274                  'name' => isset( $bp->{$component_id}->name ) ? $bp->{$component_id}->name : ucwords( $bp->{$component_id}->id ),
 275              );
 276          }
 277      }
 278  
 279      // Activate and Register are special cases. They are not components but they need WP pages.
 280      // If user registration is disabled, we can skip this step.
 281      if ( bp_get_signup_allowed() ) {
 282          $wp_page_components[] = array(
 283              'id'   => 'activate',
 284              'name' => __( 'Activate', 'buddypress' ),
 285          );
 286  
 287          $wp_page_components[] = array(
 288              'id'   => 'register',
 289              'name' => __( 'Register', 'buddypress' ),
 290          );
 291      }
 292  
 293      // On the first admin screen after a new installation, this isn't set, so grab it to suppress
 294      // a misleading error message.
 295      if ( empty( $bp->pages->members ) ) {
 296          $bp->pages = bp_core_get_directory_pages();
 297      }
 298  
 299      foreach ( $wp_page_components as $component ) {
 300          if ( ! isset( $bp->pages->{$component['id']} ) ) {
 301              $orphaned_components[] = $component['name'];
 302          }
 303      }
 304  
 305      if ( ! empty( $orphaned_components ) ) {
 306          $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
 307          $notice    = sprintf(
 308              '%1$s <a href="%2$s">%3$s</a>',
 309              sprintf(
 310                  // Translators: %s is the comma separated list of components needing a directory page.
 311                  __( 'The following active BuddyPress Components do not have associated WordPress Pages: %s.', 'buddypress' ),
 312                  '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $orphaned_components ) ) . '</strong>'
 313              ),
 314              esc_url( $admin_url ),
 315              __( 'Repair', 'buddypress' )
 316          );
 317  
 318          bp_core_add_admin_notice( $notice );
 319      }
 320  
 321      // BP components cannot share a single WP page. Check for duplicate assignments, and post a message if found.
 322      $dupe_names = array();
 323      $page_ids   = bp_core_get_directory_page_ids();
 324      $dupes      = array_diff_assoc( $page_ids, array_unique( $page_ids ) );
 325  
 326      if ( ! empty( $dupes ) ) {
 327          foreach ( array_keys( $dupes ) as $dupe_component ) {
 328              $dupe_names[] = $bp->pages->{$dupe_component}->title;
 329          }
 330  
 331          // Make sure that there are no duplicate duplicates :).
 332          $dupe_names = array_unique( $dupe_names );
 333      }
 334  
 335      // If there are duplicates, post a message about them.
 336      if ( ! empty( $dupe_names ) ) {
 337          $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
 338          $notice    = sprintf(
 339              '%1$s <a href="%2$s">%3$s</a>',
 340              sprintf(
 341                  // Translators: %s is the list of directory pages associated to more than one component.
 342                  __( 'Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %s.', 'buddypress' ),
 343                  '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $dupe_names ) ) . '</strong>'
 344              ),
 345              esc_url( $admin_url ),
 346              __( 'Repair', 'buddypress' )
 347          );
 348  
 349          bp_core_add_admin_notice( $notice );
 350      }
 351  }
 352  
 353  /**
 354   * Redirect user to BuddyPress's What's New page on activation.
 355   *
 356   * @since 1.7.0
 357   *
 358   * @internal Used internally to redirect BuddyPress to the about page on activation.
 359   */
 360  function bp_do_activation_redirect() {
 361  
 362      // Bail if no activation redirect.
 363      if ( ! get_transient( '_bp_activation_redirect' ) ) {
 364          return;
 365      }
 366  
 367      // Delete the redirect transient.
 368      delete_transient( '_bp_activation_redirect' );
 369  
 370      // Bail if activating from network, or bulk.
 371      if ( isset( $_GET['activate-multi'] ) ) {
 372          return;
 373      }
 374  
 375      $query_args = array();
 376      if ( get_transient( '_bp_is_new_install' ) ) {
 377          $query_args['is_new_install'] = '1';
 378          delete_transient( '_bp_is_new_install' );
 379      }
 380  
 381      // Redirect to dashboard and trigger the Hello screen.
 382      wp_safe_redirect( add_query_arg( $query_args, bp_get_admin_url( '?hello=buddypress' ) ) );
 383  }
 384  
 385  /** UI/Styling ****************************************************************/
 386  
 387  /**
 388   * Output the tabs in the admin area.
 389   *
 390   * @since 1.5.0
 391   *
 392   * @param string $active_tab Name of the tab that is active. Optional.
 393   */
 394  function bp_core_admin_tabs( $active_tab = '' ) {
 395      $tabs_html    = '';
 396      $idle_class   = 'nav-tab';
 397      $active_class = 'nav-tab nav-tab-active';
 398  
 399      /**
 400       * Filters the admin tabs to be displayed.
 401       *
 402       * @since 1.9.0
 403       *
 404       * @param array $value Array of tabs to output to the admin area.
 405       */
 406      $tabs = apply_filters( 'bp_core_admin_tabs', bp_core_get_admin_tabs( $active_tab ) );
 407  
 408      // Loop through tabs and build navigation.
 409      foreach ( array_values( $tabs ) as $tab_data ) {
 410          $is_current = (bool) ( $tab_data['name'] == $active_tab );
 411          $tab_class  = $is_current ? $active_class : $idle_class;
 412          $tabs_html .= '<a href="' . esc_url( $tab_data['href'] ) . '" class="' . esc_attr( $tab_class ) . '">' . esc_html( $tab_data['name'] ) . '</a>';
 413      }
 414  
 415      echo $tabs_html;
 416  
 417      /**
 418       * Fires after the output of tabs for the admin area.
 419       *
 420       * @since 1.5.0
 421       */
 422      do_action( 'bp_admin_tabs' );
 423  }
 424  
 425  /**
 426   * Get the data for the tabs in the admin area.
 427   *
 428   * @since 2.2.0
 429   *
 430   * @param string $active_tab Name of the tab that is active. Optional.
 431   * @return string
 432   */
 433  function bp_core_get_admin_tabs( $active_tab = '' ) {
 434      $tabs = array(
 435          '0' => array(
 436              'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), 'admin.php' ) ),
 437              'name' => __( 'Components', 'buddypress' ),
 438          ),
 439          '2' => array(
 440              'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ),
 441              'name' => __( 'Options', 'buddypress' ),
 442          ),
 443          '1' => array(
 444              'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) ),
 445              'name' => __( 'Pages', 'buddypress' ),
 446          ),
 447          '3' => array(
 448              'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-credits' ), 'admin.php' ) ),
 449              'name' => __( 'Credits', 'buddypress' ),
 450          ),
 451      );
 452  
 453      /**
 454       * Filters the tab data used in our wp-admin screens.
 455       *
 456       * @since 2.2.0
 457       *
 458       * @param array $tabs Tab data.
 459       */
 460      return apply_filters( 'bp_core_get_admin_tabs', $tabs );
 461  }
 462  
 463  /** Help **********************************************************************/
 464  
 465  /**
 466   * Adds contextual help to BuddyPress admin pages.
 467   *
 468   * @since 1.7.0
 469   * @todo Make this part of the BP_Component class and split into each component.
 470   *
 471   * @param string $screen Current screen.
 472   */
 473  function bp_core_add_contextual_help( $screen = '' ) {
 474  
 475      $screen = get_current_screen();
 476  
 477      switch ( $screen->id ) {
 478  
 479          // Component page.
 480          case 'settings_page_bp-components':
 481              // Help tabs.
 482              $screen->add_help_tab(
 483                  array(
 484                      'id'      => 'bp-comp-overview',
 485                      'title'   => __( 'Overview', 'buddypress' ),
 486                      'content' => bp_core_add_contextual_help_content( 'bp-comp-overview' ),
 487                  )
 488              );
 489  
 490              // Help panel - sidebar links.
 491              $screen->set_help_sidebar(
 492                  '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
 493                  '<p>' . __( '<a href="https://codex.buddypress.org/getting-started/configure-components/">Managing Components</a>', 'buddypress' ) . '</p>' .
 494                  '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
 495              );
 496              break;
 497  
 498          // Pages page.
 499          case 'settings_page_bp-page-settings':
 500              // Help tabs.
 501              $screen->add_help_tab(
 502                  array(
 503                      'id'      => 'bp-page-overview',
 504                      'title'   => __( 'Overview', 'buddypress' ),
 505                      'content' => bp_core_add_contextual_help_content( 'bp-page-overview' ),
 506                  )
 507              );
 508  
 509              // Help panel - sidebar links.
 510              $screen->set_help_sidebar(
 511                  '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
 512                  '<p>' . __( '<a href="https://codex.buddypress.org/getting-started/configure-components/#settings-buddypress-pages">Managing Pages</a>', 'buddypress' ) . '</p>' .
 513                  '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
 514              );
 515  
 516              break;
 517  
 518          // Settings page.
 519          case 'settings_page_bp-settings':
 520              // Help tabs.
 521              $screen->add_help_tab(
 522                  array(
 523                      'id'      => 'bp-settings-overview',
 524                      'title'   => __( 'Overview', 'buddypress' ),
 525                      'content' => bp_core_add_contextual_help_content( 'bp-settings-overview' ),
 526                  )
 527              );
 528  
 529              // Help panel - sidebar links.
 530              $screen->set_help_sidebar(
 531                  '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
 532                  '<p>' . __( '<a href="https://codex.buddypress.org/getting-started/configure-components/#settings-buddypress-settings">Managing Settings</a>', 'buddypress' ) . '</p>' .
 533                  '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
 534              );
 535  
 536              break;
 537  
 538          // Profile fields page.
 539          case 'users_page_bp-profile-setup':
 540              // Help tabs.
 541              $screen->add_help_tab(
 542                  array(
 543                      'id'      => 'bp-profile-overview',
 544                      'title'   => __( 'Overview', 'buddypress' ),
 545                      'content' => bp_core_add_contextual_help_content( 'bp-profile-overview' ),
 546                  )
 547              );
 548  
 549              // Help panel - sidebar links.
 550              $screen->set_help_sidebar(
 551                  '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
 552                  '<p>' . __( '<a href="https://codex.buddypress.org/administrator-guide/extended-profiles/">Managing Profile Fields</a>', 'buddypress' ) . '</p>' .
 553                  '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
 554              );
 555  
 556              break;
 557      }
 558  }
 559  add_action( 'load-settings_page_bp-components', 'bp_core_add_contextual_help' );
 560  add_action( 'load-settings_page_bp-page-settings', 'bp_core_add_contextual_help' );
 561  add_action( 'load-settings_page_bp-settings', 'bp_core_add_contextual_help' );
 562  add_action( 'load-users_page_bp-profile-setup', 'bp_core_add_contextual_help' );
 563  
 564  /**
 565   * Renders contextual help content to contextual help tabs.
 566   *
 567   * @since 1.7.0
 568   *
 569   * @param string $tab Current help content tab.
 570   * @return string
 571   */
 572  function bp_core_add_contextual_help_content( $tab = '' ) {
 573  
 574      switch ( $tab ) {
 575          case 'bp-comp-overview':
 576              $retval = __( 'By default, all but four of the BuddyPress components are enabled. You can selectively enable or disable any of the components by using the form below. Your BuddyPress installation will continue to function. However, the features of the disabled components will no longer be accessible to anyone using the site.', 'buddypress' );
 577              break;
 578  
 579          case 'bp-page-overview':
 580              $retval = __( 'BuddyPress Components use WordPress Pages for their root directory/archive pages. You can change the page associations for each active component by using the form below.', 'buddypress' );
 581              break;
 582  
 583          case 'bp-settings-overview':
 584              $retval = __( 'Extra configuration settings are provided and activated. You can selectively enable or disable any setting by using the form on this screen.', 'buddypress' );
 585              break;
 586  
 587          case 'bp-profile-overview':
 588              $retval = __( 'Your users will distinguish themselves through their profile page. Create relevant profile fields that will show on each users profile.', 'buddypress' ) . '<br /><br />' . __( 'Note: Any fields in the first group will appear on the signup page.', 'buddypress' );
 589              break;
 590  
 591          default:
 592              $retval = false;
 593              break;
 594      }
 595  
 596      // Wrap text in a paragraph tag.
 597      if ( ! empty( $retval ) ) {
 598          $retval = '<p>' . $retval . '</p>';
 599      }
 600  
 601      return $retval;
 602  }
 603  
 604  /** Separator *****************************************************************/
 605  
 606  /**
 607   * Add a separator to the WordPress admin menus.
 608   *
 609   * @since 1.7.0
 610   */
 611  function bp_admin_separator() {
 612  
 613      // Bail if BuddyPress is not network activated and viewing network admin.
 614      if ( is_network_admin() && ! bp_is_network_activated() ) {
 615          return;
 616      }
 617  
 618      // Bail if BuddyPress is network activated and viewing site admin.
 619      if ( ! is_network_admin() && bp_is_network_activated() ) {
 620          return;
 621      }
 622  
 623      // Prevent duplicate separators when no core menu items exist.
 624      if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 625          return;
 626      }
 627  
 628      // Bail if there are no components with admin UI's. Hardcoded for now, until
 629      // there's a real API for determining this later.
 630      if ( ! bp_is_active( 'activity' ) && ! bp_is_active( 'groups' ) ) {
 631          return;
 632      }
 633  
 634      global $menu;
 635  
 636      $menu[] = array( '', 'read', 'separator-buddypress', '', 'wp-menu-separator buddypress' );
 637  }
 638  
 639  /**
 640   * Tell WordPress we have a custom menu order.
 641   *
 642   * @since 1.7.0
 643   *
 644   * @param bool $menu_order Menu order.
 645   * @return bool Always true.
 646   */
 647  function bp_admin_custom_menu_order( $menu_order = false ) {
 648  
 649      // Bail if user cannot see admin pages.
 650      if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 651          return $menu_order;
 652      }
 653  
 654      return true;
 655  }
 656  
 657  /**
 658   * Move our custom separator above our custom post types.
 659   *
 660   * @since 1.7.0
 661   *
 662   * @param array $menu_order Menu Order.
 663   * @return array Modified menu order.
 664   */
 665  function bp_admin_menu_order( $menu_order = array() ) {
 666  
 667      // Bail if user cannot see admin pages.
 668      if ( empty( $menu_order ) || ! bp_current_user_can( 'bp_moderate' ) ) {
 669          return $menu_order;
 670      }
 671  
 672      // Initialize our custom order array.
 673      $bp_menu_order = array();
 674  
 675      // Menu values.
 676      $last_sep = is_network_admin() ? 'separator1' : 'separator2';
 677  
 678      /**
 679       * Filters the custom admin menus.
 680       *
 681       * @since 1.7.0
 682       *
 683       * @param array $value Empty array.
 684       */
 685      $custom_menus = (array) apply_filters( 'bp_admin_menu_order', array() );
 686  
 687      // Bail if no components have top level admin pages.
 688      if ( empty( $custom_menus ) ) {
 689          return $menu_order;
 690      }
 691  
 692      // Add our separator to beginning of array.
 693      array_unshift( $custom_menus, 'separator-buddypress' );
 694  
 695      // Loop through menu order and do some rearranging.
 696      foreach ( (array) $menu_order as $item ) {
 697  
 698          // Position BuddyPress menus above appearance.
 699          if ( $last_sep == $item ) {
 700  
 701              // Add our custom menus.
 702              foreach ( (array) $custom_menus as $custom_menu ) {
 703                  if ( array_search( $custom_menu, $menu_order ) ) {
 704                      $bp_menu_order[] = $custom_menu;
 705                  }
 706              }
 707  
 708              // Add the appearance separator.
 709              $bp_menu_order[] = $last_sep;
 710  
 711              // Skip our menu items.
 712          } elseif ( ! in_array( $item, $custom_menus ) ) {
 713              $bp_menu_order[] = $item;
 714          }
 715      }
 716  
 717      // Return our custom order.
 718      return $bp_menu_order;
 719  }
 720  
 721  /** Utility  *****************************************************************/
 722  
 723  /**
 724   * When using a WP_List_Table, get the currently selected bulk action.
 725   *
 726   * WP_List_Tables have bulk actions at the top and at the bottom of the tables,
 727   * and the inputs have different keys in the $_REQUEST array. This function
 728   * reconciles the two values and returns a single action being performed.
 729   *
 730   * @since 1.7.0
 731   *
 732   * @return string
 733   */
 734  function bp_admin_list_table_current_bulk_action() {
 735  
 736      $action = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
 737  
 738      // If the bottom is set, let it override the action.
 739      if ( ! empty( $_REQUEST['action2'] ) && $_REQUEST['action2'] != '-1' ) {
 740          $action = $_REQUEST['action2'];
 741      }
 742  
 743      return $action;
 744  }
 745  
 746  /** Menus *********************************************************************/
 747  
 748  /**
 749   * Register meta box and associated JS for BuddyPress WP Nav Menu.
 750   *
 751   * @since 1.9.0
 752   */
 753  function bp_admin_wp_nav_menu_meta_box() {
 754      if ( ! bp_is_root_blog() ) {
 755          return;
 756      }
 757  
 758      add_meta_box( 'add-buddypress-nav-menu', __( 'BuddyPress Member', 'buddypress' ), 'bp_admin_do_wp_nav_menu_meta_box', 'nav-menus', 'side', 'default' );
 759  
 760      add_action( 'admin_print_footer_scripts', 'bp_admin_wp_nav_menu_restrict_items' );
 761  }
 762  
 763  /**
 764   * BP Member nav menu filter to short-circuit WP's query.
 765   *
 766   * @since 7.0.0
 767   *
 768   * @param null     $null     A null value.
 769   * @param WP_Query $wp_query The WP_Query instance (passed by reference).
 770   * @return array   The BP Member nav items to short-circuit WP's query,
 771   */
 772  function bp_admin_get_wp_nav_menu_items( $null = null, $wp_query ) {
 773      if ( isset( $wp_query->query['orderby'], $wp_query->query['order'] ) && 'post_date' === $wp_query->query['orderby'] && 'DESC' === $wp_query->query['order'] ) {
 774          return bp_nav_menu_get_loggedin_pages();
 775      } elseif ( isset( $wp_query->query['nopaging'] ) && true === $wp_query->query['nopaging'] ) {
 776          return array_merge( bp_nav_menu_get_loggedin_pages(), bp_nav_menu_get_loggedout_pages() );
 777      }
 778  
 779      return bp_nav_menu_get_loggedout_pages();
 780  }
 781  
 782  /**
 783   * Build and populate the BuddyPress accordion on Appearance > Menus.
 784   *
 785   * @since 1.9.0
 786   * @since 7.0.0 Uses wp_nav_menu_item_post_type_meta_box()
 787   *
 788   * @global $nav_menu_selected_id
 789   */
 790  function bp_admin_do_wp_nav_menu_meta_box( $object = '', $box = array() ) {
 791      global $nav_menu_selected_id;
 792  
 793      $box['args'] = (object) array(
 794          'name'           => 'bp_nav_menu_item',
 795          '_default_query' => array(),
 796      );
 797  
 798      // Temporarly register a post type.
 799      register_post_type(
 800          'bp_nav_menu_item',
 801          array(
 802              'label'  => 'BuddyPress',
 803              'labels' => array(
 804                  'search_items' => __( 'Search BuddyPress member menu items', 'buddypress' ),
 805                  'all_items'    => __( 'All BuddyPress Member menu items', 'buddypress' ),
 806              ),
 807              'public' => true,
 808              'hierarchical' => false,
 809              'has_archive'  => false,
 810              'rewrite'      => false,
 811          )
 812      );
 813  
 814      // Temporarly override the posts query results.
 815      add_filter( 'posts_pre_query', 'bp_admin_get_wp_nav_menu_items', 10, 2 );
 816  
 817      ob_start();
 818      wp_nav_menu_item_post_type_meta_box( 'buddypress', $box );
 819      $output = ob_get_clean();
 820  
 821      $get_bp_items = new WP_Query;
 822      $all_bp_items = $get_bp_items->query( array( 'nopaging' => true ) );
 823      $walker       = new Walker_Nav_Menu_Checklist();
 824      $all_bp_tabs  = sprintf(
 825          '<div id="bp_nav_menu_item-all" class="tabs-panel tabs-panel-view-all tabs-panel-inactive" role="region" aria-label="%1$s" tabindex="0">
 826              <ul id="bp_nav_menu_itemchecklist" data-wp-lists="list:bp_nav_menu_item" class="categorychecklist form-no-clear">
 827                  %2$s
 828              </ul>
 829          </div>',
 830          esc_html__( 'All BuddyPress Member menu items', 'buddypress' ),
 831          walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $all_bp_items ), 0, (object) array( 'walker' => $walker ) )
 832      );
 833  
 834      // Remove temporary post type and filter.
 835      unregister_post_type( 'bp_nav_menu_item' );
 836      remove_filter( 'posts_pre_query', 'bp_admin_get_wp_nav_menu_items', 10, 2 );
 837  
 838      $tab_name    = 'bp_nav_menu_item-tab';
 839      $current_tab = 'logged-in';
 840      $tabs        = array(
 841          'logged-in'  => __( 'Logged-In', 'buddypress' ),
 842          'logged-out' => __( 'Logged-Out', 'buddypress' ),
 843          'all'        => __( 'All', 'buddypress' ),
 844      );
 845      $tab_urls    = array(
 846          'all'        => '',
 847          'logged-in'  => '',
 848          'logged-out' => '',
 849      );
 850  
 851      if ( isset( $_REQUEST[ $tab_name ] ) && in_array( $_REQUEST[ $tab_name ], array_keys( $tabs ), true ) ) {
 852          $current_tab = $_REQUEST[ $tab_name ];
 853      }
 854  
 855      $removed_args = array(
 856          'action',
 857          'customlink-tab',
 858          'edit-menu-item',
 859          'menu-item',
 860          'page-tab',
 861          '_wpnonce',
 862      );
 863  
 864      if ( $nav_menu_selected_id ) {
 865          $tab_urls['all']        = esc_url( add_query_arg( $tab_name, 'all', remove_query_arg( $removed_args ) ) );
 866          $tab_urls['logged-in']  = esc_url( add_query_arg( $tab_name, 'logged-in', remove_query_arg( $removed_args ) ) );
 867          $tab_urls['logged-out'] = esc_url( add_query_arg( $tab_name, 'logged-out', remove_query_arg( $removed_args ) ) );
 868      }
 869  
 870      $bp_tabs_nav = '';
 871      foreach ( $tabs as $tab => $tab_text ) {
 872          $class    = '';
 873          $datatype = 'bp_nav_menu_item-' . $tab;
 874  
 875          if ( $current_tab === $tab ) {
 876              $class = ' class="tabs"';
 877          }
 878  
 879          if ( 'all' !== $tab ) {
 880              $datatype = 'tabs-panel-posttype-bp_nav_menu_item-' . $tab;
 881          }
 882  
 883          $bp_tabs_nav .= sprintf(
 884              '<li%1$s>
 885                  <a class="nav-tab-link" data-type="%2$s" href="%3$s">
 886                      %4$s
 887                  </a>
 888              </li>',
 889              $class,
 890              $datatype,
 891              esc_url( $tab_urls[ $tab ] ) . '#' . $datatype,
 892              esc_html( $tab_text )
 893          );
 894      }
 895  
 896      $output = str_replace(
 897          array(
 898              'tabs-panel-posttype-bp_nav_menu_item-most-recent',
 899              'bp_nav_menu_itemchecklist-most-recent',
 900              'bp_nav_menu_item-all',
 901              'bp_nav_menu_itemchecklist',
 902          ),
 903          array(
 904              'tabs-panel-posttype-bp_nav_menu_item-logged-in',
 905              'bp_nav_menu_itemchecklist-logged-in',
 906              'tabs-panel-posttype-bp_nav_menu_item-logged-out',
 907              'bp_nav_menu_itemchecklist-logged-out',
 908          ),
 909          $output
 910      );
 911  
 912      preg_match( '/\<ul\sid=\"posttype-bp_nav_menu_item-tabs\"[^>]*>(.*?)\<\/ul\>\<!-- \.posttype-tabs --\>/s', $output, $tabs_nav );
 913  
 914      if ( isset( $tabs_nav[1] ) ) {
 915          $output = str_replace( $tabs_nav[1], $bp_tabs_nav, $output );
 916      }
 917  
 918      echo preg_replace( '/\<div\sclass=\".*\"\sid=\"tabs-panel-posttype-bp_nav_menu_item-search\"[^>]*>(.*?)\<\/div\>/s', $all_bp_tabs, $output );
 919  }
 920  
 921  /**
 922   * In admin emails list, for non-en_US locales, add notice explaining how to reinstall emails.
 923   *
 924   * If BuddyPress installs before its translations are in place, tell people how to reinstall
 925   * the emails so they have their contents in their site's language.
 926   *
 927   * @since 2.5.0
 928   */
 929  function bp_admin_email_maybe_add_translation_notice() {
 930      if ( get_current_screen()->post_type !== bp_get_email_post_type() || get_locale() === 'en_US' ) {
 931          return;
 932      }
 933  
 934      // If user can't access BP Tools, there's no point showing the message.
 935      if ( ! current_user_can( buddypress()->admin->capability ) ) {
 936          return;
 937      }
 938  
 939      if ( bp_core_do_network_admin() ) {
 940          $admin_page = 'admin.php';
 941      } else {
 942          $admin_page = 'tools.php';
 943      }
 944  
 945      bp_core_add_admin_notice(
 946          sprintf(
 947              // Translators: %s is the url to the BuddyPress tools administration screen.
 948              __( 'Are these emails not written in your site\'s language? Go to <a href="%s">BuddyPress Tools and try the "reinstall emails"</a> tool.', 'buddypress' ),
 949              esc_url( add_query_arg( 'page', 'bp-tools', bp_get_admin_url( $admin_page ) ) )
 950          ),
 951          'updated'
 952      );
 953  }
 954  add_action( 'admin_head-edit.php', 'bp_admin_email_maybe_add_translation_notice' );
 955  
 956  /**
 957   * In emails editor, add notice linking to token documentation on Codex.
 958   *
 959   * @since 2.5.0
 960   */
 961  function bp_admin_email_add_codex_notice() {
 962      if ( get_current_screen()->post_type !== bp_get_email_post_type() ) {
 963          return;
 964      }
 965  
 966      bp_core_add_admin_notice(
 967          sprintf(
 968              // Translators: %s is the url to the BuddyPress codex page about BP Email tokens.
 969              __( 'Phrases wrapped in braces <code>{{ }}</code> are email tokens. <a href="%s">Learn about tokens on the BuddyPress Codex</a>.', 'buddypress' ),
 970              esc_url( 'https://codex.buddypress.org/emails/email-tokens/' )
 971          ),
 972          'error'
 973      );
 974  }
 975  add_action( 'admin_head-post.php', 'bp_admin_email_add_codex_notice' );
 976  
 977  /**
 978   * Display metabox for email taxonomy type.
 979   *
 980   * Shows the term description in a list, rather than the term name itself.
 981   *
 982   * @since 2.5.0
 983   *
 984   * @param WP_Post $post Post object.
 985   * @param array   $box {
 986   *     Tags meta box arguments.
 987   *
 988   *     @type string   $id       Meta box ID.
 989   *     @type string   $title    Meta box title.
 990   *     @type callable $callback Meta box display callback.
 991   * }
 992   */
 993  function bp_email_tax_type_metabox( $post, $box ) {
 994      $r = array(
 995          'taxonomy' => bp_get_email_tax_type(),
 996      );
 997  
 998      $tax_name = esc_attr( $r['taxonomy'] );
 999      $taxonomy = get_taxonomy( $r['taxonomy'] );
1000      ?>
1001      <div id="taxonomy-<?php echo $tax_name; ?>" class="categorydiv">
1002          <div id="<?php echo $tax_name; ?>-all" class="tabs-panel">
1003              <?php
1004              $name = ( $tax_name == 'category' ) ? 'post_category' : 'tax_input[' . $tax_name . ']';
1005              echo "<input type='hidden' name='{$name}[]' value='0' />"; // Allows for an empty term set to be sent. 0 is an invalid Term ID and will be ignored by empty() checks.
1006              ?>
1007              <ul id="<?php echo $tax_name; ?>checklist" data-wp-lists="list:<?php echo $tax_name; ?>" class="categorychecklist form-no-clear">
1008                  <?php
1009                  wp_terms_checklist(
1010                      $post->ID,
1011                      array(
1012                          'taxonomy' => $tax_name,
1013                          'walker'   => new BP_Walker_Category_Checklist(),
1014                      )
1015                  );
1016                  ?>
1017              </ul>
1018          </div>
1019  
1020          <p><?php esc_html_e( 'Choose when this email will be sent.', 'buddypress' ); ?></p>
1021      </div>
1022      <?php
1023  }
1024  
1025  /**
1026   * Custom metaboxes used by our 'bp-email' post type.
1027   *
1028   * @since 2.5.0
1029   */
1030  function bp_email_custom_metaboxes() {
1031      // Remove default 'Excerpt' metabox and replace with our own.
1032      remove_meta_box( 'postexcerpt', null, 'normal' );
1033      add_meta_box( 'postexcerpt', __( 'Plain text email content', 'buddypress' ), 'bp_email_plaintext_metabox', null, 'normal', 'high' );
1034  }
1035  add_action( 'add_meta_boxes_' . bp_get_email_post_type(), 'bp_email_custom_metaboxes' );
1036  
1037  /**
1038   * Customized version of the 'Excerpt' metabox for our 'bp-email' post type.
1039   *
1040   * We are using the 'Excerpt' metabox as our plain-text email content editor.
1041   *
1042   * @since 2.5.0
1043   *
1044   * @param WP_Post $post
1045   */
1046  function bp_email_plaintext_metabox( $post ) {
1047      ?>
1048  
1049      <label class="screen-reader-text" for="excerpt">
1050      <?php
1051          /* translators: accessibility text */
1052          _e( 'Plain text email content', 'buddypress' );
1053      ?>
1054      </label><textarea rows="5" cols="40" name="excerpt" id="excerpt"><?php echo $post->post_excerpt; // textarea_escaped ?></textarea>
1055  
1056      <p><?php _e( 'Most email clients support HTML email. However, some people prefer to receive plain text email. Enter a plain text alternative version of your email here.', 'buddypress' ); ?></p>
1057  
1058      <?php
1059  }
1060  
1061  /**
1062   * Restrict various items from view if editing a BuddyPress menu.
1063   *
1064   * If a person is editing a BP menu item, that person should not be able to
1065   * see or edit the following fields:
1066   *
1067   * - CSS Classes - We use the 'bp-menu' CSS class to determine if the
1068   *   menu item belongs to BP, so we cannot allow manipulation of this field to
1069   *   occur.
1070   * - URL - This field is automatically generated by BP on output, so this
1071   *   field is useless and can cause confusion.
1072   *
1073   * Note: These restrictions are only enforced if JavaScript is enabled.
1074   *
1075   * @since 1.9.0
1076   */
1077  function bp_admin_wp_nav_menu_restrict_items() {
1078      ?>
1079      <script type="text/javascript">
1080      jQuery( '#menu-to-edit').on( 'click', 'a.item-edit', function() {
1081          var settings  = jQuery(this).closest( '.menu-item-bar' ).next( '.menu-item-settings' );
1082          var css_class = settings.find( '.edit-menu-item-classes' );
1083  
1084          if( css_class.val().indexOf( 'bp-menu' ) === 0 ) {
1085              css_class.attr( 'readonly', 'readonly' );
1086              settings.find( '.field-url' ).css( 'display', 'none' );
1087          }
1088      });
1089      </script>
1090      <?php
1091  }
1092  
1093  /**
1094   * Add "Mark as Spam/Ham" button to user row actions.
1095   *
1096   * @since 2.0.0
1097   *
1098   * @param array  $actions     User row action links.
1099   * @param object $user_object Current user information.
1100   * @return array $actions User row action links.
1101   */
1102  function bp_core_admin_user_row_actions( $actions, $user_object ) {
1103  
1104      // Setup the $user_id variable from the current user object.
1105      $user_id = 0;
1106      if ( ! empty( $user_object->ID ) ) {
1107          $user_id = absint( $user_object->ID );
1108      }
1109  
1110      // Bail early if user cannot perform this action, or is looking at themselves.
1111      if ( current_user_can( 'edit_user', $user_id ) && ( bp_loggedin_user_id() !== $user_id ) ) {
1112  
1113          // Admin URL could be single site or network.
1114          $url = bp_get_admin_url( 'users.php' );
1115  
1116          // If spammed, create unspam link.
1117          if ( bp_is_user_spammer( $user_id ) ) {
1118              $url            = add_query_arg(
1119                  array(
1120                      'action' => 'ham',
1121                      'user'   => $user_id,
1122                  ),
1123                  $url
1124              );
1125              $unspam_link    = wp_nonce_url( $url, 'bp-spam-user' );
1126              $actions['ham'] = sprintf('<a href="%1$s">%2$s</a>', esc_url( $unspam_link ), esc_html__( 'Not Spam', 'buddypress' ) );
1127  
1128              // If not already spammed, create spam link.
1129          } else {
1130              $url             = add_query_arg(
1131                  array(
1132                      'action' => 'spam',
1133                      'user'   => $user_id,
1134                  ),
1135                  $url
1136              );
1137              $spam_link       = wp_nonce_url( $url, 'bp-spam-user' );
1138              $actions['spam'] = sprintf( '<a class="submitdelete" href="%1$s">%2$s</a>', esc_url( $spam_link ), esc_html__( 'Spam', 'buddypress' ) );
1139          }
1140      }
1141  
1142      // Create a "View" link.
1143      $url             = bp_core_get_user_domain( $user_id );
1144      $actions['view'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $url ), esc_html__( 'View', 'buddypress' ) );
1145  
1146      // Return new actions.
1147      return $actions;
1148  }
1149  
1150  /**
1151   * Catch requests to mark individual users as spam/ham from users.php.
1152   *
1153   * @since 2.0.0
1154   */
1155  function bp_core_admin_user_manage_spammers() {
1156  
1157      // Print our inline scripts on non-Multisite.
1158      add_action( 'admin_footer', 'bp_core_admin_user_spammed_js' );
1159  
1160      $action  = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false;
1161      $updated = isset( $_REQUEST['updated'] ) ? $_REQUEST['updated'] : false;
1162      $mode    = isset( $_POST['mode'] ) ? $_POST['mode'] : false;
1163  
1164      // If this is a multisite, bulk request, stop now!
1165      if ( 'list' == $mode ) {
1166          return;
1167      }
1168  
1169      // Process a spam/ham request.
1170      if ( ! empty( $action ) && in_array( $action, array( 'spam', 'ham' ) ) ) {
1171  
1172          check_admin_referer( 'bp-spam-user' );
1173  
1174          $user_id = ! empty( $_REQUEST['user'] ) ? intval( $_REQUEST['user'] ) : false;
1175  
1176          if ( empty( $user_id ) ) {
1177              return;
1178          }
1179  
1180          $redirect = wp_get_referer();
1181  
1182          $status = ( $action == 'spam' ) ? 'spam' : 'ham';
1183  
1184          // Process the user.
1185          bp_core_process_spammer_status( $user_id, $status );
1186  
1187          $redirect = add_query_arg( array( 'updated' => 'marked-' . $status ), $redirect );
1188  
1189          wp_redirect( $redirect );
1190      }
1191  
1192      // Display feedback.
1193      if ( ! empty( $updated ) && in_array( $updated, array( 'marked-spam', 'marked-ham' ) ) ) {
1194  
1195          if ( 'marked-spam' === $updated ) {
1196              $notice = __( 'User marked as spammer. Spam users are visible only to site admins.', 'buddypress' );
1197          } else {
1198              $notice = __( 'User removed from spam.', 'buddypress' );
1199          }
1200  
1201          bp_core_add_admin_notice( $notice );
1202      }
1203  }
1204  
1205  /**
1206   * Inline script that adds the 'site-spammed' class to spammed users.
1207   *
1208   * @since 2.0.0
1209   */
1210  function bp_core_admin_user_spammed_js() {
1211      ?>
1212      <script type="text/javascript">
1213          jQuery( document ).ready( function($) {
1214              $( '.row-actions .ham' ).each( function() {
1215                  $( this ).closest( 'tr' ).addClass( 'site-spammed' );
1216              });
1217          });
1218      </script>
1219      <?php
1220  }
1221  
1222  /**
1223   * Catch and process an admin notice dismissal.
1224   *
1225   * @since 2.7.0
1226   */
1227  function bp_core_admin_notice_dismiss_callback() {
1228      if ( ! current_user_can( 'install_plugins' ) ) {
1229          wp_send_json_error();
1230      }
1231  
1232      if ( empty( $_POST['nonce'] ) || empty( $_POST['notice_id'] ) ) {
1233          wp_send_json_error();
1234      }
1235  
1236      $notice_id = wp_unslash( $_POST['notice_id'] );
1237  
1238      if ( ! wp_verify_nonce( $_POST['nonce'], 'bp-dismissible-notice-' . $notice_id ) ) {
1239          wp_send_json_error();
1240      }
1241  
1242      bp_update_option( "bp-dismissed-notice-$notice_id", 1 );
1243  
1244      wp_send_json_success();
1245  }
1246  add_action( 'wp_ajax_bp_dismiss_notice', 'bp_core_admin_notice_dismiss_callback' );
1247  
1248  /**
1249   * Add a "buddypress" class to body element of wp-admin.
1250   *
1251   * @since 2.8.0
1252   *
1253   * @param string $classes CSS classes for the body tag in the admin, a comma separated string.
1254   *
1255   * @return string
1256   */
1257  function bp_core_admin_body_classes( $classes ) {
1258      return $classes . ' buddypress';
1259  }
1260  add_filter( 'admin_body_class', 'bp_core_admin_body_classes' );
1261  
1262  /**
1263   * Adds a BuddyPress category to house BuddyPress blocks.
1264   *
1265   * @since 5.0.0
1266   *
1267   * @param array  $categories Array of block categories.
1268   * @param object $post       Post being loaded.
1269   */
1270  function bp_block_category( $categories = array(), $post = null ) {
1271      if ( ! ( $post instanceof WP_Post ) ) {
1272          return $categories;
1273      }
1274  
1275      /**
1276       * Filter here to add/remove the supported post types for the BuddyPress blocks category.
1277       *
1278       * @since 5.0.0
1279       *
1280       * @param array $value The list of supported post types. Defaults to WordPress built-in ones.
1281       */
1282      $post_types = apply_filters( 'bp_block_category_post_types', array( 'post', 'page' ) );
1283  
1284      if ( ! $post_types ) {
1285          return $categories;
1286      }
1287  
1288      // Get the post type of the current item.
1289      $post_type = get_post_type( $post );
1290  
1291      if ( ! in_array( $post_type, $post_types, true ) ) {
1292          return $categories;
1293      }
1294  
1295      return array_merge(
1296          $categories,
1297          array(
1298              array(
1299                  'slug'  => 'buddypress',
1300                  'title' => __( 'BuddyPress', 'buddypress' ),
1301                  'icon'  => 'buddicons-buddypress-logo',
1302              ),
1303          )
1304      );
1305  }
1306  add_filter( 'block_categories', 'bp_block_category', 1, 2 );


Generated: Sun Jul 5 01:02:21 2020 Cross-referenced by PHPXref 0.7.1