<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][4096] trunk/bp-core/bp-core-catchuri.php: Fix bug in bp_core_set_uri_globals() where partial slug matches could override exact slugs based on the component load order, by manually checking for exact matches first, and looking for partials if no exact match is found.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg > ul, #logmsg > ol { margin-left: 0; margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd>4096</dd>
<dt>Author</dt> <dd>johnjamesjacoby</dd>
<dt>Date</dt> <dd>2011-03-10 10:48:38 +0000 (Thu, 10 Mar 2011)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fix bug in bp_core_set_uri_globals() where partial slug matches could override exact slugs based on the component load order, by manually checking for exact matches first, and looking for partials if no exact match is found.

Also attempt to better assign the $bp-&gt;current_component global. Previously we set it to be the root_slug and did extra work to figure out the component name; now we set the component name/key based on the match, and rely on that to set the current_component. </pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkbpcorebpcorecatchuriphp">trunk/bp-core/bp-core-catchuri.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkbpcorebpcorecatchuriphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-core/bp-core-catchuri.php (4095 => 4096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-core/bp-core-catchuri.php        2011-03-10 07:30:28 UTC (rev 4095)
+++ trunk/bp-core/bp-core-catchuri.php        2011-03-10 10:48:38 UTC (rev 4096)
</span><span class="lines">@@ -33,9 +33,9 @@
</span><span class="cx">         $bp-&gt;current_component = $bp-&gt;current_action = $bp-&gt;current_item ='';
</span><span class="cx">         $bp-&gt;action_variables = $bp-&gt;displayed_user-&gt;id = '';
</span><span class="cx"> 
</span><ins>+        // Only catch URI's on the root blog if we are not running
+        // on multiple blogs
</ins><span class="cx">         if ( !defined( 'BP_ENABLE_MULTIBLOG' ) &amp;&amp; is_multisite() ) {
</span><del>-                // Only catch URI's on the root blog if we are not running
-                // on multiple blogs
</del><span class="cx">                 if ( BP_ROOT_BLOG != (int) $current_blog-&gt;blog_id )
</span><span class="cx">                         return false;
</span><span class="cx">         }
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">         else
</span><span class="cx">                 $path = esc_url( $_SERVER['REQUEST_URI'] );
</span><span class="cx"> 
</span><ins>+        // Filter the path
</ins><span class="cx">         $path = apply_filters( 'bp_uri', $path );
</span><span class="cx"> 
</span><span class="cx">         // Take GET variables off the URL to avoid problems,
</span><span class="lines">@@ -91,15 +92,16 @@
</span><span class="cx">         $paths = explode( '/', bp_core_get_site_path() );
</span><span class="cx"> 
</span><span class="cx">         // Take empties off the end of path
</span><del>-        if ( empty( $paths[count($paths) - 1] ) )
</del><ins>+        if ( empty( $paths[count( $paths ) - 1] ) )
</ins><span class="cx">                 array_pop( $paths );
</span><span class="cx"> 
</span><span class="cx">         // Take empties off the start of path
</span><span class="cx">         if ( empty( $paths[0] ) )
</span><span class="cx">                 array_shift( $paths );
</span><span class="cx"> 
</span><del>-        foreach ( (array)$bp_uri as $key =&gt; $uri_chunk ) {
-                if ( in_array( $uri_chunk, $paths )) {
</del><ins>+        // Unset URI indices if they intersect with the paths
+        foreach ( (array) $bp_uri as $key =&gt; $uri_chunk ) {
+                if ( in_array( $uri_chunk, $paths ) ) {
</ins><span class="cx">                         unset( $bp_uri[$key] );
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="lines">@@ -107,54 +109,75 @@
</span><span class="cx">         // Reset the keys by merging with an empty array
</span><span class="cx">         $bp_uri = array_merge( array(), $bp_uri );
</span><span class="cx"> 
</span><del>-        // If a component is set to the front page, force its name into $bp_uri so that $current_component is populated
</del><ins>+        // If a component is set to the front page, force its name into $bp_uri
+        // so that $current_component is populated
</ins><span class="cx">         if ( 'page' == get_option( 'show_on_front' ) &amp;&amp; get_option( 'page_on_front' ) &amp;&amp; empty( $bp_uri ) ) {
</span><span class="cx">                 $post = get_post( get_option( 'page_on_front' ) );
</span><span class="cx">                 if ( !empty( $post ) )
</span><span class="cx">                         $bp_uri[0] = $post-&gt;post_name;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        // Keep the unfiltered URI safe
</ins><span class="cx">         $bp_unfiltered_uri = $bp_uri;
</span><span class="cx"> 
</span><del>-        // Loop through each page in the global
</del><ins>+        // Get slugs of pages into array
</ins><span class="cx">         foreach ( (array) $bp-&gt;pages as $page_key =&gt; $bp_page ) {
</span><ins>+                $key_slugs[$page_key] = trailingslashit( '/' . $bp_page-&gt;slug );
+        }
</ins><span class="cx"> 
</span><del>-                // Look for a match (check members first)
-                if ( in_array( $bp_page-&gt;name, (array) $bp_uri ) ) {
</del><ins>+        // Loop through page slugs and look for exact match to path
+        foreach ( $key_slugs as $key =&gt; $slug ) {
+                if ( $slug == $path ) {
+                        $match      = $bp-&gt;pages-&gt;{$key};
+                        $match-&gt;key = $key;
+                        $matches[]  = 1;
+                        break;
+                }
+        }
</ins><span class="cx"> 
</span><del>-                        // Match found, now match the slug to make sure.
-                        $uri_chunks = explode( '/', $bp_page-&gt;slug );
</del><ins>+        // No exact match, so look for partials
+        if ( empty( $match ) ) {
</ins><span class="cx"> 
</span><del>-                        // Loop through uri_chunks
-                        foreach ( (array) $uri_chunks as $key =&gt; $uri_chunk ) {
</del><ins>+                // Loop through each page in the $bp-&gt;pages global
+                foreach ( (array) $bp-&gt;pages as $page_key =&gt; $bp_page ) {
</ins><span class="cx"> 
</span><del>-                                // Make sure chunk is in the correct position
-                                if ( !empty( $bp_uri[$key] ) &amp;&amp; ( $bp_uri[$key] == $uri_chunk ) ) {
-                                        $matches[] = 1;
</del><ins>+                        // Look for a match (check members first)
+                        if ( in_array( $bp_page-&gt;name, (array) $bp_uri ) ) {
</ins><span class="cx"> 
</span><del>-                                // No match
-                                } else {
-                                        $matches[] = 0;
</del><ins>+                                // Match found, now match the slug to make sure.
+                                $uri_chunks = explode( '/', $bp_page-&gt;slug );
+
+                                // Loop through uri_chunks
+                                foreach ( (array) $uri_chunks as $key =&gt; $uri_chunk ) {
+
+                                        // Make sure chunk is in the correct position
+                                        if ( !empty( $bp_uri[$key] ) &amp;&amp; ( $bp_uri[$key] == $uri_chunk ) ) {
+                                                $matches[] = 1;
+
+                                        // No match
+                                        } else {
+                                                $matches[] = 0;
+                                        }
</ins><span class="cx">                                 }
</span><ins>+
+                                // Have a match
+                                if ( !in_array( 0, (array) $matches ) ) {
+                                        $match      = $bp_page;
+                                        $match-&gt;key = $page_key;
+                                        break;
+                                };
+
+                                // Unset matches
+                                unset( $matches );
</ins><span class="cx">                         }
</span><span class="cx"> 
</span><del>-                        // Have a match
-                        if ( !in_array( 0, (array) $matches ) ) {
-                                $match      = $bp_page;
-                                $match-&gt;key = $page_key;
-                                break;
-                        };
-
-                        // Unset matches
-                        unset( $matches );
</del><ins>+                        // Unset uri chunks
+                        unset( $uri_chunks );
</ins><span class="cx">                 }
</span><del>-
-                // Unset uri chunks
-                unset( $uri_chunks );
</del><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Search doesn't have an associated page, so we check for it separately
</span><del>-        if ( !empty( $bp_uri[0] ) &amp;&amp; BP_SEARCH_SLUG == $bp_uri[0] )
</del><ins>+        if ( !empty( $bp_uri[0] ) &amp;&amp; ( BP_SEARCH_SLUG == $bp_uri[0] ) )
</ins><span class="cx">                 $matches[] = 1;
</span><span class="cx"> 
</span><span class="cx">         // This is not a BuddyPress page, so just return.
</span><span class="lines">@@ -162,10 +185,11 @@
</span><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">         // Find the offset
</span><ins>+        $slug       = !empty ( $match ) ? explode( '/', $match-&gt;slug ) : '';
</ins><span class="cx">         $uri_offset = 0;
</span><del>-        $slug       = explode( '/', $match-&gt;slug );
</del><span class="cx"> 
</span><del>-        if ( !empty( $slug ) &amp;&amp; 1 != count( $slug ) ) {
</del><ins>+        // Rejig the offset
+        if ( !empty( $slug ) &amp;&amp; ( 1 &lt; count( $slug ) ) ) {
</ins><span class="cx">                 array_pop( $slug );
</span><span class="cx">                 $uri_offset = count( $slug );
</span><span class="cx">         }
</span><span class="lines">@@ -173,47 +197,47 @@
</span><span class="cx">         // Global the unfiltered offset to use in bp_core_load_template()
</span><span class="cx">         $bp_unfiltered_uri_offset = $uri_offset;
</span><span class="cx"> 
</span><del>-        // This is a members page so lets check if we have a displayed member
-        if ( isset( $match-&gt;key ) &amp;&amp; 'members' == $match-&gt;key ) {
-                if ( !empty( $bp_uri[$uri_offset + 1] ) ) {
-                        if ( defined( 'BP_ENABLE_USERNAME_COMPATIBILITY_MODE' ) )
-                                $bp-&gt;displayed_user-&gt;id = (int) bp_core_get_userid( urldecode( $bp_uri[$uri_offset + 1] ) );
-                        else
-                                $bp-&gt;displayed_user-&gt;id = (int) bp_core_get_userid_from_nicename( urldecode( $bp_uri[$uri_offset + 1] ) );
</del><ins>+        // We have an exact match
+        if ( isset( $match-&gt;key ) ) {
</ins><span class="cx"> 
</span><del>-                        $uri_offset = $uri_offset + 2;
</del><ins>+                // Set current component to matched key
+                $bp-&gt;current_component = $match-&gt;key;
</ins><span class="cx"> 
</span><del>-                        // Remove everything from the URI up to the offset and take it from there.
-                        for ( $i = 0; $i &lt; $uri_offset; $i++ )
-                                unset( $bp_uri[$i] );
</del><ins>+                // If members component, do more work to find the actual component
+                if ( 'members' == $match-&gt;key ) {
</ins><span class="cx"> 
</span><del>-                        $bp-&gt;current_component = isset( $bp_uri[$uri_offset] ) ? $bp_uri[$uri_offset] : '';
-                }
-        }
</del><ins>+                        // Viewing a specific user
+                        if ( !empty( $bp_uri[$uri_offset + 1] ) ) {
</ins><span class="cx"> 
</span><del>-        // Reset the keys by merging with an empty array
-        $bp_uri = array_merge( array(), $bp_uri );
</del><ins>+                                // Switch the displayed_user based on cmpatbility mode
+                                if ( defined( 'BP_ENABLE_USERNAME_COMPATIBILITY_MODE' ) )
+                                        $bp-&gt;displayed_user-&gt;id = (int) bp_core_get_userid( urldecode( $bp_uri[$uri_offset + 1] ) );
+                                else
+                                        $bp-&gt;displayed_user-&gt;id = (int) bp_core_get_userid_from_nicename( urldecode( $bp_uri[$uri_offset + 1] ) );
</ins><span class="cx"> 
</span><del>-        // Set the current component
-        if ( empty( $bp-&gt;current_component ) ) {
-                for ( $i = 0; $i &lt;= $uri_offset; $i++ ) {
-                        if ( !empty( $bp_uri[$i] ) ) {
-                                $bp-&gt;current_component .= $bp_uri[$i];
</del><ins>+                                // Bump the offset
+                                if ( isset( $bp_uri[$uri_offset + 2] ) ) {
+                                        $bp_uri                = array_merge( array(), array_slice( $bp_uri, $uri_offset + 2 ) );
+                                        $bp-&gt;current_component = $bp_uri[0];
</ins><span class="cx"> 
</span><del>-                                if ( $i != $uri_offset )
-                                        $bp-&gt;current_component .= '/';
</del><ins>+                                // No component, so default will be picked later
+                                } else {
+                                        $bp_uri                = array_merge( array(), array_slice( $bp_uri, $uri_offset + 2 ) );
+                                        $bp-&gt;current_component = '';
+                                }
+                                
+                                // Reset the offset
+                                $uri_offset = 0;
</ins><span class="cx">                         }
</span><span class="cx">                 }
</span><del>-        } else {
-                $i = 1;
</del><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Set the current action
</span><del>-        $bp-&gt;current_action = isset( $bp_uri[$i] ) ? $bp_uri[$i] : '';
</del><ins>+        $bp-&gt;current_action = isset( $bp_uri[$uri_offset + 1] ) ? $bp_uri[$uri_offset + 1] : '';
</ins><span class="cx"> 
</span><del>-        // Unset the current_component and action from action_variables
-        for ( $j = 0; $j &lt;= $i; $j++ )
-                unset( $bp_uri[$j] );
</del><ins>+        // Slice the rest of the $bp_uri array and reset offset
+        $bp_uri      = array_slice( $bp_uri, $uri_offset + 2 );
+        $uri_offset  = 0;
</ins><span class="cx"> 
</span><span class="cx">         // Set the entire URI as the action variables, we will unset the current_component and action in a second
</span><span class="cx">         $bp-&gt;action_variables = $bp_uri;
</span></span></pre>
</div>
</div>

</body>
</html>