- upgraded "Fat Free Framework" PHP core framework v3.6.4 → v3.6.5
This commit is contained in:
165
app/lib/base.php
165
app/lib/base.php
@@ -45,7 +45,7 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
//@{ Framework details
|
||||
const
|
||||
PACKAGE='Fat-Free Framework',
|
||||
VERSION='3.6.4-Release';
|
||||
VERSION='3.6.5-Release';
|
||||
//@}
|
||||
|
||||
//@{ HTTP status codes (RFC 2616)
|
||||
@@ -207,11 +207,13 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
}
|
||||
|
||||
/**
|
||||
* cast string variable to php type or constant
|
||||
* Cast string variable to PHP type or constant
|
||||
* @param $val
|
||||
* @return mixed
|
||||
*/
|
||||
function cast($val) {
|
||||
if (preg_match('/^(?:0x[0-9a-f]+|0[0-7]+|0b[01]+)$/i',$val))
|
||||
return intval($val,0);
|
||||
if (is_numeric($val))
|
||||
return $val+0;
|
||||
$val=trim($val);
|
||||
@@ -241,13 +243,13 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$out='['.
|
||||
(isset($sub[3])?
|
||||
$this->compile($sub[3]):
|
||||
var_export($sub[1],TRUE)).
|
||||
$this->export($sub[1])).
|
||||
']';
|
||||
}
|
||||
else
|
||||
$out=function_exists($sub[1])?
|
||||
$sub[0]:
|
||||
('['.var_export($sub[1],TRUE).']'.$sub[2]);
|
||||
('['.$this->export($sub[1]).']'.$sub[2]);
|
||||
return $out;
|
||||
},
|
||||
$expr[2]
|
||||
@@ -680,7 +682,7 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$str='';
|
||||
foreach (get_object_vars($arg) as $key=>$val)
|
||||
$str.=($str?',':'').
|
||||
var_export($key,TRUE).'=>'.
|
||||
$this->export($key).'=>'.
|
||||
$this->stringify($val,
|
||||
array_merge($stack,[$arg]));
|
||||
return get_class($arg).'::__set_state(['.$str.'])';
|
||||
@@ -690,11 +692,11 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
ctype_digit(implode('',array_keys($arg)));
|
||||
foreach ($arg as $key=>$val)
|
||||
$str.=($str?',':'').
|
||||
($num?'':(var_export($key,TRUE).'=>')).
|
||||
($num?'':($this->export($key).'=>')).
|
||||
$this->stringify($val,array_merge($stack,[$arg]));
|
||||
return '['.$str.']';
|
||||
default:
|
||||
return var_export($arg,TRUE);
|
||||
return $this->export($arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -890,8 +892,14 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
return $expr[0];
|
||||
if (isset($type)) {
|
||||
if (isset($this->hive['FORMATS'][$type]))
|
||||
return $this->call($this->hive['FORMATS'][$type],
|
||||
[$args[$pos],isset($mod)?$mod:null,isset($prop)?$prop:null]);
|
||||
return $this->call(
|
||||
$this->hive['FORMATS'][$type],
|
||||
[
|
||||
$args[$pos],
|
||||
isset($mod)?$mod:null,
|
||||
isset($prop)?$prop:null
|
||||
]
|
||||
);
|
||||
switch ($type) {
|
||||
case 'plural':
|
||||
preg_match_all('/(?<tag>\w+)'.
|
||||
@@ -964,16 +972,22 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$args[$pos]*100,0,$decimal_point,
|
||||
$thousands_sep).'%';
|
||||
}
|
||||
$frac=$args[$pos]-(int)$args[$pos];
|
||||
return number_format(
|
||||
$args[$pos],isset($prop)?$prop:2,
|
||||
$args[$pos],
|
||||
isset($prop)?
|
||||
$prop:
|
||||
$frac?strlen($frac)-2:0,
|
||||
$decimal_point,$thousands_sep);
|
||||
case 'date':
|
||||
$prop='%d %B %Y';
|
||||
if (empty($mod) || $mod=='short')
|
||||
$prop='%x';
|
||||
elseif ($mod=='long')
|
||||
$prop='%A, %d %B %Y';
|
||||
elseif ($mod=='full')
|
||||
$prop='%A, '.$prop;
|
||||
return strftime($prop,$args[$pos]);
|
||||
case 'time':
|
||||
$prop='%r';
|
||||
if (empty($mod) || $mod=='short')
|
||||
$prop='%X';
|
||||
return strftime($prop,$args[$pos]);
|
||||
@@ -987,6 +1001,15 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string representation of expression
|
||||
* @return string
|
||||
* @param $expr mixed
|
||||
**/
|
||||
function export($expr) {
|
||||
return var_export($expr,TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign/auto-detect language
|
||||
* @return string
|
||||
@@ -1244,7 +1267,8 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
if (!is_array($loggable))
|
||||
$loggable=$this->split($loggable);
|
||||
foreach ($loggable as $status)
|
||||
if ($status=='*' || preg_match('/^'.preg_replace('/\D/','\d',$status).'$/',$code)) {
|
||||
if ($status=='*' ||
|
||||
preg_match('/^'.preg_replace('/\D/','\d',$status).'$/',$code)) {
|
||||
error_log($text);
|
||||
foreach (explode("\n",$trace) as $nexus)
|
||||
if ($nexus)
|
||||
@@ -1270,7 +1294,14 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
'beforeroute,afterroute')===FALSE) &&
|
||||
!$prior && !$this->hive['CLI'] && !$this->hive['QUIET'])
|
||||
echo $this->hive['AJAX']?
|
||||
json_encode(array_diff_key($this->hive['ERROR'],$this->hive['DEBUG']?[]:['trace'=>1])):
|
||||
json_encode(
|
||||
array_diff_key(
|
||||
$this->hive['ERROR'],
|
||||
$this->hive['DEBUG']?
|
||||
[]:
|
||||
['trace'=>1]
|
||||
)
|
||||
):
|
||||
('<!DOCTYPE html>'.$eol.
|
||||
'<html>'.$eol.
|
||||
'<head>'.
|
||||
@@ -1557,7 +1588,7 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$cors=$this->hive['CORS'];
|
||||
header('Access-Control-Allow-Origin: '.$cors['origin']);
|
||||
header('Access-Control-Allow-Credentials: '.
|
||||
var_export($cors['credentials'],TRUE));
|
||||
$this->export($cors['credentials']));
|
||||
$preflight=
|
||||
isset($this->hive['HEADERS']['Access-Control-Request-Method']);
|
||||
}
|
||||
@@ -1674,12 +1705,15 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
// URL doesn't match any route
|
||||
$this->error(404);
|
||||
elseif (!$this->hive['CLI']) {
|
||||
// Unhandled HTTP method
|
||||
header('Allow: '.implode(',',array_unique($allowed)));
|
||||
if (!preg_grep('/Allow:/',$headers_send=headers_list()))
|
||||
// Unhandled HTTP method
|
||||
header('Allow: '.implode(',',array_unique($allowed)));
|
||||
if ($cors) {
|
||||
header('Access-Control-Allow-Methods: OPTIONS,'.
|
||||
implode(',',$allowed));
|
||||
if ($cors['headers'])
|
||||
if (!preg_grep('/Access-Control-Allow-Methods:/',$headers_send))
|
||||
header('Access-Control-Allow-Methods: OPTIONS,'.
|
||||
implode(',',$allowed));
|
||||
if ($cors['headers'] &&
|
||||
!preg_grep('/Access-Control-Allow-Headers:/',$headers_send))
|
||||
header('Access-Control-Allow-Headers: '.
|
||||
(is_array($cors['headers'])?
|
||||
implode(',',$cors['headers']):
|
||||
@@ -1733,7 +1767,9 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect HTTP client
|
||||
* Disconnect HTTP client;
|
||||
* Set FcgidOutputBufferSize to zero if server uses mod_fcgid;
|
||||
* Disable mod_deflate when rendering text/html output
|
||||
**/
|
||||
function abort() {
|
||||
if (!headers_sent() && session_status()!=PHP_SESSION_ACTIVE)
|
||||
@@ -1741,9 +1777,10 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$out='';
|
||||
while (ob_get_level())
|
||||
$out=ob_get_clean().$out;
|
||||
header('Content-Encoding: none');
|
||||
header('Content-Length: '.strlen($out));
|
||||
header('Connection: close');
|
||||
if (!headers_sent()) {
|
||||
header('Content-Length: '.strlen($out));
|
||||
header('Connection: close');
|
||||
}
|
||||
session_commit();
|
||||
echo $out;
|
||||
flush();
|
||||
@@ -1771,11 +1808,13 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$parts[1]=call_user_func([$container,'get'],$parts[1]);
|
||||
elseif (is_callable($container))
|
||||
$parts[1]=call_user_func($container,$parts[1],$args);
|
||||
elseif (is_string($container) && is_subclass_of($container,'Prefab'))
|
||||
$parts[1]=call_user_func($container.'::instance')->get($parts[1]);
|
||||
elseif (is_string($container) &&
|
||||
is_subclass_of($container,'Prefab'))
|
||||
$parts[1]=call_user_func($container.'::instance')->
|
||||
get($parts[1]);
|
||||
else
|
||||
user_error(sprintf(self::E_Class,
|
||||
$this->stringify($container)),
|
||||
$this->stringify($parts[1])),
|
||||
E_USER_ERROR);
|
||||
}
|
||||
else {
|
||||
@@ -1916,7 +1955,8 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
call_user_func_array(
|
||||
[$this,$cmd[1]],
|
||||
array_merge([$match['lval']],
|
||||
str_getcsv($cmd[1]=='config'?$this->cast($match['rval']):
|
||||
str_getcsv($cmd[1]=='config'?
|
||||
$this->cast($match['rval']):
|
||||
$match['rval']))
|
||||
);
|
||||
}
|
||||
@@ -1931,9 +1971,11 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$args=array_map(
|
||||
function($val) {
|
||||
$val=$this->cast($val);
|
||||
return is_string($val)
|
||||
? preg_replace('/\\\\"/','"',$val)
|
||||
: $val;
|
||||
if (is_string($val))
|
||||
$val=strlen($val)?
|
||||
preg_replace('/\\\\"/','"',$val):
|
||||
NULL;
|
||||
return $val;
|
||||
},
|
||||
// Mark quoted strings with 0x00 whitespace
|
||||
str_getcsv(preg_replace(
|
||||
@@ -2221,6 +2263,7 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
);
|
||||
if (!isset($_SERVER['SERVER_NAME']) || $_SERVER['SERVER_NAME']==='')
|
||||
$_SERVER['SERVER_NAME']=gethostname();
|
||||
$headers=[];
|
||||
if ($cli=PHP_SAPI=='cli') {
|
||||
// Emulate HTTP request
|
||||
$_SERVER['REQUEST_METHOD']='GET';
|
||||
@@ -2251,33 +2294,30 @@ final class Base extends Prefab implements ArrayAccess {
|
||||
$_SERVER['REQUEST_URI']=$req;
|
||||
parse_str($query,$GLOBALS['_GET']);
|
||||
}
|
||||
$headers=[];
|
||||
if (!$cli) {
|
||||
if (function_exists('getallheaders')) {
|
||||
foreach (getallheaders() as $key=>$val) {
|
||||
$tmp=strtoupper(strtr($key,'-','_'));
|
||||
// TODO: use ucwords delimiters for php 5.4.32+ & 5.5.16+
|
||||
$key=strtr(ucwords(strtolower(strtr($key,'-',' '))),' ','-');
|
||||
$headers[$key]=$val;
|
||||
if (isset($_SERVER['HTTP_'.$tmp]))
|
||||
$headers[$key]=&$_SERVER['HTTP_'.$tmp];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isset($_SERVER['CONTENT_LENGTH']))
|
||||
$headers['Content-Length']=&$_SERVER['CONTENT_LENGTH'];
|
||||
if (isset($_SERVER['CONTENT_TYPE']))
|
||||
$headers['Content-Type']=&$_SERVER['CONTENT_TYPE'];
|
||||
foreach (array_keys($_SERVER) as $key)
|
||||
if (substr($key,0,5)=='HTTP_')
|
||||
$headers[strtr(ucwords(strtolower(strtr(
|
||||
substr($key,5),'_',' '))),' ','-')]=&$_SERVER[$key];
|
||||
elseif (function_exists('getallheaders')) {
|
||||
foreach (getallheaders() as $key=>$val) {
|
||||
$tmp=strtoupper(strtr($key,'-','_'));
|
||||
// TODO: use ucwords delimiters for php 5.4.32+ & 5.5.16+
|
||||
$key=strtr(ucwords(strtolower(strtr($key,'-',' '))),' ','-');
|
||||
$headers[$key]=$val;
|
||||
if (isset($_SERVER['HTTP_'.$tmp]))
|
||||
$headers[$key]=&$_SERVER['HTTP_'.$tmp];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isset($_SERVER['CONTENT_LENGTH']))
|
||||
$headers['Content-Length']=&$_SERVER['CONTENT_LENGTH'];
|
||||
if (isset($_SERVER['CONTENT_TYPE']))
|
||||
$headers['Content-Type']=&$_SERVER['CONTENT_TYPE'];
|
||||
foreach (array_keys($_SERVER) as $key)
|
||||
if (substr($key,0,5)=='HTTP_')
|
||||
$headers[strtr(ucwords(strtolower(strtr(
|
||||
substr($key,5),'_',' '))),' ','-')]=&$_SERVER[$key];
|
||||
}
|
||||
if (isset($headers['X-HTTP-Method-Override']))
|
||||
$_SERVER['REQUEST_METHOD']=$headers['X-HTTP-Method-Override'];
|
||||
elseif ($_SERVER['REQUEST_METHOD']=='POST' && isset($_POST['_method']))
|
||||
$_SERVER['REQUEST_METHOD']=$_POST['_method'];
|
||||
$_SERVER['REQUEST_METHOD']=strtoupper($_POST['_method']);
|
||||
$scheme=isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on' ||
|
||||
isset($headers['X-Forwarded-Proto']) &&
|
||||
$headers['X-Forwarded-Proto']=='https'?'https':'http';
|
||||
@@ -2493,10 +2533,9 @@ class Cache extends Prefab {
|
||||
if (!$this->dsn)
|
||||
return TRUE;
|
||||
$ndx=$this->prefix.'.'.$key;
|
||||
$time=microtime(TRUE);
|
||||
if ($cached=$this->exists($key))
|
||||
list($time,$ttl)=$cached;
|
||||
$data=$fw->serialize([$val,$time,$ttl]);
|
||||
$ttl=$cached[1];
|
||||
$data=$fw->serialize([$val,microtime(TRUE),$ttl]);
|
||||
$parts=explode('=',$this->dsn,2);
|
||||
switch ($parts[0]) {
|
||||
case 'apc':
|
||||
@@ -2513,7 +2552,8 @@ class Cache extends Prefab {
|
||||
case 'xcache':
|
||||
return xcache_set($ndx,$data,$ttl);
|
||||
case 'folder':
|
||||
return $fw->write($parts[1].str_replace(['/','\\'],'',$ndx),$data);
|
||||
return $fw->write($parts[1].
|
||||
str_replace(['/','\\'],'',$ndx),$data);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2824,6 +2864,7 @@ class Preview extends View {
|
||||
'c'=>'$this->c',
|
||||
'esc'=>'$this->esc',
|
||||
'raw'=>'$this->raw',
|
||||
'export'=>'Base::instance()->export',
|
||||
'alias'=>'Base::instance()->alias',
|
||||
'format'=>'Base::instance()->format'
|
||||
];
|
||||
@@ -2833,7 +2874,7 @@ class Preview extends View {
|
||||
$interpolation=true;
|
||||
|
||||
/**
|
||||
* enable/disable markup parsing interpolation
|
||||
* Enable/disable markup parsing interpolation
|
||||
* mainly used for adding appropriate newlines
|
||||
* @param $bool bool
|
||||
*/
|
||||
@@ -2867,16 +2908,18 @@ class Preview extends View {
|
||||
$str,$parts)) {
|
||||
$str=trim($parts[1]);
|
||||
foreach ($fw->split(trim($parts[2],"\xC2\xA0")) as $func)
|
||||
$str=is_string($cmd=$this->filter($func))?
|
||||
$str=((empty($this->filter[$cmd=$func]) &&
|
||||
function_exists($cmd)) ||
|
||||
is_string($cmd=$this->filter($func)))?
|
||||
$cmd.'('.$str.')':
|
||||
'Base::instance()->'.
|
||||
'call($this->filter(\''.$func.'\'),['.$str.'])';
|
||||
'call($this->filter(\''.$func.'\'),['.$str.'])';
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register or get (a specific one or all) token filters
|
||||
* Register or get (one specific or all) token filters
|
||||
* @param string $key
|
||||
* @param string|closure $func
|
||||
* @return array|closure|string
|
||||
|
||||
Reference in New Issue
Block a user