X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;ds=sidebyside;f=includes%2FPathRouter.php;h=faf4db4f623744aae48cccd77c595dadc927f4a5;hb=1d9fd23ab3583788fb2e3ae8e641cf83b09ef8df;hp=cc6fc4a399a6e4cf4c840117da7f9f613738a1e5;hpb=e61f2aee418b2a2895c114e380c4738b29f682c7;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/PathRouter.php b/includes/PathRouter.php index cc6fc4a399..faf4db4f62 100644 --- a/includes/PathRouter.php +++ b/includes/PathRouter.php @@ -240,6 +240,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 + // 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; + } + + /** + * 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,17 +270,12 @@ 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; } /** * @param string $path - * @param string $pattern + * @param object $pattern * @return array|null */ protected static function extractTitle( $path, $pattern ) { @@ -319,13 +336,8 @@ class PathRouter { $value = $paramData['value']; } elseif ( isset( $paramData['pattern'] ) ) { // For patterns we have to make value replacements on the string - $value = $paramData['pattern']; - $replacer = new PathRouterPatternReplacer; - $replacer->params = $m; - if ( isset( $pattern->key ) ) { - $replacer->key = $pattern->key; - } - $value = $replacer->replace( $value ); + $value = self::expandParamValue( $m, $pattern->key ?? null, + $paramData['pattern'] ); if ( $value === false ) { // Pattern required data that wasn't available, abort return null; @@ -352,48 +364,43 @@ class PathRouter { return $matches; } -} - -class PathRouterPatternReplacer { - - public $key, $params, $error; - /** - * Replace keys inside path router patterns with text. - * We do this inside of a replacement callback because after replacement we can't tell the - * difference between a $1 that was not replaced and a $1 that was part of - * the content a $1 was replaced with. - * @param string $value + * Replace $key etc. in param values with the matched strings from the path. + * + * @param array $pathMatches The match results from the path + * @param string|null $key The key of the matching pattern + * @param string $value The param value to be expanded * @return string|false */ - public function replace( $value ) { - $this->error = false; - $value = preg_replace_callback( '/\$(\d+|key)/u', [ $this, 'callback' ], $value ); - if ( $this->error ) { - return false; - } - return $value; - } + protected static function expandParamValue( $pathMatches, $key, $value ) { + $error = false; - /** - * @param array $m - * @return string - */ - protected function callback( $m ) { - if ( $m[1] == "key" ) { - if ( is_null( $this->key ) ) { - $this->error = true; - return ''; - } - return $this->key; - } else { - $d = $m[1]; - if ( !isset( $this->params["par$d"] ) ) { - $this->error = true; - return ''; + $replacer = function ( $m ) use ( $pathMatches, $key, &$error ) { + if ( $m[1] == "key" ) { + if ( is_null( $key ) ) { + $error = true; + + return ''; + } + + return $key; + } else { + $d = $m[1]; + if ( !isset( $pathMatches["par$d"] ) ) { + $error = true; + + return ''; + } + + return rawurldecode( $pathMatches["par$d"] ); } - return rawurldecode( $this->params["par$d"] ); + }; + + $value = preg_replace_callback( '/\$(\d+|key)/u', $replacer, $value ); + if ( $error ) { + return false; } - } + return $value; + } }