Advertisement
Guest User

bp-core-catchuri.php

a guest
Nov 17th, 2012
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 23.56 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4.  * BuddyPress URI catcher
  5.  *
  6.  * Functions for parsing the URI and determining which BuddyPress template file
  7.  * to use on-screen.
  8.  *
  9.  * @package BuddyPress
  10.  * @subpackage Core
  11.  */
  12.  
  13. // Exit if accessed directly
  14. if ( !defined( 'ABSPATH' ) ) exit;
  15.  
  16. /**
  17.  * Analyzes the URI structure and breaks it down into parts for use in code.
  18.  * BuddyPress can use complete custom friendly URI's without the user having to
  19.  * add new re-write rules. Custom components are able to use their own custom
  20.  * URI structures with very little work.
  21.  *
  22.  * @package BuddyPress Core
  23.  * @since BuddyPress (1.0)
  24.  *
  25.  * The URI's are broken down as follows:
  26.  *   - http:// domain.com / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ...
  27.  *   - OUTSIDE ROOT: http:// domain.com / sites / buddypress / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ...
  28.  *
  29.  *  Example:
  30.  *    - http://domain.com/members/andy/profile/edit/group/5/
  31.  *    - $bp->current_component: string 'xprofile'
  32.  *    - $bp->current_action: string 'edit'
  33.  *    - $bp->action_variables: array ['group', 5]
  34.  *
  35.  */
  36. function bp_core_set_uri_globals() {
  37.     global $bp, $current_blog, $wp_rewrite;
  38.  
  39.     // Don't catch URIs on non-root blogs unless multiblog mode is on
  40.     if ( !bp_is_root_blog() && !bp_is_multiblog_mode() )
  41.         return false;
  42.  
  43.     // Define local variables
  44.     $root_profile = $match   = false;
  45.     $key_slugs    = $matches = $uri_chunks = array();
  46.  
  47.     // Fetch all the WP page names for each component
  48.     if ( empty( $bp->pages ) )
  49.         $bp->pages = bp_core_get_directory_pages();
  50.  
  51.     // Ajax or not?
  52.     if ( defined( 'DOING_AJAX' ) && DOING_AJAX || strpos( $_SERVER['REQUEST_URI'], 'wp-load.php' ) )
  53.         $path = bp_core_referrer();
  54.     else
  55.         $path = esc_url( $_SERVER['REQUEST_URI'] );
  56.  
  57.     // Filter the path
  58.     $path = apply_filters( 'bp_uri', $path );
  59.  
  60.     // Take GET variables off the URL to avoid problems
  61.     $path = strtok( $path, '?' );
  62.  
  63.     // Fetch current URI and explode each part separated by '/' into an array
  64.     $bp_uri = explode( '/', $path );
  65.  
  66.     // Loop and remove empties
  67.     foreach ( (array) $bp_uri as $key => $uri_chunk ) {
  68.         if ( empty( $bp_uri[$key] ) ) {
  69.             unset( $bp_uri[$key] );
  70.         }
  71.     }
  72.  
  73.     // If running off blog other than root, any subdirectory names must be
  74.     // removed from $bp_uri. This includes two cases:
  75.     //
  76.     //    1. when WP is installed in a subdirectory,
  77.     //    2. when BP is running on secondary blog of a subdirectory
  78.     //       multisite installation. Phew!
  79.     if ( is_multisite() && !is_subdomain_install() && ( bp_is_multiblog_mode() || 1 != bp_get_root_blog_id() ) ) {
  80.  
  81.         // Blow chunks
  82.         $chunks = explode( '/', $current_blog->path );
  83.  
  84.         // If chunks exist...
  85.         if ( !empty( $chunks ) ) {
  86.  
  87.             // ...loop through them...
  88.             foreach( $chunks as $key => $chunk ) {
  89.                 $bkey = array_search( $chunk, $bp_uri );
  90.  
  91.                 // ...and unset offending keys
  92.                 if ( false !== $bkey ) {
  93.                     unset( $bp_uri[$bkey] );
  94.                 }
  95.  
  96.                 $bp_uri = array_values( $bp_uri );
  97.             }
  98.         }
  99.     }
  100.  
  101.     // Get site path items
  102.     $paths = explode( '/', bp_core_get_site_path() );
  103.  
  104.     // Take empties off the end of path
  105.     if ( empty( $paths[count( $paths ) - 1] ) )
  106.         array_pop( $paths );
  107.  
  108.     // Take empties off the start of path
  109.     if ( empty( $paths[0] ) )
  110.         array_shift( $paths );
  111.  
  112.     // Reset indexes
  113.     $bp_uri = array_values( $bp_uri );
  114.     $paths  = array_values( $paths );
  115.  
  116.     // Unset URI indices if they intersect with the paths
  117.     foreach ( (array) $bp_uri as $key => $uri_chunk ) {
  118.         if ( isset( $paths[$key] ) && $uri_chunk == $paths[$key] ) {
  119.             unset( $bp_uri[$key] );
  120.         }
  121.     }
  122.  
  123.     // Reset the keys by merging with an empty array
  124.     $bp_uri = array_merge( array(), $bp_uri );
  125.  
  126.     // If a component is set to the front page, force its name into $bp_uri
  127.     // so that $current_component is populated (unless a specific WP post is being requested
  128.     // via a URL parameter, usually signifying Preview mode)
  129.     if ( 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) && empty( $bp_uri ) && empty( $_GET['p'] ) && empty( $_GET['page_id'] ) ) {
  130.         $post = get_post( get_option( 'page_on_front' ) );
  131.         if ( !empty( $post ) ) {
  132.             $bp_uri[0] = $post->post_name;
  133.         }
  134.     }
  135.  
  136.     // Keep the unfiltered URI safe
  137.     $bp->unfiltered_uri = $bp_uri;
  138.  
  139.     // Get slugs of pages into array
  140.     foreach ( (array) $bp->pages as $page_key => $bp_page )
  141.         $key_slugs[$page_key] = trailingslashit( '/' . $bp_page->slug );
  142.  
  143.     // Bail if keyslugs are empty, as BP is not setup correct
  144.     if ( empty( $key_slugs ) )
  145.         return;
  146.  
  147.     // Loop through page slugs and look for exact match to path
  148.     foreach ( $key_slugs as $key => $slug ) {
  149.         if ( $slug == $path ) {
  150.             $match      = $bp->pages->{$key};
  151.             $match->key = $key;
  152.             $matches[]  = 1;
  153.             break;
  154.         }
  155.     }
  156.  
  157.     // No exact match, so look for partials
  158.     if ( empty( $match ) ) {
  159.  
  160.         // Loop through each page in the $bp->pages global
  161.         foreach ( (array) $bp->pages as $page_key => $bp_page ) {
  162.  
  163.             // Look for a match (check members first)
  164.             if ( in_array( $bp_page->name, (array) $bp_uri ) ) {
  165.  
  166.                 // Match found, now match the slug to make sure.
  167.                 $uri_chunks = explode( '/', $bp_page->slug );
  168.  
  169.                 // Loop through uri_chunks
  170.                 foreach ( (array) $uri_chunks as $key => $uri_chunk ) {
  171.  
  172.                     // Make sure chunk is in the correct position
  173.                     if ( !empty( $bp_uri[$key] ) && ( $bp_uri[$key] == $uri_chunk ) ) {
  174.                         $matches[] = 1;
  175.  
  176.                     // No match
  177.                     } else {
  178.                         $matches[] = 0;
  179.                     }
  180.                 }
  181.  
  182.                 // Have a match
  183.                 if ( !in_array( 0, (array) $matches ) ) {
  184.                     $match      = $bp_page;
  185.                     $match->key = $page_key;
  186.                     break;
  187.                 };
  188.  
  189.                 // Unset matches
  190.                 unset( $matches );
  191.             }
  192.  
  193.             // Unset uri chunks
  194.             unset( $uri_chunks );
  195.         }
  196.     }
  197.  
  198.     // URLs with BP_ENABLE_ROOT_PROFILES enabled won't be caught above
  199.     if ( empty( $matches ) && bp_core_enable_root_profiles() ) {
  200.  
  201.         // Switch field based on compat
  202.         $field = bp_is_username_compatibility_mode() ? 'login' : 'slug';
  203.  
  204.         // Make sure there's a user corresponding to $bp_uri[0]
  205.         if ( !empty( $bp->pages->members ) && !empty( $bp_uri[0] ) && $root_profile = get_user_by( $field, $bp_uri[0] ) ) {
  206.  
  207.             // Force BP to recognize that this is a members page
  208.             $matches[]  = 1;
  209.             $match      = $bp->pages->members;
  210.             $match->key = 'members';
  211.  
  212.             // Without the 'members' URL chunk, WordPress won't know which page to load
  213.             // This filter intercepts the WP query and tells it to load the members page
  214.             add_filter( 'request', create_function( '$query_args', '$query_args["pagename"] = "' . $match->name . '"; return $query_args;' ) );
  215.         }
  216.     }
  217.  
  218.     // Search doesn't have an associated page, so we check for it separately
  219.     if ( !empty( $bp_uri[0] ) && ( bp_get_search_slug() == $bp_uri[0] ) ) {
  220.         $matches[]   = 1;
  221.         $match       = new stdClass;
  222.         $match->key  = 'search';
  223.         $match->slug = bp_get_search_slug();
  224.     }
  225.  
  226.     // This is not a BuddyPress page, so just return.
  227.     if ( empty( $matches ) )
  228.         return false;
  229.  
  230.     $wp_rewrite->use_verbose_page_rules = false;
  231.  
  232.     // Find the offset. With $root_profile set, we fudge the offset down so later parsing works
  233.     $slug       = !empty ( $match ) ? explode( '/', $match->slug ) : '';
  234.     $uri_offset = empty( $root_profile ) ? 0 : -1;
  235.  
  236.     // Rejig the offset
  237.     if ( !empty( $slug ) && ( 1 < count( $slug ) ) ) {
  238.         array_pop( $slug );
  239.         $uri_offset = count( $slug );
  240.     }
  241.  
  242.     // Global the unfiltered offset to use in bp_core_load_template().
  243.     // To avoid PHP warnings in bp_core_load_template(), it must always be >= 0
  244.     $bp->unfiltered_uri_offset = $uri_offset >= 0 ? $uri_offset : 0;
  245.  
  246.     // We have an exact match
  247.     if ( isset( $match->key ) ) {
  248.  
  249.         // Set current component to matched key
  250.         $bp->current_component = $match->key;
  251.  
  252.         // If members component, do more work to find the actual component
  253.         if ( 'members' == $match->key ) {
  254.  
  255.             // Viewing a specific user
  256.             if ( !empty( $bp_uri[$uri_offset + 1] ) ) {
  257.  
  258.                 // Switch the displayed_user based on compatbility mode
  259.                 if ( bp_is_username_compatibility_mode() ) {
  260.                     $bp->displayed_user->id = (int) bp_core_get_userid( urldecode( $bp_uri[$uri_offset + 1] ) );
  261.                 } else {
  262.                     $bp->displayed_user->id = (int) bp_core_get_userid_from_nicename( urldecode( $bp_uri[$uri_offset + 1] ) );
  263.                 }
  264.  
  265.                 if ( !bp_displayed_user_id() ) {
  266.  
  267.                     // Prevent components from loading their templates
  268.                     $bp->current_component = '';
  269.  
  270.                     bp_do_404();
  271.                     return;
  272.                 }
  273.  
  274.                 // If the displayed user is marked as a spammer, 404 (unless logged-
  275.                 // in user is a super admin)
  276.                 if ( bp_displayed_user_id() && bp_is_user_spammer( bp_displayed_user_id() ) ) {
  277.                     if ( bp_current_user_can( 'bp_moderate' ) ) {
  278.                         bp_core_add_message( __( 'This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress' ), 'warning' );
  279.                     } else {
  280.                         bp_do_404();
  281.                         return;
  282.                     }
  283.                 }
  284.  
  285.                 // Bump the offset
  286.                 if ( isset( $bp_uri[$uri_offset + 2] ) ) {
  287.                     $bp_uri                = array_merge( array(), array_slice( $bp_uri, $uri_offset + 2 ) );
  288.                     $bp->current_component = $bp_uri[0];
  289.  
  290.                 // No component, so default will be picked later
  291.                 } else {
  292.                     $bp_uri                = array_merge( array(), array_slice( $bp_uri, $uri_offset + 2 ) );
  293.                     $bp->current_component = '';
  294.                 }
  295.  
  296.                 // Reset the offset
  297.                 $uri_offset = 0;
  298.             }
  299.         }
  300.     }
  301.  
  302.     // Set the current action
  303.     $bp->current_action = isset( $bp_uri[$uri_offset + 1] ) ? $bp_uri[$uri_offset + 1] : '';
  304.  
  305.     // Slice the rest of the $bp_uri array and reset offset
  306.     $bp_uri      = array_slice( $bp_uri, $uri_offset + 2 );
  307.     $uri_offset  = 0;
  308.  
  309.     // Set the entire URI as the action variables, we will unset the current_component and action in a second
  310.     $bp->action_variables = $bp_uri;
  311.  
  312.     // Reset the keys by merging with an empty array
  313.     $bp->action_variables = array_merge( array(), $bp->action_variables );
  314. }
  315.  
  316. /**
  317.  * Are root profiles enabled and allowed
  318.  *
  319.  * @since BuddyPress (1.6)
  320.  * @return bool True if yes, false if no
  321.  */
  322. function bp_core_enable_root_profiles() {
  323.  
  324.     $retval = false;
  325.  
  326.     if ( defined( 'BP_ENABLE_ROOT_PROFILES' ) && ( true == BP_ENABLE_ROOT_PROFILES ) )
  327.         $retval = true;
  328.  
  329.     return apply_filters( 'bp_core_enable_root_profiles', $retval );
  330. }
  331.  
  332. /**
  333.  * bp_core_load_template()
  334.  *
  335.  * Load a specific template file with fallback support.
  336.  *
  337.  * Example:
  338.  *   bp_core_load_template( 'members/index' );
  339.  * Loads:
  340.  *   wp-content/themes/[activated_theme]/members/index.php
  341.  *
  342.  * @package BuddyPress Core
  343.  * @param $username str Username to check.
  344.  * @return false|int The user ID of the matched user, or false.
  345.  */
  346. function bp_core_load_template( $templates ) {
  347.     global $post, $bp, $wp_query, $wpdb;
  348.  
  349.     // Determine if the root object WP page exists for this request
  350.     // note: get_page_by_path() breaks non-root pages
  351.     if ( !empty( $bp->unfiltered_uri_offset ) ) {
  352.         if ( !$page_exists = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_name = %s", $bp->unfiltered_uri[$bp->unfiltered_uri_offset] ) ) ) {
  353.             return false;
  354.         }
  355.     }
  356.  
  357.     // Set the root object as the current wp_query-ied item
  358.     $object_id = 0;
  359.     foreach ( (array) $bp->pages as $page ) {
  360.         if ( $page->name == $bp->unfiltered_uri[$bp->unfiltered_uri_offset] ) {
  361.             $object_id = $page->id;
  362.         }
  363.     }
  364.  
  365.     // Make the queried/post object an actual valid page
  366.     if ( !empty( $object_id ) ) {
  367.         $wp_query->queried_object    = &get_post( $object_id );
  368.         $wp_query->queried_object_id = $object_id;
  369.         $post                        = $wp_query->queried_object;
  370.     }
  371.  
  372.     // Define local variables
  373.     $located_template   = false;
  374.     $filtered_templates = array();
  375.  
  376.     // Fetch each template and add the php suffix
  377.     foreach ( (array) $templates as $template )
  378.         $filtered_templates[] = $template . '.php';
  379.  
  380.     // Filter the template locations so that plugins can alter where they are located
  381.     $located_template = apply_filters( 'bp_located_template', locate_template( (array) $filtered_templates, false ), $filtered_templates );
  382.     if ( !empty( $located_template ) ) {
  383.  
  384.         // Template was located, lets set this as a valid page and not a 404.
  385.         status_header( 200 );
  386.         $wp_query->is_page = $wp_query->is_singular = true;
  387.         $wp_query->is_404  = false;
  388.  
  389.         do_action( 'bp_core_pre_load_template', $located_template );
  390.  
  391.         load_template( apply_filters( 'bp_load_template', $located_template ) );
  392.  
  393.         do_action( 'bp_core_post_load_template', $located_template );
  394.     }
  395.  
  396.     // Kill any other output after this.
  397.     die;
  398. }
  399.  
  400. /**
  401.  * bp_core_catch_profile_uri()
  402.  *
  403.  * If the extended profiles component is not installed we still need
  404.  * to catch the /profile URI's and display whatever we have installed.
  405.  *
  406.  */
  407. function bp_core_catch_profile_uri() {
  408.     if ( !bp_is_active( 'xprofile' ) ) {
  409.         bp_core_load_template( apply_filters( 'bp_core_template_display_profile', 'members/single/home' ) );
  410.     }
  411. }
  412.  
  413. /**
  414.  * Catches invalid access to BuddyPress pages and redirects them accordingly.
  415.  *
  416.  * @package BuddyPress Core
  417.  * @since BuddyPress (1.5)
  418.  */
  419. function bp_core_catch_no_access() {
  420.     global $bp, $wp_query;
  421.  
  422.     // If coming from bp_core_redirect() and $bp_no_status_set is true,
  423.     // we are redirecting to an accessible page so skip this check.
  424.     if ( !empty( $bp->no_status_set ) )
  425.         return false;
  426.  
  427.     if ( !isset( $wp_query->queried_object ) && !bp_is_blog_page() ) {
  428.         bp_do_404();
  429.     }
  430. }
  431. add_action( 'bp_template_redirect', 'bp_core_catch_no_access', 1 );
  432.  
  433. /**
  434.  * Redirects a user to login for BP pages that require access control and adds an error message (if
  435.  * one is provided).
  436.  * If authenticated, redirects user back to requested content by default.
  437.  *
  438.  * @package BuddyPress Core
  439.  * @since BuddyPress (1.5)
  440.  */
  441. function bp_core_no_access( $args = '' ) {
  442.  
  443.     // Build the redirect URL
  444.     $redirect_url  = is_ssl() ? 'https://' : 'http://';
  445.     $redirect_url .= $_SERVER['HTTP_HOST'];
  446.     $redirect_url .= $_SERVER['REQUEST_URI'];
  447.  
  448.     $defaults = array(
  449.         'mode'     => '1',                  // 1 = $root, 2 = wp-login.php
  450.         'redirect' => $redirect_url,        // the URL you get redirected to when a user successfully logs in
  451.         'root'     => bp_get_root_domain(), // the landing page you get redirected to when a user doesn't have access
  452.         'message'  => __( 'You must log in to access the page you requested.', 'buddypress' )
  453.     );
  454.  
  455.     $r = wp_parse_args( $args, $defaults );
  456.     $r = apply_filters( 'bp_core_no_access', $r );
  457.     extract( $r, EXTR_SKIP );
  458.  
  459.     /**
  460.      * @ignore Ignore these filters and use 'bp_core_no_access' above
  461.      */
  462.     $mode       = apply_filters( 'bp_no_access_mode',     $mode,     $root,     $redirect, $message );
  463.     $redirect   = apply_filters( 'bp_no_access_redirect', $redirect, $root,     $message,  $mode    );
  464.     $root       = apply_filters( 'bp_no_access_root',     $root,     $redirect, $message,  $mode    );
  465.     $message    = apply_filters( 'bp_no_access_message',  $message,  $root,     $redirect, $mode    );
  466.     $root       = trailingslashit( $root );
  467.  
  468.     switch ( $mode ) {
  469.  
  470.         // Option to redirect to wp-login.php
  471.         // Error message is displayed with bp_core_no_access_wp_login_error()
  472.         case 2 :
  473.             if ( !empty( $redirect ) ) {
  474.                 bp_core_redirect( add_query_arg( array( 'action' => 'bpnoaccess' ), wp_login_url( $redirect ) ) );
  475.             } else {
  476.                 bp_core_redirect( $root );
  477.             }
  478.  
  479.             break;
  480.  
  481.         // Redirect to root with "redirect_to" parameter
  482.         // Error message is displayed with bp_core_add_message()
  483.         case 1 :
  484.         default :
  485.  
  486.             $url = $root;
  487.             if ( !empty( $redirect ) )
  488.                 $url = add_query_arg( 'redirect_to', urlencode( $redirect ), $root );
  489.  
  490.             if ( !empty( $message ) ) {
  491.                 bp_core_add_message( $message, 'error' );
  492.             }
  493.  
  494.             bp_core_redirect( $url );
  495.  
  496.             break;
  497.     }
  498. }
  499.  
  500. /**
  501.  * Adds an error message to wp-login.php.
  502.  * Hooks into the "bpnoaccess" action defined in bp_core_no_access().
  503.  *
  504.  * @package BuddyPress Core
  505.  * @global $error
  506.  * @since BuddyPress (1.5)
  507.  */
  508. function bp_core_no_access_wp_login_error() {
  509.     global $error;
  510.  
  511.     $error = apply_filters( 'bp_wp_login_error', __( 'You must log in to access the page you requested.', 'buddypress' ), $_REQUEST['redirect_to'] );
  512.  
  513.     // shake shake shake!
  514.     add_action( 'login_head', 'wp_shake_js', 12 );
  515. }
  516. add_action( 'login_form_bpnoaccess', 'bp_core_no_access_wp_login_error' );
  517.  
  518. /**
  519.  * Canonicalizes BuddyPress URLs
  520.  *
  521.  * This function ensures that requests for BuddyPress content are always redirected to their
  522.  * canonical versions. Canonical versions are always trailingslashed, and are typically the most
  523.  * general possible versions of the URL - eg, example.com/groups/mygroup/ instead of
  524.  * example.com/groups/mygroup/home/
  525.  *
  526.  * @since 1.6
  527.  * @see BP_Members_Component::setup_globals() where $bp->canonical_stack['base_url'] and
  528.  *   ['component'] may be set
  529.  * @see bp_core_new_nav_item() where $bp->canonical_stack['action'] may be set
  530.  * @uses bp_get_canonical_url()
  531.  * @uses bp_get_requested_url()
  532.  */
  533. function bp_redirect_canonical() {
  534.     global $bp;
  535.  
  536.     if ( !bp_is_blog_page() && apply_filters( 'bp_do_redirect_canonical', true ) ) {
  537.         // If this is a POST request, don't do a canonical redirect.
  538.         // This is for backward compatibility with plugins that submit form requests to
  539.         // non-canonical URLs. Plugin authors should do their best to use canonical URLs in
  540.         // their form actions.
  541.         if ( !empty( $_POST ) ) {
  542.             return;
  543.         }
  544.  
  545.         // build the URL in the address bar
  546.         $requested_url  = bp_get_requested_url();
  547.  
  548.         // Stash query args
  549.         $url_stack      = explode( '?', $requested_url );
  550.         $req_url_clean  = $url_stack[0];
  551.         $query_args     = isset( $url_stack[1] ) ? $url_stack[1] : '';
  552.  
  553.         $canonical_url  = bp_get_canonical_url();
  554.  
  555.         // Only redirect if we've assembled a URL different from the request
  556.         if ( $canonical_url !== $req_url_clean ) {
  557.  
  558.             // Template messages have been deleted from the cookie by this point, so
  559.             // they must be readded before redirecting
  560.             if ( isset( $bp->template_message ) ) {
  561.                 $message      = stripslashes( $bp->template_message );
  562.                 $message_type = isset( $bp->template_message_type ) ? $bp->template_message_type : 'success';
  563.  
  564.                 bp_core_add_message( $message, $message_type );
  565.             }
  566.  
  567.             if ( !empty( $query_args ) ) {
  568.                 $canonical_url .= '?' . $query_args;
  569.             }
  570.  
  571.             bp_core_redirect( $canonical_url, 301 );
  572.         }
  573.     }
  574. }
  575.  
  576. /**
  577.  * Output rel=canonical header tag for BuddyPress content
  578.  *
  579.  * @since 1.6
  580.  */
  581. function bp_rel_canonical() {
  582.     $canonical_url = bp_get_canonical_url();
  583.  
  584.     // Output rel=canonical tag
  585.     echo "<link rel='canonical' href='" . esc_attr( $canonical_url ) . "' />\n";
  586. }
  587.  
  588. /**
  589.  * Returns the canonical URL of the current page
  590.  *
  591.  * @since BuddyPress (1.6)
  592.  * @uses apply_filters() Filter bp_get_canonical_url to modify return value
  593.  * @param array $args
  594.  * @return string
  595.  */
  596. function bp_get_canonical_url( $args = array() ) {
  597.     global $bp;
  598.  
  599.     // For non-BP content, return the requested url, and let WP do the work
  600.     if ( bp_is_blog_page() ) {
  601.         return bp_get_requested_url();
  602.     }
  603.  
  604.     $defaults = array(
  605.         'include_query_args' => false // Include URL arguments, eg ?foo=bar&foo2=bar2
  606.     );
  607.     $r = wp_parse_args( $args, $defaults );
  608.     extract( $r );
  609.  
  610.     if ( empty( $bp->canonical_stack['canonical_url'] ) ) {
  611.         // Build the URL in the address bar
  612.         $requested_url  = bp_get_requested_url();
  613.  
  614.         // Stash query args
  615.         $url_stack      = explode( '?', $requested_url );
  616.  
  617.         // Build the canonical URL out of the redirect stack
  618.         if ( isset( $bp->canonical_stack['base_url'] ) )
  619.             $url_stack[0] = $bp->canonical_stack['base_url'];
  620.  
  621.         if ( isset( $bp->canonical_stack['component'] ) )
  622.             $url_stack[0] = trailingslashit( $url_stack[0] . $bp->canonical_stack['component'] );
  623.  
  624.         if ( isset( $bp->canonical_stack['action'] ) )
  625.             $url_stack[0] = trailingslashit( $url_stack[0] . $bp->canonical_stack['action'] );
  626.  
  627.         if ( !empty( $bp->canonical_stack['action_variables'] ) ) {
  628.             foreach( (array) $bp->canonical_stack['action_variables'] as $av ) {
  629.                 $url_stack[0] = trailingslashit( $url_stack[0] . $av );
  630.             }
  631.         }
  632.  
  633.         // Add trailing slash
  634.         $url_stack[0] = trailingslashit( $url_stack[0] );
  635.  
  636.         // Stash in the $bp global
  637.         $bp->canonical_stack['canonical_url'] = implode( '?', $url_stack );
  638.     }
  639.  
  640.     $canonical_url = $bp->canonical_stack['canonical_url'];
  641.  
  642.     if ( !$include_query_args ) {
  643.         $canonical_url = array_pop( array_reverse( explode( '?', $canonical_url ) ) );
  644.     }
  645.  
  646.     return apply_filters( 'bp_get_canonical_url', $canonical_url, $args );
  647. }
  648.  
  649. /**
  650.  * Returns the URL as requested on the current page load by the user agent
  651.  *
  652.  * @since BuddyPress (1.6)
  653.  * @return string
  654.  */
  655. function bp_get_requested_url() {
  656.     global $bp;
  657.  
  658.     if ( empty( $bp->canonical_stack['requested_url'] ) ) {
  659.         $bp->canonical_stack['requested_url']  = is_ssl() ? 'https://' : 'http://';
  660.         $bp->canonical_stack['requested_url'] .= $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  661.     }
  662.  
  663.     return $bp->canonical_stack['requested_url'];
  664. }
  665.  
  666. /**
  667.  * Remove WordPress's really awesome canonical redirect if we are trying to load
  668.  * BuddyPress specific content. Avoids issues with WordPress thinking that a
  669.  * BuddyPress URL might actually be a blog post or page.
  670.  *
  671.  * This function should be considered temporary, and may be removed without
  672.  * notice in future versions of BuddyPress.
  673.  *
  674.  * @since BuddyPress (1.6)
  675.  * @uses bp_is_blog_page()
  676.  */
  677. function _bp_maybe_remove_redirect_canonical() {
  678.     if ( ! bp_is_blog_page() )
  679.         remove_action( 'template_redirect', 'redirect_canonical' );
  680. }
  681. add_action( 'bp_init', '_bp_maybe_remove_redirect_canonical' );
  682.  
  683. /**
  684.  * Rehook maybe_redirect_404() to run later than the default
  685.  *
  686.  * WordPress's maybe_redirect_404() allows admins on a multisite installation
  687.  * to define 'NOBLOGREDIRECT', a URL to which 404 requests will be redirected.
  688.  * maybe_redirect_404() is hooked to template_redirect at priority 10, which
  689.  * creates a race condition with bp_template_redirect(), our piggyback hook.
  690.  * Due to a legacy bug in BuddyPress, internal BP content (such as members and
  691.  * groups) is marked 404 in $wp_query until bp_core_load_template(), when BP
  692.  * manually overrides the automatic 404. However, the race condition with
  693.  * maybe_redirect_404() means that this manual un-404-ing doesn't happen in
  694.  * time, with the results that maybe_redirect_404() thinks that the page is
  695.  * a legitimate 404, and redirects incorrectly to NOBLOGREDIRECT.
  696.  *
  697.  * By switching maybe_redirect_404() to catch at a higher priority, we avoid
  698.  * the race condition. If bp_core_load_template() runs, it dies before reaching
  699.  * maybe_redirect_404(). If bp_core_load_template() does not run, it means that
  700.  * the 404 is legitimate, and maybe_redirect_404() can proceed as expected.
  701.  *
  702.  * This function will be removed in a later version of BuddyPress. Plugins
  703.  * (and plugin authors!) should ignore it.
  704.  *
  705.  * @since 1.6.1
  706.  *
  707.  * @link http://buddypress.trac.wordpress.org/ticket/4329
  708.  * @link http://buddypress.trac.wordpress.org/ticket/4415
  709.  */
  710. function _bp_rehook_maybe_redirect_404() {
  711.     if ( defined( 'NOBLOGREDIRECT' ) ) {
  712.         remove_action( 'template_redirect', 'maybe_redirect_404' );
  713.         add_action( 'template_redirect', 'maybe_redirect_404', 100 );
  714.     }
  715. }
  716. add_action( 'template_redirect', '_bp_rehook_maybe_redirect_404', 1 );
  717.  
  718. /**
  719.  * Remove WordPress's rel=canonical HTML tag if we are trying to load BuddyPress
  720.  * specific content.
  721.  *
  722.  * This function should be considered temporary, and may be removed without
  723.  * notice in future versions of BuddyPress.
  724.  *
  725.  * @since 1.6
  726.  */
  727. function _bp_maybe_remove_rel_canonical() {
  728.     if ( ! bp_is_blog_page() && ! is_404() ) {
  729.         remove_action( 'wp_head', 'rel_canonical' );
  730.         add_action( 'bp_head', 'bp_rel_canonical' );
  731.     }
  732. }
  733. add_action( 'wp_head', '_bp_maybe_remove_rel_canonical', 8 );
  734. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement