Index: StringFunctions.body.php
===================================================================
--- StringFunctions.body.php (revision 0)
+++ StringFunctions.body.php (revision 0)
@@ -0,0 +1,297 @@
+mUniqPrefix, '/' );
+
+ if ( defined('Parser::MARKER_SUFFIX') )
+ $suffix = preg_quote( Parser::MARKER_SUFFIX, '/' );
+ elseif ( isset($parser->mMarkerSuffix) )
+ $suffix = preg_quote( $parser->mMarkerSuffix, '/' );
+ elseif ( defined('MW_PARSER_VERSION') && strcmp( MW_PARSER_VERSION, '1.6.1' ) > 0 )
+ $suffix = "QINU\x07";
+ else $suffix = 'QINU';
+
+ self::$markerRegex = '/' .$prefix. '(?:(?!' .$suffix. ').)*' . $suffix . '/us';
+
+ wfProfileOut( __METHOD__ );
+ return true;
+ }
+
+ // Removes unique markers from passed parameters.
+ private function killMarkers ( $text ) {
+ if( self::$markerRegex ) {
+ return preg_replace( self::$markerRegex , '' , $text );
+ } else {
+ return $text;
+ }
+ }
+
+ // Verifies parameter is less than max string length.
+ private function checkLength( $text ) {
+ global $wgStringFunctionsLimit;
+ return ( mb_strlen( $text ) < $wgStringFunctionsLimit );
+ }
+
+ // Generates error message. Called when string is too long.
+ private function tooLongError() {
+ global $wgStringFunctionsLimit;
+ return wfMsg( 'stringfunctions-toolong', $wgStringFunctionsLimit );
+ }
+
+ /**
+ * {{#len:string}}
+ */
+ function runLen ( &$parser, $inStr = '' ) {
+ wfProfileIn( __METHOD__ );
+
+ $inStr = $this->killMarkers( (string)$inStr );
+ $len = mb_strlen( $inStr );
+
+ wfProfileOut( __METHOD__ );
+ return $len;
+ }
+
+ /**
+ * {{#pos:value|key|offset}}
+ * Note: If the needle is an empty string, single space is used instead.
+ * Note: If the needle is not found, -1 is returned.
+ */
+ function runPos ( &$parser, $inStr = '', $inNeedle = '', $inOffset = 0 ) {
+ wfProfileIn( __METHOD__ );
+
+ $inStr = $this->killMarkers( (string)$inStr );
+ $inNeedle = $this->killMarkers( (string)$inNeedle );
+
+ if( !$this->checkLength( $inStr ) ||
+ !$this->checkLength( $inNeedle ) ) {
+ wfProfileOut( __METHOD__ );
+ return $this->tooLongError();
+ }
+
+ if( $inNeedle == '' ) { $inNeedle = ' '; }
+
+ $pos = mb_strpos( $inStr, $inNeedle, $inOffset );
+ if( $pos === false ) { $pos = -1; }
+
+ wfProfileOut( __METHOD__ );
+ return $pos;
+ }
+
+ /**
+ * {{#rpos:value|key}}
+ * Note: If the needle is an empty string, single space is used instead.
+ * Note: If the needle is not found, -1 is returned.
+ */
+ function runRPos ( &$parser, $inStr = '', $inNeedle = '' ) {
+ wfProfileIn( __METHOD__ );
+
+ $inStr = $this->killMarkers( (string)$inStr );
+ $inNeedle = $this->killMarkers( (string)$inNeedle );
+
+ if( !$this->checkLength( $inStr ) ||
+ !$this->checkLength( $inNeedle ) ) {
+ wfProfileOut( __METHOD__ );
+ return $this->tooLongError();
+ }
+
+ if( $inNeedle == '' ) { $inNeedle = ' '; }
+
+ $pos = mb_strrpos( $inStr, $inNeedle );
+ if( $pos === false ) { $pos = -1; }
+
+ wfProfileOut( __METHOD__ );
+ return $pos;
+ }
+
+ /**
+ * {{#sub:value|start|length}}
+ * Note: If length is zero, the rest of the input is returned.
+ */
+ function runSub ( &$parser, $inStr = '', $inStart = 0, $inLength = 0 ) {
+ wfProfileIn( __METHOD__ );
+
+ $inStr = $this->killMarkers( (string)$inStr );
+
+ if( !$this->checkLength( $inStr ) ) {
+ wfProfileOut( __METHOD__ );
+ return $this->tooLongError();
+ }
+
+ if ( intval($inLength) == 0 ) {
+ $result = mb_substr( $inStr, $inStart );
+ } else {
+ $result = mb_substr( $inStr, $inStart, $inLength );
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $result;
+ }
+
+ /**
+ * {{#replace:value|from|to}}
+ * Note: If "from" is an empty string, single space is used instead.
+ */
+ function runReplace( &$parser, $inStr = '', $inReplaceFrom = '', $inReplaceTo = '' ) {
+ global $wgStringFunctionsLimit;
+ wfProfileIn( __METHOD__ );
+
+ $inStr = $this->killMarkers( (string)$inStr );
+ $inReplaceFrom = $this->killMarkers( (string)$inReplaceFrom );
+ $inReplaceTo = $this->killMarkers( (string)$inReplaceTo );
+
+ if( !$this->checkLength( $inStr ) ||
+ !$this->checkLength( $inReplaceFrom ) ||
+ !$this->checkLength( $inReplaceTo ) ) {
+ wfProfileOut( __METHOD__ );
+ return $this->tooLongError();
+ }
+
+ if( $inReplaceFrom == '' ) { $inReplaceFrom = ' '; }
+
+ // Precompute limit to avoid generating enormous string:
+ $diff = mb_strlen( $inReplaceTo ) - mb_strlen( $inReplaceFrom );
+ if( $diff > 0 ) {
+ $limit = ( ( $wgStringFunctionsLimit - mb_strlen( $inStr ) ) / $diff ) + 1;
+ } else {
+ $limit = -1;
+ }
+
+ $inReplaceFrom = preg_quote( $inReplaceFrom, '/' );
+ $inReplaceTo = preg_quote( $inReplaceTo, '/' );
+
+ $result = preg_replace( '/' . $inReplaceFrom . '/u', $inReplaceTo, $inStr, $limit);
+
+ if( !$this->checkLength( $result ) ) {
+ wfProfileOut( __METHOD__ );
+ return $this->tooLongError();
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $result;
+ }
+
+
+ /**
+ * {{#explode:value|delimiter|position}}
+ * Note: Negative position can be used to specify tokens from the end.
+ * Note: If the divider is an empty string, single space is used instead.
+ * Note: Empty string is returned, if there is not enough exploded chunks.
+ */
+ function runExplode ( &$parser, $inStr = '', $inDiv = '', $inPos = 0 ) {
+ wfProfileIn( __METHOD__ );
+
+ $inStr = $this->killMarkers( (string)$inStr );
+ $inDiv = $this->killMarkers( (string)$inDiv );
+
+ if( $inDiv == '' ) { $inDiv = ' '; }
+
+ $inStr = preg_quote( $inStr, '/' );
+ $inDiv = preg_quote( $inDiv, '/' );
+
+ if( !$this->checkLength( $inStr ) ||
+ !$this->checkLength( $inDiv ) ) {
+ wfProfileOut( __METHOD__ );
+ return $this->tooLongError();
+ }
+
+ $matches = preg_split( '/'.$inDiv.'/u', $inStr );
+
+ if( $inPos >= 0 && isset( $matches[$inPos] ) ) {
+ $result = $matches[$inPos];
+ } elseif ( $inPos < 0 && isset( $matches[count($matches) + $inPos] ) ) {
+ $result = $matches[count($matches) + $inPos];
+ } else {
+ $result = '';
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $result;
+ }
+}
+
+
+/*
+ The following section reimplements the necessary multi-byte
+ string functions if they are not present. This removes multi-byte
+ support as a requirement for this extension; however, these
+ substitutes are very inefficient. True multi-byte support is
+ recommended.
+
+ In addition, please note that the only parameters implemented below
+ are the ones necessary for this extension.
+*/
+
+if( !function_exists( 'mb_strlen' ) ) {
+
+ function mb_strlen( $text ) {
+ if( $text == '' ) { return 0; }
+
+ $ar = array();
+ preg_match_all('/./us', $text, $ar );
+ return count($ar[0]);
+ }
+
+}
+
+if( !function_exists( 'mb_strpos' ) ) {
+
+ function mb_strpos( $haystack, $needle, $offset = 0 ) {
+ $needle = preg_quote( $needle, '/' );
+
+ $ar = array();
+ preg_match( '/'.$needle.'/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
+
+ if( isset( $ar[0][1] ) ) {
+ return $ar[0][1];
+ } else {
+ return false;
+ }
+ }
+
+}
+
+if( !function_exists( 'mb_strrpos' ) ) {
+
+ function mb_strrpos( $haystack, $needle, $offset = 0 ) {
+ $needle = preg_quote( $needle, '/' );
+
+ $ar = array();
+ preg_match_all( '/'.$needle.'/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
+
+ if( isset( $ar[0] ) && count( $ar[0] ) > 0 &&
+ isset( $ar[0][count($ar[0])-1][1] ) ) {
+ return $ar[0][count($ar[0])-1][1];
+ } else {
+ return false;
+ }
+ }
+}
+
+if( !function_exists( 'mb_substr' ) ) {
+
+ function mb_substr( $text, $start, $length = 0 ) {
+ if( $text == '' ) { return ''; }
+
+ $ar = array();
+ preg_match_all('/./us', $text, $ar );
+
+ $res = '';
+
+ if( $length == 0 ) { $length = count($ar[0]); }
+
+ while( $length > 0 && isset( $ar[0][$start] ) ) {
+ $res .= $ar[0][$start];
+ $start++;
+ $length--;
+ }
+
+ return $res;
+ }
+}
Property changes on: StringFunctions.body.php
___________________________________________________________________
Added: svn:eol-style
+ native
Index: StringFunctions.i18n.php
===================================================================
--- StringFunctions.i18n.php (revision 49027)
+++ StringFunctions.i18n.php (working copy)
@@ -14,6 +14,7 @@
*/
$messages['en'] = array(
'stringfunctions-desc' => 'Enhances the parser with string functions',
+ 'stringfunctions-toolong' => 'String is exceeds $1 character limit.',
);
/** Message documentation (Message documentation)
Index: StringFunctions.php
===================================================================
--- StringFunctions.php (revision 49027)
+++ StringFunctions.php (working copy)
@@ -1,75 +1,82 @@
, ,