Merge "Revert "objectcache: fix race conditions in RedisBagOStuff::incr()""
[lhc/web/wiklou.git] / includes / PathRouter.php
index f24e298..2882e66 100644 (file)
@@ -53,8 +53,8 @@
  *   - In a pattern $1, $2, etc... will be replaced with the relevant contents
  *   - If you used a keyed array as a path pattern, $key will be replaced with
  *     the relevant contents
- *   - The default behavior is equivalent to `array( 'title' => '$1' )`,
- *     if you don't want the title parameter you can explicitly use `array( 'title' => false )`
+ *   - The default behavior is equivalent to `[ 'title' => '$1' ]`,
+ *     if you don't want the title parameter you can explicitly use `[ 'title' => false ]`
  *   - You can specify a value that won't have replacements in it
  *     using `'foo' => [ 'value' => 'bar' ];`
  *
@@ -80,7 +80,7 @@ class PathRouter {
        /**
         * Protected helper to do the actual bulk work of adding a single pattern.
         * This is in a separate method so that add() can handle the difference between
-        * a single string $path and an array() $path that contains multiple path
+        * a single string $path and an array $path that contains multiple path
         * patterns each with an associated $key to pass on.
         * @param string $path
         * @param array $params
@@ -133,10 +133,8 @@ class PathRouter {
                // Loop over our options and convert any single value $# restrictions
                // into an array so we only have to do in_array tests.
                foreach ( $options as $optionName => $optionData ) {
-                       if ( preg_match( '/^\$\d+$/u', $optionName ) ) {
-                               if ( !is_array( $optionData ) ) {
-                                       $options[$optionName] = [ $optionData ];
-                               }
+                       if ( preg_match( '/^\$\d+$/u', $optionName ) && !is_array( $optionData ) ) {
+                               $options[$optionName] = [ $optionData ];
                        }
                }
 
@@ -240,6 +238,28 @@ class PathRouter {
                // matches are tested first
                $this->sortByWeight();
 
+               $matches = $this->internalParse( $path );
+               if ( is_null( $matches ) ) {
+                       // Try with the normalized path (T100782)
+                       $path = wfRemoveDotSegments( $path );
+                       $path = preg_replace( '#/+#', '/', $path );
+                       $matches = $this->internalParse( $path );
+               }
+
+               // We know the difference between null (no matches) and
+               // [] (a match with no data) but our WebRequest caller
+               // expects [] even when we have no matches so return
+               // a [] when we have null
+               return $matches ?? [];
+       }
+
+       /**
+        * Match a path against each defined pattern
+        *
+        * @param string $path
+        * @return array|null
+        */
+       protected function internalParse( $path ) {
                $matches = null;
 
                foreach ( $this->patterns as $pattern ) {
@@ -248,12 +268,7 @@ class PathRouter {
                                break;
                        }
                }
-
-               // We know the difference between null (no matches) and
-               // array() (a match with no data) but our WebRequest caller
-               // expects array() even when we have no matches so return
-               // a array() when we have null
-               return is_null( $matches ) ? [] : $matches;
+               return $matches;
        }
 
        /**