StringMatcher.php

Go to the documentation of this file.
00001 <?php
00016 interface StringMangler {
00018     public static function EmptyMatcher();
00019 
00024     public function setConf( $configuration );
00025 
00032     public function match( $string );
00033 
00039     public function mangle( $data );
00040 
00046     public function unMangle( $data );
00047 }
00048 
00054 class StringMatcher implements StringMangler {
00056     protected $sPrefix = '';
00058     protected $aExact = array();
00060     protected $aPrefix = array();
00062     protected $aRegex = array();
00063 
00068     public static function EmptyMatcher() {
00069         return new StringMatcher;
00070     }
00071 
00075     public function __construct( $prefix = '', $patterns = array() ) {
00076         $this->sPrefix = $prefix;
00077         $this->init( $patterns );
00078     }
00079 
00080     protected static function getValidKeyChars() {
00081         static $valid = null;
00082         if ( $valid === null ) {
00083             global $wgLegalTitleChars;
00084             $valid = strtr( $wgLegalTitleChars, array(
00085                 '=' => '', // equals sign, which is itself usef for escaping
00086                 '&' => '', // ampersand, for entities
00087                 '%' => '', // percent sign, which is used in URL encoding
00088             ) );
00089         }
00090 
00091         return $valid;
00092     }
00093 
00094     public function setConf( $conf ) {
00095         $this->sPrefix = $conf['prefix'];
00096         $this->init( $conf['patterns'] );
00097     }
00098 
00105     protected function init( array $strings ) {
00106         foreach ( $strings as $string ) {
00107             $pos = strpos( $string, '*' );
00108             if ( $pos === false ) {
00109                 $this->aExact[] = $string;
00110             } elseif ( $pos + 1 === strlen( $string ) ) {
00111                 $prefix = substr( $string, 0, -1 );
00112                 $this->aPrefix[$prefix] = strlen( $prefix );
00113             } else {
00114                 $string = str_replace( '\\*', '.+', preg_quote( $string ) );
00115                 $this->aRegex[] = "/^$string$/";
00116             }
00117         }
00118     }
00119 
00124     public function match( $string ) {
00125         if ( in_array( $string, $this->aExact ) ) {
00126             return true;
00127         }
00128 
00129         foreach ( $this->aPrefix as $prefix => $len ) {
00130             if ( strncmp( $string, $prefix, $len ) === 0 ) {
00131                 return true;
00132             }
00133         }
00134 
00135         foreach ( $this->aRegex as $regex ) {
00136             if ( preg_match( $regex, $string ) ) {
00137                 return true;
00138             }
00139         }
00140 
00141         return false;
00142     }
00143 
00149     public function mangle( $data ) {
00150         if ( is_array( $data ) ) {
00151             return $this->mangleArray( $data );
00152         } elseif ( is_string( $data ) ) {
00153             return $this->mangleString( $data );
00154         } elseif ( $data === null ) {
00155             return $data;
00156         } else {
00157             throw new MWException( __METHOD__ . ": Unsupported datatype" );
00158         }
00159     }
00160 
00161     public function unMangle( $data ) {
00162         if ( is_array( $data ) ) {
00163             return $this->mangleArray( $data, true );
00164         } elseif ( is_string( $data ) ) {
00165             return $this->mangleString( $data, true );
00166         } elseif ( $data === null ) {
00167             return $data;
00168         } else {
00169             throw new MWException( __METHOD__ . ": Unsupported datatype" );
00170         }
00171     }
00172 
00179     protected function mangleString( $string, $reverse = false ) {
00180         if ( $reverse ) {
00181             return $this->unMangleString( $string );
00182         }
00183 
00184         if ( $this->match( $string ) ) {
00185             $string = $this->sPrefix . $string;
00186         }
00187 
00188         // Apply a "quoted-printable"-like escaping
00189         $valid = self::getValidKeyChars();
00190         $escapedString = preg_replace_callback( "/[^$valid]/",
00191             function ( $match ) {
00192                 return '=' . sprintf( '%02X', ord( $match[0] ) );
00193             },
00194             $string
00195         );
00196 
00197         return $escapedString;
00198     }
00199 
00205     protected function unMangleString( $string ) {
00206         // Unescape the "quoted-printable"-like escaping,
00207         // which is applied in mangleString.
00208         $unescapedString = preg_replace_callback( "/=([A-F0-9]{2})/",
00209             function ( $match ) {
00210                 return chr( hexdec( $match[0] ) );
00211             },
00212             $string
00213         );
00214 
00215         if ( strncmp( $unescapedString, $this->sPrefix, strlen( $this->sPrefix ) ) === 0 ) {
00216             return substr( $unescapedString, strlen( $this->sPrefix ) );
00217         } else {
00218             return $unescapedString;
00219         }
00220     }
00221 
00228     protected function mangleArray( array $array, $reverse = false ) {
00229         $temp = array();
00230 
00231         if ( isset( $array[0] ) ) {
00232             foreach ( $array as $key => &$value ) {
00233                 $value = $this->mangleString( $value, $reverse );
00234                 $temp[$key] = $value; // Assign a reference
00235             }
00236         } else {
00237             foreach ( $array as $key => &$value ) {
00238                 $key = $this->mangleString( $key, $reverse );
00239                 $temp[$key] = $value; // Assign a reference
00240             }
00241         }
00242 
00243         return $temp;
00244     }
00245 }
Generated on Tue Oct 29 00:00:26 2013 for MediaWiki Translate Extension by  doxygen 1.6.3