Skip to content

Commit

Permalink
3.6.4-Release
Browse files Browse the repository at this point in the history
  • Loading branch information
ikkez committed Apr 19, 2018
1 parent 1d1fe8f commit dee4d73
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 108 deletions.
25 changes: 25 additions & 0 deletions lib/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
CHANGELOG

3.6.4 (19 April 2018)
* NEW: Added Dependency Injection support with CONTAINER variable [#221](https://github.com/bcosca/fatfree-core/issues/221)
* NEW: configurable LOGGABLE error codes [#1091](https://github.com/bcosca/fatfree/issues/1091#issuecomment-364674701)
* NEW: JAR.lifetime option, [#178](https://github.com/bcosca/fatfree-core/issues/178)
* Template: reduced Prefab calls
* Template: optimized reflection for better derivative support, [bcosca/fatfree#1088](https://github.com/bcosca/fatfree/issues/1088)
* Template: optimized parsing for template attributes and tokens
* DB\Mongo: fixed logging with mongodb extention
* DB\Jig: added lazy-loading [#7e1cd9b9b89](https://github.com/bcosca/fatfree-core/commit/7e1cd9b9b89c4175d0f6b86ced9d9bd49c04ac39)
* DB\Jig\Mapper: Added group feature, bcosca/fatfree#616
* DB\SQL\Mapper: fix PostgreSQL RETURNING ID when no pkey is available, [bcosca/fatfree#1069](https://github.com/bcosca/fatfree/issues/1069), [#230](https://github.com/bcosca/fatfree-core/issues/230)
* DB\SQL\Mapper: disable order clause auto-quoting when it's already been quoted
* Web->location: add failsafe for geoip_region_name_by_code() [#GB:Bxyn9xn9AgAJ](https://groups.google.com/d/msg/f3-framework/APau4wnwNzE/Bxyn9xn9AgAJ)
* Web->request: Added proxy support [#e936361b](https://github.com/bcosca/fatfree-core/commit/e936361bc03010c4c7c38a396562e5e96a8a100d)
* Web->mime: Added JFIF format
* Markdown: handle line breaks in paragraph blocks, [bcosca/fatfree#1100](https://github.com/bcosca/fatfree/issues/1100)
* config: reduced cast calls on parsing config sections
* Patch empty SERVER_NAME [bcosca/fatfree#1084](https://github.com/bcosca/fatfree/issues/1084)
* Bugfix: unreliable request headers in Web->request() response [bcosca/fatfree#1092](https://github.com/bcosca/fatfree/issues/1092)
* Fixed, View->render: utilizing multiple UI paths, [bcosca/fatfree#1083](https://github.com/bcosca/fatfree/issues/1083)
* Fixed URL parsing with PHP 5.4 [#247](https://github.com/bcosca/fatfree-core/issues/247)
* Fixed PHP 7.2 warnings when session is active prematurely, [#238](https://github.com/bcosca/fatfree-core/issues/238)
* Fixed setcookie $expire variable type [#240](https://github.com/bcosca/fatfree-core/issues/240)
* Fixed expiration time when updating an existing cookie

3.6.3 (31 December 2017)
* PHP7 fix: remove deprecated (unset) cast
* Web->request: restricted follow_location to 3XX responses only
Expand Down
107 changes: 73 additions & 34 deletions lib/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ final class Base extends Prefab implements ArrayAccess {
//@{ Framework details
const
PACKAGE='Fat-Free Framework',
VERSION='3.6.3-Release';
VERSION='3.6.4-Release';
//@}

//@{ HTTP status codes (RFC 2616)
Expand Down Expand Up @@ -346,17 +346,16 @@ function devoid($key,&$val=NULL) {
* @param $ttl int
**/
function set($key,$val,$ttl=0) {
$time=$this->hive['TIME'];
$time=(int)$this->hive['TIME'];
if (preg_match('/^(GET|POST|COOKIE)\b(.+)/',$key,$expr)) {
$this->set('REQUEST'.$expr[2],$val);
if ($expr[1]=='COOKIE') {
$parts=$this->cut($key);
$jar=$this->unserialize($this->serialize($this->hive['JAR']));
if (isset($_COOKIE[$parts[1]])) {
$jar['expire']=0;
unset($jar['lifetime']);
if (isset($_COOKIE[$parts[1]]))
call_user_func_array('setcookie',
array_merge([$parts[1],NULL],$jar));
}
array_merge([$parts[1],NULL],['expire'=>0]+$jar));
if ($ttl)
$jar['expire']=$time+$ttl;
call_user_func_array('setcookie',[$parts[1],$val]+$jar);
Expand Down Expand Up @@ -395,9 +394,17 @@ function set($key,$val,$ttl=0) {
$ref=&$this->ref($key);
$ref=$val;
if (preg_match('/^JAR\b/',$key)) {
$jar=$this->unserialize($this->serialize($this->hive['JAR']));
$jar['expire']-=$time;
call_user_func_array('session_set_cookie_params',$jar);
if ($key=='JAR.lifetime')
$this->set('JAR.expire',$val==0?0:
(is_int($val)?$time+$val:strtotime($val)));
else {
if ($key=='JAR.expire')
$this->hive['JAR']['lifetime']=max(0,$val-$time);
$jar=$this->unserialize($this->serialize($this->hive['JAR']));
unset($jar['expire']);
if (!headers_sent() && session_status()!=PHP_SESSION_ACTIVE)
call_user_func_array('session_set_cookie_params',$jar);
}
}
if ($ttl)
// Persist the key-value pair
Expand Down Expand Up @@ -442,6 +449,7 @@ function clear($key) {
if ($expr[1]=='COOKIE') {
$parts=$this->cut($key);
$jar=$this->hive['JAR'];
unset($jar['lifetime']);
$jar['expire']=0;
call_user_func_array('setcookie',
array_merge([$parts[1],NULL],$jar));
Expand Down Expand Up @@ -1231,11 +1239,18 @@ function error($code,$text='',array $trace=NULL,$level=0) {
$req.='?'.$this->hive['QUERY'];
if (!$text)
$text='HTTP '.$code.' ('.$req.')';
error_log($text);
$trace=$this->trace($trace);
foreach (explode("\n",$trace) as $nexus)
if ($nexus)
error_log($nexus);
$loggable=$this->hive['LOGGABLE'];
if (!is_array($loggable))
$loggable=$this->split($loggable);
foreach ($loggable as $status)
if ($status=='*' || preg_match('/^'.preg_replace('/\D/','\d',$status).'$/',$code)) {
error_log($text);
foreach (explode("\n",$trace) as $nexus)
if ($nexus)
error_log($nexus);
break;
}
if ($highlight=!$this->hive['CLI'] && !$this->hive['AJAX'] &&
$this->hive['HIGHLIGHT'] && is_file($css=__DIR__.'/'.self::CSS))
$trace=$this->highlight($trace);
Expand Down Expand Up @@ -1750,6 +1765,19 @@ function grab($func,$args=NULL) {
if ($parts[2]=='->') {
if (is_subclass_of($parts[1],'Prefab'))
$parts[1]=call_user_func($parts[1].'::instance');
elseif ($container=$this->get('CONTAINER')) {
if (is_object($container) && is_callable([$container,'has'])
&& $container->has($parts[1])) // PSR11
$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]);
else
user_error(sprintf(self::E_Class,
$this->stringify($container)),
E_USER_ERROR);
}
else {
$ref=new ReflectionClass($parts[1]);
$parts[1]=method_exists($parts[1],'__construct') && $args?
Expand Down Expand Up @@ -1888,7 +1916,8 @@ function config($source,$allow=FALSE) {
call_user_func_array(
[$this,$cmd[1]],
array_merge([$match['lval']],
str_getcsv($this->cast($match['rval'])))
str_getcsv($cmd[1]=='config'?$this->cast($match['rval']):
$match['rval']))
);
}
else {
Expand Down Expand Up @@ -2190,7 +2219,7 @@ function($level,$text,$file,$line) {
$this->error(500,$text,NULL,$level);
}
);
if (!isset($_SERVER['SERVER_NAME']))
if (!isset($_SERVER['SERVER_NAME']) || $_SERVER['SERVER_NAME']==='')
$_SERVER['SERVER_NAME']=gethostname();
if ($cli=PHP_SAPI=='cli') {
// Emulate HTTP request
Expand Down Expand Up @@ -2266,22 +2295,21 @@ function($level,$text,$file,$line) {
$base=rtrim($this->fixslashes(
dirname($_SERVER['SCRIPT_NAME'])),'/');
$uri=parse_url((preg_match('/^\w+:\/\//',$_SERVER['REQUEST_URI'])?'':
'//'.$_SERVER['SERVER_NAME']).$_SERVER['REQUEST_URI']);
$scheme.'://'.$_SERVER['SERVER_NAME']).$_SERVER['REQUEST_URI']);
$_SERVER['REQUEST_URI']=$uri['path'].
(isset($uri['query'])?'?'.$uri['query']:'').
(isset($uri['fragment'])?'#'.$uri['fragment']:'');
$path=preg_replace('/^'.preg_quote($base,'/').'/','',$uri['path']);
session_cache_limiter('');
$jar=[
'expire'=>0,
'lifetime'=>0,
'path'=>$base?:'/',
'domain'=>is_int(strpos($_SERVER['SERVER_NAME'],'.')) &&
!filter_var($_SERVER['SERVER_NAME'],FILTER_VALIDATE_IP)?
$_SERVER['SERVER_NAME']:'',
'secure'=>($scheme=='https'),
'httponly'=>TRUE
];
call_user_func_array('session_set_cookie_params',$jar);
$port=80;
if (isset($headers['X-Forwarded-Port']))
$port=$headers['X-Forwarded-Port'];
Expand Down Expand Up @@ -2328,6 +2356,7 @@ function($level,$text,$file,$line) {
$this->language($headers['Accept-Language']):
$this->fallback,
'LOCALES'=>'./',
'LOGGABLE'=>'*',
'LOGS'=>'./',
'MB'=>extension_loaded('mbstring'),
'ONERROR'=>NULL,
Expand Down Expand Up @@ -2363,6 +2392,11 @@ function($level,$text,$file,$line) {
'VERSION'=>self::VERSION,
'XFRAME'=>'SAMEORIGIN'
];
if (!headers_sent() && session_status()!=PHP_SESSION_ACTIVE) {
unset($jar['expire']);
session_cache_limiter('');
call_user_func_array('session_set_cookie_params',$jar);
}
if (PHP_SAPI=='cli-server' &&
preg_match('/^'.preg_quote($base,'/').'$/',$this->hive['URI']))
$this->reroute('/');
Expand Down Expand Up @@ -2673,16 +2707,22 @@ class View extends Prefab {
//! Nesting level
$level=0;

/** @var \Base Framework instance */
protected $fw;

function __construct() {
$this->fw=\Base::instance();
}

/**
* Encode characters to equivalent HTML entities
* @return string
* @param $arg mixed
**/
function esc($arg) {
$fw=Base::instance();
return $fw->recursive($arg,
function($val) use($fw) {
return is_string($val)?$fw->encode($val):$val;
return $this->fw->recursive($arg,
function($val) {
return is_string($val)?$this->fw->encode($val):$val;
}
);
}
Expand All @@ -2693,10 +2733,9 @@ function($val) use($fw) {
* @param $arg mixed
**/
function raw($arg) {
$fw=Base::instance();
return $fw->recursive($arg,
function($val) use($fw) {
return is_string($val)?$fw->decode($val):$val;
return $this->fw->recursive($arg,
function($val) {
return is_string($val)?$this->fw->decode($val):$val;
}
);
}
Expand All @@ -2708,7 +2747,7 @@ function($val) use($fw) {
* @param $mime string
**/
protected function sandbox(array $hive=NULL,$mime=NULL) {
$fw=Base::instance();
$fw=$this->fw;
$implicit=FALSE;
if (is_null($hive)) {
$implicit=TRUE;
Expand Down Expand Up @@ -2744,9 +2783,9 @@ protected function sandbox(array $hive=NULL,$mime=NULL) {
* @param $ttl int
**/
function render($file,$mime='text/html',array $hive=NULL,$ttl=0) {
$fw=Base::instance();
$fw=$this->fw;
$cache=Cache::instance();
foreach ($fw->split($fw->UI) as $dir)
foreach ($fw->split($fw->UI) as $dir) {
if ($cache->exists($hash=$fw->hash($dir.$file),$data))
return $data;
if (is_file($this->file=$fw->fixslashes($dir.$file))) {
Expand All @@ -2762,6 +2801,7 @@ function render($file,$mime='text/html',array $hive=NULL,$ttl=0) {
$cache->set($hash,$data,$ttl);
return $data;
}
}
user_error(sprintf(Base::E_Open,$file),E_USER_ERROR);
}

Expand Down Expand Up @@ -2807,7 +2847,6 @@ function interpolation($bool) {
* @param $val int|float
**/
function c($val) {
$fw=Base::instance();
$locale=setlocale(LC_NUMERIC,0);
setlocale(LC_NUMERIC,'C');
$out=(string)(float)$val;
Expand All @@ -2821,13 +2860,13 @@ function c($val) {
* @param $str string
**/
function token($str) {
$fw = Base::instance();
$fw=$this->fw;
$str=trim(preg_replace('/\{\{(.+?)\}\}/s',trim('\1'),
$fw->compile($str)));
if (preg_match('/^(.+)(?<!\|)\|((?:\h*\w+(?:\h*[,;]?))+)$/s',
$str,$parts)) {
$str=trim($parts[1]);
foreach ($fw->split($parts[2]) as $func)
foreach ($fw->split(trim($parts[2],"\xC2\xA0")) as $func)
$str=is_string($cmd=$this->filter($func))?
$cmd.'('.$str.')':
'Base::instance()->'.
Expand Down Expand Up @@ -2890,7 +2929,7 @@ function($expr) {
* @param $escape bool
**/
function resolve($node,array $hive=NULL,$ttl=0,$persist=FALSE,$escape=NULL) {
$fw=Base::instance();
$fw=$this->fw;
$cache=Cache::instance();
if ($escape!==NULL) {
$esc=$fw->ESCAPE;
Expand Down Expand Up @@ -2951,7 +2990,7 @@ function parse($text) {
* @param $ttl int
**/
function render($file,$mime='text/html',array $hive=NULL,$ttl=0) {
$fw=Base::instance();
$fw=$this->fw;
$cache=Cache::instance();
if (!is_dir($tmp=$fw->TEMP))
mkdir($tmp,Base::MODE,TRUE);
Expand Down
24 changes: 21 additions & 3 deletions lib/db/jig.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ class Jig {
//! Jig log
$log,
//! Memory-held data
$data;
$data,
//! lazy load/save files
$lazy;

/**
* Read data from memory/file
Expand All @@ -54,6 +56,8 @@ function &read($file) {
$this->data[$file]=[];
return $this->data[$file];
}
if ($this->lazy && isset($this->data[$file]))
return $this->data[$file];
$fw=\Base::instance();
$raw=$fw->read($dst);
switch ($this->format) {
Expand All @@ -75,7 +79,7 @@ function &read($file) {
* @param $data array
**/
function write($file,array $data=NULL) {
if (!$this->dir)
if (!$this->dir || $this->lazy)
return count($this->data[$file]=$data);
$fw=\Base::instance();
switch ($this->format) {
Expand Down Expand Up @@ -131,6 +135,8 @@ function jot($frame) {
* @return NULL
**/
function drop() {
if ($this->lazy) // intentional
$this->data=[];
if (!$this->dir)
$this->data=[];
elseif ($glob=@glob($this->dir.'/*',GLOB_NOSORT))
Expand All @@ -147,11 +153,23 @@ private function __clone() {
* @param $dir string
* @param $format int
**/
function __construct($dir=NULL,$format=self::FORMAT_JSON) {
function __construct($dir=NULL,$format=self::FORMAT_JSON,$lazy=FALSE) {
if ($dir && !is_dir($dir))
mkdir($dir,\Base::MODE,TRUE);
$this->uuid=\Base::instance()->hash($this->dir=$dir);
$this->format=$format;
$this->lazy=$lazy;
}

/**
* save file on destruction
**/
function __destruct() {
if ($this->lazy) {
$this->lazy = FALSE;
foreach ($this->data as $file => $data)
$this->write($file,$data);
}
}

}
Loading

0 comments on commit dee4d73

Please sign in to comment.