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


Generated: Wed Apr 21 01:01:43 2021 Cross-referenced by PHPXref 0.7.1