[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/ -> bp-core-theme-compatibility.php (source)

   1  <?php
   2  /**
   3   * BuddyPress Core Theme Compatibility.
   4   *
   5   * @package BuddyPress
   6   * @subpackage ThemeCompatibility
   7   * @since 1.7.0
   8   */
   9  
  10  // Exit if accessed directly.
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  /** Theme Compat **************************************************************/
  14  
  15  /**
  16   * What follows is an attempt at intercepting the natural page load process
  17   * to replace the_content() with the appropriate BuddyPress content.
  18   *
  19   * To do this, BuddyPress does several direct manipulations of global variables
  20   * and forces them to do what they are not supposed to be doing.
  21   *
  22   * Don't try anything you're about to witness here, at home. Ever.
  23   */
  24  
  25  /** Functions *****************************************************************/
  26  
  27  /**
  28   * Set up the default theme compat theme.
  29   *
  30   * @since 1.7.0
  31   *
  32   * @param string $theme Optional. The unique ID identifier of a theme package.
  33   */
  34  function bp_setup_theme_compat( $theme = '' ) {
  35      $bp = buddypress();
  36  
  37      // Make sure theme package is available, set to default if not.
  38      if ( ! isset( $bp->theme_compat->packages[$theme] ) || ! is_a( $bp->theme_compat->packages[$theme], 'BP_Theme_Compat' ) ) {
  39          $theme = 'legacy';
  40      }
  41  
  42      // Set the active theme compat theme.
  43      $bp->theme_compat->theme = $bp->theme_compat->packages[$theme];
  44  }
  45  
  46  /**
  47   * Get the ID of the theme package being used.
  48   *
  49   * This can be filtered or set manually. Tricky theme authors can override the
  50   * default and include their own BuddyPress compatibility layers for their themes.
  51   *
  52   * @since 1.7.0
  53   *
  54   * @return string ID of the theme package in use.
  55   */
  56  function bp_get_theme_compat_id() {
  57  
  58      /**
  59       * Filters the ID of the theme package being used.
  60       *
  61       * @since 1.7.0
  62       *
  63       * @param string $id ID of the theme package in use.
  64       */
  65      return apply_filters( 'bp_get_theme_compat_id', buddypress()->theme_compat->theme->id );
  66  }
  67  
  68  /**
  69   * Get the name of the theme package being used.
  70   *
  71   * This can be filtered or set manually. Tricky theme authors can override the
  72   * default and include their own BuddyPress compatibility layers for their themes.
  73   *
  74   * @since 1.7.0
  75   *
  76   * @return string Name of the theme package currently in use.
  77   */
  78  function bp_get_theme_compat_name() {
  79  
  80      /**
  81       * Filters the name of the theme package being used.
  82       *
  83       * @since 1.7.0
  84       *
  85       * @param string $name Name of the theme package in use.
  86       */
  87      return apply_filters( 'bp_get_theme_compat_name', buddypress()->theme_compat->theme->name );
  88  }
  89  
  90  /**
  91   * Get the version of the theme package being used.
  92   *
  93   * This can be filtered or set manually. Tricky theme authors can override the
  94   * default and include their own BuddyPress compatibility layers for their themes.
  95   *
  96   * @since 1.7.0
  97   *
  98   * @return string The version string of the theme package currently in use.
  99   */
 100  function bp_get_theme_compat_version() {
 101  
 102      /**
 103       * Filters the version of the theme package being used.
 104       *
 105       * @since 1.7.0
 106       *
 107       * @param string $version The version string of the theme package in use.
 108       */
 109      return apply_filters( 'bp_get_theme_compat_version', buddypress()->theme_compat->theme->version );
 110  }
 111  
 112  /**
 113   * Get the absolute path of the theme package being used.
 114   *
 115   * Or set manually. Tricky theme authors can override the default and include
 116   * their own BuddyPress compatibility layers for their themes.
 117   *
 118   * @since 1.7.0
 119   *
 120   * @return string The absolute path of the theme package currently in use.
 121   */
 122  function bp_get_theme_compat_dir() {
 123  
 124      /**
 125       * Filters the absolute path of the theme package being used.
 126       *
 127       * @since 1.7.0
 128       *
 129       * @param string $dir The absolute path of the theme package in use.
 130       */
 131      return apply_filters( 'bp_get_theme_compat_dir', buddypress()->theme_compat->theme->dir );
 132  }
 133  
 134  /**
 135   * Get the URL of the theme package being used.
 136   *
 137   * This can be filtered, or set manually. Tricky theme authors can override
 138   * the default and include their own BuddyPress compatibility layers for their
 139   * themes.
 140   *
 141   * @since 1.7.0
 142   *
 143   * @return string URL of the theme package currently in use.
 144   */
 145  function bp_get_theme_compat_url() {
 146  
 147      /**
 148       * Filters the URL of the theme package being used.
 149       *
 150       * @since 1.7.0
 151       *
 152       * @param string $url URL of the theme package in use.
 153       */
 154      return apply_filters( 'bp_get_theme_compat_url', buddypress()->theme_compat->theme->url );
 155  }
 156  
 157  /**
 158   * Should we use theme compat for this theme?
 159   *
 160   * If the current theme's need for theme compat hasn't yet been detected, we
 161   * do so using bp_detect_theme_compat_with_current_theme().
 162   *
 163   * @since 1.9.0
 164   *
 165   * @return bool True if the current theme needs theme compatibility.
 166   */
 167  function bp_use_theme_compat_with_current_theme() {
 168      if ( ! isset( buddypress()->theme_compat->use_with_current_theme ) ) {
 169          bp_detect_theme_compat_with_current_theme();
 170      }
 171  
 172      /**
 173       * Filters whether or not to use theme compat for the active theme.
 174       *
 175       * @since 1.9.0
 176       *
 177       * @param bool $use_with_current_theme True if the current theme needs theme compatibility.
 178       */
 179      return apply_filters( 'bp_use_theme_compat_with_current_theme', buddypress()->theme_compat->use_with_current_theme );
 180  }
 181  
 182  /**
 183   * Set our flag to determine whether theme compat should be enabled.
 184   *
 185   * Theme compat is disabled when a theme meets one of the following criteria:
 186   * 1) It declares BP support with add_theme_support( 'buddypress' )
 187   * 2) It is bp-default, or a child theme of bp-default
 188   * 3) A legacy template is found at members/members-loop.php. This is a
 189   *    fallback check for themes that were derived from bp-default, and have
 190   *    not been updated for BP 1.7+; we make the assumption that any theme in
 191   *    this category will have the members-loop.php template, and so use its
 192   *    presence as an indicator that theme compatibility is not required
 193   *
 194   * @since 1.9.0
 195   *
 196   * @return bool True if the current theme needs theme compatibility.
 197   */
 198  function bp_detect_theme_compat_with_current_theme() {
 199      if ( isset( buddypress()->theme_compat->use_with_current_theme ) ) {
 200          return buddypress()->theme_compat->use_with_current_theme;
 201      }
 202  
 203      // Theme compat enabled by default.
 204      $theme_compat = true;
 205  
 206      // If the theme supports 'buddypress', bail.
 207      if ( current_theme_supports( 'buddypress' ) ) {
 208          $theme_compat = false;
 209  
 210      // If the theme doesn't support BP, do some additional checks.
 211      } else {
 212          // Bail if theme is a derivative of bp-default.
 213          if ( in_array( 'bp-default', array( get_template(), get_stylesheet() ) ) ) {
 214              $theme_compat = false;
 215  
 216          // Brute-force check for a BP template.
 217          // Examples are clones of bp-default.
 218          } elseif ( locate_template( 'members/members-loop.php', false, false ) ) {
 219              $theme_compat = false;
 220          }
 221      }
 222  
 223      // Set a flag in the buddypress() singleton so we don't have to run this again.
 224      buddypress()->theme_compat->use_with_current_theme = $theme_compat;
 225  
 226      return $theme_compat;
 227  }
 228  
 229  /**
 230   * Is the current page using theme compatibility?
 231   *
 232   * @since 1.7.0
 233   *
 234   * @return bool True if the current page uses theme compatibility.
 235   */
 236  function bp_is_theme_compat_active() {
 237      $bp = buddypress();
 238  
 239      if ( empty( $bp->theme_compat->active ) ) {
 240          return false;
 241      }
 242  
 243      return $bp->theme_compat->active;
 244  }
 245  
 246  /**
 247   * Set the flag that tells whether the current page is using theme compatibility.
 248   *
 249   * @since 1.7.0
 250   *
 251   * @param bool $set True to set the flag to true, false to set it to false.
 252   * @return bool Returns the value of $set.
 253   */
 254  function bp_set_theme_compat_active( $set = true ) {
 255      buddypress()->theme_compat->active = $set;
 256  
 257      return (bool) buddypress()->theme_compat->active;
 258  }
 259  
 260  /**
 261   * Set the theme compat templates global.
 262   *
 263   * Stash possible template files for the current query. Useful if plugins want
 264   * to override them, or see what files are being scanned for inclusion.
 265   *
 266   * @since 1.7.0
 267   *
 268   * @param array $templates The template stack.
 269   * @return array The template stack (value of $templates).
 270   */
 271  function bp_set_theme_compat_templates( $templates = array() ) {
 272      buddypress()->theme_compat->templates = $templates;
 273  
 274      return buddypress()->theme_compat->templates;
 275  }
 276  
 277  /**
 278   * Set the theme compat template global.
 279   *
 280   * Stash the template file for the current query. Useful if plugins want
 281   * to override it, or see what file is being included.
 282   *
 283   * @since 1.7.0
 284   *
 285   * @param string $template The template currently in use.
 286   * @return string The template currently in use (value of $template).
 287   */
 288  function bp_set_theme_compat_template( $template = '' ) {
 289      buddypress()->theme_compat->template = $template;
 290  
 291      return buddypress()->theme_compat->template;
 292  }
 293  
 294  /**
 295   * Set the theme compat original_template global.
 296   *
 297   * Stash the original template file for the current query. Useful for checking
 298   * if BuddyPress was able to find a more appropriate template.
 299   *
 300   * @since 1.7.0
 301   *
 302   * @param string $template The template originally selected by WP.
 303   * @return string The template originally selected by WP (value of $template).
 304   */
 305  function bp_set_theme_compat_original_template( $template = '' ) {
 306      buddypress()->theme_compat->original_template = $template;
 307  
 308      return buddypress()->theme_compat->original_template;
 309  }
 310  
 311  /**
 312   * Set a theme compat feature
 313   *
 314   * @since 2.4.0
 315   *
 316   * @param string $theme_id The theme id (eg: legacy).
 317   * @param array  $feature  An associative array (eg: array( name => 'feature_name', 'settings' => array() )).
 318   */
 319  function bp_set_theme_compat_feature( $theme_id, $feature = array() ) {
 320      if ( empty( $theme_id ) || empty( $feature['name'] ) ) {
 321          return;
 322      }
 323  
 324      // Get BuddyPress instance.
 325      $bp = buddypress();
 326  
 327      // Get current theme compat theme.
 328      $theme_compat_theme = $bp->theme_compat->theme;
 329  
 330      // Bail if the Theme Compat theme is not in use.
 331      if ( $theme_id !== bp_get_theme_compat_id() ) {
 332          return;
 333      }
 334  
 335      $features = $theme_compat_theme->__get( 'features' );
 336      if ( empty( $features ) ) {
 337          $features = array();
 338      }
 339  
 340      // Bail if the feature is already registered or no settings were provided.
 341      if ( isset( $features[ $feature['name'] ] ) || empty( $feature['settings'] ) ) {
 342          return;
 343      }
 344  
 345      // Add the feature.
 346      $features[ $feature['name'] ] = (object) $feature['settings'];
 347  
 348      // The feature is attached to components.
 349      if ( isset( $features[ $feature['name'] ]->components ) ) {
 350          // Set the feature for each concerned component.
 351          foreach ( (array) $features[ $feature['name'] ]->components as $component ) {
 352              // The xProfile component is specific.
 353              if ( 'xprofile' === $component ) {
 354                  $component = 'profile';
 355              }
 356  
 357              if ( isset( $bp->{$component} ) ) {
 358                  if ( isset( $bp->{$component}->features ) ) {
 359                      $bp->{$component}->features[] = $feature['name'];
 360                  } else {
 361                      $bp->{$component}->features = array( $feature['name'] );
 362                  }
 363              }
 364          }
 365      }
 366  
 367      // Finally update the theme compat features.
 368      $theme_compat_theme->__set( 'features', $features );
 369  }
 370  
 371  /**
 372   * Get a theme compat feature
 373   *
 374   * @since 2.4.0
 375   *
 376   * @param string $feature The feature (eg: cover_image).
 377   * @return object The feature settings.
 378   */
 379  function bp_get_theme_compat_feature( $feature = '' ) {
 380      // Get current theme compat theme.
 381      $theme_compat_theme = buddypress()->theme_compat->theme;
 382  
 383      // Get features.
 384      $features = $theme_compat_theme->__get( 'features' );
 385  
 386      if ( ! isset( $features[ $feature ] ) ) {
 387          return false;
 388      }
 389  
 390      return $features[ $feature ];
 391  }
 392  
 393  /**
 394   * Setup the theme's features.
 395   *
 396   * Note: BP Legacy's buddypress-functions.php is not loaded in WP Administration
 397   * as it's loaded using bp_locate_template(). That's why this function is here.
 398   *
 399   * @since 2.4.0
 400   *
 401   * @global string $content_width the content width of the theme
 402   */
 403  function bp_register_theme_compat_default_features() {
 404      global $content_width;
 405  
 406      // Do not set up default features on deactivation.
 407      if ( bp_is_deactivation() ) {
 408          return;
 409      }
 410  
 411      // If the current theme doesn't need theme compat, bail at this point.
 412      if ( ! bp_use_theme_compat_with_current_theme() ) {
 413          return;
 414      }
 415  
 416      // Make sure BP Legacy is the Theme Compat in use.
 417      if ( 'legacy' !== bp_get_theme_compat_id() ) {
 418          return;
 419      }
 420  
 421      // Get the theme.
 422      $current_theme = wp_get_theme();
 423      $theme_handle  = $current_theme->get_stylesheet();
 424      $parent        = $current_theme->parent();
 425  
 426      if ( $parent ) {
 427          $theme_handle = $parent->get_stylesheet();
 428      }
 429  
 430      /**
 431       * Since Companion stylesheets, the $content_width is smaller
 432       * than the width used by BuddyPress, so we need to manually set the
 433       * content width for the concerned themes.
 434       *
 435       * Example: array( stylesheet => content width used by BuddyPress )
 436       */
 437      $bp_content_widths = array(
 438          'twentyfifteen'  => 1300,
 439          'twentyfourteen' => 955,
 440          'twentythirteen' => 890,
 441      );
 442  
 443      // Default values.
 444      $bp_content_width = (int) $content_width;
 445      $bp_handle        = 'bp-legacy-css';
 446  
 447      // Specific to themes having companion stylesheets.
 448      if ( isset( $bp_content_widths[ $theme_handle ] ) ) {
 449          $bp_content_width = $bp_content_widths[ $theme_handle ];
 450          $bp_handle        = 'bp-' . $theme_handle;
 451      }
 452  
 453      if ( is_rtl() ) {
 454          $bp_handle .= '-rtl';
 455      }
 456  
 457      $top_offset    = 150;
 458      $avatar_height = apply_filters( 'bp_core_avatar_full_height', $top_offset );
 459  
 460      if ( $avatar_height > $top_offset ) {
 461          $top_offset = $avatar_height;
 462      }
 463  
 464      bp_set_theme_compat_feature( 'legacy', array(
 465          'name'     => 'cover_image',
 466          'settings' => array(
 467              'components'   => array( 'xprofile', 'groups' ),
 468              'width'        => $bp_content_width,
 469              'height'       => $top_offset + round( $avatar_height / 2 ),
 470              'callback'     => 'bp_legacy_theme_cover_image',
 471              'theme_handle' => $bp_handle,
 472          ),
 473      ) );
 474  }
 475  
 476  /**
 477   * Check whether a given template is the one that WP originally selected to display current page.
 478   *
 479   * @since 1.7.0
 480   *
 481   * @param string $template The template name to check.
 482   * @return bool True if the value of $template is the same as the
 483   *              "original_template" originally selected by WP. Otherwise false.
 484   */
 485  function bp_is_theme_compat_original_template( $template = '' ) {
 486      $bp = buddypress();
 487  
 488      if ( empty( $bp->theme_compat->original_template ) ) {
 489          return false;
 490      }
 491  
 492      return (bool) ( $bp->theme_compat->original_template == $template );
 493  }
 494  
 495  /**
 496   * Register a new BuddyPress theme package in the active theme packages array.
 497   *
 498   * For an example of how this function is used, see:
 499   * {@link BuddyPress::register_theme_packages()}.
 500   *
 501   * @since 1.7.0
 502   *
 503   * @see BP_Theme_Compat for a description of the $theme parameter arguments.
 504   *
 505   * @param array $theme    See {@link BP_Theme_Compat}.
 506   * @param bool  $override If true, overrides whatever package is currently set.
 507   *                        Default: true.
 508   */
 509  function bp_register_theme_package( $theme = array(), $override = true ) {
 510  
 511      // Create new BP_Theme_Compat object from the $theme array.
 512      if ( is_array( $theme ) ) {
 513          $theme = new BP_Theme_Compat( $theme );
 514      }
 515  
 516      // Bail if $theme isn't a proper object.
 517      if ( ! is_a( $theme, 'BP_Theme_Compat' ) ) {
 518          return;
 519      }
 520  
 521      // Load up BuddyPress.
 522      $bp = buddypress();
 523  
 524      // Only set if the theme package was not previously registered or if the
 525      // override flag is set.
 526      if ( empty( $bp->theme_compat->packages[$theme->id] ) || ( true === $override ) ) {
 527          $bp->theme_compat->packages[$theme->id] = $theme;
 528      }
 529  }
 530  
 531  /**
 532   * Populate various WordPress globals with dummy data to prevent errors.
 533   *
 534   * This dummy data is necessary because theme compatibility essentially fakes
 535   * WordPress into thinking that there is content where, in fact, there is none
 536   * (at least, no WordPress post content). By providing dummy data, we ensure
 537   * that template functions - things like is_page() - don't throw errors.
 538   *
 539   * @since 1.7.0
 540   *
 541   * @global WP_Query $wp_query WordPress database access object.
 542   * @global object $post Current post object.
 543   *
 544   * @param array $args Array of optional arguments. Arguments parallel the properties
 545   *                    of {@link WP_Post}; see that class for more details.
 546   */
 547  function bp_theme_compat_reset_post( $args = array() ) {
 548      global $wp_query, $post;
 549  
 550      // Switch defaults if post is set.
 551      if ( isset( $wp_query->post ) ) {
 552          $dummy = wp_parse_args( $args, array(
 553              'ID'                    => $wp_query->post->ID,
 554              'post_status'           => $wp_query->post->post_status,
 555              'post_author'           => $wp_query->post->post_author,
 556              'post_parent'           => $wp_query->post->post_parent,
 557              'post_type'             => $wp_query->post->post_type,
 558              'post_date'             => $wp_query->post->post_date,
 559              'post_date_gmt'         => $wp_query->post->post_date_gmt,
 560              'post_modified'         => $wp_query->post->post_modified,
 561              'post_modified_gmt'     => $wp_query->post->post_modified_gmt,
 562              'post_content'          => $wp_query->post->post_content,
 563              'post_title'            => $wp_query->post->post_title,
 564              'post_excerpt'          => $wp_query->post->post_excerpt,
 565              'post_content_filtered' => $wp_query->post->post_content_filtered,
 566              'post_mime_type'        => $wp_query->post->post_mime_type,
 567              'post_password'         => $wp_query->post->post_password,
 568              'post_name'             => $wp_query->post->post_name,
 569              'guid'                  => $wp_query->post->guid,
 570              'menu_order'            => $wp_query->post->menu_order,
 571              'pinged'                => $wp_query->post->pinged,
 572              'to_ping'               => $wp_query->post->to_ping,
 573              'ping_status'           => $wp_query->post->ping_status,
 574              'comment_status'        => $wp_query->post->comment_status,
 575              'comment_count'         => $wp_query->post->comment_count,
 576              'filter'                => $wp_query->post->filter,
 577  
 578              'is_404'                => false,
 579              'is_page'               => false,
 580              'is_single'             => false,
 581              'is_archive'            => false,
 582              'is_tax'                => false,
 583          ) );
 584      } else {
 585          $dummy = wp_parse_args( $args, array(
 586              'ID'                    => -9999,
 587              'post_status'           => 'public',
 588              'post_author'           => 0,
 589              'post_parent'           => 0,
 590              'post_type'             => 'page',
 591              'post_date'             => 0,
 592              'post_date_gmt'         => 0,
 593              'post_modified'         => 0,
 594              'post_modified_gmt'     => 0,
 595              'post_content'          => '',
 596              'post_title'            => '',
 597              'post_excerpt'          => '',
 598              'post_content_filtered' => '',
 599              'post_mime_type'        => '',
 600              'post_password'         => '',
 601              'post_name'             => '',
 602              'guid'                  => '',
 603              'menu_order'            => 0,
 604              'pinged'                => '',
 605              'to_ping'               => '',
 606              'ping_status'           => '',
 607              'comment_status'        => 'closed',
 608              'comment_count'         => 0,
 609              'filter'                => 'raw',
 610  
 611              'is_404'                => false,
 612              'is_page'               => false,
 613              'is_single'             => false,
 614              'is_archive'            => false,
 615              'is_tax'                => false,
 616          ) );
 617      }
 618  
 619      // Bail if dummy post is empty.
 620      if ( empty( $dummy ) ) {
 621          return;
 622      }
 623  
 624      // Set the $post global.
 625      $post = new WP_Post( (object) $dummy );
 626  
 627      // Copy the new post global into the main $wp_query.
 628      $wp_query->post       = $post;
 629      $wp_query->posts      = array( $post );
 630  
 631      // Prevent comments form from appearing.
 632      $wp_query->post_count = 1;
 633      $wp_query->is_404     = $dummy['is_404'];
 634      $wp_query->is_page    = $dummy['is_page'];
 635      $wp_query->is_single  = $dummy['is_single'];
 636      $wp_query->is_archive = $dummy['is_archive'];
 637      $wp_query->is_tax     = $dummy['is_tax'];
 638  
 639      // Clean up the dummy post.
 640      unset( $dummy );
 641  
 642      /**
 643       * Force the header back to 200 status if not a deliberate 404.
 644       *
 645       * @see https://bbpress.trac.wordpress.org/ticket/1973
 646       */
 647      if ( ! $wp_query->is_404() ) {
 648          status_header( 200 );
 649      }
 650  
 651      // If we are resetting a post, we are in theme compat.
 652      bp_set_theme_compat_active( true );
 653  
 654      // If we are in theme compat, we don't need the 'Edit' post link.
 655      add_filter( 'get_edit_post_link', 'bp_core_filter_edit_post_link', 10, 2 );
 656  }
 657  
 658  /**
 659   * Reset main query vars and filter 'the_content' to output a BuddyPress template part as needed.
 660   *
 661   * @since 1.7.0
 662   *
 663   * @param string $template Template name.
 664   * @return string $template Template name.
 665   */
 666  function bp_template_include_theme_compat( $template = '' ) {
 667      // If embed template, bail.
 668      if ( true === function_exists( 'is_embed' ) && is_embed() ) {
 669          return $template;
 670      }
 671  
 672      // If the current theme doesn't need theme compat, bail at this point.
 673      if ( ! bp_use_theme_compat_with_current_theme() ) {
 674          return $template;
 675      }
 676  
 677      /**
 678       * Fires when resetting main query vars and filtering 'the_content' to output BuddyPress template parts.
 679       *
 680       * Use this action to execute code that will communicate to BuddyPress's
 681       * theme compatibility layer whether or not we're replacing the_content()
 682       * with some other template part.
 683       *
 684       * @since 1.7.0
 685       */
 686      do_action( 'bp_template_include_reset_dummy_post_data' );
 687  
 688      // Bail if the template already matches a BuddyPress template.
 689      if ( isset( buddypress()->theme_compat->found_template ) && buddypress()->theme_compat->found_template ) {
 690          return $template;
 691      }
 692  
 693      /**
 694       * If we are relying on BuddyPress's built in theme compatibility to load
 695       * the proper content, we need to intercept the_content, replace the
 696       * output, and display ours instead.
 697       *
 698       * To do this, we first remove all filters from 'the_content' and hook
 699       * our own function into it, which runs a series of checks to determine
 700       * the context, and then uses the built in shortcodes to output the
 701       * correct results from inside an output buffer.
 702       *
 703       * Uses bp_get_theme_compat_templates() to provide fall-backs that
 704       * should be coded without superfluous mark-up and logic (prev/next
 705       * navigation, comments, date/time, etc...)
 706       *
 707       * Hook into 'bp_get_buddypress_template' to override the array of
 708       * possible templates, or 'bp_buddypress_template' to override the result.
 709       */
 710      if ( bp_is_theme_compat_active() ) {
 711          $template = bp_get_theme_compat_templates();
 712  
 713          add_filter( 'the_content', 'bp_replace_the_content' );
 714  
 715          // Add BuddyPress's head action to wp_head.
 716          if ( ! has_action( 'wp_head', 'bp_head' ) ) {
 717              add_action( 'wp_head', 'bp_head' );
 718          }
 719      }
 720  
 721      /**
 722       * Filters the template name to include.
 723       *
 724       * @since 1.7.0
 725       *
 726       * @param string $template Template name.
 727       */
 728      return apply_filters( 'bp_template_include_theme_compat', $template );
 729  }
 730  
 731  /**
 732   * Conditionally replace 'the_content'.
 733   *
 734   * Replaces the_content() if the post_type being displayed is one that would
 735   * normally be handled by BuddyPress, but proper single page templates do not
 736   * exist in the currently active theme.
 737   *
 738   * @since 1.7.0
 739   *
 740   * @param string $content Original post content.
 741   * @return string $content Post content, potentially modified.
 742   */
 743  function bp_replace_the_content( $content = '' ) {
 744  
 745      // Bail if not the main loop where theme compat is happening.
 746      if ( ! bp_do_theme_compat() ) {
 747          return $content;
 748      }
 749  
 750      // Set theme compat to false early, to avoid recursion from nested calls to
 751      // the_content() that execute before theme compat has unhooked itself.
 752      bp_set_theme_compat_active( false );
 753  
 754      /**
 755       * Filters the content to replace in the post.
 756       *
 757       * @since 1.7.0
 758       *
 759       * @param string $content Original post content.
 760       */
 761      $new_content = apply_filters( 'bp_replace_the_content', $content );
 762  
 763      // Juggle the content around and try to prevent unsightly comments.
 764      if ( ! empty( $new_content ) && ( $new_content !== $content ) ) {
 765  
 766          // Set the content to be the new content.
 767          $content = $new_content;
 768  
 769          // Clean up after ourselves.
 770          unset( $new_content );
 771  
 772          // Reset the $post global.
 773          wp_reset_postdata();
 774      }
 775  
 776      // Return possibly hi-jacked content.
 777      return $content;
 778  }
 779  
 780  /**
 781   * Are we currently replacing the_content?
 782   *
 783   * @since 1.8.0
 784   *
 785   * @return bool True if the_content is currently in the process of being
 786   *              filtered and replaced.
 787   */
 788  function bp_do_theme_compat() {
 789      return (bool) ( ! bp_is_template_included() && in_the_loop() && bp_is_theme_compat_active() );
 790  }
 791  
 792  /** Filters *******************************************************************/
 793  
 794  /**
 795   * Remove all filters from a WordPress filter hook.
 796   *
 797   * Removed filters are stashed in the $bp global, in case they need to be
 798   * restored later.
 799   *
 800   * @since 1.7.0
 801   *
 802   * @global WP_filter $wp_filter
 803   * @global array $merged_filters
 804   *
 805   * @param string   $tag      The filter tag to remove filters from.
 806   * @param int|bool $priority Optional. If present, only those callbacks attached
 807   *                           at a given priority will be removed. Otherwise, all callbacks
 808   *                           attached to the tag will be removed, regardless of priority.
 809   * @return bool True on success.
 810   */
 811  function bp_remove_all_filters( $tag, $priority = false ) {
 812      global $wp_filter, $merged_filters;
 813  
 814      $bp = buddypress();
 815  
 816      // Filters exist.
 817      if ( isset( $wp_filter[$tag] ) ) {
 818  
 819          // Filters exist in this priority.
 820          if ( ! empty( $priority ) && isset( $wp_filter[$tag][$priority] ) ) {
 821  
 822              // Store filters in a backup.
 823              $bp->filters->wp_filter[$tag][$priority] = $wp_filter[$tag][$priority];
 824  
 825              // Unset the filters.
 826              unset( $wp_filter[$tag][$priority] );
 827  
 828          // Priority is empty.
 829          } else {
 830  
 831              // Store filters in a backup.
 832              $bp->filters->wp_filter[$tag] = $wp_filter[$tag];
 833  
 834              // Unset the filters.
 835              unset( $wp_filter[$tag] );
 836          }
 837      }
 838  
 839      // Check merged filters.
 840      if ( isset( $merged_filters[$tag] ) ) {
 841  
 842          // Store filters in a backup.
 843          $bp->filters->merged_filters[$tag] = $merged_filters[$tag];
 844  
 845          // Unset the filters.
 846          unset( $merged_filters[$tag] );
 847      }
 848  
 849      return true;
 850  }
 851  
 852  /**
 853   * Restore filters that were removed using bp_remove_all_filters().
 854   *
 855   * @since 1.7.0
 856   *
 857   * @global WP_filter $wp_filter
 858   * @global array $merged_filters
 859   *
 860   * @param string   $tag      The tag to which filters should be restored.
 861   * @param int|bool $priority Optional. If present, only those filters that were originally
 862   *                           attached to the tag with $priority will be restored. Otherwise,
 863   *                           all available filters will be restored, regardless of priority.
 864   * @return bool True on success.
 865   */
 866  function bp_restore_all_filters( $tag, $priority = false ) {
 867      global $wp_filter, $merged_filters;
 868  
 869      $bp = buddypress();
 870  
 871      // Filters exist.
 872      if ( isset( $bp->filters->wp_filter[$tag] ) ) {
 873  
 874          // Filters exist in this priority.
 875          if ( ! empty( $priority ) && isset( $bp->filters->wp_filter[$tag][$priority] ) ) {
 876  
 877              // Store filters in a backup.
 878              $wp_filter[$tag][$priority] = $bp->filters->wp_filter[$tag][$priority];
 879  
 880              // Unset the filters.
 881              unset( $bp->filters->wp_filter[$tag][$priority] );
 882  
 883          // Priority is empty.
 884          } else {
 885  
 886              // Store filters in a backup.
 887              $wp_filter[$tag] = $bp->filters->wp_filter[$tag];
 888  
 889              // Unset the filters.
 890              unset( $bp->filters->wp_filter[$tag] );
 891          }
 892      }
 893  
 894      // Check merged filters.
 895      if ( isset( $bp->filters->merged_filters[$tag] ) ) {
 896  
 897          // Store filters in a backup.
 898          $merged_filters[$tag] = $bp->filters->merged_filters[$tag];
 899  
 900          // Unset the filters.
 901          unset( $bp->filters->merged_filters[$tag] );
 902      }
 903  
 904      return true;
 905  }
 906  
 907  /**
 908   * Force comments_status to 'closed' for BuddyPress post types.
 909   *
 910   * @since 1.7.0
 911   *
 912   * @param bool $open    True if open, false if closed.
 913   * @param int  $post_id ID of the post to check.
 914   * @return bool True if open, false if closed.
 915   */
 916  function bp_comments_open( $open, $post_id = 0 ) {
 917  
 918      $retval = is_buddypress() ? false : $open;
 919  
 920      /**
 921       * Filters whether or not to force comments_status to closed for BuddyPress post types.
 922       *
 923       * @since 1.7.0
 924       *
 925       * @param bool $retval  Whether or not we are on a BuddyPress post type.
 926       * @param bool $open    True if comments open, false if closed.
 927       * @param int  $post_id Post ID for the checked post.
 928       */
 929      return apply_filters( 'bp_force_comment_status', $retval, $open, $post_id );
 930  }
 931  
 932  /**
 933   * Do not allow {@link comments_template()} to render during theme compatibility.
 934   *
 935   * When theme compatibility sets the 'is_page' flag to true via
 936   * {@link bp_theme_compat_reset_post()}, themes that use comments_template()
 937   * in their page template will run.
 938   *
 939   * To prevent comments_template() from rendering, we set the 'is_page' and
 940   * 'is_single' flags to false since that function looks at these conditionals
 941   * before querying the database for comments and loading the comments template.
 942   *
 943   * This is done during the output buffer as late as possible to prevent any
 944   * wonkiness.
 945   *
 946   * @since 1.9.2
 947   *
 948   * @param string $retval The current post content.
 949   * @return string $retval
 950   */
 951  function bp_theme_compat_toggle_is_page( $retval = '' ) {
 952      global $wp_query;
 953  
 954      if ( $wp_query->is_page ) {
 955          $wp_query->is_page = false;
 956  
 957          // Set a switch so we know that we've toggled these WP_Query properties.
 958          buddypress()->theme_compat->is_page_toggled = true;
 959      }
 960  
 961      return $retval;
 962  }
 963  add_filter( 'bp_replace_the_content', 'bp_theme_compat_toggle_is_page', 9999 );
 964  
 965  /**
 966   * Restores the 'is_single' and 'is_page' flags if toggled by BuddyPress.
 967   *
 968   * @since 1.9.2
 969   *
 970   * @see bp_theme_compat_toggle_is_page()
 971   * @param object $query The WP_Query object.
 972   */
 973  function bp_theme_compat_loop_end( $query ) {
 974  
 975      // Get BuddyPress.
 976      $bp = buddypress();
 977  
 978      // Bail if page is not toggled.
 979      if ( ! isset( $bp->theme_compat->is_page_toggled ) ) {
 980          return;
 981      }
 982  
 983      // Revert our toggled WP_Query properties.
 984      $query->is_page = true;
 985  
 986      // Unset our switch.
 987      unset( $bp->theme_compat->is_page_toggled );
 988  }
 989  add_action( 'loop_end', 'bp_theme_compat_loop_end' );
 990  
 991  /**
 992   * Maybe override the preferred template pack if the theme declares a dependency.
 993   *
 994   * @since 3.0.0
 995   */
 996  function bp_check_theme_template_pack_dependency() {
 997      if ( bp_is_deactivation() ) {
 998          return;
 999      }
1000  
1001      $all_packages = array_keys( buddypress()->theme_compat->packages );
1002  
1003      foreach ( $all_packages as $package ) {
1004          // e.g. "buddypress-use-nouveau", "buddypress-use-legacy".
1005          if ( ! current_theme_supports( "buddypress-use-{$package}" ) ) {
1006              continue;
1007          }
1008  
1009          bp_setup_theme_compat( $package );
1010          return;
1011      }
1012  }


Generated: Sat Sep 21 01:01:46 2019 Cross-referenced by PHPXref 0.7.1