mirror of
https://github.com/YunoHost-Apps/mediawiki_ynh.git
synced 2024-09-03 19:46:05 +02:00
187 lines
4.8 KiB
PHP
187 lines
4.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Quickie parser class that can happily read the subset of PHP we need
|
|
* for our localization arrays safely.
|
|
*
|
|
* About an order of magnitude faster than ConfEditor(), but still an
|
|
* order of magnitude slower than eval().
|
|
*/
|
|
class QuickArrayReader {
|
|
var $vars = array();
|
|
|
|
/**
|
|
* @param $string string
|
|
*/
|
|
function __construct( $string ) {
|
|
$scalarTypes = array(
|
|
T_LNUMBER => true,
|
|
T_DNUMBER => true,
|
|
T_STRING => true,
|
|
T_CONSTANT_ENCAPSED_STRING => true,
|
|
);
|
|
$skipTypes = array(
|
|
T_WHITESPACE => true,
|
|
T_COMMENT => true,
|
|
T_DOC_COMMENT => true,
|
|
);
|
|
$tokens = token_get_all( $string );
|
|
$count = count( $tokens );
|
|
for( $i = 0; $i < $count; ) {
|
|
while( isset($skipTypes[$tokens[$i][0]] ) ) {
|
|
$i++;
|
|
}
|
|
switch( $tokens[$i][0] ) {
|
|
case T_OPEN_TAG:
|
|
$i++;
|
|
continue;
|
|
case T_VARIABLE:
|
|
// '$messages' -> 'messages'
|
|
$varname = trim( substr( $tokens[$i][1], 1 ) );
|
|
$varindex = null;
|
|
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( $tokens[$i] === '[' ) {
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( isset($scalarTypes[$tokens[$i][0]] ) ) {
|
|
$varindex = $this->parseScalar( $tokens[$i] );
|
|
} else {
|
|
throw $this->except( $tokens[$i], 'scalar index' );
|
|
}
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( $tokens[$i] !== ']' ) {
|
|
throw $this->except( $tokens[$i], ']' );
|
|
}
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
}
|
|
|
|
if( $tokens[$i] !== '=' ) {
|
|
throw $this->except( $tokens[$i], '=' );
|
|
}
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( isset($scalarTypes[$tokens[$i][0]] ) ) {
|
|
$buildval = $this->parseScalar( $tokens[$i] );
|
|
} elseif( $tokens[$i][0] === T_ARRAY ) {
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
if( $tokens[$i] !== '(' ) {
|
|
throw $this->except( $tokens[$i], '(' );
|
|
}
|
|
$buildval = array();
|
|
do {
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( $tokens[$i] === ')' ) {
|
|
break;
|
|
}
|
|
if( isset($scalarTypes[$tokens[$i][0]] ) ) {
|
|
$key = $this->parseScalar( $tokens[$i] );
|
|
}
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( $tokens[$i][0] !== T_DOUBLE_ARROW ) {
|
|
throw $this->except( $tokens[$i], '=>' );
|
|
}
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( isset($scalarTypes[$tokens[$i][0]] ) ) {
|
|
$val = $this->parseScalar( $tokens[$i] );
|
|
}
|
|
@$buildval[$key] = $val;
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
|
|
if( $tokens[$i] === ',' ) {
|
|
continue;
|
|
} elseif( $tokens[$i] === ')' ) {
|
|
break;
|
|
} else {
|
|
throw $this->except( $tokens[$i], ', or )' );
|
|
}
|
|
} while(true);
|
|
} else {
|
|
throw $this->except( $tokens[$i], 'scalar or array' );
|
|
}
|
|
if( is_null( $varindex ) ) {
|
|
$this->vars[$varname] = $buildval;
|
|
} else {
|
|
@$this->vars[$varname][$varindex] = $buildval;
|
|
}
|
|
while( isset($skipTypes[$tokens[++$i][0]] ) );
|
|
if( $tokens[$i] !== ';' ) {
|
|
throw $this->except($tokens[$i], ';');
|
|
}
|
|
$i++;
|
|
break;
|
|
default:
|
|
throw $this->except($tokens[$i], 'open tag, whitespace, or variable.');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $got string
|
|
* @param $expected string
|
|
* @return Exception
|
|
*/
|
|
private function except( $got, $expected ) {
|
|
if( is_array( $got ) ) {
|
|
$got = token_name( $got[0] ) . " ('" . $got[1] . "')";
|
|
} else {
|
|
$got = "'" . $got . "'";
|
|
}
|
|
return new Exception( "Expected $expected, got $got" );
|
|
}
|
|
|
|
/**
|
|
* Parse a scalar value in PHP
|
|
*
|
|
* @param $token string
|
|
*
|
|
* @return mixed Parsed value
|
|
*/
|
|
function parseScalar( $token ) {
|
|
if( is_array( $token ) ) {
|
|
$str = $token[1];
|
|
} else {
|
|
$str = $token;
|
|
}
|
|
if ( $str !== '' && $str[0] == '\'' )
|
|
// Single-quoted string
|
|
// @fixme trim() call is due to mystery bug where whitespace gets
|
|
// appended to the token; without it we ended up reading in the
|
|
// extra quote on the end!
|
|
return strtr( substr( trim( $str ), 1, -1 ),
|
|
array( '\\\'' => '\'', '\\\\' => '\\' ) );
|
|
if ( $str !== '' && @$str[0] == '"' )
|
|
// Double-quoted string
|
|
// @fixme trim() call is due to mystery bug where whitespace gets
|
|
// appended to the token; without it we ended up reading in the
|
|
// extra quote on the end!
|
|
return stripcslashes( substr( trim( $str ), 1, -1 ) );
|
|
if ( substr( $str, 0, 4 ) === 'true' )
|
|
return true;
|
|
if ( substr( $str, 0, 5 ) === 'false' )
|
|
return false;
|
|
if ( substr( $str, 0, 4 ) === 'null' )
|
|
return null;
|
|
// Must be some kind of numeric value, so let PHP's weak typing
|
|
// be useful for a change
|
|
return $str;
|
|
}
|
|
|
|
/**
|
|
* @param $varname string
|
|
* @return null|string
|
|
*/
|
|
function getVar( $varname ) {
|
|
if( isset( $this->vars[$varname] ) ) {
|
|
return $this->vars[$varname];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|