From: Tim Starling Date: Wed, 16 Feb 2011 07:24:36 +0000 (+0000) Subject: * Fix for r81960: List the local magic word synonyms first, so that they will be... X-Git-Tag: 1.31.0-rc.0~31978 X-Git-Url: http://git.cyclocoop.org/%28?a=commitdiff_plain;h=3bc410efa7f58b0cf148ba4440260e04e31d0086;p=lhc%2Fweb%2Fwiklou.git * Fix for r81960: List the local magic word synonyms first, so that they will be returned by $magic->getSynonym( 0 ). Apply array_values() to fix up the keys, potentially corrupted by array_unique(). * In MagicWord::initRegex(), put the longest synonyms first in the alternation. This means that when one synonym is an initial substring of another, the longest one will match in precedence, which is generally in line with user expectations. --- diff --git a/includes/LocalisationCache.php b/includes/LocalisationCache.php index af2ed65ce5..888722ad23 100644 --- a/includes/LocalisationCache.php +++ b/includes/LocalisationCache.php @@ -448,7 +448,8 @@ class LocalisationCache { } else { $oldSynonyms = array_slice( $fallbackInfo, 1 ); $newSynonyms = array_slice( $value[$magicName], 1 ); - $synonyms = array_unique( array_merge( $oldSynonyms, $newSynonyms ) ); + $synonyms = array_values( array_unique( array_merge( + $newSynonyms, $oldSynonyms ) ) ); $value[$magicName] = array_merge( array( $fallbackInfo[0] ), $synonyms ); } } diff --git a/includes/MagicWord.php b/includes/MagicWord.php index 9988232f5c..a0c14c265c 100644 --- a/includes/MagicWord.php +++ b/includes/MagicWord.php @@ -273,13 +273,13 @@ class MagicWord { * @private */ function initRegex() { - #$variableClass = Title::legalChars(); - # This was used for matching "$1" variables, but different uses of the feature will have - # different restrictions, which should be checked *after* the MagicWord has been matched, - # not here. - IMSoP + // Sort the synonyms by length, descending, so that the longest synonym + // matches in precedence to the shortest + $synonyms = $this->mSynonyms; + usort( $synonyms, array( $this, 'compareStringLength' ) ); $escSyn = array(); - foreach ( $this->mSynonyms as $synonym ) + foreach ( $synonyms as $synonym ) // In case a magic word contains /, like that's going to happen;) $escSyn[] = preg_quote( $synonym, '/' ); $this->mBaseRegex = implode( '|', $escSyn ); @@ -292,6 +292,23 @@ class MagicWord { "/^(?:{$this->mBaseRegex})$/{$case}" ); } + /** + * A comparison function that returns -1, 0 or 1 depending on whether the + * first string is longer, the same length or shorter than the second + * string. + */ + function compareStringLength( $s1, $s2 ) { + $l1 = strlen( $s1 ); + $l2 = strlen( $s2 ); + if ( $l1 < $l2 ) { + return 1; + } elseif ( $l1 > $l2 ) { + return -1; + } else { + return 0; + } + } + /** * Gets a regex representing matching the word */