Add accessor callback; Add ?? operator

This commit is contained in:
bzick
2016-06-09 13:44:43 +03:00
parent 19ba9d3031
commit 24621099bf
4 changed files with 59 additions and 15 deletions

View File

@ -844,16 +844,31 @@ class Fenom
} }
/** /**
* Add global accessor ($.) * Add global accessor as PHP code ($.)
* @param string $name * @param string $name
* @param mixed $accessor * @param mixed $accessor
* @param string $parser * @param string $parser
* @return Fenom * @return Fenom
*/ */
public function addAccessorSmart($name, $accessor, $parser) { public function addAccessorSmart($name, $accessor, $parser = self::ACCESSOR_VAR)
{
$this->_accessors[$name] = array( $this->_accessors[$name] = array(
"accessor" => $accessor, "accessor" => $accessor,
"parser" => $parser "parser" => $parser,
);
return $this;
}
/**
* Add global accessor handler as callback ($.X)
* @param string $name
* @param callable $callback
* @return Fenom
*/
public function addAccessorCallback($name, callable $callback)
{
$this->_accessors[$name] = array(
"callback" => $callback
); );
return $this; return $this;
} }
@ -872,11 +887,17 @@ class Fenom
/** /**
* Get an accessor * Get an accessor
* @param string $name * @param string $name
* @param string $key
* @return callable * @return callable
*/ */
public function getAccessor($name) { public function getAccessor($name, $key = null)
{
if(isset($this->_accessors[$name])) { if(isset($this->_accessors[$name])) {
return $this->_accessors[$name]; if($key) {
return $this->_accessors[$name][$key];
} else {
return $this->_accessors[$name];
}
} else { } else {
return false; return false;
} }
@ -888,7 +909,8 @@ class Fenom
* @param string $pattern * @param string $pattern
* @return $this * @return $this
*/ */
public function addCallFilter($pattern) { public function addCallFilter($pattern)
{
$this->call_filters[] = $pattern; $this->call_filters[] = $pattern;
return $this; return $this;
} }
@ -1029,7 +1051,7 @@ class Fenom
*/ */
protected function _load($template, $opts) protected function _load($template, $opts)
{ {
$file_name = $this->getCompilePath($template, $opts); $file_name = $this->getCompileName($template, $opts);
if (is_file($this->_compile_dir . "/" . $file_name)) { if (is_file($this->_compile_dir . "/" . $file_name)) {
$fenom = $this; // used in template $fenom = $this; // used in template
$_tpl = include($this->_compile_dir . "/" . $file_name); $_tpl = include($this->_compile_dir . "/" . $file_name);
@ -1047,11 +1069,11 @@ class Fenom
/** /**
* Generate unique name of compiled template * Generate unique name of compiled template
* *
* @param string $tpl * @param string|string[] $tpl
* @param int $options * @param int $options additional options
* @return string * @return string
*/ */
public function getCompilePath($tpl, $options = 0) public function getCompileName($tpl, $options = 0)
{ {
$options = $this->_options | $options; $options = $this->_options | $options;
if (is_array($tpl)) { if (is_array($tpl)) {
@ -1086,7 +1108,7 @@ class Fenom
} }
} }
if ($store) { if ($store) {
$cache_name = $this->getCompilePath($tpl, $options); $cache_name = $this->getCompileName($tpl, $options);
$compile_path = $this->_compile_dir . "/" . $cache_name . "." . mt_rand(0, 100000) . ".tmp"; $compile_path = $this->_compile_dir . "/" . $cache_name . "." . mt_rand(0, 100000) . ".tmp";
if(!file_put_contents($compile_path, $template->getTemplateCode())) { if(!file_put_contents($compile_path, $template->getTemplateCode())) {
throw new \RuntimeException("Can't to write to the file $compile_path. Directory " . $this->_compile_dir . " is writable?"); throw new \RuntimeException("Can't to write to the file $compile_path. Directory " . $this->_compile_dir . " is writable?");

View File

@ -964,7 +964,7 @@ class Compiler
return; return;
} }
$tokens->next(); $tokens->next();
if($tokens->is('(') || !$tokens->isNext(')')){ if ($tokens->is('(') || !$tokens->isNext(')')) {
$tokens->next(); $tokens->next();
while ($tokens->is(Tokenizer::MACRO_STRING, T_VARIABLE)) { while ($tokens->is(Tokenizer::MACRO_STRING, T_VARIABLE)) {
$param = $tokens->current(); $param = $tokens->current();

View File

@ -1003,12 +1003,18 @@ class Template extends Render
$is_var = false; $is_var = false;
if($parser) { if($parser) {
if(is_array($parser)) { if(is_array($parser)) {
return call_user_func_array($parser['parser'], array($parser['accessor'], $tokens->next(), $this, &$is_var)); if(isset($parser['callback'])) {
$tokens->next();
return 'call_user_func($tpl->getStorage()->getAccessor('.var_export($accessor, true).
', "callback"), '.var_export($accessor, true).', $tpl, $var)';
} else {
return call_user_func_array($parser['parser'], array($parser['accessor'], $tokens->next(), $this, &$is_var));
}
} else { } else {
return call_user_func_array($parser, array($tokens->next(), $this, &$is_var)); return call_user_func_array($parser, array($tokens->next(), $this, &$is_var));
} }
} else { } else {
throw new \RuntimeException("Unknown accessor '$accessor'"); throw new \RuntimeException("Unknown accessor '\$.$accessor'");
} }
} }
@ -1025,7 +1031,7 @@ class Template extends Render
{ {
$empty = $tokens->is('?'); $empty = $tokens->is('?');
$tokens->next(); $tokens->next();
if ($tokens->is(":")) { if ($tokens->is(":", "?")) {
$tokens->next(); $tokens->next();
if ($empty) { if ($empty) {
if ($is_var) { if ($is_var) {

View File

@ -256,4 +256,20 @@ class AccessorTest extends TestCase
$this->fenom->addAccessorSmart($name, $accessor, $type); $this->fenom->addAccessorSmart($name, $accessor, $type);
$this->assertRender($code, $result, $this->getVars()); $this->assertRender($code, $result, $this->getVars());
} }
/**
* @group dev
*/
public function testCallbackAccessor() {
$index = 1;
$this->fenom->addAccessorCallback('index', function($name, $template, $vars) use (&$index) {
$this->assertInstanceOf('Fenom\Render', $template);
$this->assertSame(1, $vars['one']);
$this->assertSame('index', $name);
return $index++;
});
$this->assertRender('{$.index}, {$.index}, {$.index}', '1, 2, 3', $this->getVars());
}
} }