[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-templates/bp-legacy/ -> buddypress-functions.php (source)

   1  <?php
   2  /**
   3   * Functions of BuddyPress's Legacy theme.
   4   *
   5   * @since 1.7.0
   6   *
   7   * @package BuddyPress
   8   * @subpackage BP_Theme_Compat
   9   * @version 10.0.0
  10   */
  11  
  12  // Exit if accessed directly.
  13  defined( 'ABSPATH' ) || exit;
  14  
  15  /** Theme Setup ***************************************************************/
  16  
  17  if ( !class_exists( 'BP_Legacy' ) ) :
  18  
  19  /**
  20   * Loads BuddyPress Legacy Theme functionality.
  21   *
  22   * This is not a real theme by WordPress standards, and is instead used as the
  23   * fallback for any WordPress theme that does not have BuddyPress templates in it.
  24   *
  25   * To make your custom theme BuddyPress compatible and customize the templates, you
  26   * can copy these files into your theme without needing to merge anything
  27   * together; BuddyPress should safely handle the rest.
  28   *
  29   * See @link BP_Theme_Compat() for more.
  30   *
  31   * @since 1.7.0
  32   *
  33   * @package BuddyPress
  34   * @subpackage BP_Theme_Compat
  35   */
  36  class BP_Legacy extends BP_Theme_Compat {
  37  
  38      /** Functions *************************************************************/
  39  
  40      /**
  41       * The main BuddyPress (Legacy) Loader.
  42       *
  43       * @since 1.7.0
  44       *
  45       */
  46  	public function __construct() {
  47          parent::start();
  48      }
  49  
  50      /**
  51       * Component global variables.
  52       *
  53       * You'll want to customize the values in here, so they match whatever your
  54       * needs are.
  55       *
  56       * @since 1.7.0
  57       */
  58  	protected function setup_globals() {
  59          $bp            = buddypress();
  60          $this->id      = 'legacy';
  61          $this->name    = __( 'BuddyPress Legacy', 'buddypress' );
  62          $this->version = bp_get_version();
  63          $this->dir     = trailingslashit( $bp->themes_dir . '/bp-legacy' );
  64          $this->url     = trailingslashit( $bp->themes_url . '/bp-legacy' );
  65      }
  66  
  67      /**
  68       * Setup the theme hooks.
  69       *
  70       * @since 1.7.0
  71       *
  72       */
  73  	protected function setup_actions() {
  74  
  75          // Template Output.
  76          add_filter( 'bp_get_activity_action_pre_meta', array( $this, 'secondary_avatars' ), 10, 2 );
  77  
  78          // Filter BuddyPress template hierarchy and look for page templates.
  79          add_filter( 'bp_get_buddypress_template', array( $this, 'theme_compat_page_templates' ), 10, 1 );
  80  
  81          /** Scripts ***********************************************************/
  82  
  83          add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_styles'   ) ); // Enqueue theme CSS
  84          add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_scripts'  ) ); // Enqueue theme JS
  85          add_filter( 'bp_enqueue_scripts', array( $this, 'localize_scripts' ) ); // Enqueue theme script localization
  86  
  87          /** Body no-js Class **************************************************/
  88  
  89          add_filter( 'body_class', array( $this, 'add_nojs_body_class' ), 20, 1 );
  90  
  91          /** Buttons ***********************************************************/
  92  
  93          if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
  94              // Register buttons for the relevant component templates
  95              // Friends button.
  96              if ( bp_is_active( 'friends' ) )
  97                  add_action( 'bp_member_header_actions',    'bp_add_friend_button',           5 );
  98  
  99              // Activity button.
 100              if ( bp_is_active( 'activity' ) && bp_activity_do_mentions() )
 101                  add_action( 'bp_member_header_actions',    'bp_send_public_message_button',  20 );
 102  
 103              // Messages button.
 104              if ( bp_is_active( 'messages' ) )
 105                  add_action( 'bp_member_header_actions',    'bp_send_private_message_button', 20 );
 106  
 107              // Group buttons.
 108              if ( bp_is_active( 'groups' ) ) {
 109                  add_action( 'bp_group_header_actions',          'bp_group_join_button',               5           );
 110                  add_action( 'bp_directory_groups_actions',      'bp_group_join_button'                            );
 111                  add_action( 'bp_groups_directory_group_filter', 'bp_legacy_theme_group_create_nav', 999           );
 112                  add_action( 'bp_after_group_admin_content',     'bp_legacy_groups_admin_screen_hidden_input'      );
 113                  add_action( 'bp_before_group_admin_form',       'bp_legacy_theme_group_manage_members_add_search' );
 114              }
 115  
 116              // Blog button.
 117              if ( bp_is_active( 'blogs' ) ) {
 118                  add_action( 'bp_directory_blogs_actions',    'bp_blogs_visit_blog_button'           );
 119                  add_action( 'bp_blogs_directory_blog_types', 'bp_legacy_theme_blog_create_nav', 999 );
 120              }
 121          }
 122  
 123          /** Notices ***********************************************************/
 124  
 125          // Only hook the 'sitewide_notices' overlay if the Sitewide
 126          // Notices widget is not in use (to avoid duplicate content).
 127          if ( bp_is_active( 'messages' ) && ! bp_is_widget_block_active( 'bp/sitewide-notices', 'bp_messages_sitewide_notices_widget', true ) ) {
 128              add_action( 'wp_footer', array( $this, 'sitewide_notices' ), 9999 );
 129          }
 130  
 131          /** Ajax **************************************************************/
 132  
 133          $actions = array(
 134  
 135              // Directory filters.
 136              'blogs_filter'    => 'bp_legacy_theme_object_template_loader',
 137              'forums_filter'   => 'bp_legacy_theme_object_template_loader',
 138              'groups_filter'   => 'bp_legacy_theme_object_template_loader',
 139              'members_filter'  => 'bp_legacy_theme_object_template_loader',
 140              'messages_filter' => 'bp_legacy_theme_messages_template_loader',
 141              'invite_filter'   => 'bp_legacy_theme_invite_template_loader',
 142              'requests_filter' => 'bp_legacy_theme_requests_template_loader',
 143  
 144              // Friends.
 145              'accept_friendship' => 'bp_legacy_theme_ajax_accept_friendship',
 146              'addremove_friend'  => 'bp_legacy_theme_ajax_addremove_friend',
 147              'reject_friendship' => 'bp_legacy_theme_ajax_reject_friendship',
 148  
 149              // Activity.
 150              'activity_get_older_updates'  => 'bp_legacy_theme_activity_template_loader',
 151              'activity_mark_fav'           => 'bp_legacy_theme_mark_activity_favorite',
 152              'activity_mark_unfav'         => 'bp_legacy_theme_unmark_activity_favorite',
 153              'activity_widget_filter'      => 'bp_legacy_theme_activity_template_loader',
 154              'delete_activity'             => 'bp_legacy_theme_delete_activity',
 155              'delete_activity_comment'     => 'bp_legacy_theme_delete_activity_comment',
 156              'get_single_activity_content' => 'bp_legacy_theme_get_single_activity_content',
 157              'new_activity_comment'        => 'bp_legacy_theme_new_activity_comment',
 158              'post_update'                 => 'bp_legacy_theme_post_update',
 159              'bp_spam_activity'            => 'bp_legacy_theme_spam_activity',
 160              'bp_spam_activity_comment'    => 'bp_legacy_theme_spam_activity',
 161  
 162              // Groups.
 163              'groups_invite_user' => 'bp_legacy_theme_ajax_invite_user',
 164              'joinleave_group'    => 'bp_legacy_theme_ajax_joinleave_group',
 165  
 166              // Messages.
 167              'messages_autocomplete_results' => 'bp_legacy_theme_ajax_messages_autocomplete_results',
 168              'messages_close_notice'         => 'bp_legacy_theme_ajax_close_notice',
 169              'messages_delete'               => 'bp_legacy_theme_ajax_messages_delete',
 170              'messages_markread'             => 'bp_legacy_theme_ajax_message_markread',
 171              'messages_markunread'           => 'bp_legacy_theme_ajax_message_markunread',
 172              'messages_send_reply'           => 'bp_legacy_theme_ajax_messages_send_reply',
 173          );
 174  
 175          // Conditional actions.
 176          if ( bp_is_active( 'messages', 'star' ) ) {
 177              $actions['messages_star'] = 'bp_legacy_theme_ajax_messages_star_handler';
 178          }
 179  
 180          /**
 181           * Register all of these AJAX handlers.
 182           *
 183           * The "wp_ajax_" action is used for logged in users, and "wp_ajax_nopriv_"
 184           * executes for users that aren't logged in. This is for backpat with BP <1.6.
 185           */
 186          foreach( $actions as $name => $function ) {
 187              add_action( 'wp_ajax_'        . $name, $function );
 188              add_action( 'wp_ajax_nopriv_' . $name, $function );
 189          }
 190  
 191          add_filter( 'bp_ajax_querystring', 'bp_legacy_theme_ajax_querystring', 10, 2 );
 192  
 193          /** Override **********************************************************/
 194  
 195          /**
 196           * Fires after all of the BuddyPress theme compat actions have been added.
 197           *
 198           * @since 1.7.0
 199           *
 200           * @param BP_Legacy $this Current BP_Legacy instance.
 201           */
 202          do_action_ref_array( 'bp_theme_compat_actions', array( &$this ) );
 203      }
 204  
 205      /**
 206       * Load the theme CSS
 207       *
 208       * @since 1.7.0
 209       * @since 2.3.0 Support custom CSS file named after the current theme or parent theme.
 210       *
 211       */
 212  	public function enqueue_styles() {
 213          $min = bp_core_get_minified_asset_suffix();
 214  
 215          // Locate the BP stylesheet.
 216          $ltr = $this->locate_asset_in_stack( "buddypress{$min}.css",     'css' );
 217  
 218          // LTR.
 219          if ( ! is_rtl() && isset( $ltr['location'], $ltr['handle'] ) ) {
 220              wp_enqueue_style( $ltr['handle'], $ltr['location'], array(), $this->version, 'screen' );
 221  
 222              if ( $min ) {
 223                  wp_style_add_data( $ltr['handle'], 'suffix', $min );
 224              }
 225          }
 226  
 227          // RTL.
 228          if ( is_rtl() ) {
 229              $rtl = $this->locate_asset_in_stack( "buddypress-rtl{$min}.css", 'css' );
 230  
 231              if ( isset( $rtl['location'], $rtl['handle'] ) ) {
 232                  $rtl['handle'] = str_replace( '-css', '-css-rtl', $rtl['handle'] );  // Backwards compatibility.
 233                  wp_enqueue_style( $rtl['handle'], $rtl['location'], array(), $this->version, 'screen' );
 234  
 235                  if ( $min ) {
 236                      wp_style_add_data( $rtl['handle'], 'suffix', $min );
 237                  }
 238              }
 239          }
 240  
 241          // Compatibility stylesheets for specific themes.
 242          $theme = $this->locate_asset_in_stack( get_template() . "{$min}.css", 'css' );
 243          if ( ! is_rtl() && isset( $theme['location'] ) ) {
 244              // Use a unique handle.
 245              $theme['handle'] = 'bp-' . get_template();
 246              wp_enqueue_style( $theme['handle'], $theme['location'], array(), $this->version, 'screen' );
 247  
 248              if ( $min ) {
 249                  wp_style_add_data( $theme['handle'], 'suffix', $min );
 250              }
 251          }
 252  
 253          // Compatibility stylesheet for specific themes, RTL-version.
 254          if ( is_rtl() ) {
 255              $theme_rtl = $this->locate_asset_in_stack( get_template() . "-rtl{$min}.css", 'css' );
 256  
 257              if ( isset( $theme_rtl['location'] ) ) {
 258                  $theme_rtl['handle'] = $theme['handle'] . '-rtl';
 259                  wp_enqueue_style( $theme_rtl['handle'], $theme_rtl['location'], array(), $this->version, 'screen' );
 260  
 261                  if ( $min ) {
 262                      wp_style_add_data( $theme_rtl['handle'], 'suffix', $min );
 263                  }
 264              }
 265          }
 266      }
 267  
 268      /**
 269       * Enqueue the required JavaScript files
 270       *
 271       * @since 1.7.0
 272       */
 273  	public function enqueue_scripts() {
 274          $min = bp_core_get_minified_asset_suffix();
 275  
 276          // Locate the BP JS file.
 277          $asset = $this->locate_asset_in_stack( "buddypress{$min}.js", 'js' );
 278  
 279          // Enqueue the global JS, if found - AJAX will not work
 280          // without it.
 281          if ( isset( $asset['location'], $asset['handle'] ) ) {
 282              wp_enqueue_script( $asset['handle'], $asset['location'], bp_core_get_js_dependencies(), $this->version );
 283          }
 284  
 285          /**
 286           * Filters whether directory filter settings ('scope', etc) should be stored in a persistent cookie.
 287           *
 288           * @since 4.0.0
 289           *
 290           * @param bool $store_filter_settings Whether to store settings. Defaults to true for logged-in users.
 291           */
 292          $store_filter_settings = apply_filters( 'bp_legacy_store_filter_settings', is_user_logged_in() );
 293  
 294          /**
 295           * Filters core JavaScript strings for internationalization before AJAX usage.
 296           *
 297           * @since 2.0.0
 298           *
 299           * @param array $value Array of key/value pairs for AJAX usage.
 300           */
 301          $params = apply_filters( 'bp_core_get_js_strings', array(
 302              // Strings for display.
 303              'accepted'            => __( 'Accepted', 'buddypress' ),
 304              'close'               => __( 'Close', 'buddypress' ),
 305              'comments'            => __( 'comments', 'buddypress' ),
 306              'leave_group_confirm' => __( 'Are you sure you want to leave this group?', 'buddypress' ),
 307              'mark_as_fav'          => __( 'Favorite', 'buddypress' ),
 308              'my_favs'             => __( 'My Favorites', 'buddypress' ),
 309              'rejected'            => __( 'Rejected', 'buddypress' ),
 310              'remove_fav'          => __( 'Remove Favorite', 'buddypress' ),
 311              'show_all'            => __( 'Show all', 'buddypress' ),
 312              'show_all_comments'   => __( 'Show all comments for this thread', 'buddypress' ),
 313  
 314              /* translators: %s: number of activity comments */
 315              'show_x_comments'     => __( 'Show all comments (%d)', 'buddypress' ),
 316              'unsaved_changes'     => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
 317              'view'                => __( 'View', 'buddypress' ),
 318  
 319              // Settings.
 320              'store_filter_settings' => $store_filter_settings,
 321          ) );
 322          wp_localize_script( $asset['handle'], 'BP_DTheme', $params );
 323  
 324          // Maybe enqueue comment reply JS.
 325          if ( is_singular() && bp_is_blog_page() && get_option( 'thread_comments' ) ) {
 326              wp_enqueue_script( 'comment-reply' );
 327          }
 328  
 329          // Maybe enqueue password verify JS (register page or user settings page).
 330          if ( bp_is_register_page() || ( function_exists( 'bp_is_user_settings_general' ) && bp_is_user_settings_general() ) ) {
 331  
 332              // Locate the Register Page JS file.
 333              $asset = $this->locate_asset_in_stack( "password-verify{$min}.js", 'js', 'bp-legacy-password-verify' );
 334  
 335              $dependencies = array_merge( bp_core_get_js_dependencies(), array(
 336                  'password-strength-meter',
 337              ) );
 338  
 339              // Enqueue script.
 340              wp_enqueue_script( $asset['handle'] . '-password-verify', $asset['location'], $dependencies, $this->version );
 341              wp_localize_script(
 342                  $asset['handle'] . '-password-verify',
 343                  'bpPasswordVerify',
 344                  array(
 345                      'tooWeakPasswordWarning' => __( 'Your password is too weak, please use a stronger password.', 'buddypress' ),
 346                      'requiredPassStrength'   => bp_members_user_pass_required_strength(),
 347                  )
 348              );
 349          }
 350  
 351          // Star private messages.
 352          if ( bp_is_active( 'messages', 'star' ) && bp_is_user_messages() ) {
 353              wp_localize_script( $asset['handle'], 'BP_PM_Star', array(
 354                  'strings' => array(
 355                      'text_unstar'  => __( 'Unstar', 'buddypress' ),
 356                      'text_star'    => __( 'Star', 'buddypress' ),
 357                      'title_unstar' => __( 'Starred', 'buddypress' ),
 358                      'title_star'   => __( 'Not starred', 'buddypress' ),
 359                      'title_unstar_thread' => __( 'Remove all starred messages in this thread', 'buddypress' ),
 360                      'title_star_thread'   => __( 'Star the first message in this thread', 'buddypress' ),
 361                  ),
 362                  'is_single_thread' => (int) bp_is_messages_conversation(),
 363                  'star_counter'     => 0,
 364                  'unstar_counter'   => 0
 365              ) );
 366          }
 367      }
 368  
 369      /**
 370       * Get the URL and handle of a web-accessible CSS or JS asset
 371       *
 372       * We provide two levels of customizability with respect to where CSS
 373       * and JS files can be stored: (1) the child theme/parent theme/theme
 374       * compat hierarchy, and (2) the "template stack" of /buddypress/css/,
 375       * /community/css/, and /css/. In this way, CSS and JS assets can be
 376       * overloaded, and default versions provided, in exactly the same way
 377       * as corresponding PHP templates.
 378       *
 379       * We are duplicating some of the logic that is currently found in
 380       * bp_locate_template() and the _template_stack() functions. Those
 381       * functions were built with PHP templates in mind, and will require
 382       * refactoring in order to provide "stack" functionality for assets
 383       * that must be accessible both using file_exists() (the file path)
 384       * and at a public URI.
 385       *
 386       * This method is marked private, with the understanding that the
 387       * implementation is subject to change or removal in an upcoming
 388       * release, in favor of a unified _template_stack() system. Plugin
 389       * and theme authors should not attempt to use what follows.
 390       *
 391       * @since 1.8.0
 392       * @param string $file A filename like buddypress.css.
 393       * @param string $type Optional. Either "js" or "css" (the default).
 394       * @param string $script_handle Optional. If set, used as the script name in `wp_enqueue_script`.
 395       * @return array An array of data for the wp_enqueue_* function:
 396       *   'handle' (eg 'bp-child-css') and a 'location' (the URI of the
 397       *   asset)
 398       */
 399  	private function locate_asset_in_stack( $file, $type = 'css', $script_handle = '' ) {
 400          $locations = array();
 401  
 402          // Ensure the assets can be located when running from /src/.
 403          if ( defined( 'BP_SOURCE_SUBDIRECTORY' ) && BP_SOURCE_SUBDIRECTORY === 'src' ) {
 404              $file = str_replace( '.min', '', $file );
 405          }
 406  
 407          // No need to check child if template == stylesheet.
 408          if ( is_child_theme() ) {
 409              $locations[] = array(
 410                  'type' => 'bp-child',
 411                  'dir'  => get_stylesheet_directory(),
 412                  'uri'  => get_stylesheet_directory_uri(),
 413                  'file' => $file,
 414              );
 415  
 416              $locations[] = array(
 417                  'type' => 'bp-child',
 418                  'dir'  => get_stylesheet_directory(),
 419                  'uri'  => get_stylesheet_directory_uri(),
 420                  'file' => str_replace( '.min', '', $file ),
 421              );
 422          }
 423  
 424          $locations[] = array(
 425              'type' => 'bp-parent',
 426              'dir'  => get_template_directory(),
 427              'uri'  => get_template_directory_uri(),
 428              'file' => str_replace( '.min', '', $file ),
 429          );
 430  
 431          $locations[] = array(
 432              'type' => 'bp-legacy',
 433              'dir'  => bp_get_theme_compat_dir(),
 434              'uri'  => bp_get_theme_compat_url(),
 435              'file' => $file,
 436          );
 437  
 438          // Subdirectories within the top-level $locations directories.
 439          $subdirs = array(
 440              'buddypress/' . $type,
 441              'community/' . $type,
 442              $type,
 443          );
 444  
 445          $retval = array();
 446  
 447          foreach ( $locations as $location ) {
 448              foreach ( $subdirs as $subdir ) {
 449                  if ( file_exists( trailingslashit( $location['dir'] ) . trailingslashit( $subdir ) . $location['file'] ) ) {
 450                      $retval['location'] = trailingslashit( $location['uri'] ) . trailingslashit( $subdir ) . $location['file'];
 451                      $retval['handle']   = ( $script_handle ) ? $script_handle : "{$location['type']}-{$type}";
 452  
 453                      break 2;
 454                  }
 455              }
 456          }
 457  
 458          return $retval;
 459      }
 460  
 461      /**
 462       * Adds the no-js class to the body tag.
 463       *
 464       * This function ensures that the <body> element will have the 'no-js' class by default. If you're
 465       * using JavaScript for some visual functionality in your theme, and you want to provide noscript
 466       * support, apply those styles to body.no-js.
 467       *
 468       * The no-js class is removed by the JavaScript created in buddypress.js.
 469       *
 470       * @since 1.7.0
 471       *
 472       * @param array $classes Array of classes to append to body tag.
 473       * @return array $classes
 474       */
 475  	public function add_nojs_body_class( $classes ) {
 476          if ( ! in_array( 'no-js', $classes ) )
 477              $classes[] = 'no-js';
 478  
 479          return array_unique( $classes );
 480      }
 481  
 482      /**
 483       * Load localizations for topic script.
 484       *
 485       * These localizations require information that may not be loaded even by init.
 486       *
 487       * @since 1.7.0
 488       */
 489  	public function localize_scripts() {
 490      }
 491  
 492      /**
 493       * Outputs sitewide notices markup in the footer.
 494       *
 495       * @since 1.7.0
 496       *
 497       * @see https://buddypress.trac.wordpress.org/ticket/4802
 498       */
 499  	public function sitewide_notices() {
 500          // Do not show notices if user is not logged in.
 501          if ( ! is_user_logged_in() || is_admin() ) {
 502              return;
 503          }
 504  
 505          // Add a class to determine if the admin bar is on or not.
 506          $class = did_action( 'admin_bar_menu' ) ? 'admin-bar-on' : 'admin-bar-off';
 507  
 508          echo '<div id="sitewide-notice" class="' . $class . '">';
 509          bp_message_get_notices();
 510          echo '</div>';
 511      }
 512  
 513      /**
 514       * Add secondary avatar image to this activity stream's record, if supported.
 515       *
 516       * @since 1.7.0
 517       *
 518       * @param string               $action   The text of this activity.
 519       * @param BP_Activity_Activity $activity Activity object.
 520       * @return string
 521       */
 522  	function secondary_avatars( $action, $activity ) {
 523          switch ( $activity->component ) {
 524              case 'groups' :
 525              case 'friends' :
 526                  // Only insert avatar if one exists.
 527                  if ( $secondary_avatar = bp_get_activity_secondary_avatar() ) {
 528                      $reverse_content = strrev( $action );
 529                      $position        = strpos( $reverse_content, 'a<' );
 530                      $action          = substr_replace( $action, $secondary_avatar, -$position - 2, 0 );
 531                  }
 532                  break;
 533          }
 534  
 535          return $action;
 536      }
 537  
 538      /**
 539       * Filter the default theme compatibility root template hierarchy, and prepend
 540       * a page template to the front if it's set.
 541       *
 542       * @see https://buddypress.trac.wordpress.org/ticket/6065
 543       *
 544       * @since 2.2.0
 545       *
 546       * @param  array $templates Array of templates.
 547       *                         to use the defined page template for component's directory and its single items
 548       * @return array
 549       */
 550  	public function theme_compat_page_templates( $templates = array() ) {
 551  
 552          /**
 553           * Filters whether or not we are looking at a directory to determine if to return early.
 554           *
 555           * @since 2.2.0
 556           *
 557           * @param bool $value Whether or not we are viewing a directory.
 558           */
 559          if ( true === (bool) apply_filters( 'bp_legacy_theme_compat_page_templates_directory_only', ! bp_is_directory() ) ) {
 560              return $templates;
 561          }
 562  
 563          // No page ID yet.
 564          $page_id = 0;
 565  
 566          // Get the WordPress Page ID for the current view.
 567          foreach ( (array) buddypress()->pages as $component => $bp_page ) {
 568  
 569              // Handles the majority of components.
 570              if ( bp_is_current_component( $component ) ) {
 571                  $page_id = (int) $bp_page->id;
 572              }
 573  
 574              // Stop if not on a user page.
 575              if ( ! bp_is_user() && ! empty( $page_id ) ) {
 576                  break;
 577              }
 578  
 579              // The Members component requires an explicit check due to overlapping components.
 580              if ( bp_is_user() && ( 'members' === $component ) ) {
 581                  $page_id = (int) $bp_page->id;
 582                  break;
 583              }
 584          }
 585  
 586          // Bail if no directory page set.
 587          if ( 0 === $page_id ) {
 588              return $templates;
 589          }
 590  
 591          // Check for page template.
 592          $page_template = get_page_template_slug( $page_id );
 593  
 594          // Add it to the beginning of the templates array so it takes precedence
 595          // over the default hierarchy.
 596          if ( ! empty( $page_template ) ) {
 597  
 598              /**
 599               * Check for existence of template before adding it to template
 600               * stack to avoid accidentally including an unintended file.
 601               *
 602               * @see: https://buddypress.trac.wordpress.org/ticket/6190
 603               */
 604              if ( '' !== locate_template( $page_template ) ) {
 605                  array_unshift( $templates, $page_template );
 606              }
 607          }
 608  
 609          return $templates;
 610      }
 611  }
 612  new BP_Legacy();
 613  endif;
 614  
 615  /**
 616   * Add the Create a Group button to the Groups directory title.
 617   *
 618   * The bp-legacy puts the Create a Group button into the page title, to mimic
 619   * the behavior of bp-default.
 620   *
 621   * @since 2.0.0
 622   * @todo Deprecate
 623   *
 624   * @param string $title Groups directory title.
 625   * @return string
 626   */
 627  function bp_legacy_theme_group_create_button( $title ) {
 628      return $title . ' ' . bp_get_group_create_button();
 629  }
 630  
 631  /**
 632   * Add the Create a Group nav to the Groups directory navigation.
 633   *
 634   * The bp-legacy puts the Create a Group nav at the last position of
 635   * the Groups directory navigation.
 636   *
 637   * @since 2.2.0
 638   *
 639   */
 640  function bp_legacy_theme_group_create_nav() {
 641      bp_group_create_nav_item();
 642  }
 643  
 644  /**
 645   * Renders the group ID hidden input on group admin screens.
 646   *
 647   * @since 2.7.0
 648   *
 649   * @return string|null html
 650   */
 651  function bp_legacy_groups_admin_screen_hidden_input() {
 652      ?>
 653       <input type="hidden" name="group-id" id="group-id" value="<?php bp_group_id(); ?>" />
 654      <?php
 655  }
 656  
 657  /**
 658   * Add the Create a Site button to the Sites directory title.
 659   *
 660   * The bp-legacy puts the Create a Site button into the page title, to mimic
 661   * the behavior of bp-default.
 662   *
 663   * @since 2.0.0
 664   * @todo Deprecate
 665   *
 666   * @param string $title Sites directory title.
 667   * @return string
 668   */
 669  function bp_legacy_theme_blog_create_button( $title ) {
 670      return $title . ' ' . bp_get_blog_create_button();
 671  }
 672  
 673  /**
 674   * Add the Create a Site nav to the Sites directory navigation.
 675   *
 676   * The bp-legacy puts the Create a Site nav at the last position of
 677   * the Sites directory navigation.
 678   *
 679   * @since 2.2.0
 680   *
 681   */
 682  function bp_legacy_theme_blog_create_nav() {
 683      bp_blog_create_nav_item();
 684  }
 685  
 686  /**
 687   * This function looks scarier than it actually is. :)
 688   * Each object loop (activity/members/groups/blogs/forums) contains default
 689   * parameters to show specific information based on the page we are currently
 690   * looking at.
 691   *
 692   * The following function will take into account any cookies set in the JS and
 693   * allow us to override the parameters sent. That way we can change the results
 694   * returned without reloading the page.
 695   *
 696   * By using cookies we can also make sure that user settings are retained
 697   * across page loads.
 698   *
 699   * @since 1.2.0
 700   *
 701   * @param string $query_string Query string for the current request.
 702   * @param string $object       Object for cookie.
 703   * @return string Query string for the component loops.
 704   */
 705  function bp_legacy_theme_ajax_querystring( $query_string, $object ) {
 706      if ( empty( $object ) )
 707          return '';
 708  
 709      // Set up the cookies passed on this AJAX request. Store a local var to avoid conflicts.
 710      if ( ! empty( $_POST['cookie'] ) ) {
 711          $_BP_COOKIE = bp_parse_args(
 712              str_replace( '; ', '&', urldecode( $_POST['cookie'] ) )
 713          );
 714      } else {
 715          $_BP_COOKIE = &$_COOKIE;
 716      }
 717  
 718      $qs = array();
 719  
 720      /**
 721       * Check if any cookie values are set. If there are then override the
 722       * default params passed to the template loop.
 723       */
 724  
 725      // Activity stream filtering on action.
 726      if ( ! empty( $_BP_COOKIE['bp-' . $object . '-filter'] ) && '-1' != $_BP_COOKIE['bp-' . $object . '-filter'] ) {
 727          $qs[] = 'type=' . urlencode( $_BP_COOKIE['bp-' . $object . '-filter'] );
 728  
 729          if ( bp_is_active( 'activity' ) ) {
 730              $actions = bp_activity_get_actions_for_context();
 731  
 732              // Handle multiple actions (eg. 'friendship_accepted,friendship_created')
 733              $action_filter = explode( ',', $_BP_COOKIE['bp-' . $object . '-filter'] );
 734  
 735              // See if action filter matches registered actions. If so, add it to qs.
 736              if ( ! array_diff( $action_filter, wp_list_pluck( $actions, 'key' ) ) ) {
 737                  $qs[] = 'action=' . join( ',', $action_filter );
 738              }
 739          }
 740      }
 741  
 742      if ( ! empty( $_BP_COOKIE['bp-' . $object . '-scope'] ) ) {
 743          if ( 'personal' == $_BP_COOKIE['bp-' . $object . '-scope'] ) {
 744              $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
 745              $qs[] = 'user_id=' . $user_id;
 746          }
 747  
 748          // Activity stream scope only on activity directory.
 749          if ( 'all' != $_BP_COOKIE['bp-' . $object . '-scope'] && ! bp_displayed_user_id() && ! bp_is_single_item() )
 750              $qs[] = 'scope=' . urlencode( $_BP_COOKIE['bp-' . $object . '-scope'] );
 751      }
 752  
 753      // If page and search_terms have been passed via the AJAX post request, use those.
 754      if ( ! empty( $_POST['page'] ) && '-1' != $_POST['page'] )
 755          $qs[] = 'page=' . absint( $_POST['page'] );
 756  
 757      // Excludes activity just posted and avoids duplicate ids.
 758      if ( ! empty( $_POST['exclude_just_posted'] ) ) {
 759          $just_posted = wp_parse_id_list( $_POST['exclude_just_posted'] );
 760          $qs[] = 'exclude=' . implode( ',', $just_posted );
 761      }
 762  
 763      // To get newest activities.
 764      if ( ! empty( $_POST['offset'] ) ) {
 765          $qs[] = 'offset=' . intval( $_POST['offset'] );
 766      }
 767  
 768      $object_search_text = bp_get_search_default_text( $object );
 769      if ( ! empty( $_POST['search_terms'] ) && is_string( $_POST['search_terms'] ) && $object_search_text != $_POST['search_terms'] && 'false' != $_POST['search_terms'] && 'undefined' != $_POST['search_terms'] )
 770          $qs[] = 'search_terms=' . urlencode( $_POST['search_terms'] );
 771  
 772      // Now pass the querystring to override default values.
 773      $query_string = empty( $qs ) ? '' : join( '&', (array) $qs );
 774  
 775      $object_filter = '';
 776      if ( isset( $_BP_COOKIE['bp-' . $object . '-filter'] ) )
 777          $object_filter = $_BP_COOKIE['bp-' . $object . '-filter'];
 778  
 779      $object_scope = '';
 780      if ( isset( $_BP_COOKIE['bp-' . $object . '-scope'] ) )
 781          $object_scope = $_BP_COOKIE['bp-' . $object . '-scope'];
 782  
 783      $object_page = '';
 784      if ( isset( $_BP_COOKIE['bp-' . $object . '-page'] ) )
 785          $object_page = $_BP_COOKIE['bp-' . $object . '-page'];
 786  
 787      $object_search_terms = '';
 788      if ( isset( $_BP_COOKIE['bp-' . $object . '-search-terms'] ) )
 789          $object_search_terms = $_BP_COOKIE['bp-' . $object . '-search-terms'];
 790  
 791      $object_extras = '';
 792      if ( isset( $_BP_COOKIE['bp-' . $object . '-extras'] ) )
 793          $object_extras = $_BP_COOKIE['bp-' . $object . '-extras'];
 794  
 795      /**
 796       * Filters the AJAX query string for the component loops.
 797       *
 798       * @since 1.7.0
 799       *
 800       * @param string $query_string        The query string we are working with.
 801       * @param string $object              The type of page we are on.
 802       * @param string $object_filter       The current object filter.
 803       * @param string $object_scope        The current object scope.
 804       * @param string $object_page         The current object page.
 805       * @param string $object_search_terms The current object search terms.
 806       * @param string $object_extras       The current object extras.
 807       */
 808      return apply_filters( 'bp_legacy_theme_ajax_querystring', $query_string, $object, $object_filter, $object_scope, $object_page, $object_search_terms, $object_extras );
 809  }
 810  
 811  /**
 812   * Load the template loop for the current object.
 813   *
 814   * @since 1.2.0
 815   *
 816   * @return string|null Prints template loop for the specified object
 817   */
 818  function bp_legacy_theme_object_template_loader() {
 819      if ( ! bp_is_post_request() ) {
 820          return;
 821      }
 822  
 823      // Bail if no object passed.
 824      if ( empty( $_POST['object'] ) ) {
 825          return;
 826      }
 827  
 828      // Sanitize the object.
 829      $object = sanitize_title( $_POST['object'] );
 830  
 831      // Bail if object is not an active component to prevent arbitrary file inclusion.
 832      if ( ! bp_is_active( $object ) ) {
 833          return;
 834      }
 835  
 836      /**
 837       * AJAX requests happen too early to be seen by bp_update_is_directory()
 838       * so we do it manually here to ensure templates load with the correct
 839       * context. Without this check, templates will load the 'single' version
 840       * of themselves rather than the directory version.
 841       */
 842      if ( ! bp_current_action() )
 843          bp_update_is_directory( true, bp_current_component() );
 844  
 845      // The template part can be overridden by the calling JS function.
 846      if ( ! empty( $_POST['template'] ) && 'groups/single/members' === $_POST['template'] ) {
 847          $template_part = 'groups/single/members.php';
 848      } else {
 849          $template_part = $object . '/' . $object . '-loop.php';
 850      }
 851  
 852      $template_path = bp_locate_template( array( $template_part ), false );
 853  
 854      $template_path = apply_filters( 'bp_legacy_object_template_path', $template_path );
 855  
 856      load_template( $template_path );
 857      exit();
 858  }
 859  
 860  /**
 861   * Load messages template loop when searched on the private message page
 862   *
 863   * @since 1.6.0
 864   *
 865   * @return string|null Prints template loop for the Messages component.
 866   */
 867  function bp_legacy_theme_messages_template_loader() {
 868      bp_get_template_part( 'members/single/messages/messages-loop' );
 869      exit();
 870  }
 871  
 872  /**
 873   * Load group invitations loop to handle pagination requests sent via AJAX.
 874   *
 875   * @since 2.0.0
 876   */
 877  function bp_legacy_theme_invite_template_loader() {
 878      bp_get_template_part( 'groups/single/invites-loop' );
 879      exit();
 880  }
 881  
 882  /**
 883   * Load group membership requests loop to handle pagination requests sent via AJAX.
 884   *
 885   * @since 2.0.0
 886   */
 887  function bp_legacy_theme_requests_template_loader() {
 888      bp_get_template_part( 'groups/single/requests-loop' );
 889      exit();
 890  }
 891  
 892  /**
 893   * Load the activity loop template when activity is requested via AJAX.
 894   *
 895   * @since 1.2.0
 896   *
 897   * @return string|null JSON object containing 'contents' (output of the template loop
 898   *                     for the Activity component) and 'feed_url' (URL to the relevant RSS feed).
 899   */
 900  function bp_legacy_theme_activity_template_loader() {
 901      if ( ! bp_is_post_request() ) {
 902          return;
 903      }
 904  
 905      $scope = '';
 906      if ( ! empty( $_POST['scope'] ) )
 907          $scope = $_POST['scope'];
 908  
 909      // We need to calculate and return the feed URL for each scope.
 910      switch ( $scope ) {
 911          case 'friends':
 912              $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/friends/feed/';
 913              break;
 914          case 'groups':
 915              $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/groups/feed/';
 916              break;
 917          case 'favorites':
 918              $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/feed/';
 919              break;
 920          case 'mentions':
 921              $feed_url = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/feed/';
 922  
 923              if ( isset( $_POST['_wpnonce_activity_filter'] ) && wp_verify_nonce( wp_unslash( $_POST['_wpnonce_activity_filter'] ), 'activity_filter' ) ) {
 924                  bp_activity_clear_new_mentions( bp_loggedin_user_id() );
 925              }
 926  
 927              break;
 928          default:
 929              $feed_url = home_url( bp_get_activity_root_slug() . '/feed/' );
 930              break;
 931      }
 932  
 933      // Buffer the loop in the template to a var for JS to spit out.
 934      ob_start();
 935      bp_get_template_part( 'activity/activity-loop' );
 936      $result['contents'] = ob_get_contents();
 937  
 938      /**
 939       * Filters the feed URL for when activity is requested via AJAX.
 940       *
 941       * @since 1.7.0
 942       *
 943       * @param string $feed_url URL for the feed to be used.
 944       * @param string $scope    Scope for the activity request.
 945       */
 946      $result['feed_url'] = apply_filters( 'bp_legacy_theme_activity_feed_url', $feed_url, $scope );
 947      ob_end_clean();
 948  
 949      exit( json_encode( $result ) );
 950  }
 951  
 952  /**
 953   * Processes Activity updates received via a POST request.
 954   *
 955   * @since 1.2.0
 956   *
 957   * @return string|null HTML
 958   */
 959  function bp_legacy_theme_post_update() {
 960      $bp = buddypress();
 961  
 962      if ( ! bp_is_post_request() ) {
 963          return;
 964      }
 965  
 966      // Check the nonce.
 967      check_admin_referer( 'post_update', '_wpnonce_post_update' );
 968  
 969      if ( ! is_user_logged_in() )
 970          exit( '-1' );
 971  
 972      if ( empty( $_POST['content'] ) )
 973          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . __( 'Please enter some content to post.', 'buddypress' ) . '</p></div>' );
 974  
 975      $activity_id = 0;
 976      $item_id     = 0;
 977      $object      = '';
 978  
 979  
 980      // Try to get the item id from posted variables.
 981      if ( ! empty( $_POST['item_id'] ) ) {
 982          $item_id = (int) $_POST['item_id'];
 983      }
 984  
 985      // Try to get the object from posted variables.
 986      if ( ! empty( $_POST['object'] ) ) {
 987          $object  = sanitize_key( $_POST['object'] );
 988  
 989      // If the object is not set and we're in a group, set the item id and the object
 990      } elseif ( bp_is_group() ) {
 991          $item_id = bp_get_current_group_id();
 992          $object = 'groups';
 993      }
 994  
 995      if ( ! $object && bp_is_active( 'activity' ) ) {
 996          $activity_id = bp_activity_post_update( array( 'content' => $_POST['content'], 'error_type' => 'wp_error' ) );
 997  
 998      } elseif ( 'groups' === $object ) {
 999          if ( $item_id && bp_is_active( 'groups' ) )
1000              $activity_id = groups_post_update( array( 'content' => $_POST['content'], 'group_id' => $item_id, 'error_type' => 'wp_error' ) );
1001  
1002      } else {
1003  
1004          /** This filter is documented in bp-activity/actions/post.php */
1005          $activity_id = apply_filters( 'bp_activity_custom_update', false, $object, $item_id, $_POST['content'] );
1006      }
1007  
1008      if ( false === $activity_id ) {
1009          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . __( 'There was a problem posting your update. Please try again.', 'buddypress' ) . '</p></div>' );
1010      } elseif ( is_wp_error( $activity_id ) && $activity_id->get_error_code() ) {
1011          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . $activity_id->get_error_message() . '</p></div>' );
1012      }
1013  
1014      $last_recorded = ! empty( $_POST['since'] ) ? date( 'Y-m-d H:i:s', intval( $_POST['since'] ) ) : 0;
1015      if ( $last_recorded ) {
1016          $activity_args = array( 'since' => $last_recorded );
1017          $bp->activity->last_recorded = $last_recorded;
1018          add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
1019      } else {
1020          $activity_args = array( 'include' => $activity_id );
1021      }
1022  
1023      if ( bp_has_activities ( $activity_args ) ) {
1024          while ( bp_activities() ) {
1025              bp_the_activity();
1026              bp_get_template_part( 'activity/entry' );
1027          }
1028      }
1029  
1030      if ( ! empty( $last_recorded ) ) {
1031          remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10 );
1032      }
1033  
1034      exit;
1035  }
1036  
1037  /**
1038   * Posts new Activity comments received via a POST request.
1039   *
1040   * @since 1.2.0
1041   *
1042   * @global BP_Activity_Template $activities_template
1043   *
1044   * @return string|null HTML
1045   */
1046  function bp_legacy_theme_new_activity_comment() {
1047      global $activities_template;
1048  
1049      $bp = buddypress();
1050  
1051      if ( ! bp_is_post_request() ) {
1052          return;
1053      }
1054  
1055      // Check the nonce.
1056      check_admin_referer( 'new_activity_comment', '_wpnonce_new_activity_comment' );
1057  
1058      if ( ! is_user_logged_in() ) {
1059          exit( '-1' );
1060      }
1061  
1062      $feedback = __( 'There was an error posting your reply. Please try again.', 'buddypress' );
1063  
1064      if ( empty( $_POST['content'] ) ) {
1065          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . esc_html__( 'Please do not leave the comment area blank.', 'buddypress' ) . '</p></div>' );
1066      }
1067  
1068      if ( empty( $_POST['form_id'] ) || empty( $_POST['comment_id'] ) || ! is_numeric( $_POST['form_id'] ) || ! is_numeric( $_POST['comment_id'] ) ) {
1069          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . esc_html( $feedback ) . '</p></div>' );
1070      }
1071  
1072      $activity_id   = (int) $_POST['form_id'];
1073      $activity_item = new BP_Activity_Activity( $activity_id );
1074      if ( ! bp_activity_user_can_read( $activity_item ) ) {
1075          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . esc_html( $feedback ) . '</p></div>' );
1076      }
1077  
1078      $comment_id = bp_activity_new_comment( array(
1079          'activity_id' => $activity_id,
1080          'content'     => $_POST['content'],
1081          'parent_id'   => $_POST['comment_id'],
1082          'error_type'  => 'wp_error'
1083      ) );
1084  
1085      if ( is_wp_error( $comment_id ) ) {
1086          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . esc_html( $comment_id->get_error_message() ) . '</p></div>' );
1087      }
1088  
1089      // Load the new activity item into the $activities_template global.
1090      bp_has_activities( 'display_comments=stream&hide_spam=false&show_hidden=true&include=' . $comment_id );
1091  
1092      // Swap the current comment with the activity item we just loaded.
1093      if ( isset( $activities_template->activities[0] ) ) {
1094          $activities_template->activity = new stdClass();
1095          $activities_template->activity->id              = $activities_template->activities[0]->item_id;
1096          $activities_template->activity->current_comment = $activities_template->activities[0];
1097  
1098          // Because the whole tree has not been loaded, we manually
1099          // determine depth.
1100          $depth = 1;
1101          $parent_id = (int) $activities_template->activities[0]->secondary_item_id;
1102          while ( $parent_id !== (int) $activities_template->activities[0]->item_id ) {
1103              $depth++;
1104              $p_obj = new BP_Activity_Activity( $parent_id );
1105              $parent_id = (int) $p_obj->secondary_item_id;
1106          }
1107          $activities_template->activity->current_comment->depth = $depth;
1108      }
1109  
1110      // Get activity comment template part.
1111      bp_get_template_part( 'activity/comment' );
1112  
1113      unset( $activities_template );
1114      exit;
1115  }
1116  
1117  /**
1118   * Deletes an Activity item received via a POST request.
1119   *
1120   * @since 1.2.0
1121   *
1122   * @return mixed String on error, void on success.
1123   */
1124  function bp_legacy_theme_delete_activity() {
1125      if ( ! bp_is_post_request() ) {
1126          return;
1127      }
1128  
1129      // Check the nonce.
1130      check_admin_referer( 'bp_activity_delete_link' );
1131  
1132      if ( ! is_user_logged_in() )
1133          exit( '-1' );
1134  
1135      if ( empty( $_POST['id'] ) || ! is_numeric( $_POST['id'] ) )
1136          exit( '-1' );
1137  
1138      $activity = new BP_Activity_Activity( (int) $_POST['id'] );
1139  
1140      // Check access.
1141      if ( ! bp_activity_user_can_delete( $activity ) )
1142          exit( '-1' );
1143  
1144      /** This action is documented in bp-activity/bp-activity-actions.php */
1145      do_action( 'bp_activity_before_action_delete_activity', $activity->id, $activity->user_id );
1146  
1147      if ( ! bp_activity_delete( array( 'id' => $activity->id, 'user_id' => $activity->user_id ) ) )
1148          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . __( 'There was a problem when deleting. Please try again.', 'buddypress' ) . '</p></div>' );
1149  
1150      /** This action is documented in bp-activity/bp-activity-actions.php */
1151      do_action( 'bp_activity_action_delete_activity', $activity->id, $activity->user_id );
1152      exit;
1153  }
1154  
1155  /**
1156   * Deletes an Activity comment received via a POST request.
1157   *
1158   * @since 1.2.0
1159   *
1160   * @return mixed String on error, void on success.
1161   */
1162  function bp_legacy_theme_delete_activity_comment() {
1163      if ( ! bp_is_post_request() ) {
1164          return;
1165      }
1166  
1167      // Check the nonce.
1168      check_admin_referer( 'bp_activity_delete_link' );
1169  
1170      if ( empty( $_POST['id'] ) || ! is_numeric( $_POST['id'] ) ) {
1171          exit( '-1' );
1172      }
1173  
1174      if ( ! is_user_logged_in() ) {
1175          exit( '-1' );
1176      }
1177  
1178      $comment = new BP_Activity_Activity( $_POST['id'] );
1179  
1180      // Check access.
1181      if ( ! bp_current_user_can( 'bp_moderate' ) && $comment->user_id != bp_loggedin_user_id() )
1182          exit( '-1' );
1183  
1184      /** This action is documented in bp-activity/bp-activity-actions.php */
1185      do_action( 'bp_activity_before_action_delete_activity', $_POST['id'], $comment->user_id );
1186  
1187      if ( ! bp_activity_delete_comment( $comment->item_id, $comment->id ) )
1188          exit( '-1<div id="message" class="error bp-ajax-message"><p>' . __( 'There was a problem when deleting. Please try again.', 'buddypress' ) . '</p></div>' );
1189  
1190      /** This action is documented in bp-activity/bp-activity-actions.php */
1191      do_action( 'bp_activity_action_delete_activity', $_POST['id'], $comment->user_id );
1192      exit;
1193  }
1194  
1195  /**
1196   * AJAX spam an activity item or comment.
1197   *
1198   * @since 1.6.0
1199   *
1200   * @return mixed String on error, void on success.
1201   */
1202  function bp_legacy_theme_spam_activity() {
1203      $bp = buddypress();
1204  
1205      if ( ! bp_is_post_request() ) {
1206          return;
1207      }
1208  
1209      // Check that user is logged in, Activity Streams are enabled, and Akismet is present.
1210      if ( ! is_user_logged_in() || ! bp_is_active( 'activity' ) || empty( $bp->activity->akismet ) )
1211          exit( '-1' );
1212  
1213      // Check an item ID was passed.
1214      if ( empty( $_POST['id'] ) || ! is_numeric( $_POST['id'] ) )
1215          exit( '-1' );
1216  
1217      // Is the current user allowed to spam items?
1218      if ( ! bp_activity_user_can_mark_spam() )
1219          exit( '-1' );
1220  
1221      // Load up the activity item.
1222      $activity = new BP_Activity_Activity( (int) $_POST['id'] );
1223      if ( empty( $activity->component ) )
1224          exit( '-1' );
1225  
1226      // Check nonce.
1227      check_admin_referer( 'bp_activity_akismet_spam_' . $activity->id );
1228  
1229      /** This action is documented in bp-activity/bp-activity-actions.php */
1230      do_action( 'bp_activity_before_action_spam_activity', $activity->id, $activity );
1231  
1232      // Mark as spam.
1233      bp_activity_mark_as_spam( $activity );
1234      $activity->save();
1235  
1236      /** This action is documented in bp-activity/bp-activity-actions.php */
1237      do_action( 'bp_activity_action_spam_activity', $activity->id, $activity->user_id );
1238      exit;
1239  }
1240  
1241  /**
1242   * Mark an activity as a favourite via a POST request.
1243   *
1244   * @since 1.2.0
1245   *
1246   * @return string|null HTML
1247   */
1248  function bp_legacy_theme_mark_activity_favorite() {
1249      // Bail if not a POST action.
1250      if ( ! bp_is_post_request() ) {
1251          return;
1252      }
1253  
1254      if ( ! isset( $_POST['nonce'] ) ) {
1255          return;
1256      }
1257  
1258      // Either the 'mark' or 'unmark' nonce is accepted, for backward compatibility.
1259      $nonce = wp_unslash( $_POST['nonce'] );
1260      if ( ! wp_verify_nonce( $nonce, 'mark_favorite' ) && ! wp_verify_nonce( $nonce, 'unmark_favorite' ) ) {
1261          return;
1262      }
1263  
1264      $activity_id   = (int) $_POST['id'];
1265      $activity_item = new BP_Activity_Activity( $activity_id );
1266      if ( ! bp_activity_user_can_read( $activity_item, bp_loggedin_user_id() ) ) {
1267          return;
1268      }
1269  
1270      if ( bp_activity_add_user_favorite( $_POST['id'] ) )
1271          _e( 'Remove Favorite', 'buddypress' );
1272      else
1273          _e( 'Favorite', 'buddypress' );
1274  
1275      exit;
1276  }
1277  
1278  /**
1279   * Un-favourite an activity via a POST request.
1280   *
1281   * @since 1.2.0
1282   *
1283   * @return string|null HTML
1284   */
1285  function bp_legacy_theme_unmark_activity_favorite() {
1286      if ( ! bp_is_post_request() ) {
1287          return;
1288      }
1289  
1290      if ( ! isset( $_POST['nonce'] ) ) {
1291          return;
1292      }
1293  
1294      // Either the 'mark' or 'unmark' nonce is accepted, for backward compatibility.
1295      $nonce = wp_unslash( $_POST['nonce'] );
1296      if ( ! wp_verify_nonce( $nonce, 'mark_favorite' ) && ! wp_verify_nonce( $nonce, 'unmark_favorite' ) ) {
1297          return;
1298      }
1299  
1300      if ( bp_activity_remove_user_favorite( $_POST['id'] ) )
1301          _e( 'Favorite', 'buddypress' );
1302      else
1303          _e( 'Remove Favorite', 'buddypress' );
1304  
1305      exit;
1306  }
1307  
1308  /**
1309   * Fetches an activity's full, non-excerpted content via a POST request.
1310   * Used for the 'Read More' link on long activity items.
1311   *
1312   * @since 1.5.0
1313   *
1314   * @return string|null HTML
1315   */
1316  function bp_legacy_theme_get_single_activity_content() {
1317      if ( ! bp_is_post_request() ) {
1318          return;
1319      }
1320  
1321      $activity_array = bp_activity_get_specific( array(
1322          'activity_ids'     => $_POST['activity_id'],
1323          'display_comments' => 'stream'
1324      ) );
1325  
1326      $activity = ! empty( $activity_array['activities'][0] ) ? $activity_array['activities'][0] : false;
1327  
1328      if ( empty( $activity ) )
1329          exit; // @todo: error?
1330  
1331      /**
1332       * Fires before the return of an activity's full, non-excerpted content via a POST request.
1333       *
1334       * @since 1.7.0
1335       *
1336       * @param string $activity Activity content. Passed by reference.
1337       */
1338      do_action_ref_array( 'bp_legacy_theme_get_single_activity_content', array( &$activity ) );
1339  
1340      // Activity content retrieved through AJAX should run through normal filters, but not be truncated.
1341      remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
1342  
1343      /** This filter is documented in bp-activity/bp-activity-template.php */
1344      $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $activity->content, &$activity ) );
1345  
1346      exit( $content );
1347  }
1348  
1349  /**
1350   * Invites a friend to join a group via a POST request.
1351   *
1352   * @since 1.2.0
1353   *
1354   * @todo Audit return types
1355   */
1356  function bp_legacy_theme_ajax_invite_user() {
1357      if ( ! bp_is_post_request() ) {
1358          return;
1359      }
1360  
1361      check_ajax_referer( 'groups_invite_uninvite_user' );
1362  
1363      if ( ! $_POST['friend_id'] || ! $_POST['friend_action'] || ! $_POST['group_id'] )
1364          return;
1365  
1366      if ( ! bp_groups_user_can_send_invites( $_POST['group_id'] ) )
1367          return;
1368  
1369      $group_id = (int) $_POST['group_id'];
1370      $friend_id = (int) $_POST['friend_id'];
1371  
1372      if ( 'invite' == $_POST['friend_action'] ) {
1373          if ( ! friends_check_friendship( bp_loggedin_user_id(), $_POST['friend_id'] ) ) {
1374              return;
1375          }
1376  
1377          $group = groups_get_group( $group_id );
1378  
1379          // Users who have previously requested membership do not need
1380          // another invitation created for them.
1381          if ( groups_check_for_membership_request( $friend_id, $group_id ) ) {
1382              $user_status = 'is_pending';
1383  
1384          // Create the user invitation.
1385          } elseif ( groups_invite_user( array( 'user_id' => $friend_id, 'group_id' => $group_id ) ) ) {
1386              $user_status = 'is_invited';
1387  
1388          // Miscellaneous failure.
1389          } else {
1390              return;
1391          }
1392  
1393          $user = new BP_Core_User( $friend_id );
1394  
1395          $uninvite_url = bp_is_current_action( 'create' )
1396              ? bp_get_groups_directory_permalink() . 'create/step/group-invites/?user_id=' . $friend_id
1397              : bp_get_group_permalink( $group )    . 'send-invites/remove/' . $friend_id;
1398  
1399          echo '<li id="uid-' . esc_attr( $user->id ) . '">';
1400          echo $user->avatar_thumb;
1401          echo '<h4>' . $user->user_link . '</h4>';
1402          echo '<span class="activity">' . esc_attr( $user->last_active ) . '</span>';
1403          echo '<div class="action">
1404                  <a class="button remove" href="' . wp_nonce_url( $uninvite_url, 'groups_invite_uninvite_user' ) . '" id="uid-' . esc_attr( $user->id ) . '">' . __( 'Remove Invite', 'buddypress' ) . '</a>
1405                </div>';
1406  
1407          if ( 'is_pending' == $user_status ) {
1408              /* translators: %s: user link */
1409              echo '<p class="description">' . sprintf( __( '%s has previously requested to join this group. Sending an invitation will automatically add the member to the group.', 'buddypress' ), $user->user_link ) . '</p>';
1410          }
1411  
1412          echo '</li>';
1413          exit;
1414  
1415      } elseif ( 'uninvite' == $_POST['friend_action'] ) {
1416          // Users who have previously requested membership should not
1417          // have their requests deleted on the "uninvite" action.
1418          if ( BP_Groups_Member::check_for_membership_request( $friend_id, $group_id ) ) {
1419              return;
1420          }
1421  
1422          // Remove the unsent invitation.
1423          if ( ! groups_uninvite_user( $friend_id, $group_id ) ) {
1424              return;
1425          }
1426  
1427          exit;
1428  
1429      } else {
1430          return;
1431      }
1432  }
1433  
1434  /**
1435   * Friend/un-friend a user via a POST request.
1436   *
1437   * @since 1.2.0
1438   *
1439   * @return string|null HTML
1440   */
1441  function bp_legacy_theme_ajax_addremove_friend() {
1442      if ( ! bp_is_post_request() ) {
1443          return;
1444      }
1445  
1446      // Cast fid as an integer.
1447      $friend_id = (int) $_POST['fid'];
1448  
1449      $user = get_user_by( 'id', $friend_id );
1450      if ( ! $user ) {
1451          die( __( 'No member found by that ID.', 'buddypress' ) );
1452      }
1453  
1454      // Trying to cancel friendship.
1455      if ( 'is_friend' == BP_Friends_Friendship::check_is_friend( bp_loggedin_user_id(), $friend_id ) ) {
1456          check_ajax_referer( 'friends_remove_friend' );
1457  
1458          if ( ! friends_remove_friend( bp_loggedin_user_id(), $friend_id ) ) {
1459              echo __( 'Friendship could not be canceled.', 'buddypress' );
1460          } else {
1461              echo '<a id="friend-' . esc_attr( $friend_id ) . '" class="friendship-button not_friends add" rel="add" href="' . wp_nonce_url( bp_loggedin_user_domain() . bp_get_friends_slug() . '/add-friend/' . $friend_id, 'friends_add_friend' ) . '">' . __( 'Add Friend', 'buddypress' ) . '</a>';
1462          }
1463  
1464      // Trying to request friendship.
1465      } elseif ( 'not_friends' == BP_Friends_Friendship::check_is_friend( bp_loggedin_user_id(), $friend_id ) ) {
1466          check_ajax_referer( 'friends_add_friend' );
1467  
1468          if ( ! friends_add_friend( bp_loggedin_user_id(), $friend_id ) ) {
1469              echo __(' Friendship could not be requested.', 'buddypress' );
1470          } else {
1471              echo '<a id="friend-' . esc_attr( $friend_id ) . '" class="remove friendship-button pending_friend requested" rel="remove" href="' . wp_nonce_url( bp_loggedin_user_domain() . bp_get_friends_slug() . '/requests/cancel/' . $friend_id . '/', 'friends_withdraw_friendship' ) . '" class="requested">' . __( 'Cancel Friendship Request', 'buddypress' ) . '</a>';
1472          }
1473  
1474      // Trying to cancel pending request.
1475      } elseif ( 'pending' == BP_Friends_Friendship::check_is_friend( bp_loggedin_user_id(), $friend_id ) ) {
1476          check_ajax_referer( 'friends_withdraw_friendship' );
1477  
1478          if ( friends_withdraw_friendship( bp_loggedin_user_id(), $friend_id ) ) {
1479              echo '<a id="friend-' . esc_attr( $friend_id ) . '" class="friendship-button not_friends add" rel="add" href="' . wp_nonce_url( bp_loggedin_user_domain() . bp_get_friends_slug() . '/add-friend/' . $friend_id, 'friends_add_friend' ) . '">' . __( 'Add Friend', 'buddypress' ) . '</a>';
1480          } else {
1481              echo __("Friendship request could not be cancelled.", 'buddypress');
1482          }
1483  
1484      // Request already pending.
1485      } else {
1486          echo __( 'Request Pending', 'buddypress' );
1487      }
1488  
1489      exit;
1490  }
1491  
1492  /**
1493   * Accept a user friendship request via a POST request.
1494   *
1495   * @since 1.2.0
1496   *
1497   * @return mixed String on error, void on success.
1498   */
1499  function bp_legacy_theme_ajax_accept_friendship() {
1500      if ( ! bp_is_post_request() ) {
1501          return;
1502      }
1503  
1504      check_admin_referer( 'friends_accept_friendship' );
1505  
1506      if ( ! friends_accept_friendship( (int) $_POST['id'] ) )
1507          echo "-1<div id='message' class='error'><p>" . __( 'There was a problem accepting that request. Please try again.', 'buddypress' ) . '</p></div>';
1508  
1509      exit;
1510  }
1511  
1512  /**
1513   * Reject a user friendship request via a POST request.
1514   *
1515   * @since 1.2.0
1516   *
1517   * @return mixed String on error, void on success.
1518   */
1519  function bp_legacy_theme_ajax_reject_friendship() {
1520      if ( ! bp_is_post_request() ) {
1521          return;
1522      }
1523  
1524      check_admin_referer( 'friends_reject_friendship' );
1525  
1526      if ( ! friends_reject_friendship( (int) $_POST['id'] ) )
1527          echo "-1<div id='message' class='error'><p>" . __( 'There was a problem rejecting that request. Please try again.', 'buddypress' ) . '</p></div>';
1528  
1529      exit;
1530  }
1531  
1532  /**
1533   * Join or leave a group when clicking the "join/leave" button via a POST request.
1534   *
1535   * @since 1.2.0
1536   *
1537   * @return string|null HTML
1538   */
1539  function bp_legacy_theme_ajax_joinleave_group() {
1540      if ( ! bp_is_post_request() ) {
1541          return;
1542      }
1543  
1544      // Cast gid as integer.
1545      $group_id = (int) $_POST['gid'];
1546  
1547      if ( groups_is_user_banned( bp_loggedin_user_id(), $group_id ) ) {
1548          return;
1549      }
1550  
1551      $group = groups_get_group( $group_id );
1552  
1553      if ( ! $group ) {
1554          return;
1555      }
1556  
1557      $action = '';
1558      if ( isset( $_POST['action'] ) ) {
1559          $action = sanitize_key( wp_unslash( $_POST['action'] ) );
1560      }
1561  
1562      // Client doesn't distinguish between different request types, so we infer from user status.
1563      if ( groups_is_user_member( bp_loggedin_user_id(), $group->id ) ) {
1564          $request_type = 'leave_group';
1565      } elseif ( groups_check_user_has_invite( bp_loggedin_user_id(), $group->id ) && 'joinleave_group' !== $action ) {
1566          $request_type = 'accept_invite';
1567      } elseif ( 'private' === $group->status ) {
1568          $request_type = 'request_membership';
1569      } else {
1570          $request_type = 'join_group';
1571      }
1572  
1573      switch ( $request_type ) {
1574          case 'join_group' :
1575              if ( ! bp_current_user_can( 'groups_join_group', array( 'group_id' => $group->id ) ) ) {
1576                  esc_html_e( 'Error joining group', 'buddypress' );
1577              }
1578  
1579              check_ajax_referer( 'groups_join_group' );
1580  
1581              if ( ! groups_join_group( $group->id ) ) {
1582                  _e( 'Error joining group', 'buddypress' );
1583              } else {
1584                  echo '<a id="group-' . esc_attr( $group->id ) . '" class="group-button leave-group" rel="leave" href="' . wp_nonce_url( bp_get_group_permalink( $group ) . 'leave-group', 'groups_leave_group' ) . '">' . __( 'Leave Group', 'buddypress' ) . '</a>';
1585              }
1586          break;
1587  
1588          case 'accept_invite' :
1589              if ( ! bp_current_user_can( 'groups_request_membership', array( 'group_id' => $group->id ) ) ) {
1590                  esc_html_e( 'Error accepting invitation', 'buddypress' );
1591              }
1592  
1593              check_ajax_referer( 'groups_accept_invite' );
1594  
1595              if ( ! groups_accept_invite( bp_loggedin_user_id(), $group->id ) ) {
1596                  _e( 'Error requesting membership', 'buddypress' );
1597              } else {
1598                  echo '<a id="group-' . esc_attr( $group->id ) . '" class="group-button leave-group" rel="leave" href="' . wp_nonce_url( bp_get_group_permalink( $group ) . 'leave-group', 'groups_leave_group' ) . '">' . __( 'Leave Group', 'buddypress' ) . '</a>';
1599              }
1600          break;
1601  
1602          case 'request_membership' :
1603              check_ajax_referer( 'groups_request_membership' );
1604  
1605              if ( ! groups_send_membership_request( [ 'user_id' => bp_loggedin_user_id(), 'group_id' => $group->id ] ) ) {
1606                  _e( 'Error requesting membership', 'buddypress' );
1607              } else {
1608                  echo '<a id="group-' . esc_attr( $group->id ) . '" class="group-button disabled pending membership-requested" rel="membership-requested" href="' . bp_get_group_permalink( $group ) . '">' . __( 'Request Sent', 'buddypress' ) . '</a>';
1609              }
1610          break;
1611  
1612          case 'leave_group' :
1613              check_ajax_referer( 'groups_leave_group' );
1614  
1615              if ( ! groups_leave_group( $group->id ) ) {
1616                  _e( 'Error leaving group', 'buddypress' );
1617              } elseif ( 'public' === $group->status ) {
1618                  echo '<a id="group-' . esc_attr( $group->id ) . '" class="group-button join-group" rel="join" href="' . wp_nonce_url( bp_get_group_permalink( $group ) . 'join', 'groups_join_group' ) . '">' . __( 'Join Group', 'buddypress' ) . '</a>';
1619              } else {
1620                  echo '<a id="group-' . esc_attr( $group->id ) . '" class="group-button request-membership" rel="join" href="' . wp_nonce_url( bp_get_group_permalink( $group ) . 'request-membership', 'groups_request_membership' ) . '">' . __( 'Request Membership', 'buddypress' ) . '</a>';
1621              }
1622          break;
1623      }
1624  
1625      exit;
1626  }
1627  
1628  /**
1629   * Close and keep closed site wide notices from an admin in the sidebar, via a POST request.
1630   *
1631   * @since 1.2.0
1632   *
1633   * @return mixed String on error, void on success.
1634   */
1635  function bp_legacy_theme_ajax_close_notice() {
1636      if ( ! bp_is_post_request() ) {
1637          return;
1638      }
1639  
1640      $nonce_check = isset( $_POST['nonce'] ) && wp_verify_nonce( wp_unslash( $_POST['nonce'] ), 'bp_messages_close_notice' );
1641  
1642      if ( ! $nonce_check || ! isset( $_POST['notice_id'] ) ) {
1643          echo "-1<div id='message' class='error'><p>" . __( 'There was a problem closing the notice.', 'buddypress' ) . '</p></div>';
1644  
1645      } else {
1646          bp_messages_dismiss_sitewide_notice( bp_loggedin_user_id(), (int) $_POST['notice_id'] );
1647      }
1648  
1649      exit;
1650  }
1651  
1652  /**
1653   * Send a private message reply to a thread via a POST request.
1654   *
1655   * @since 1.2.0
1656   *
1657   * @return string|null HTML
1658   */
1659  function bp_legacy_theme_ajax_messages_send_reply() {
1660      if ( ! bp_is_post_request() ) {
1661          return;
1662      }
1663  
1664      check_ajax_referer( 'messages_send_message' );
1665  
1666      $thread_id = (int) $_POST['thread_id'];
1667  
1668      // Cannot respond to a thread you're not already a recipient on.
1669      if ( ! bp_current_user_can( 'bp_moderate' ) && ( ! messages_is_valid_thread( $thread_id ) || ! messages_check_thread_access( $thread_id ) ) ) {
1670          echo "-1<div id='message' class='error'><p>" . __( 'There was a problem sending that reply. Please try again.', 'buddypress' ) . '</p></div>';
1671          die;
1672      }
1673  
1674      $result = messages_new_message( array( 'thread_id' => $thread_id, 'content' => $_REQUEST['content'] ) );
1675  
1676      if ( !empty( $result ) ) {
1677  
1678          // Pretend we're in the message loop.
1679          global $thread_template;
1680  
1681          bp_thread_has_messages( array( 'thread_id' => $thread_id ) );
1682  
1683          // Set the current message to the 2nd last.
1684          $thread_template->message = end( $thread_template->thread->messages );
1685          $thread_template->message = prev( $thread_template->thread->messages );
1686  
1687          // Set current message to current key.
1688          $thread_template->current_message = key( $thread_template->thread->messages );
1689  
1690          // Now manually iterate message like we're in the loop.
1691          bp_thread_the_message();
1692  
1693          // Manually call oEmbed
1694          // this is needed because we're not at the beginning of the loop.
1695          bp_messages_embed();
1696  
1697          // Add new-message css class.
1698          add_filter( 'bp_get_the_thread_message_css_class', function( $retval ) {
1699              $retval[] = 'new-message';
1700              return $retval;
1701          } );
1702  
1703          // Output single message template part.
1704          bp_get_template_part( 'members/single/messages/message' );
1705  
1706          // Clean up the loop.
1707          bp_thread_messages();
1708  
1709      } else {
1710          echo "-1<div id='message' class='error'><p>" . __( 'There was a problem sending that reply. Please try again.', 'buddypress' ) . '</p></div>';
1711      }
1712  
1713      exit;
1714  }
1715  
1716  /**
1717   * Mark a private message as unread in your inbox via a POST request.
1718   *
1719   * No longer used.
1720   *
1721   * @since 1.2.0
1722   * @deprecated 2.2.0
1723   *
1724   * @return mixed String on error, void on success.
1725   */
1726  function bp_legacy_theme_ajax_message_markunread() {
1727      die( '-1' );
1728  }
1729  
1730  /**
1731   * Mark a private message as read in your inbox via a POST request.
1732   *
1733   * No longer used.
1734   *
1735   * @since 1.2.0
1736   * @deprecated 2.2.0
1737   *
1738   * @return mixed String on error, void on success.
1739   */
1740  function bp_legacy_theme_ajax_message_markread() {
1741      die( '-1' );
1742  }
1743  
1744  /**
1745   * Delete a private message(s) in your inbox via a POST request.
1746   *
1747   * No longer used.
1748   *
1749   * @since 1.2.0
1750   * @deprecated 2.2.0
1751   *
1752   * @return string|null HTML
1753   */
1754  function bp_legacy_theme_ajax_messages_delete() {
1755      die( '-1' );
1756  }
1757  
1758  /**
1759   * AJAX handler for autocomplete.
1760   *
1761   * Displays friends only, unless BP_MESSAGES_AUTOCOMPLETE_ALL is defined.
1762   *
1763   * @since 1.2.0
1764   */
1765  function bp_legacy_theme_ajax_messages_autocomplete_results() {
1766  
1767      /**
1768       * Filters the max results default value for ajax messages autocomplete results.
1769       *
1770       * @since 1.5.0
1771       *
1772       * @param int $value Max results for autocomplete. Default 10.
1773       */
1774      $limit = isset( $_GET['limit'] ) ? absint( $_GET['limit'] )          : (int) apply_filters( 'bp_autocomplete_max_results', 10 );
1775      $term  = isset( $_GET['q'] )     ? sanitize_text_field( $_GET['q'] ) : '';
1776  
1777      // Include everyone in the autocomplete, or just friends?
1778      if ( bp_is_current_component( bp_get_messages_slug() ) ) {
1779          $only_friends = ( buddypress()->messages->autocomplete_all === false );
1780      } else {
1781          $only_friends = true;
1782      }
1783  
1784      $suggestions = bp_core_get_suggestions( array(
1785          'limit'        => $limit,
1786          'only_friends' => $only_friends,
1787          'term'         => $term,
1788          'type'         => 'members',
1789      ) );
1790  
1791      if ( $suggestions && ! is_wp_error( $suggestions ) ) {
1792          foreach ( $suggestions as $user ) {
1793  
1794              // Note that the final line break acts as a delimiter for the
1795              // autocomplete JavaScript and thus should not be removed.
1796              printf( '<span id="%s" href="#"></span><img src="%s" style="width: 15px"> &nbsp; %s (%s)' . "\n",
1797                  esc_attr( 'link-' . $user->ID ),
1798                  esc_url( $user->image ),
1799                  esc_html( $user->name ),
1800                  esc_html( $user->ID )
1801              );
1802          }
1803      }
1804  
1805      exit;
1806  }
1807  
1808  /**
1809   * AJAX callback to set a message's star status.
1810   *
1811   * @since 2.3.0
1812   */
1813  function bp_legacy_theme_ajax_messages_star_handler() {
1814      if ( false === bp_is_active( 'messages', 'star' ) || empty( $_POST['message_id'] ) ) {
1815          return;
1816      }
1817  
1818      // Check nonce.
1819      check_ajax_referer( 'bp-messages-star-' . (int) $_POST['message_id'], 'nonce' );
1820  
1821      // Check capability.
1822      if ( ! is_user_logged_in() || ! bp_core_can_edit_settings() ) {
1823          return;
1824      }
1825  
1826      if ( true === bp_messages_star_set_action( array(
1827          'action'     => $_POST['star_status'],
1828          'message_id' => (int) $_POST['message_id'],
1829          'bulk'       => ! empty( $_POST['bulk'] ) ? true : false
1830       ) ) ) {
1831          echo '1';
1832          die();
1833      }
1834  
1835      echo '-1';
1836      die();
1837  }
1838  
1839  /**
1840   * BP Legacy's callback for the cover image feature.
1841   *
1842   * @since  2.4.0
1843   *
1844   * @param  array $params the current component's feature parameters.
1845   * @return null|string An array to inform about the css handle to attach the css rules to
1846   */
1847  function bp_legacy_theme_cover_image( $params = array() ) {
1848      if ( empty( $params ) ) {
1849          return;
1850      }
1851  
1852      // Avatar height - padding - 1/2 avatar height.
1853      $avatar_offset = $params['height'] - 5 - round( (int) bp_core_avatar_full_height() / 2 );
1854  
1855      // Header content offset + spacing.
1856      $top_offset  = bp_core_avatar_full_height() - 10;
1857      $left_offset = bp_core_avatar_full_width() + 20;
1858  
1859      $cover_image = ( !empty( $params['cover_image'] ) ) ? 'background-image: url(' . $params['cover_image'] . ');' : '';
1860  
1861      $hide_avatar_style = '';
1862  
1863      // Adjust the cover image header, in case avatars are completely disabled.
1864      if ( ! buddypress()->avatar->show_avatars ) {
1865          $hide_avatar_style = '
1866              #buddypress #item-header-cover-image #item-header-avatar {
1867                  display:  none;
1868              }
1869          ';
1870  
1871          if ( bp_is_user() ) {
1872              $hide_avatar_style = '
1873                  #buddypress #item-header-cover-image #item-header-avatar a {
1874                      display: block;
1875                      height: ' . $top_offset . 'px;
1876                      margin: 0 15px 19px 0;
1877                  }
1878  
1879                  #buddypress div#item-header #item-header-cover-image #item-header-content {
1880                      margin-left: auto;
1881                  }
1882              ';
1883          }
1884      }
1885  
1886      return '
1887          /* Cover image */
1888          #buddypress #header-cover-image {
1889              height: ' . $params["height"] . 'px;
1890              ' . $cover_image . '
1891          }
1892  
1893          #buddypress #create-group-form #header-cover-image {
1894              margin: 1em 0;
1895              position: relative;
1896          }
1897  
1898          .bp-user #buddypress #item-header {
1899              padding-top: 0;
1900          }
1901  
1902          #buddypress #item-header-cover-image #item-header-avatar {
1903              margin-top: '. $avatar_offset .'px;
1904              float: left;
1905              overflow: visible;
1906              width: auto;
1907          }
1908  
1909          #buddypress div#item-header #item-header-cover-image #item-header-content {
1910              clear: both;
1911              float: left;
1912              margin-left: ' . $left_offset . 'px;
1913              margin-top: -' . $top_offset . 'px;
1914              width: auto;
1915          }
1916  
1917          body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-header-content,
1918          body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
1919              clear: none;
1920              margin-top: ' . $params["height"] . 'px;
1921              margin-left: 0;
1922              max-width: 50%;
1923          }
1924  
1925          body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
1926              max-width: 20%;
1927              padding-top: 20px;
1928          }
1929  
1930          ' . $hide_avatar_style . '
1931  
1932          #buddypress div#item-header-cover-image .user-nicename a,
1933          #buddypress div#item-header-cover-image .user-nicename {
1934              font-size: 200%;
1935              color: #fff;
1936              margin: 0 0 0.6em;
1937              text-rendering: optimizelegibility;
1938              text-shadow: 0 0 3px rgba( 0, 0, 0, 0.8 );
1939          }
1940  
1941          #buddypress #item-header-cover-image #item-header-avatar img.avatar {
1942              background: rgba( 255, 255, 255, 0.8 );
1943              border: solid 2px #fff;
1944          }
1945  
1946          #buddypress #item-header-cover-image #item-header-avatar a {
1947              border: 0;
1948              text-decoration: none;
1949          }
1950  
1951          #buddypress #item-header-cover-image #item-buttons {
1952              margin: 0 0 10px;
1953              padding: 0 0 5px;
1954          }
1955  
1956          #buddypress #item-header-cover-image #item-buttons:after {
1957              clear: both;
1958              content: "";
1959              display: table;
1960          }
1961  
1962          @media screen and (max-width: 782px) {
1963              #buddypress #item-header-cover-image #item-header-avatar,
1964              .bp-user #buddypress #item-header #item-header-cover-image #item-header-avatar,
1965              #buddypress div#item-header #item-header-cover-image #item-header-content {
1966                  width: 100%;
1967                  text-align: center;
1968              }
1969  
1970              #buddypress #item-header-cover-image #item-header-avatar a {
1971                  display: inline-block;
1972              }
1973  
1974              #buddypress #item-header-cover-image #item-header-avatar img {
1975                  margin: 0;
1976              }
1977  
1978              #buddypress div#item-header #item-header-cover-image #item-header-content,
1979              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-header-content,
1980              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
1981                  margin: 0;
1982              }
1983  
1984              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-header-content,
1985              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
1986                  max-width: 100%;
1987              }
1988  
1989              #buddypress div#item-header-cover-image h2 a,
1990              #buddypress div#item-header-cover-image h2 {
1991                  color: inherit;
1992                  text-shadow: none;
1993                  margin: 25px 0 0;
1994                  font-size: 200%;
1995              }
1996  
1997              #buddypress #item-header-cover-image #item-buttons div {
1998                  float: none;
1999                  display: inline-block;
2000              }
2001  
2002              #buddypress #item-header-cover-image #item-buttons:before {
2003                  content: "";
2004              }
2005  
2006              #buddypress #item-header-cover-image #item-buttons {
2007                  margin: 5px 0;
2008              }
2009          }
2010      ';
2011  }
2012  
2013  /**
2014   * Add a search box to a single group's manage members screen.
2015   *
2016   * @since 2.7.0
2017   *
2018   * @return string|null HTML for the search form.
2019   */
2020  function bp_legacy_theme_group_manage_members_add_search() {
2021      if ( bp_is_action_variable( 'manage-members' ) ) :
2022          ?>
2023          <div id="members-dir-search" class="dir-search no-ajax" role="search">
2024              <?php bp_directory_members_search_form(); ?>
2025          </div>
2026          <?php
2027      endif;
2028  }
2029  
2030  /**
2031   * Modify welcome message in Legacy template pack when
2032   * community invitations are enabled.
2033   *
2034   * @since 8.0.0
2035   */
2036  function bp_members_invitations_add_legacy_welcome_message() {
2037      $message = bp_members_invitations_get_registration_welcome_message();
2038  
2039      if ( $message ) {
2040          // Surround the message with `<p>` tags.
2041          echo wpautop( $message );
2042      }
2043  }
2044  add_action( 'bp_before_register_page', 'bp_members_invitations_add_legacy_welcome_message' );
2045  
2046  
2047  /**
2048   * Modify "registration disabled" message in Legacy template pack when
2049   * community invitations are enabled.
2050   *
2051   * @since 8.0.0
2052   */
2053  function bp_members_invitations_add_legacy_registration_disabled_message() {
2054      $message = bp_members_invitations_get_modified_registration_disabled_message();
2055  
2056      if ( $message ) {
2057          // Surround the message with `<p>` tags.
2058          echo wpautop( $message );
2059      }
2060  }
2061  add_action( 'bp_after_registration_disabled', 'bp_members_invitations_add_legacy_registration_disabled_message' );


Generated: Fri Dec 6 01:00:58 2024 Cross-referenced by PHPXref 0.7.1