diff options
author | Brian Evans <grknight@gentoo.org> | 2020-10-02 15:24:06 -0400 |
---|---|---|
committer | Brian Evans <grknight@gentoo.org> | 2020-10-02 15:24:06 -0400 |
commit | 60dd5fd95847643eab04ce173f0774c9c584e795 (patch) | |
tree | 52299ac4e3c5c69df75997bfd7d62b71ef9e0089 /MLEB/Translate/stringmangler/StringMatcher.php | |
parent | Update Widgets to 1.35 (diff) | |
download | extensions-60dd5fd95847643eab04ce173f0774c9c584e795.tar.gz extensions-60dd5fd95847643eab04ce173f0774c9c584e795.tar.bz2 extensions-60dd5fd95847643eab04ce173f0774c9c584e795.zip |
Update MLEB to 2020.07
Signed-off-by: Brian Evans <grknight@gentoo.org>
Diffstat (limited to 'MLEB/Translate/stringmangler/StringMatcher.php')
-rw-r--r-- | MLEB/Translate/stringmangler/StringMatcher.php | 229 |
1 files changed, 91 insertions, 138 deletions
diff --git a/MLEB/Translate/stringmangler/StringMatcher.php b/MLEB/Translate/stringmangler/StringMatcher.php index e238062d..5a8a68ef 100644 --- a/MLEB/Translate/stringmangler/StringMatcher.php +++ b/MLEB/Translate/stringmangler/StringMatcher.php @@ -1,6 +1,5 @@ <?php /** - * Default StringMangler implementation. * @file * @author Niklas Laxström * @license GPL-2.0-or-later @@ -22,51 +21,23 @@ class StringMatcher implements StringMangler, MetaYamlSchemaExtender { protected $aRegex = []; /** - * Alias for making NO-OP string mangler. - * - * @return self - */ - public static function EmptyMatcher() { - return new self(); - } - - /** - * Constructor, see EmptyMatcher(); - * * @param string $prefix * @param array $patterns */ - public function __construct( $prefix = '', array $patterns = [] ) { + public function __construct( string $prefix = '', array $patterns = [] ) { $this->sPrefix = $prefix; $this->init( $patterns ); } - protected static function getValidKeyChars() { - static $valid = null; - if ( $valid === null ) { - global $wgLegalTitleChars; - $valid = strtr( $wgLegalTitleChars, [ - '=' => '', // equals sign, which is itself usef for escaping - '&' => '', // ampersand, for entities - '%' => '', // percent sign, which is used in URL encoding - ] ); - } - - return $valid; - } - - public function setConf( $conf ) { - $this->sPrefix = $conf['prefix']; - $this->init( $conf['patterns'] ); - } - /** * Preprocesses the patterns. + * * They are split into exact keys, prefix matches and pattern matches to * speed up matching process. + * * @param string[] $strings Key patterns. */ - protected function init( array $strings ) { + protected function init( array $strings ): void { foreach ( $strings as $string ) { $pos = strpos( $string, '*' ); if ( $pos === false ) { @@ -81,23 +52,43 @@ class StringMatcher implements StringMangler, MetaYamlSchemaExtender { } } - /** - * @param string $string - * @return bool - */ - public function match( $string ) { - if ( in_array( $string, $this->aExact ) ) { + protected static function getValidKeyChars(): string { + static $valid = null; + if ( $valid === null ) { + global $wgLegalTitleChars; + $valid = strtr( + $wgLegalTitleChars, + [ + '=' => '', // equals sign, which is itself usef for escaping + '&' => '', // ampersand, for entities + '%' => '', // percent sign, which is used in URL encoding + ] + ); + } + + return $valid; + } + + /** @inheritDoc */ + public function setConf( array $conf ): void { + $this->sPrefix = $conf['prefix']; + $this->init( $conf['patterns'] ); + } + + /** @inheritDoc */ + public function match( string $key ): bool { + if ( in_array( $key, $this->aExact ) ) { return true; } foreach ( $this->aPrefix as $prefix => $len ) { - if ( strncmp( $string, $prefix, $len ) === 0 ) { + if ( strncmp( $key, $prefix, $len ) === 0 ) { return true; } } foreach ( $this->aRegex as $regex ) { - if ( preg_match( $regex, $string ) ) { + if ( preg_match( $regex, $key ) ) { return true; } } @@ -105,57 +96,15 @@ class StringMatcher implements StringMangler, MetaYamlSchemaExtender { return false; } - /** - * Mangles the input. Input can either be a plain string, a list of strings - * or an associative array. In the last case the keys of the array are - * mangled. - * - * @param string|string[]|array $data - * @return string|string[]|array - * @throws MWException - */ - public function mangle( $data ) { - if ( is_array( $data ) ) { - return $this->mangleArray( $data ); - } elseif ( is_string( $data ) ) { - return $this->mangleString( $data ); - } elseif ( $data === null ) { - return $data; - } else { - throw new MWException( __METHOD__ . ': Unsupported datatype' ); - } - } - - public function unmangle( $data ) { - if ( is_array( $data ) ) { - return $this->mangleArray( $data, true ); - } elseif ( is_string( $data ) ) { - return $this->mangleString( $data, true ); - } elseif ( $data === null ) { - return $data; - } else { - throw new MWException( __METHOD__ . ': Unsupported datatype' ); - } - } - - /** - * Mangles or unmangles single string. - * @param string $string Message key. - * @param bool $reverse Direction of mangling or unmangling. - * @return string - */ - protected function mangleString( $string, $reverse = false ) { - if ( $reverse ) { - return $this->unMangleString( $string ); - } - - if ( $this->match( $string ) ) { - $string = $this->sPrefix . $string; + /** @inheritDoc */ + public function mangle( string $key ): string { + if ( $this->match( $key ) ) { + $key = $this->sPrefix . $key; } $escaper = function ( $match ) { $esc = ''; - foreach ( str_split( $match[ 0 ] ) as $c ) { + foreach ( str_split( $match[0] ) as $c ) { $esc .= '=' . sprintf( '%02X', ord( $c ) ); } return $esc; @@ -163,74 +112,78 @@ class StringMatcher implements StringMangler, MetaYamlSchemaExtender { // Apply a "quoted-printable"-like escaping $valid = self::getValidKeyChars(); - $string = preg_replace_callback( "/[^$valid]/", $escaper, $string ); + $key = preg_replace_callback( "/[^$valid]/", $escaper, $key ); // Additional limitations in MediaWiki, see MediaWikiTitleCodec::splitTitleString - $string = preg_replace_callback( '/(~~~|^[ _]|[ _]$|[ _]{2,}|^:)/', $escaper, $string ); + $key = preg_replace_callback( '/(~~~|^[ _]|[ _]$|[ _]{2,}|^:)/', $escaper, $key ); // TODO: length check + truncation // TODO: forbid path travels - return $string; + return $key; } - /** - * Unmangles the message key by removing the prefix it it exists. - * @param string $string Message key. - * @return string Unmangled message key. - */ - protected function unMangleString( $string ) { + /** @inheritDoc */ + public function mangleList( array $list ): array { + foreach ( $list as $index => $key ) { + $list[$index] = $this->mangle( $key ); + } + + return $list; + } + + /** @inheritDoc */ + public function mangleArray( array $array ): array { + $out = []; + foreach ( $array as $key => $value ) { + $out[$this->mangle( $key )] = $value; + } + + return $out; + } + + /** @inheritDoc */ + public function unmangle( string $key ): string { // Unescape the "quoted-printable"-like escaping, - // which is applied in mangleString. - $unescapedString = preg_replace_callback( '/=([A-F0-9]{2})/', + // which is applied in mangle + $unescapedString = preg_replace_callback( + '/=([A-F0-9]{2})/', function ( $match ) { - return chr( hexdec( $match[0] ) ); + return chr( hexdec( $match[1] ) ); }, - $string + $key ); if ( strncmp( $unescapedString, $this->sPrefix, strlen( $this->sPrefix ) ) === 0 ) { - return substr( $unescapedString, strlen( $this->sPrefix ) ); - } else { - return $unescapedString; + $unmangled = substr( $unescapedString, strlen( $this->sPrefix ) ); + + // Check if this string should be mangled / un-mangled to begin with + if ( $this->match( $unmangled ) ) { + return $unmangled; + } } + return $unescapedString; } - /** - * Mangles or unmangles list of strings. If an associative array is given, - * the keys of the array will be mangled. For lists the values are mangled. - * - * @param string[]|array $array Strings. - * @param bool $reverse Direction of mangling or unmangling. - * @return string[]|array (Un)mangled strings. - */ - protected function mangleArray( array $array, $reverse = false ) { - $temp = []; - - if ( !$this->isAssoc( $array ) ) { - foreach ( $array as $key => &$value ) { - $value = $this->mangleString( $value, $reverse ); - $temp[$key] = $value; // Assign a reference - } - } else { - foreach ( $array as $key => &$value ) { - $key = $this->mangleString( $key, $reverse ); - $temp[$key] = $value; // Assign a reference - } + /** @inheritDoc */ + public function unmangleList( array $list ): array { + foreach ( $list as $index => $key ) { + $list[$index] = $this->unmangle( $key ); } - return $temp; + return $list; } - protected function isAssoc( array $array ) { - $assoc = (bool)count( array_filter( array_keys( $array ), 'is_string' ) ); - if ( $assoc ) { - return true; + /** @inheritDoc */ + public function unmangleArray( array $array ): array { + $out = []; + foreach ( $array as $key => $value ) { + $out[$this->unmangle( $key )] = $value; } - // Also check that the indexing starts from zero - return !array_key_exists( 0, $array ); + return $out; } - public static function getExtraSchema() { + /** @inheritDoc */ + public static function getExtraSchema(): array { $schema = [ 'root' => [ '_type' => 'array', @@ -240,7 +193,7 @@ class StringMatcher implements StringMangler, MetaYamlSchemaExtender { '_children' => [ 'prefix' => [ '_type' => 'text', - '_not_empty' => true + '_not_empty' => true, ], 'patterns' => [ '_type' => 'array', @@ -248,10 +201,10 @@ class StringMatcher implements StringMangler, MetaYamlSchemaExtender { '_ignore_extra_keys' => true, '_children' => [], ], - ] - ] - ] - ] + ], + ], + ], + ], ]; return $schema; |