jenkins-bot has submitted this change and it was merged. Change subject: Add String Functions (version 0.4.2) ......................................................................
Add String Functions (version 0.4.2) * add $wgNamespacesWithFoxway * add Settings.php * fix for passByReference * small optimization for FArray Change-Id: Id3a7f6ed3303660cff3bd3c3a41ffd45fa887993 --- M Foxway.body.php M Foxway.i18n.php M Foxway.php A Settings.php M includes/Debug.php M includes/Interpreter.php M includes/Runtime.php M includes/RuntimeDebug.php M includes/functions/BaseFunction.php M includes/functions/FArray.php A includes/functions/FString.php M tests/phpunit/includes/InterpreterTest.php 12 files changed, 575 insertions(+), 158 deletions(-) Approvals: Pastakhov: Looks good to me, approved jenkins-bot: Verified diff --git a/Foxway.body.php b/Foxway.body.php index 0013902..f707185 100644 --- a/Foxway.body.php +++ b/Foxway.body.php @@ -11,38 +11,12 @@ static $frames=array(); - /** - * Render function used in hook ParserFirstCallInit - * - * @param Parser $parser - * @return string - */ - public static function renderParserFunction(Parser &$parser) { - $params = func_get_args(); - array_shift( $params ); - - if( count($params) < 2 ) { - return '<span class="error">' . wfMessage( 'foxway-not-enough-parameters' )->escaped() . '</span>'; - } - - $action = strtolower( $params[0] ); - switch ($action) { - case 'set': - $matches = array(); - if( preg_match('/^\s*([^=]+)\s*=\s*(.+)\s*$/si', $params[1], $matches) ) { - $propertyName = $matches[1]; - $propertyValue = $matches[2]; - return \Foxway\ORM::SetProperty($propertyName, $propertyValue); - break; - } - break; - default: - return '<span class="error">' . wfMessage( 'foxway-unknown-action', $action )->escaped() . '</span>'; - break; - } - } - public static function render($input, array $args, Parser $parser, PPFrame $frame) { + global $wgNamespacesWithFoxway; + if( $wgNamespacesWithFoxway !== true && empty($wgNamespacesWithFoxway[$frame->getTitle()->getNamespace()]) ) { + return Html::element( 'span', array('class'=>'error'), wfMessage('foxway-disabled-for-namespace', $frame->getTitle()->getNsText())->escaped() ); + } + $is_debug = isset($args['debug']); $return = ''; @@ -56,9 +30,7 @@ foreach ($result as &$value) { if( $value instanceof Foxway\iRawOutput ) { $value = (string)$value; - }/*else{ // @todo ???? - $value = strtr( $value, array('&'=>'&', '<'=>'<') ); - }*/ + } } if( $is_debug ) { @@ -66,7 +38,7 @@ $return .= self::insertNoWiki( $parser, array_shift($result) ) . "\n"; } - return $return . self::insertGeneral( $parser, $parser->recursiveTagParse(implode('', $result),$frame) ); + return $return . self::insertGeneral( $parser, $parser->recursiveTagParse(implode($result),$frame) ); } /** diff --git a/Foxway.i18n.php b/Foxway.i18n.php index 124afe8..fdc0eb9 100644 --- a/Foxway.i18n.php +++ b/Foxway.i18n.php @@ -13,7 +13,8 @@ * @author pastakhov */ $messages['en'] = array( - 'foxway-desc' => 'Allows to store an object-oriented data and implements its own runtime for PHP code on pages', + 'foxway-desc' => 'Adds in the wikitext parser the ability to use the syntax and functions of PHP', + 'foxway-disabled-for-namespace' => 'Extension foxway disabled for this namespace $1', 'foxway-php-fatal-error-undefined-function' => 'PHP fatal error: Call to undefined function $1() on page $2 line $3.', 'foxway-php-not-variable-passed-by-reference' => 'PHP fatal error: Only variables can be passed by reference, function $1() on page $2 line $3.', 'foxway-php-syntax-error-unexpected' => 'PHP parse error: Syntax error, unexpected $1 in command line code on line $2.', @@ -27,6 +28,8 @@ */ $messages['qqq'] = array( 'foxway-desc' => '{{desc|name=Foxway|url=https://www.mediawiki.org/wiki/Extension:Foxway}}', + 'foxway-disabled-for-namespace' => 'Error message when trying use this extension on the pages of the namespace where it is not permitted, parameters: +* $1 - the namespace name', 'foxway-php-fatal-error-undefined-function' => 'Error message, parameters: * $1 - user-specified function name * $2 - the name of the page on which the error occurred diff --git a/Foxway.php b/Foxway.php index 2ddd4b0..de30ac2 100644 --- a/Foxway.php +++ b/Foxway.php @@ -15,7 +15,7 @@ die( 'This file is an extension to MediaWiki and thus not a valid entry point.' ); } -define( 'Foxway_VERSION' , '0.4.1' ); +define( 'Foxway_VERSION' , '0.4.2' ); // Register this extension on Special:Version $wgExtensionCredits['parserhook'][] = array( @@ -64,6 +64,7 @@ $wgAutoloadClasses['Foxway\\BaseFunction'] = $dir . '/includes/functions/BaseFunction.php'; $wgAutoloadClasses['Foxway\\FArray'] = $dir . '/includes/functions/FArray.php'; +$wgAutoloadClasses['Foxway\\FString'] = $dir . '/includes/functions/FString.php'; $wgAutoloadClasses['Foxway\\FVariable'] = $dir . '/includes/functions/FVariable.php'; // Resources @@ -85,6 +86,10 @@ return true; }; +include_once 'Settings.php'; + +// @todo Reverse shift ??? +// Do not change the value of this variable in LocalSettings.php!!! $wgFoxwayPassByReference = array( 'settype' => 1, 'unset' => -1, @@ -111,101 +116,8 @@ 'rsort' => 1, 'shuffle' => 1, 'sort' => 1, -); - -$wgFoxwayFunctions = array( - 'FVariable' => array( // Variable handling Functions @see http://www.php.net/manual/en/ref.var.php - 'boolval', - //'debug_zval_dump', - 'doubleval', - 'empty', - 'floatval', - 'get_defined_vars', //implemented in Runtime.php - //'get_resource_type', - 'gettype', - //'import_request_variables', @todo need hide not foxway Cookie - 'intval', - 'is_array', - 'is_bool', - //'is_callable', - 'is_double', - 'is_float', - 'is_int', - 'is_integer', - 'is_long', - 'is_null', - 'is_numeric', - //'is_object', - 'is_real', - //'is_resource', - 'is_scalar', - 'is_string', - 'isset', - 'print_r', - //'serialize', - 'settype', - 'strval', - //'unserialize', - 'unset', - 'var_dump', - 'var_export', - ), - 'FArray' => array( // Array Functions @see http://www.php.net/manual/en/ref.array.php - 'array_change_key_case', - 'array_chunk', - //'array_column', @todo PHP 5 >= 5.5.0 - 'array_combine', - 'array_count_values', - 'array_diff_assoc', - 'array_diff_key', - 'array_diff', - 'array_fill_keys', - 'array_fill', - 'array_flip', - 'array_intersect_assoc', - 'array_intersect_key', - 'array_intersect', - 'array_key_exists', - 'array_keys', - 'array_merge_recursive', - 'array_merge', - 'array_multisort', - 'array_pad', - 'array_pop', - 'array_product', - 'array_push', - 'array_rand', - 'array_replace_recursive', - 'array_replace', - 'array_reverse', - 'array_search', - 'array_shift', - 'array_slice', - 'array_splice', - 'array_sum', - 'array_unique', - 'array_unshift', - 'array_values', - 'arsort', - 'asort', - 'count', - 'current', - 'each', - 'end', - 'in_array', - 'key', - 'krsort', - 'ksort', - 'natcasesort', - 'natsort', - 'next', - 'pos', - 'prev', - 'range', - 'reset', - 'rsort', - 'shuffle', - 'sizeof', - 'sort', - ), + 'similar_text' => 4, // 0b100 + 'sscanf' => 2147483644, // 0b1111111111111111111111111111100 + 'str_ireplace' => 8, // 0b1000 + 'str_replace' => 8, // 0b1000 ); diff --git a/Settings.php b/Settings.php new file mode 100644 index 0000000..be813f8 --- /dev/null +++ b/Settings.php @@ -0,0 +1,324 @@ +<?php +/** + * File defining the settings for the Foxway extension. + * More info can be found at https://www.mediawiki.org/wiki/Extension:Foxway + * + * NOTICE: + * Changing one of these settings can be done by copieng or cutting it, + * and placing it in LocalSettings.php, AFTER the inclusion of Foxway. + * + * @file Settings.php + * @ingroup Foxway + * @author Pavel Astakhov <pastak...@yandex.ru> + */ + +// Check to see if we are being called as an extension or directly +if ( !defined( 'MEDIAWIKI' ) ) { + die( 'This file is an extension to MediaWiki and thus not a valid entry point.' ); +} + +// Default settings + + +/** + * You can specify the namespaces in which is allowed to use the extension Foxway. + * + * Thus it is possible to give permission to use this extension is just a special user group, example: + * define("NS_PHP", 1000); + * define("NS_PHP_TALK", 1001); + * $wgExtraNamespaces[NS_PHP] = "PHP"; + * $wgExtraNamespaces[NS_PHP_TALK] = "PHP_Talk"; + * + * $wgNamespacesWithFoxway = array( NS_PHP ); + * $wgNamespaceProtection[NS_PHP] = array( 'php_editor' ); + * $wgGroupPermissions['sysop']['php_editor'] = true; + * + * @var array Namespaces in which is allowed to use the extension Foxway, boolean 'true' for unlimited + */ +$wgNamespacesWithFoxway = true; + +$wgFoxwayFunctions = array( + 'FVariable' => array( // Variable handling Functions @see http://www.php.net/manual/en/ref.var.php + 'boolval', + //'debug_zval_dump', + 'doubleval', + 'empty', + 'floatval', + 'get_defined_vars', //implemented in Runtime.php + //'get_resource_type', + 'gettype', + //'import_request_variables', @todo need hide not foxway Cookie + 'intval', + 'is_array', + 'is_bool', + //'is_callable', + 'is_double', + 'is_float', + 'is_int', + 'is_integer', + 'is_long', + 'is_null', + 'is_numeric', + //'is_object', + 'is_real', + //'is_resource', + 'is_scalar', + 'is_string', + 'isset', + 'print_r', + //'serialize', + 'settype', + 'strval', + //'unserialize', + 'unset', + 'var_dump', + 'var_export', + ), + 'FArray' => array( // Array Functions @see http://www.php.net/manual/en/ref.array.php + 'array_change_key_case', + 'array_chunk', + //'array_column', @todo PHP 5 >= 5.5.0 + 'array_combine', + 'array_count_values', + 'array_diff_assoc', + 'array_diff_key', + 'array_diff', + 'array_fill_keys', + 'array_fill', + 'array_flip', + 'array_intersect_assoc', + 'array_intersect_key', + 'array_intersect', + 'array_key_exists', + 'array_keys', + 'array_merge_recursive', + 'array_merge', + 'array_multisort', + 'array_pad', + 'array_pop', + 'array_product', + 'array_push', + 'array_rand', + 'array_replace_recursive', + 'array_replace', + 'array_reverse', + 'array_search', + 'array_shift', + 'array_slice', + 'array_splice', + 'array_sum', + 'array_unique', + 'array_unshift', + 'array_values', + 'arsort', + 'asort', + 'count', + 'current', + 'each', + 'end', + 'in_array', + 'key', + 'krsort', + 'ksort', + 'natcasesort', + 'natsort', + 'next', + 'pos', + 'prev', + 'range', + 'reset', + 'rsort', + 'shuffle', + 'sizeof', + 'sort', + ), + 'FString' => array( // String Functions @see http://www.php.net/manual/en/ref.strings.php + 'addcslashes', + 'addslashes', + 'chop', + 'chr', + 'chunk_split', + 'convert_cyr_string', + 'convert_uudecode', + 'convert_uuencode', + 'count_chars', + 'crc32', + 'crypt', + 'explode', + 'html_entity_decode', + 'htmlentities', + 'htmlspecialchars_decode', + 'htmlspecialchars', + 'implode', + 'join', + 'lcfirst', + 'levenshtein', + 'ltrim', + 'md5', + 'metaphone', + 'money_format', + 'nl_langinfo', + 'nl2br', + 'number_format', + 'ord', + 'printf', + 'quotemeta', + 'rtrim', + 'sha1', + 'similar_text', + 'soundex', + 'sprintf', + 'sscanf', + 'str_ireplace', + 'str_pad', + 'str_repeat', + 'str_replace', + 'str_rot13', + 'str_shuffle', + 'str_split', + 'str_word_count', + 'strcasecmp', + 'strchr', + 'strcmp', + 'strcspn', + 'strip_tags', + 'stripcslashes', + 'stripos', + 'stripslashes', + 'stristr', + 'strlen', + 'strnatcasecmp', + 'strnatcmp', + 'strncmp', + 'strpbrk', + 'strpos', + 'strrchr', + 'strrev', + 'strripos', + 'strrpos', + 'strspn', + 'strstr', + 'strtok', + 'strtolower', + 'strtoupper', + 'strtr', + 'substr_compare', + 'substr_count', + 'substr_replace', + 'substr', + 'trim', + 'ucfirst', + 'ucwords', + 'vprintf', + 'vsprintf', + 'wordwrap', + ), +); + +$wgFoxwayAllowedPHPConstants = array( + 'CASE_UPPER', + 'CASE_LOWER', + 'SORT_ASC', + 'SORT_DESC', + 'SORT_REGULAR', + 'SORT_NUMERIC', + 'SORT_STRING', + 'SORT_LOCALE_STRING', + 'SORT_NATURAL', // PHP >= 5.4.0 + 'SORT_FLAG_CASE', // PHP >= 5.4.0 + 'COUNT_RECURSIVE', + 'CRYPT_STD_DES', + 'CRYPT_EXT_DES', + 'CRYPT_MD5', + 'CRYPT_BLOWFISH', + 'CRYPT_SHA256', + 'CRYPT_SHA512', + 'ENT_COMPAT', + 'ENT_QUOTES', + 'ENT_NOQUOTES', + 'ENT_HTML401', // PHP >= 5.4.0 + 'ENT_XML1', // PHP >= 5.4.0 + 'ENT_XHTML', // PHP >= 5.4.0 + 'ENT_HTML5', // PHP >= 5.4.0 + 'ENT_IGNORE', + 'ENT_SUBSTITUTE', // PHP >= 5.4.0 + 'ENT_DISALLOWED', // PHP >= 5.4.0 + 'STR_PAD_RIGHT', + 'STR_PAD_LEFT', + 'STR_PAD_BOTH', + 'ABDAY_1', + 'ABDAY_2', + 'ABDAY_3', + 'ABDAY_4', + 'ABDAY_5', + 'ABDAY_6', + 'ABDAY_7', + 'DAY_1', + 'DAY_2', + 'DAY_3', + 'DAY_4', + 'DAY_5', + 'DAY_6', + 'DAY_7', + 'ABMON_1', + 'ABMON_2', + 'ABMON_3', + 'ABMON_4', + 'ABMON_5', + 'ABMON_6', + 'ABMON_7', + 'ABMON_8', + 'ABMON_9', + 'ABMON_10', + 'ABMON_11', + 'ABMON_12', + 'MON_1', + 'MON_2', + 'MON_3', + 'MON_4', + 'MON_5', + 'MON_6', + 'MON_7', + 'MON_8', + 'MON_9', + 'MON_10', + 'MON_11', + 'MON_12', + 'AM_STR', + 'PM_STR', + 'D_T_FMT', + 'D_FMT', + 'T_FMT', + 'T_FMT_AMPM', + 'ERA', + 'ERA_YEAR', + 'ERA_D_T_FMT', + 'ERA_D_FMT', + 'ERA_T_FMT', + 'INT_CURR_SYMBOL', + 'CURRENCY_SYMBOL', + 'CRNCYSTR', + 'MON_DECIMAL_POINT', + 'MON_THOUSANDS_SEP', + 'MON_GROUPING', + 'POSITIVE_SIGN', + 'NEGATIVE_SIGN', + 'INT_FRAC_DIGITS', + 'FRAC_DIGITS', + 'P_CS_PRECEDES', + 'P_SEP_BY_SPACE', + 'N_CS_PRECEDES', + 'N_SEP_BY_SPACE', + 'P_SIGN_POSN', + 'N_SIGN_POSN', + 'DECIMAL_POINT', + 'RADIXCHAR', + 'THOUSANDS_SEP', + 'THOUSEP', + 'GROUPING', + 'YESEXPR', + 'NOEXPR', + 'YESSTR', + 'NOSTR', + 'CODESET', +); \ No newline at end of file diff --git a/includes/Debug.php b/includes/Debug.php index 25f7d23..437bfca 100644 --- a/includes/Debug.php +++ b/includes/Debug.php @@ -77,6 +77,7 @@ case T_BOOL_CAST: // (bool) case T_UNSET_CAST: // (unset) case T_ECHO: + case T_PRINT: case T_IF: case T_ELSE: case T_ELSEIF: diff --git a/includes/Interpreter.php b/includes/Interpreter.php index 57f0955..5dc21f0 100644 --- a/includes/Interpreter.php +++ b/includes/Interpreter.php @@ -116,6 +116,8 @@ ); public static function run($source, array $args=array(), $scope='', $is_debug=false) { + global $wgFoxwayAllowedPHPConstants; + $tokens = self::getTokens($source); $return = array(); @@ -292,6 +294,10 @@ $runtime->addCommand($id); $parenthesFlags = FOXWAY_ALLOW_LIST_PARAMS | FOXWAY_EXPECT_SEMICOLON; break; + case T_PRINT: + $runtime->addCommand($id); + $parenthesFlags = FOXWAY_EXPECT_SEMICOLON; + break; case T_CONSTANT_ENCAPSED_STRING: $is_apostrophe = substr($text, 0, 1) == '\'' ? true : false; $string = substr($text, 1, -1); @@ -403,8 +409,8 @@ $debug[] = $token; } continue 2; - } elseif( isset(self::$PHPConstants[$text]) ) { - $runtime->addParamValue( self::$PHPConstants[$text] ); + } elseif( in_array($text, $wgFoxwayAllowedPHPConstants) && defined($text) ) { + $runtime->addParamValue( constant($text) ); } else { $return[] = new ErrorMessage(__LINE__, $tokenLine, E_PARSE, $id); break 2; @@ -443,6 +449,7 @@ } switch ($command) { case T_ECHO: + case T_PRINT: $return = array_merge($return, $result); break; case T_IF: @@ -554,6 +561,7 @@ } // break is not necessary here case T_ECHO: + case T_PRINT: case ',': case T_CONCAT_EQUAL: // .= case T_PLUS_EQUAL: // += @@ -960,19 +968,5 @@ } return (float)( substr($string, 0, $epos) * pow(10, substr($string, $epos+1)) ); } - - private static $PHPConstants = array( - 'CASE_UPPER' => CASE_UPPER, - 'CASE_LOWER' => CASE_LOWER, - 'SORT_ASC' => SORT_ASC, - 'SORT_DESC' => SORT_DESC, - 'SORT_REGULAR' => SORT_REGULAR, - 'SORT_NUMERIC' => SORT_NUMERIC, - 'SORT_STRING' => SORT_STRING, - 'SORT_LOCALE_STRING' => SORT_LOCALE_STRING, - //'SORT_NATURAL' => SORT_NATURAL, // @todo PHP >= 5.4.0 - //'SORT_FLAG_CASE' => SORT_FLAG_CASE, // @todo PHP >= 5.4.0 - 'COUNT_RECURSIVE' => COUNT_RECURSIVE, - ); } diff --git a/includes/Runtime.php b/includes/Runtime.php index 564bb39..a85826a 100644 --- a/includes/Runtime.php +++ b/includes/Runtime.php @@ -209,9 +209,6 @@ }else{ $this->listParams[] = $this->lastParam->getValue(); } - if( $this->passByReference > 0 ) { - $this->passByReference <<= 1; - } } $this->lastParam = $this->listParams; } @@ -231,7 +228,7 @@ $this->listParams[] = $this->lastParam->getValue(); } if( $this->passByReference > 0 ) { - $this->passByReference <<= 1; + $this->passByReference >>= 1; } } $this->lastParam = null; @@ -259,6 +256,7 @@ switch ($this->lastCommand) { case false: case T_ECHO: + case T_PRINT: break 2; case T_IF: $this->lastCommand = false; @@ -484,6 +482,7 @@ // Remember the child class RuntimeDebug switch ($this->lastCommand) { case T_ECHO: + case T_PRINT: $return = array( T_ECHO, $this->listParams ); break; case false: diff --git a/includes/RuntimeDebug.php b/includes/RuntimeDebug.php index a6e66f5..75cb095 100644 --- a/includes/RuntimeDebug.php +++ b/includes/RuntimeDebug.php @@ -102,6 +102,7 @@ case false: case T_ARRAY: case T_ECHO: + case T_PRINT: break; case T_IF: $this->debug[] = self::getHTMLForCommand(T_IF) . @@ -121,6 +122,7 @@ switch ($lastCommand) { case T_ECHO: + case T_PRINT: $this->debug[] = self::getHTMLForCommand($lastCommand) . ' ' . implode(', ', $this->savedListParams) . ';'; $this->debug[] = implode('', $return[1]); break; @@ -199,6 +201,9 @@ case T_ECHO: $return = \Html::element('span', array('class'=>'foxway_construct'), 'echo'); break; + case T_PRINT: + $return = \Html::element('span', array('class'=>'foxway_construct'), 'print'); + break; case T_IF: $return = \Html::element('span', array('class'=>'foxway_construct'), 'if'); break; diff --git a/includes/functions/BaseFunction.php b/includes/functions/BaseFunction.php index e5bea8b..2bbcdd4 100644 --- a/includes/functions/BaseFunction.php +++ b/includes/functions/BaseFunction.php @@ -1,6 +1,6 @@ <?php namespace Foxway; -define('FOXWAY_MAX_PAST_PARAM', 16); +define('FOXWAY_MAX_PAST_PARAM', 16); // Max 31 ? /** * BaseFunction base class for functions classes of Foxway extension. diff --git a/includes/functions/FArray.php b/includes/functions/FArray.php index 154e2f7..20290cc 100644 --- a/includes/functions/FArray.php +++ b/includes/functions/FArray.php @@ -90,12 +90,16 @@ ); public static function __callStatic($name, $arguments) { + global $wgFoxwayPassByReference; + if( isset(self::$listFunction[$name]) ) { $funcData = &self::$listFunction[$name]; $refarg = &$arguments[0]; - foreach ($refarg as $key => &$value) { - if( $value instanceof RValue ) { - $refarg[$key] = &$value->getReference(); + if( isset($wgFoxwayPassByReference[$funcData[0]]) ) { + foreach ($refarg as $key => &$value) { + if( $value instanceof RValue ) { + $refarg[$key] = &$value->getReference(); + } } } $c = count($refarg); diff --git a/includes/functions/FString.php b/includes/functions/FString.php new file mode 100644 index 0000000..2e983ff --- /dev/null +++ b/includes/functions/FString.php @@ -0,0 +1,196 @@ +<?php +namespace Foxway; +/** + * FString class implements String Functions for Foxway extension. + * + * @file FString.php + * @ingroup Foxway + * @author Pavel Astakhov <pastak...@yandex.ru> + * @licence GNU General Public Licence 2.0 or later + */ +class FString extends BaseFunction { + protected static $listFunction = array( + 'f_addcslashes' => array('addcslashes', 2, 2), + 'f_addslashes' => array('addslashes', 1, 1), + //'f_bin2hex' => array('bin2hex', 1, 1), + 'f_chop' => array('rtrim', 1, 2), //chop — Alias of rtrim() + 'f_chr' => array('chr', 1, 1), + 'f_chunk_split' => array('chunk_split', 1, 3), + 'f_convert_cyr_string' => array('convert_cyr_string', 3, 3), + 'f_convert_uudecode' => array('convert_uudecode', 1, 1), + 'f_convert_uuencode' => array('convert_uuencode', 1, 1), + 'f_count_chars' => array('count_chars', 1, 2), + 'f_crc32' => array('crc32', 1, 1), + 'f_crypt' => array('crypt', 1, 2), + 'f_explode' => array('explode', 2, 3), + // ### fprintf — Write a formatted string to a stream ### + //'f_get_html_translation_table' => array('get_html_translation_table', 0, 3), + //'f_hebrev' => array('hebrev', 1, 2), + //'f_hebrevc' => array('hebrevc', 1, 2), + //'f_hex2bin' => array('hex2bin', 1, 1), PHP >= 5.4.0 + 'f_html_entity_decode' => array('html_entity_decode', 1, 3), + 'f_htmlentities' => array('htmlentities', 1, 4), + 'f_htmlspecialchars_decode' => array('htmlspecialchars_decode', 1, 2), + 'f_htmlspecialchars' => array('htmlspecialchars', 1, 4), + 'f_implode' => array('implode', 1, 2), + 'f_join' => array('implode', 1, 2), //join — Alias of implode() + 'f_lcfirst' => array('lcfirst', 1, 1), + //'levenshtein', @see self::f_levenshtein + //'localeconv' @todo get info from MW + 'f_ltrim' => array('ltrim', 1, 2), //@todo check exsample + // ### md5_ file + 'f_md5' => array('md5', 1, 2), + 'f_metaphone' => array('metaphone', 1, 2), + 'f_money_format' => array('money_format', 2, 2), // @todo need setlocale + 'f_nl_langinfo' => array('nl_langinfo', 1, 1), // @todo need setlocale + 'f_nl2br' => array('nl2br', 1, 2), + // 'number_format' @see self::number_format + 'f_ord' => array('ord', 1, 1), + // @todo parse_str + // 'print' implemented in Runtime.php + //'f_printf', @see self::f_printf + //'f_quoted_printable_decode' => array('quoted_printable_decode', 1, 1), + //'f_quoted_printable_encode' => array('quoted_printable_encode', 1, 1), + 'f_quotemeta' => array('quotemeta', 1, 1), + 'f_rtrim' => array('rtrim', 1, 2), + // setlocale @todo need check for security + // ### sha1_file + 'f_sha1' => array('sha1', 1, 2), + 'f_similar_text' => array('similar_text', 2, 3), + 'f_soundex' => array('soundex', 1, 1), + 'f_sprintf' => array('sprintf', 1, FOXWAY_MAX_PAST_PARAM), + 'f_sscanf' => array('sscanf', 2, FOXWAY_MAX_PAST_PARAM), + //str_getcsv + 'f_str_ireplace' => array('str_ireplace', 3, 4), + 'f_str_pad' => array('str_pad', 2, 4), + 'f_str_repeat' => array('str_repeat', 2, 2), + 'f_str_replace' => array('str_replace', 3, 4), + 'f_str_rot13' => array('str_rot13', 1, 1), + 'f_str_shuffle' => array('str_shuffle', 1, 1), + 'f_str_split' => array('str_split', 1, 2), + 'f_str_word_count' => array('str_word_count', 1, 3), + 'f_strcasecmp' => array('strcasecmp', 2, 2), + 'f_strchr' => array('strstr', 2, 3), //strchr — Alias of strstr() + 'f_strcmp' => array('strcmp', 2, 2), + // strcoll function is not binary safe. + 'f_strcspn' => array('strcspn', 2, 4), + 'f_strip_tags' => array('strip_tags', 1, 2), + 'f_stripcslashes' => array('stripcslashes', 1, 1), + 'f_stripos' => array('stripos', 2, 3), + 'f_stripslashes' => array('stripslashes', 1, 1), + 'f_stristr' => array('stristr', 2, 3), + 'f_strlen' => array('strlen', 1, 1), + 'f_strnatcasecmp' => array('strnatcasecmp', 2, 2), + 'f_strnatcmp' => array('strnatcmp', 2, 2), + 'f_strncasecmp' => array('strncasecmp', 3, 3), + 'f_strncmp' => array('strncmp', 3, 3), + 'f_strpbrk' => array('strpbrk', 2, 2), + 'f_strpos' => array('strpos', 2, 3), + 'f_strrchr' => array('strrchr', 2, 2), + 'f_strrev' => array('strrev', 1, 1), + 'f_strripos' => array('strripos', 2, 3), + 'f_strrpos' => array('strrpos', 2, 3), + 'f_strspn' => array('strspn', 2, 4), + 'f_strstr' => array('strstr', 2, 3), + 'f_strtok' => array('strtok', 1, 2), + 'f_strtolower' => array('strtolower', 1, 1), + 'f_strtoupper' => array('strtoupper', 1, 1), + 'f_strtr' => array('strtr', 2, 3), + 'f_substr_compare' => array('substr_compare', 3, 5), + 'f_substr_count' => array('substr_count', 2, 4), + 'f_substr_replace' => array('substr_replace', 3, 4), + 'f_substr' => array('substr', 2, 3), + 'f_trim' => array('trim', 1, 2), + 'f_ucfirst' => array('ucfirst', 1, 1), + 'f_ucwords' => array('ucwords', 1, 1), + // ### vfprintf — Write a formatted string to a stream + // 'f_vprintf', @see self::f_vprintf + 'f_vsprintf' => array('vsprintf', 2, 2), + 'f_wordwrap' => array('wordwrap', 1, 4), + + ); + + public static function __callStatic($name, $arguments) { + global $wgFoxwayPassByReference; + + if( isset(self::$listFunction[$name]) ) { + $funcData = &self::$listFunction[$name]; + $refarg = &$arguments[0]; + if( isset($wgFoxwayPassByReference[$funcData[0]]) ) { + foreach ($refarg as $key => &$value) { + if( $value instanceof RValue ) { + $refarg[$key] = &$value->getReference(); + } + } + } + $c = count($refarg); + if( $c >= $funcData[1] && $c <= $funcData[2] ) { + return new RValue( call_user_func_array($funcData[0], $refarg) ); + }else{ + return self::wrongParameterCount($name, __LINE__); + } + } else { + return self::callUnknownMethod($name, __LINE__); + } + } + + /** + * Output a formatted string + * @param array $arguments + * @return \Foxway\RValue + */ + public static function f_printf($arguments) { + if( count($arguments) == 0 ) { + return self::wrongParameterCount( __FUNCTION__, __LINE__ ); + } + ob_start(); + call_user_func_array('printf', $arguments); + return new ROutput( null, ob_get_clean(), 'pre' ); + } + + /** + * Calculate Levenshtein distance between two strings + * @param array $arguments + * @return \Foxway\RValue + */ + public static function f_levenshtein($arguments) { + switch ( count($arguments) ) { + case 2: + case 5: + return new RValue( call_user_func_array('levenshtein', $arguments) ); + break; + } + return self::wrongParameterCount( __FUNCTION__, __LINE__ ); + } + + /** + * Calculate Levenshtein distance between two strings + * @param array $arguments + * @return \Foxway\RValue + */ + public static function f_number_format($arguments) { + switch ( count($arguments) ) { + case 1: + case 2: + case 4: + return new RValue( call_user_func_array('number_format', $arguments) ); + break; + } + return self::wrongParameterCount( __FUNCTION__, __LINE__ ); + } + + /** + * Output a formatted string + * @param array $arguments + * @return \Foxway\RValue + */ + public static function f_vprintf($arguments) { + if( count($arguments) != 2 ) { + return self::wrongParameterCount( __FUNCTION__, __LINE__ ); + } + ob_start(); + call_user_func_array('vprintf', $arguments); + return new ROutput( null, ob_get_clean(), 'pre' ); + } + +} diff --git a/tests/phpunit/includes/InterpreterTest.php b/tests/phpunit/includes/InterpreterTest.php index cddfa50..35e549f 100644 --- a/tests/phpunit/includes/InterpreterTest.php +++ b/tests/phpunit/includes/InterpreterTest.php @@ -1995,6 +1995,13 @@ ); } + public function testRun_RString_similar_text() { + $this->assertEquals( + Interpreter::run('$var_1 = "PHP IS GREAT"; $var_2 = "WITH MYSQL"; similar_text($var_1, $var_2, $percent); echo $percent;'), + array('27.272727272727') + ); + } + } // @todo echo is_scalar(array("foo","bar") ? "true" : "false"; // most return error -- To view, visit https://gerrit.wikimedia.org/r/67651 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id3a7f6ed3303660cff3bd3c3a41ffd45fa887993 Gerrit-PatchSet: 6 Gerrit-Project: mediawiki/extensions/Foxway Gerrit-Branch: master Gerrit-Owner: Pastakhov <pastak...@yandex.ru> Gerrit-Reviewer: Pastakhov <pastak...@yandex.ru> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits