[ 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( 'members', '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 = bp_parse_args(
 553              $args,
 554              array(
 555                  'ID'                    => $wp_query->post->ID,
 556                  'post_status'           => $wp_query->post->post_status,
 557                  'post_author'           => $wp_query->post->post_author,
 558                  'post_parent'           => $wp_query->post->post_parent,
 559                  'post_type'             => $wp_query->post->post_type,
 560                  'post_date'             => $wp_query->post->post_date,
 561                  'post_date_gmt'         => $wp_query->post->post_date_gmt,
 562                  'post_modified'         => $wp_query->post->post_modified,
 563                  'post_modified_gmt'     => $wp_query->post->post_modified_gmt,
 564                  'post_content'          => $wp_query->post->post_content,
 565                  'post_title'            => $wp_query->post->post_title,
 566                  'post_excerpt'          => $wp_query->post->post_excerpt,
 567                  'post_content_filtered' => $wp_query->post->post_content_filtered,
 568                  'post_mime_type'        => $wp_query->post->post_mime_type,
 569                  'post_password'         => $wp_query->post->post_password,
 570                  'post_name'             => $wp_query->post->post_name,
 571                  'guid'                  => $wp_query->post->guid,
 572                  'menu_order'            => $wp_query->post->menu_order,
 573                  'pinged'                => $wp_query->post->pinged,
 574                  'to_ping'               => $wp_query->post->to_ping,
 575                  'ping_status'           => $wp_query->post->ping_status,
 576                  'comment_status'        => $wp_query->post->comment_status,
 577                  'comment_count'         => $wp_query->post->comment_count,
 578                  'filter'                => $wp_query->post->filter,
 579  
 580                  'is_404'                => false,
 581                  'is_page'               => false,
 582                  'is_single'             => false,
 583                  'is_archive'            => false,
 584                  'is_tax'                => false,
 585              )
 586          );
 587      } else {
 588          $dummy = bp_parse_args(
 589              $args,
 590              array(
 591                  'ID'                    => -9999,
 592                  'post_status'           => 'public',
 593                  'post_author'           => 0,
 594                  'post_parent'           => 0,
 595                  'post_type'             => 'page',
 596                  'post_date'             => 0,
 597                  'post_date_gmt'         => 0,
 598                  'post_modified'         => 0,
 599                  'post_modified_gmt'     => 0,
 600                  'post_content'          => '',
 601                  'post_title'            => '',
 602                  'post_excerpt'          => '',
 603                  'post_content_filtered' => '',
 604                  'post_mime_type'        => '',
 605                  'post_password'         => '',
 606                  'post_name'             => '',
 607                  'guid'                  => '',
 608                  'menu_order'            => 0,
 609                  'pinged'                => '',
 610                  'to_ping'               => '',
 611                  'ping_status'           => '',
 612                  'comment_status'        => 'closed',
 613                  'comment_count'         => 0,
 614                  'filter'                => 'raw',
 615  
 616                  'is_404'                => false,
 617                  'is_page'               => false,
 618                  'is_single'             => false,
 619                  'is_archive'            => false,
 620                  'is_tax'                => false,
 621              )
 622          );
 623      }
 624  
 625      // Bail if dummy post is empty.
 626      if ( empty( $dummy ) ) {
 627          return;
 628      }
 629  
 630      // Set the $post global.
 631      $post = new WP_Post( (object) $dummy );
 632  
 633      // Copy the new post global into the main $wp_query.
 634      $wp_query->post       = $post;
 635      $wp_query->posts      = array( $post );
 636  
 637      // Prevent comments form from appearing.
 638      $wp_query->post_count = 1;
 639      $wp_query->is_404     = $dummy['is_404'];
 640      $wp_query->is_page    = $dummy['is_page'];
 641      $wp_query->is_single  = $dummy['is_single'];
 642      $wp_query->is_archive = $dummy['is_archive'];
 643      $wp_query->is_tax     = $dummy['is_tax'];
 644  
 645      // Clean up the dummy post.
 646      unset( $dummy );
 647  
 648      /**
 649       * Force the header back to 200 status if not a deliberate 404.
 650       *
 651       * @see https://bbpress.trac.wordpress.org/ticket/1973
 652       */
 653      if ( ! $wp_query->is_404() ) {
 654          status_header( 200 );
 655      }
 656  
 657      // If we are resetting a post, we are in theme compat.
 658      bp_set_theme_compat_active( true );
 659  
 660      // If we are in theme compat, we don't need the 'Edit' post link.
 661      add_filter( 'get_edit_post_link', 'bp_core_filter_edit_post_link', 10, 2 );
 662  }
 663  
 664  /**
 665   * Reset main query vars and filter 'the_content' to output a BuddyPress template part as needed.
 666   *
 667   * @since 1.7.0
 668   *
 669   * @param string $template Template name.
 670   * @return string $template Template name.
 671   */
 672  function bp_template_include_theme_compat( $template = '' ) {
 673      // If embed template, bail.
 674      if ( is_embed() ) {
 675          return $template;
 676      }
 677  
 678      // If the current theme doesn't need theme compat, bail at this point.
 679      if ( ! bp_use_theme_compat_with_current_theme() ) {
 680          return $template;
 681      }
 682  
 683      /**
 684       * Fires when resetting main query vars and filtering 'the_content' to output BuddyPress template parts.
 685       *
 686       * Use this action to execute code that will communicate to BuddyPress's
 687       * theme compatibility layer whether or not we're replacing the_content()
 688       * with some other template part.
 689       *
 690       * @since 1.7.0
 691       */
 692      do_action( 'bp_template_include_reset_dummy_post_data' );
 693  
 694      // Bail if the template already matches a BuddyPress template.
 695      if ( isset( buddypress()->theme_compat->found_template ) && buddypress()->theme_compat->found_template ) {
 696          return $template;
 697      }
 698  
 699      /**
 700       * If we are relying on BuddyPress's built in theme compatibility to load
 701       * the proper content, we need to intercept the_content, replace the
 702       * output, and display ours instead.
 703       *
 704       * To do this, we first remove all filters from 'the_content' and hook
 705       * our own function into it, which runs a series of checks to determine
 706       * the context, and then uses the built in shortcodes to output the
 707       * correct results from inside an output buffer.
 708       *
 709       * Uses bp_get_theme_compat_templates() to provide fall-backs that
 710       * should be coded without superfluous mark-up and logic (prev/next
 711       * navigation, comments, date/time, etc...)
 712       *
 713       * Hook into 'bp_get_buddypress_template' to override the array of
 714       * possible templates, or 'bp_buddypress_template' to override the result.
 715       */
 716      if ( bp_is_theme_compat_active() ) {
 717          $template = bp_get_theme_compat_templates();
 718  
 719          add_filter( 'the_content', 'bp_replace_the_content' );
 720  
 721          // Add BuddyPress's head action to wp_head.
 722          if ( ! has_action( 'wp_head', 'bp_head' ) ) {
 723              add_action( 'wp_head', 'bp_head' );
 724          }
 725      }
 726  
 727      /**
 728       * Filters the template name to include.
 729       *
 730       * @since 1.7.0
 731       *
 732       * @param string $template Template name.
 733       */
 734      return apply_filters( 'bp_template_include_theme_compat', $template );
 735  }
 736  
 737  /**
 738   * Conditionally replace 'the_content'.
 739   *
 740   * Replaces the_content() if the post_type being displayed is one that would
 741   * normally be handled by BuddyPress, but proper single page templates do not
 742   * exist in the currently active theme.
 743   *
 744   * @since 1.7.0
 745   *
 746   * @param string $content Original post content.
 747   * @return string $content Post content, potentially modified.
 748   */
 749  function bp_replace_the_content( $content = '' ) {
 750  
 751      // Bail if not the main loop where theme compat is happening.
 752      if ( ! bp_do_theme_compat() ) {
 753          return $content;
 754      }
 755  
 756      // Set theme compat to false early, to avoid recursion from nested calls to
 757      // the_content() that execute before theme compat has unhooked itself.
 758      bp_set_theme_compat_active( false );
 759  
 760      /**
 761       * Filters the content to replace in the post.
 762       *
 763       * @since 1.7.0
 764       *
 765       * @param string $content Original post content.
 766       */
 767      $new_content = apply_filters( 'bp_replace_the_content', $content );
 768  
 769      // Juggle the content around and try to prevent unsightly comments.
 770      if ( ! empty( $new_content ) && ( $new_content !== $content ) ) {
 771  
 772          // Set the content to be the new content.
 773          $content = $new_content;
 774  
 775          // Clean up after ourselves.
 776          unset( $new_content );
 777  
 778          // Reset the $post global.
 779          wp_reset_postdata();
 780      }
 781  
 782      // Return possibly hi-jacked content.
 783      return $content;
 784  }
 785  
 786  /**
 787   * Are we currently replacing the_content?
 788   *
 789   * @since 1.8.0
 790   *
 791   * @return bool True if the_content is currently in the process of being
 792   *              filtered and replaced.
 793   */
 794  function bp_do_theme_compat() {
 795      return (bool) ( ! bp_is_template_included() && in_the_loop() && bp_is_theme_compat_active() );
 796  }
 797  
 798  /** Filters *******************************************************************/
 799  
 800  /**
 801   * Remove all filters from a WordPress filter hook.
 802   *
 803   * Removed filters are stashed in the $bp global, in case they need to be
 804   * restored later.
 805   *
 806   * @since 1.7.0
 807   *
 808   * @global WP_filter $wp_filter
 809   * @global array $merged_filters
 810   *
 811   * @param string   $tag      The filter tag to remove filters from.
 812   * @param int|bool $priority Optional. If present, only those callbacks attached
 813   *                           at a given priority will be removed. Otherwise, all callbacks
 814   *                           attached to the tag will be removed, regardless of priority.
 815   * @return bool True on success.
 816   */
 817  function bp_remove_all_filters( $tag, $priority = false ) {
 818      global $wp_filter, $merged_filters;
 819  
 820      $bp = buddypress();
 821  
 822      // Filters exist.
 823      if ( isset( $wp_filter[$tag] ) ) {
 824  
 825          // Filters exist in this priority.
 826          if ( ! empty( $priority ) && isset( $wp_filter[$tag][$priority] ) ) {
 827  
 828              // Store filters in a backup.
 829              $bp->filters->wp_filter[$tag][$priority] = $wp_filter[$tag][$priority];
 830  
 831              // Unset the filters.
 832              unset( $wp_filter[$tag][$priority] );
 833  
 834          // Priority is empty.
 835          } else {
 836  
 837              // Store filters in a backup.
 838              $bp->filters->wp_filter[$tag] = $wp_filter[$tag];
 839  
 840              // Unset the filters.
 841              unset( $wp_filter[$tag] );
 842          }
 843      }
 844  
 845      // Check merged filters.
 846      if ( isset( $merged_filters[$tag] ) ) {
 847  
 848          // Store filters in a backup.
 849          $bp->filters->merged_filters[$tag] = $merged_filters[$tag];
 850  
 851          // Unset the filters.
 852          unset( $merged_filters[$tag] );
 853      }
 854  
 855      return true;
 856  }
 857  
 858  /**
 859   * Restore filters that were removed using bp_remove_all_filters().
 860   *
 861   * @since 1.7.0
 862   *
 863   * @global WP_filter $wp_filter
 864   * @global array $merged_filters
 865   *
 866   * @param string   $tag      The tag to which filters should be restored.
 867   * @param int|bool $priority Optional. If present, only those filters that were originally
 868   *                           attached to the tag with $priority will be restored. Otherwise,
 869   *                           all available filters will be restored, regardless of priority.
 870   * @return bool True on success.
 871   */
 872  function bp_restore_all_filters( $tag, $priority = false ) {
 873      global $wp_filter, $merged_filters;
 874  
 875      $bp = buddypress();
 876  
 877      // Filters exist.
 878      if ( isset( $bp->filters->wp_filter[$tag] ) ) {
 879  
 880          // Filters exist in this priority.
 881          if ( ! empty( $priority ) && isset( $bp->filters->wp_filter[$tag][$priority] ) ) {
 882  
 883              // Store filters in a backup.
 884              $wp_filter[$tag][$priority] = $bp->filters->wp_filter[$tag][$priority];
 885  
 886              // Unset the filters.
 887              unset( $bp->filters->wp_filter[$tag][$priority] );
 888  
 889          // Priority is empty.
 890          } else {
 891  
 892              // Store filters in a backup.
 893              $wp_filter[$tag] = $bp->filters->wp_filter[$tag];
 894  
 895              // Unset the filters.
 896              unset( $bp->filters->wp_filter[$tag] );
 897          }
 898      }
 899  
 900      // Check merged filters.
 901      if ( isset( $bp->filters->merged_filters[$tag] ) ) {
 902  
 903          // Store filters in a backup.
 904          $merged_filters[$tag] = $bp->filters->merged_filters[$tag];
 905  
 906          // Unset the filters.
 907          unset( $bp->filters->merged_filters[$tag] );
 908      }
 909  
 910      return true;
 911  }
 912  
 913  /**
 914   * Force comments_status to 'closed' for BuddyPress post types.
 915   *
 916   * @since 1.7.0
 917   *
 918   * @param bool $open    True if open, false if closed.
 919   * @param int  $post_id ID of the post to check.
 920   * @return bool True if open, false if closed.
 921   */
 922  function bp_comments_open( $open, $post_id = 0 ) {
 923  
 924      $retval = is_buddypress() ? false : $open;
 925  
 926      /**
 927       * Filters whether or not to force comments_status to closed for BuddyPress post types.
 928       *
 929       * @since 1.7.0
 930       *
 931       * @param bool $retval  Whether or not we are on a BuddyPress post type.
 932       * @param bool $open    True if comments open, false if closed.
 933       * @param int  $post_id Post ID for the checked post.
 934       */
 935      return apply_filters( 'bp_force_comment_status', $retval, $open, $post_id );
 936  }
 937  
 938  /**
 939   * Do not allow {@link comments_template()} to render during theme compatibility.
 940   *
 941   * When theme compatibility sets the 'is_page' flag to true via
 942   * {@link bp_theme_compat_reset_post()}, themes that use comments_template()
 943   * in their page template will run.
 944   *
 945   * To prevent comments_template() from rendering, we set the 'is_page' and
 946   * 'is_single' flags to false since that function looks at these conditionals
 947   * before querying the database for comments and loading the comments template.
 948   *
 949   * This is done during the output buffer as late as possible to prevent any
 950   * wonkiness.
 951   *
 952   * @since 1.9.2
 953   *
 954   * @param  string $retval The current post content.
 955   * @return string $retval
 956   */
 957  function bp_theme_compat_toggle_is_page( $retval = '' ) {
 958      global $wp_query;
 959  
 960      if ( $wp_query->is_page ) {
 961          $wp_query->is_page = false;
 962  
 963          // Set a switch so we know that we've toggled these WP_Query properties.
 964          buddypress()->theme_compat->is_page_toggled = true;
 965      }
 966  
 967      return $retval;
 968  }
 969  add_filter( 'bp_replace_the_content', 'bp_theme_compat_toggle_is_page', 9999 );
 970  
 971  /**
 972   * Restores the 'is_single' and 'is_page' flags if toggled by BuddyPress.
 973   *
 974   * @since 1.9.2
 975   *
 976   * @see bp_theme_compat_toggle_is_page()
 977   * @param object $query The WP_Query object.
 978   */
 979  function bp_theme_compat_loop_end( $query ) {
 980  
 981      // Get BuddyPress.
 982      $bp = buddypress();
 983  
 984      // Bail if page is not toggled.
 985      if ( ! isset( $bp->theme_compat->is_page_toggled ) ) {
 986          return;
 987      }
 988  
 989      // Revert our toggled WP_Query properties.
 990      $query->is_page = true;
 991  
 992      // Unset our switch.
 993      unset( $bp->theme_compat->is_page_toggled );
 994  }
 995  add_action( 'loop_end', 'bp_theme_compat_loop_end' );
 996  
 997  /**
 998   * Maybe override the preferred template pack if the theme declares a dependency.
 999   *
1000   * @since 3.0.0
1001   */
1002  function bp_check_theme_template_pack_dependency() {
1003      if ( bp_is_deactivation() ) {
1004          return;
1005      }
1006  
1007      $all_packages = array_keys( buddypress()->theme_compat->packages );
1008  
1009      foreach ( $all_packages as $package ) {
1010          // e.g. "buddypress-use-nouveau", "buddypress-use-legacy".
1011          if ( ! current_theme_supports( "buddypress-use-{$package}" ) ) {
1012              continue;
1013          }
1014  
1015          bp_setup_theme_compat( $package );
1016          return;
1017      }
1018  }


Generated: Thu Nov 21 01:00:57 2024 Cross-referenced by PHPXref 0.7.1