MediaWiki
REL1_19
|
00001 <?php 00002 00007 class StripState { 00008 protected $prefix; 00009 protected $data; 00010 protected $regex; 00011 00012 protected $tempType, $tempMergePrefix; 00013 00017 function __construct( $prefix ) { 00018 $this->prefix = $prefix; 00019 $this->data = array( 00020 'nowiki' => array(), 00021 'general' => array() 00022 ); 00023 $this->regex = "/{$this->prefix}([^\x7f]+)" . Parser::MARKER_SUFFIX . '/'; 00024 } 00025 00031 function addNoWiki( $marker, $value ) { 00032 $this->addItem( 'nowiki', $marker, $value ); 00033 } 00034 00039 function addGeneral( $marker, $value ) { 00040 $this->addItem( 'general', $marker, $value ); 00041 } 00042 00049 protected function addItem( $type, $marker, $value ) { 00050 if ( !preg_match( $this->regex, $marker, $m ) ) { 00051 throw new MWException( "Invalid marker: $marker" ); 00052 } 00053 00054 $this->data[$type][$m[1]] = $value; 00055 } 00056 00061 function unstripGeneral( $text ) { 00062 return $this->unstripType( 'general', $text ); 00063 } 00064 00069 function unstripNoWiki( $text ) { 00070 return $this->unstripType( 'nowiki', $text ); 00071 } 00072 00077 function unstripBoth( $text ) { 00078 $text = $this->unstripType( 'general', $text ); 00079 $text = $this->unstripType( 'nowiki', $text ); 00080 return $text; 00081 } 00082 00088 protected function unstripType( $type, $text ) { 00089 // Shortcut 00090 if ( !count( $this->data[$type] ) ) { 00091 return $text; 00092 } 00093 00094 wfProfileIn( __METHOD__ ); 00095 $this->tempType = $type; 00096 do { 00097 $oldText = $text; 00098 $text = preg_replace_callback( $this->regex, array( $this, 'unstripCallback' ), $text ); 00099 } while ( $text !== $oldText ); 00100 $this->tempType = null; 00101 wfProfileOut( __METHOD__ ); 00102 return $text; 00103 } 00104 00109 protected function unstripCallback( $m ) { 00110 if ( isset( $this->data[$this->tempType][$m[1]] ) ) { 00111 return $this->data[$this->tempType][$m[1]]; 00112 } else { 00113 return $m[0]; 00114 } 00115 } 00116 00125 function getSubState( $text ) { 00126 $subState = new StripState( $this->prefix ); 00127 $pos = 0; 00128 while ( true ) { 00129 $startPos = strpos( $text, $this->prefix, $pos ); 00130 $endPos = strpos( $text, Parser::MARKER_SUFFIX, $pos ); 00131 if ( $startPos === false || $endPos === false ) { 00132 break; 00133 } 00134 00135 $endPos += strlen( Parser::MARKER_SUFFIX ); 00136 $marker = substr( $text, $startPos, $endPos - $startPos ); 00137 if ( !preg_match( $this->regex, $marker, $m ) ) { 00138 continue; 00139 } 00140 00141 $key = $m[1]; 00142 if ( isset( $this->data['nowiki'][$key] ) ) { 00143 $subState->data['nowiki'][$key] = $this->data['nowiki'][$key]; 00144 } elseif ( isset( $this->data['general'][$key] ) ) { 00145 $subState->data['general'][$key] = $this->data['general'][$key]; 00146 } 00147 $pos = $endPos; 00148 } 00149 return $subState; 00150 } 00151 00161 function merge( $otherState, $texts ) { 00162 $mergePrefix = Parser::getRandomString(); 00163 00164 foreach ( $otherState->data as $type => $items ) { 00165 foreach ( $items as $key => $value ) { 00166 $this->data[$type]["$mergePrefix-$key"] = $value; 00167 } 00168 } 00169 00170 $this->tempMergePrefix = $mergePrefix; 00171 $texts = preg_replace_callback( $otherState->regex, array( $this, 'mergeCallback' ), $texts ); 00172 $this->tempMergePrefix = null; 00173 return $texts; 00174 } 00175 00180 protected function mergeCallback( $m ) { 00181 $key = $m[1]; 00182 return "{$this->prefix}{$this->tempMergePrefix}-$key" . Parser::MARKER_SUFFIX; 00183 } 00184 00191 function killMarkers( $text ) { 00192 return preg_replace( $this->regex, '', $text ); 00193 } 00194 } 00195