mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/ParserFunctions
synced 2024-11-15 11:59:54 +00:00
Revert r39618 "Per discussion for bug 6455, merged functionality of StringFunctions into the ParserFunctions extension."
o_O These look like the least CPU- and memory-efficient implementations of strlen(), strpos() etc that could possibly be created...
This commit is contained in:
parent
c17e837fa1
commit
e42686cd0a
|
@ -25,16 +25,6 @@ function efParserFunctionsWords( $lang ) {
|
|||
'timel' => array( 0, 'timel' ),
|
||||
'rel2abs' => array( 0, 'rel2abs' ),
|
||||
'titleparts' => array( 0, 'titleparts' ),
|
||||
|
||||
'len' => array( 0, 'len' ),
|
||||
'pos' => array( 0, 'pos' ),
|
||||
'rpos' => array( 0, 'rpos' ),
|
||||
'sub' => array( 0, 'sub' ),
|
||||
'pad' => array( 0, 'pad' ),
|
||||
'replace' => array( 0, 'replace' ),
|
||||
'explode' => array( 0, 'explode' ),
|
||||
'urlencode' => array( 0, 'urlencode' ),
|
||||
'urldecode' => array( 0, 'urldecode' ),
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,9 +7,9 @@ if ( !defined( 'MEDIAWIKI' ) ) {
|
|||
$wgExtensionFunctions[] = 'wfSetupParserFunctions';
|
||||
$wgExtensionCredits['parserhook'][] = array(
|
||||
'name' => 'ParserFunctions',
|
||||
'version' => '2.0',
|
||||
'version' => '1.1.1',
|
||||
'url' => 'http://meta.wikimedia.org/wiki/ParserFunctions',
|
||||
'author' => array('Tim Starling', 'Ross McClure', 'Juraj Simlovic', 'Fran Rogers'),
|
||||
'author' => 'Tim Starling',
|
||||
'description' => 'Enhance parser with logical functions',
|
||||
'descriptionmsg' => 'pfunc_desc',
|
||||
);
|
||||
|
@ -17,10 +17,6 @@ $wgExtensionCredits['parserhook'][] = array(
|
|||
$wgExtensionMessagesFiles['ParserFunctions'] = dirname(__FILE__) . '/ParserFunctions.i18n.php';
|
||||
$wgHooks['LanguageGetMagic'][] = 'wfParserFunctionsLanguageGetMagic';
|
||||
|
||||
$wgStringFunctionsLimitSearch = 30;
|
||||
$wgStringFunctionsLimitReplace = 30;
|
||||
$wgStringFunctionsLimitPad = 100;
|
||||
|
||||
class ExtParserFunctions {
|
||||
var $mExprParser;
|
||||
var $mTimeCache = array();
|
||||
|
@ -51,16 +47,6 @@ class ExtParserFunctions {
|
|||
$parser->setFunctionHook( 'rel2abs', array( &$this, 'rel2abs' ) );
|
||||
$parser->setFunctionHook( 'titleparts', array( &$this, 'titleparts' ) );
|
||||
|
||||
$parser->setFunctionHook( 'len', array( &$this, 'len' ) );
|
||||
$parser->setFunctionHook( 'pos', array( &$this, 'pos' ) );
|
||||
$parser->setFunctionHook( 'rpos', array( &$this, 'rpos' ) );
|
||||
$parser->setFunctionHook( 'sub', array( &$this, 'sub' ) );
|
||||
$parser->setFunctionHook( 'pad', array( &$this, 'pad' ) );
|
||||
$parser->setFunctionHook( 'replace', array( &$this, 'replace' ) );
|
||||
$parser->setFunctionHook( 'explode', array( &$this, 'explode' ) );
|
||||
$parser->setFunctionHook( 'urlencode', array( &$this, 'urlencode' ) );
|
||||
$parser->setFunctionHook( 'urldecode', array( &$this, 'urldecode' ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -490,294 +476,6 @@ class ExtParserFunctions {
|
|||
return $title;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the string into its component parts using preg_match_all().
|
||||
* $chars is set to the resulting array of multibyte characters.
|
||||
* Returns count($chars).
|
||||
*/
|
||||
function mwSplit ( &$parser, $str, &$chars ) {
|
||||
# Get marker prefix & suffix
|
||||
$prefix = preg_quote( $parser->mUniqPrefix );
|
||||
if( isset($parser->mMarkerSuffix) )
|
||||
$suffix = preg_quote( $parser->mMarkerSuffix );
|
||||
else if ( strcmp( MW_PARSER_VERSION, '1.6.1' ) > 0 )
|
||||
$suffix = 'QINU\x07';
|
||||
else $suffix = 'QINU';
|
||||
|
||||
# Treat strip markers as single multibyte characters
|
||||
$count = preg_match_all('/' . $prefix . '.*?' . $suffix . '|./su', $str, $arr);
|
||||
$chars = $arr[0];
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#len:value}}
|
||||
*/
|
||||
function len( &$parser, $inStr = '' ) {
|
||||
return $this->mwSplit ( $parser, $inStr, $chars );
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#pos:value|key|offset}}
|
||||
* Note: If the needle is an empty string, single space is used instead.
|
||||
* Note: If the needle is not found, empty string is returned.
|
||||
* Note: The needle is limited to specific length.
|
||||
*/
|
||||
function pos( &$parser, $inStr = '', $inNeedle = '', $inOffset = 0 ) {
|
||||
global $wgStringFunctionsLimitSearch;
|
||||
|
||||
if ( $inNeedle === '' ) {
|
||||
# empty needle
|
||||
$needle = array(' ');
|
||||
$nSize = 1;
|
||||
} else {
|
||||
# convert needle
|
||||
$nSize = $this->mwSplit ( $parser, $inNeedle, $needle );
|
||||
|
||||
if ( $nSize > $wgStringFunctionsLimitSearch ) {
|
||||
$nSize = $wgStringFunctionsLimitSearch;
|
||||
$needle = array_slice ( $needle, 0, $nSize );
|
||||
}
|
||||
}
|
||||
|
||||
# convert string
|
||||
$size = $this->mwSplit( $parser, $inStr, $chars ) - $nSize;
|
||||
$inOffset = max ( intval($inOffset), 0 );
|
||||
|
||||
# find needle
|
||||
for ( $i = $inOffset; $i <= $size; $i++ ) {
|
||||
if ( $chars[$i] !== $needle[0] ) continue;
|
||||
for ( $j = 1; ; $j++ ) {
|
||||
if ( $j >= $nSize ) return $i;
|
||||
if ( $chars[$i + $j] !== $needle[$j] ) break;
|
||||
}
|
||||
}
|
||||
|
||||
# return empty string upon not found
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#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.
|
||||
* Note: The needle is limited to specific length.
|
||||
*/
|
||||
function rPos( &$parser, $inStr = '', $inNeedle = '' ) {
|
||||
global $wgStringFunctionsLimitSearch;
|
||||
|
||||
if ( $inNeedle === '' ) {
|
||||
# empty needle
|
||||
$needle = array(' ');
|
||||
$nSize = 1;
|
||||
} else {
|
||||
# convert needle
|
||||
$nSize = $this->mwSplit ( $parser, $inNeedle, $needle );
|
||||
|
||||
if ( $nSize > $wgStringFunctionsLimitSearch ) {
|
||||
$nSize = $wgStringFunctionsLimitSearch;
|
||||
$needle = array_slice ( $needle, 0, $nSize );
|
||||
}
|
||||
}
|
||||
|
||||
# convert string
|
||||
$size = $this->mwSplit( $parser, $inStr, $chars ) - $nSize;
|
||||
|
||||
# find needle
|
||||
for ( $i = $size; $i >= 0; $i-- ) {
|
||||
if ( $chars[$i] !== $needle[0] ) continue;
|
||||
for ( $j = 1; ; $j++ ) {
|
||||
if ( $j >= $nSize ) return $i;
|
||||
if ( $chars[$i + $j] !== $needle[$j] ) break;
|
||||
}
|
||||
}
|
||||
|
||||
# return -1 upon not found
|
||||
return "-1";
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#sub:value|start|length}}
|
||||
* Note: If length is zero, the rest of the input is returned.
|
||||
*/
|
||||
function sub( &$parser, $inStr = '', $inStart = 0, $inLength = 0 ) {
|
||||
# convert string
|
||||
$this->mwSplit( $parser, $inStr, $chars );
|
||||
|
||||
# zero length
|
||||
if ( intval($inLength) == 0 )
|
||||
return join('', array_slice( $chars, intval($inStart) ));
|
||||
|
||||
# non-zero length
|
||||
return join('', array_slice( $chars, intval($inStart), intval($inLength) ));
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#pad:value|length|with|direction}}
|
||||
* Note: Length of the resulting string is limited.
|
||||
*/
|
||||
function pad( &$parser, $inStr = '', $inLen = 0, $inWith = '', $inDirection = '' ) {
|
||||
global $wgStringFunctionsLimitPad;
|
||||
|
||||
# direction
|
||||
switch ( strtolower ( $inDirection ) ) {
|
||||
case 'center':
|
||||
$direction = STR_PAD_BOTH;
|
||||
break;
|
||||
case 'right':
|
||||
$direction = STR_PAD_RIGHT;
|
||||
break;
|
||||
case 'left':
|
||||
default:
|
||||
$direction = STR_PAD_LEFT;
|
||||
break;
|
||||
}
|
||||
|
||||
# prevent markers in padding
|
||||
$a = explode ( $parser->mUniqPrefix, $inWith, 2 );
|
||||
if ( $a[0] === '' )
|
||||
$inWith = ' ';
|
||||
else $inWith = $a[0];
|
||||
|
||||
# limit pad length
|
||||
$inLen = intval ( $inLen );
|
||||
if ($wgStringFunctionsLimitPad > 0)
|
||||
$inLen = min ( $inLen, $wgStringFunctionsLimitPad );
|
||||
|
||||
# adjust for multibyte strings
|
||||
$inLen += strlen( $inStr ) - $this->mwSplit( $parser, $inStr, $a );
|
||||
|
||||
# pad
|
||||
return str_pad ( $inStr, $inLen, $inWith, $direction );
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#replace:value|from|to}}
|
||||
* Note: If the needle is an empty string, single space is used instead.
|
||||
* Note: The needle is limited to specific length.
|
||||
* Note: The product is limited to specific length.
|
||||
*/
|
||||
function replace( &$parser, $inStr = '', $inReplaceFrom = '', $inReplaceTo = '' ) {
|
||||
global $wgStringFunctionsLimitSearch, $wgStringFunctionsLimitReplace;
|
||||
|
||||
if ( $inReplaceFrom === '' ) {
|
||||
# empty needle
|
||||
$needle = array(' ');
|
||||
$nSize = 1;
|
||||
} else {
|
||||
# convert needle
|
||||
$nSize = $this->mwSplit ( $parser, $inReplaceFrom, $needle );
|
||||
if ( $nSize > $wgStringFunctionsLimitSearch ) {
|
||||
$nSize = $wgStringFunctionsLimitSearch;
|
||||
$needle = array_slice ( $needle, 0, $nSize );
|
||||
}
|
||||
}
|
||||
|
||||
# convert product
|
||||
$pSize = $this->mwSplit ( $parser, $inReplaceTo, $product );
|
||||
if ( $pSize > $wgStringFunctionsLimitReplace ) {
|
||||
$pSize = $wgStringFunctionsLimitReplace;
|
||||
$product = array_slice ( $product, 0, $pSize );
|
||||
}
|
||||
|
||||
# remove markers in product
|
||||
for( $i = 0; $i < $pSize; $i++ ) {
|
||||
if( strlen( $product[$i] ) > 6 ) $product[$i] = ' ';
|
||||
}
|
||||
|
||||
# convert string
|
||||
$size = $this->mwSplit ( $parser, $inStr, $chars ) - $nSize;
|
||||
|
||||
# replace
|
||||
for ( $i = 0; $i <= $size; $i++ ) {
|
||||
if ( $chars[$i] !== $needle[0] ) continue;
|
||||
for ( $j = 1; ; $j++ ) {
|
||||
if ( $j >= $nSize ) {
|
||||
array_splice ( $chars, $i, $j, $product );
|
||||
$size += ( $pSize - $nSize );
|
||||
$i += ( $pSize - 1 );
|
||||
break;
|
||||
}
|
||||
if ( $chars[$i + $j] !== $needle[$j] ) break;
|
||||
}
|
||||
}
|
||||
return join('', $chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#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: The divider is limited to specific length.
|
||||
* Note: Empty string is returned, if there is not enough exploded chunks.
|
||||
*/
|
||||
function explode( &$parser, $inStr = '', $inDiv = '', $inPos = 0 ) {
|
||||
global $wgStringFunctionsLimitSearch;
|
||||
|
||||
if ( $inDiv === '' ) {
|
||||
# empty divider
|
||||
$div = array(' ');
|
||||
$dSize = 1;
|
||||
} else {
|
||||
# convert divider
|
||||
$dSize = $this->mwSplit ( $parser, $inDiv, $div );
|
||||
if ( $dSize > $wgStringFunctionsLimitSearch ) {
|
||||
$dSize = $wgStringFunctionsLimitSearch;
|
||||
$div = array_slice ( $div, 0, $dSize );
|
||||
}
|
||||
}
|
||||
|
||||
# convert string
|
||||
$size = $this->mwSplit ( $parser, $inStr, $chars ) - $dSize;
|
||||
|
||||
# explode
|
||||
$inPos = intval ( $inPos );
|
||||
$tokens = array();
|
||||
$start = 0;
|
||||
for ( $i = 0; $i <= $size; $i++ ) {
|
||||
if ( $chars[$i] !== $div[0] ) continue;
|
||||
for ( $j = 1; ; $j++ ) {
|
||||
if ( $j >= $dSize ) {
|
||||
if ( $inPos > 0 ) $inPos--;
|
||||
else {
|
||||
$tokens[] = join('', array_slice($chars, $start, ($i - $start)));
|
||||
if ( $inPos == 0 ) return $tokens[0];
|
||||
}
|
||||
$start = $i + $j;
|
||||
$i = $start - 1;
|
||||
break;
|
||||
}
|
||||
if ( $chars[$i + $j] !== $div[$j] ) break;
|
||||
}
|
||||
}
|
||||
$tokens[] = join('', array_slice( $chars, $start ));
|
||||
|
||||
# negative $inPos
|
||||
if ( $inPos < 0 ) $inPos += count ( $tokens );
|
||||
|
||||
# out of range
|
||||
if ( !isset ( $tokens[$inPos] ) ) return "";
|
||||
|
||||
# in range
|
||||
return $tokens[$inPos];
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#urlencode:value}}
|
||||
*/
|
||||
function urlEncode ( &$parser, $inStr = '' ) {
|
||||
# encode
|
||||
return urlencode ( $inStr );
|
||||
}
|
||||
|
||||
/**
|
||||
* {{#urldecode:value}}
|
||||
*/
|
||||
function urlDecode ( &$parser, $inStr = '' ) {
|
||||
# decode
|
||||
return urldecode ( $inStr );
|
||||
}
|
||||
}
|
||||
|
||||
function wfSetupParserFunctions() {
|
||||
|
@ -804,3 +502,4 @@ function wfParserFunctionsLanguageGetMagic( &$magicWords, $langCode ) {
|
|||
$magicWords[$word] = $trans;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue