mirror of
https://github.com/fenom-template/fenom.git
synced 2023-08-10 21:13:07 +03:00
Big update
This commit is contained in:
parent
b2f2e61be4
commit
ee9cd9b746
@ -234,7 +234,7 @@ class Aspect {
|
||||
*/
|
||||
public static function factory($source, $compile_dir = '/tmp', $options = 0) {
|
||||
if(is_string($source)) {
|
||||
$provider = new \Aspect\Provider\FS($source);
|
||||
$provider = new \Aspect\FSProvider($source);
|
||||
} elseif($source instanceof Aspect\ProviderInterface) {
|
||||
$provider = $source;
|
||||
} else {
|
||||
@ -464,7 +464,7 @@ class Aspect {
|
||||
*/
|
||||
public function setOptions($options) {
|
||||
if(is_array($options)) {
|
||||
$options = Aspect\Misc::makeMask($options, self::$_option_list);
|
||||
$options = self::_makeMask($options, self::$_option_list);
|
||||
}
|
||||
$this->_storage = array();
|
||||
$this->_options = $options;
|
||||
@ -652,4 +652,28 @@ class Aspect {
|
||||
return Template::factory($this)->source($name, $code);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create bit-mask from associative array use fully associative array possible keys with bit values
|
||||
* @static
|
||||
* @param array $values custom assoc array, ["a" => true, "b" => false]
|
||||
* @param array $options possible values, ["a" => 0b001, "b" => 0b010, "c" => 0b100]
|
||||
* @param int $mask the initial value of the mask
|
||||
* @return int result, ( $mask | a ) & ~b
|
||||
* @throws \RuntimeException if key from custom assoc doesn't exists into possible values
|
||||
*/
|
||||
private static function _makeMask(array $values, array $options, $mask = 0) {
|
||||
foreach($values as $value) {
|
||||
if(isset($options[$value])) {
|
||||
if($options[$value]) {
|
||||
$mask |= $options[$value];
|
||||
} else {
|
||||
$mask &= ~$options[$value];
|
||||
}
|
||||
} else {
|
||||
throw new \RuntimeException("Undefined parameter $value");
|
||||
}
|
||||
}
|
||||
return $mask;
|
||||
}
|
||||
}
|
||||
|
@ -661,4 +661,53 @@ class Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import macros from templates
|
||||
*
|
||||
* @param Tokenizer $tokens
|
||||
* @param Template $tpl
|
||||
* @return string
|
||||
* @throws ImproperUseException
|
||||
*/
|
||||
public static function tagImport(Tokenizer $tokens, Template $tpl) {
|
||||
$tpl->parseFirstArg($tokens, $name);
|
||||
if(!$name) {
|
||||
throw new ImproperUseException("Invalid usage tag {import}");
|
||||
}
|
||||
$donor = $tpl->getStorage()->getRawTemplate()->load($name, true);
|
||||
if(!empty($donor->_macros)) {
|
||||
$tpl->_macros = array_merge($tpl->_macros, $donor->_macros);
|
||||
$tpl->addDepend($donor);
|
||||
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare or invoke macros
|
||||
*
|
||||
* @param Tokenizer $tokens
|
||||
* @param Scope $scope
|
||||
* @return string
|
||||
*/
|
||||
public static function macrosOpen(Tokenizer $tokens, Scope $scope) {
|
||||
$tokens->get('.');
|
||||
$name = $tokens->get(Tokenizer::MACRO_STRING);
|
||||
if($tokens->is('(')) {
|
||||
$tokens->skip();
|
||||
|
||||
return '';
|
||||
} elseif(isset($scope->tpl->_macros[$name])) {
|
||||
$p = $scope->tpl->parseParams($tokens);
|
||||
$scope->closed = true;
|
||||
return '$_tpl = $tpl; $tpl = '.self::_toArray($p).' + '.$scope->tpl->_macros[$name]["defaults"].'; '.$scope->tpl->_macros[$name]["body"].'; $tpl = $_tpl; unset($_tpl);';
|
||||
} else {
|
||||
throw new ImproperUseException("Unknown tag or macros {{$name}}");
|
||||
}
|
||||
}
|
||||
|
||||
public static function macrosClose(Tokenizer $tokens, Scope $scope) {
|
||||
$scope->tpl->_macros[ $scope["name"] ] = $scope->getContent();
|
||||
}
|
||||
|
||||
}
|
||||
|
129
src/Aspect/FSProvider.php
Normal file
129
src/Aspect/FSProvider.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace Aspect;
|
||||
|
||||
use Aspect\ProviderInterface;
|
||||
/**
|
||||
* Templates provider
|
||||
* @author Ivan Shalganov
|
||||
*/
|
||||
class FSProvider implements ProviderInterface {
|
||||
private $_path;
|
||||
|
||||
/**
|
||||
* Clean directory from files
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public static function clean($path) {
|
||||
if(is_file($path)) {
|
||||
unlink($path);
|
||||
} elseif(is_dir($path)) {
|
||||
$iterator = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path,
|
||||
\FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST));
|
||||
foreach($iterator as $file) {
|
||||
/* @var \splFileInfo $file*/
|
||||
if($file->isFile()) {
|
||||
if(strpos($file->getBasename(), ",") !== 0) {
|
||||
unlink($file->getRealPath());
|
||||
}
|
||||
} elseif($file->isDir()) {
|
||||
rmdir($file->getRealPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive remove directory
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public static function rm($path) {
|
||||
self::clean($path);
|
||||
if(is_dir($path)) {
|
||||
rmdir($path);
|
||||
}
|
||||
}
|
||||
|
||||
public static function put($path, $content) {
|
||||
file_put_contents($path, $content);
|
||||
}
|
||||
|
||||
public function __construct($template_dir) {
|
||||
if($_dir = realpath($template_dir)) {
|
||||
$this->_path = $_dir;
|
||||
} else {
|
||||
throw new \LogicException("Template directory {$template_dir} doesn't exists");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tpl
|
||||
* @param int $time
|
||||
* @return string
|
||||
*/
|
||||
public function getSource($tpl, &$time) {
|
||||
$tpl = $this->_getTemplatePath($tpl);
|
||||
clearstatcache(null, $tpl);
|
||||
$time = filemtime($tpl);
|
||||
return file_get_contents($tpl);
|
||||
}
|
||||
|
||||
public function getLastModified($tpl) {
|
||||
clearstatcache(null, $tpl = $this->_getTemplatePath($tpl));
|
||||
return filemtime($tpl);
|
||||
}
|
||||
|
||||
public function getList() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template path
|
||||
* @param $tpl
|
||||
* @return string
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function _getTemplatePath($tpl) {
|
||||
if(($path = realpath($this->_path."/".$tpl)) && strpos($path, $this->_path) === 0) {
|
||||
return $path;
|
||||
} else {
|
||||
throw new \RuntimeException("Template $tpl not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tpl
|
||||
* @return bool
|
||||
*/
|
||||
public function isTemplateExists($tpl) {
|
||||
return file_exists($this->_path."/".$tpl);
|
||||
}
|
||||
|
||||
public function getLastModifiedBatch($tpls) {
|
||||
$tpls = array_flip($tpls);
|
||||
foreach($tpls as $tpl => &$time) {
|
||||
$time = $this->getLastModified($tpl);
|
||||
}
|
||||
return $tpls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify templates by change time
|
||||
*
|
||||
* @param array $templates [template_name => modified, ...] By conversation you may trust the template's name
|
||||
* @return bool
|
||||
*/
|
||||
public function verify(array $templates) {
|
||||
foreach($templates as $template => $mtime) {
|
||||
clearstatcache(null, $template = $this->_path.'/'.$template);
|
||||
if(@filemtime($template) !== $mtime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
namespace Aspect;
|
||||
|
||||
class Func {
|
||||
public static function mailto($params) {
|
||||
if(empty($params["address"])) {
|
||||
trigger_error(E_USER_WARNING, "Modifier mailto: paramenter 'address' required");
|
||||
return "";
|
||||
}
|
||||
|
||||
if(empty($params["text"])) {
|
||||
$params["text"] = $params["address"];
|
||||
}
|
||||
|
||||
return '<a href="mailto:'.$params["address"].'">'.$params["text"].'</a>';
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
<?php
|
||||
namespace Aspect;
|
||||
|
||||
|
||||
class Misc {
|
||||
|
||||
/**
|
||||
* Create bit-mask from associative array use fully associative array possible keys with bit values
|
||||
* @static
|
||||
* @param array $values custom assoc array, ["a" => true, "b" => false]
|
||||
* @param array $options possible values, ["a" => 0b001, "b" => 0b010, "c" => 0b100]
|
||||
* @param int $mask the initial value of the mask
|
||||
* @return int result, ( $mask | a ) & ~b
|
||||
* @throws \RuntimeException if key from custom assoc doesn't exists into possible values
|
||||
*/
|
||||
public static function makeMask(array $values, array $options, $mask = 0) {
|
||||
foreach($values as $value) {
|
||||
if(isset($options[$value])) {
|
||||
if($options[$value]) {
|
||||
$mask |= $options[$value];
|
||||
} else {
|
||||
$mask &= ~$options[$value];
|
||||
}
|
||||
} else {
|
||||
throw new \RuntimeException("Undefined parameter $value");
|
||||
}
|
||||
}
|
||||
return $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean directory from files
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public static function clean($path) {
|
||||
if(is_file($path)) {
|
||||
unlink($path);
|
||||
} elseif(is_dir($path)) {
|
||||
$iterator = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path,
|
||||
\FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST));
|
||||
foreach($iterator as $file) {
|
||||
/* @var \splFileInfo $file*/
|
||||
if($file->isFile()) {
|
||||
if(strpos($file->getBasename(), ",") !== 0) {
|
||||
unlink($file->getRealPath());
|
||||
}
|
||||
} elseif($file->isDir()) {
|
||||
rmdir($file->getRealPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive remove directory
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public static function rm($path) {
|
||||
self::clean($path);
|
||||
if(is_dir($path)) {
|
||||
rmdir($path);
|
||||
}
|
||||
}
|
||||
|
||||
public static function put($path, $content) {
|
||||
file_put_contents($path, $content);
|
||||
}
|
||||
}
|
@ -1,19 +1,43 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Aspect.
|
||||
*
|
||||
* (c) 2013 Ivan Shalganov
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Aspect;
|
||||
|
||||
|
||||
/**
|
||||
* Collection of modifiers
|
||||
*
|
||||
* @package aspect
|
||||
* @author Ivan Shalganov <owner@bzick.net>
|
||||
*/
|
||||
class Modifier {
|
||||
|
||||
public static function dateFormat($date, $format = "%b %e, %Y") {
|
||||
/**
|
||||
* Date format
|
||||
*
|
||||
* @param string|int $date
|
||||
* @param string $format
|
||||
* @return string
|
||||
*/
|
||||
public static function dateFormat($date, $format = "%b %e, %Y") {
|
||||
if(is_string($date) && !is_numeric($date)) {
|
||||
$date = strtotime($date);
|
||||
if(!$date) $date = time();
|
||||
}
|
||||
//dump($format, $date);
|
||||
return strftime($format, $date);
|
||||
}
|
||||
|
||||
public static function date($date, $format = "Y m d") {
|
||||
/**
|
||||
* @param string $date
|
||||
* @param string $format
|
||||
* @return string
|
||||
*/
|
||||
public static function date($date, $format = "Y m d") {
|
||||
if(is_string($date) && !is_numeric($date)) {
|
||||
$date = strtotime($date);
|
||||
if(!$date) $date = time();
|
||||
@ -21,6 +45,13 @@ class Modifier {
|
||||
return date($format, $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape string
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
public static function escape($text, $type = 'html') {
|
||||
switch($type) {
|
||||
case "url":
|
||||
@ -32,7 +63,14 @@ class Modifier {
|
||||
}
|
||||
}
|
||||
|
||||
public static function unescape($text, $type = 'html') {
|
||||
/**
|
||||
* Unescape escaped string
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
public static function unescape($text, $type = 'html') {
|
||||
switch($type) {
|
||||
case "url":
|
||||
return urldecode($text);
|
||||
@ -43,10 +81,14 @@ class Modifier {
|
||||
}
|
||||
}
|
||||
|
||||
public static function defaultValue(&$value, $default = null) {
|
||||
return ($value === null) ? $default : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param int $length
|
||||
* @param string $etc
|
||||
* @param bool $break_words
|
||||
* @param bool $middle
|
||||
* @return string
|
||||
*/
|
||||
public static function truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
|
||||
$length -= min($length, strlen($etc));
|
||||
if (!$break_words && !$middle) {
|
||||
@ -73,4 +115,18 @@ class Modifier {
|
||||
return preg_replace('#[ \t]{2,}#', ' ', $str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $item
|
||||
* @return int
|
||||
*/
|
||||
public static function length($item) {
|
||||
if(is_scalar($item)) {
|
||||
return strlen($item);
|
||||
} elseif (is_array($item)) {
|
||||
return count($item);
|
||||
} else {
|
||||
return count((array)$item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,71 +0,0 @@
|
||||
<?php
|
||||
namespace Aspect\Provider;
|
||||
|
||||
use Aspect\ProviderInterface;
|
||||
/**
|
||||
* Templates provider
|
||||
* @author Ivan Shalganov
|
||||
*/
|
||||
class FS implements ProviderInterface {
|
||||
private $_path;
|
||||
|
||||
public function __construct($template_dir) {
|
||||
if($_dir = realpath($template_dir)) {
|
||||
$this->_path = $_dir;
|
||||
} else {
|
||||
throw new \LogicException("Template directory {$template_dir} doesn't exists");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $tpl
|
||||
* @param int $time
|
||||
* @return string
|
||||
*/
|
||||
public function getSource($tpl, &$time) {
|
||||
$tpl = $this->_getTemplatePath($tpl);
|
||||
clearstatcache(null, $tpl);
|
||||
$time = filemtime($tpl);
|
||||
return file_get_contents($tpl);
|
||||
}
|
||||
|
||||
public function getLastModified($tpl) {
|
||||
clearstatcache(null, $tpl = $this->_getTemplatePath($tpl));
|
||||
return filemtime($tpl);
|
||||
}
|
||||
|
||||
public function getList() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template path
|
||||
* @param $tpl
|
||||
* @return string
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function _getTemplatePath($tpl) {
|
||||
if(($path = realpath($this->_path."/".$tpl)) && strpos($path, $this->_path) === 0) {
|
||||
return $path;
|
||||
} else {
|
||||
throw new \RuntimeException("Template $tpl not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tpl
|
||||
* @return bool
|
||||
*/
|
||||
public function isTemplateExists($tpl) {
|
||||
return file_exists($this->_path."/".$tpl);
|
||||
}
|
||||
|
||||
public function getLastModifiedBatch($tpls) {
|
||||
$tpls = array_flip($tpls);
|
||||
foreach($tpls as $tpl => &$time) {
|
||||
$time = $this->getLastModified($tpl);
|
||||
}
|
||||
return $tpls;
|
||||
}
|
||||
}
|
@ -20,7 +20,13 @@ interface ProviderInterface {
|
||||
*/
|
||||
public function getLastModified($tpl);
|
||||
|
||||
public function getLastModifiedBatch($tpls);
|
||||
/**
|
||||
* Verify templates by change time
|
||||
*
|
||||
* @param array $templates [template_name => modified, ...] By conversation you may trust the template's name
|
||||
* @return bool
|
||||
*/
|
||||
public function verify(array $templates);
|
||||
|
||||
/**
|
||||
* @return array
|
||||
|
@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Aspect.
|
||||
*
|
||||
* (c) 2013 Ivan Shalganov
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Aspect;
|
||||
|
||||
use Aspect;
|
||||
|
||||
/**
|
||||
* Aspect template compiler
|
||||
* Template compiler
|
||||
*
|
||||
* @package aspect
|
||||
* @author Ivan Shalganov <owner@bzick.net>
|
||||
*/
|
||||
class Template extends Render {
|
||||
|
||||
@ -303,7 +313,7 @@ class Template extends Render {
|
||||
$this->_ignore = true;
|
||||
$tokens->next();
|
||||
$code = '';
|
||||
} else {
|
||||
} else {
|
||||
$code = $this->_parseAct($tokens);
|
||||
}
|
||||
}
|
||||
@ -326,6 +336,7 @@ class Template extends Render {
|
||||
|
||||
/**
|
||||
* Close tag handler
|
||||
*
|
||||
* @param Tokenizer $tokens
|
||||
* @return mixed
|
||||
* @throws TokenizeException
|
||||
@ -358,14 +369,14 @@ class Template extends Render {
|
||||
if($tokens->is(Tokenizer::MACRO_STRING)) {
|
||||
$action = $tokens->current();
|
||||
} else {
|
||||
return 'echo '.$this->parseExp($tokens).';';
|
||||
return 'echo '.$this->parseExp($tokens).';'; // may be math and boolean expression
|
||||
}
|
||||
|
||||
if($tokens->isNext("(")) {
|
||||
if($tokens->isNext("(", T_NAMESPACE, T_DOUBLE_COLON)) { // just invoke function or static method
|
||||
return "echo ".$this->parseExp($tokens).";";
|
||||
}
|
||||
|
||||
if($act = $this->_aspect->getFunction($action)) {
|
||||
if($act = $this->_aspect->getFunction($action)) { // call some function
|
||||
$tokens->next();
|
||||
switch($act["type"]) {
|
||||
case Aspect::BLOCK_COMPILER:
|
||||
@ -386,19 +397,32 @@ class Template extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
for($j = $i = count($this->_stack)-1; $i>=0; $i--) {
|
||||
for($j = $i = count($this->_stack)-1; $i>=0; $i--) { // call function's internal tag
|
||||
if($this->_stack[$i]->hasTag($action, $j - $i)) {
|
||||
$tokens->next();
|
||||
return $this->_stack[$i]->tag($action, $tokens);
|
||||
}
|
||||
}
|
||||
if($tags = $this->_aspect->getTagOwners($action)) {
|
||||
if($tags = $this->_aspect->getTagOwners($action)) { // unknown template tag
|
||||
throw new TokenizeException("Unexpected tag '$action' (this tag can be used with '".implode("', '", $tags)."')");
|
||||
} else {
|
||||
throw new TokenizeException("Unexpected tag $action");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tokenizer $tokens
|
||||
*/
|
||||
private function _parseMacros(Tokenizer $tokens) {
|
||||
$tokens->get('.');
|
||||
$name = $tokens->get(Tokenizer::MACRO_STRING);
|
||||
if($tokens->is('(')) {
|
||||
$tokens->skip();
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse expressions. The mix of math operations, boolean operations, scalars, arrays and variables.
|
||||
*
|
||||
@ -610,9 +634,9 @@ class Template extends Render {
|
||||
}
|
||||
$expr2 = $this->parseExp($tokens, true);
|
||||
if($empty) {
|
||||
return '(empty('.$_var.') ? '.$expr2.' : '.$expr1;
|
||||
return '(empty('.$_var.') ? '.$expr2.' : '.$expr1.')';
|
||||
} else {
|
||||
return '(isset('.$_var.') ? '.$expr1.' : '.$expr2;
|
||||
return '(isset('.$_var.') ? '.$expr1.' : '.$expr2.')';
|
||||
}
|
||||
}
|
||||
} elseif($t === "!") {
|
||||
@ -676,11 +700,42 @@ class Template extends Render {
|
||||
$_str .= $tokens->current();
|
||||
$tokens->next();
|
||||
} elseif($t === T_VARIABLE) {
|
||||
$_str .= '".$tpl["'.substr($tokens->current(), 1).'"]."';
|
||||
if(strlen($_str) > 1) {
|
||||
$_str .= '".';
|
||||
} else {
|
||||
$_str = "";
|
||||
}
|
||||
$_str .= '$tpl["'.substr($tokens->current(), 1).'"]';
|
||||
$tokens->next();
|
||||
if($tokens->is($stop)) {
|
||||
$tokens->skip();
|
||||
return $_str;
|
||||
} else {
|
||||
$_str .= '."';
|
||||
}
|
||||
} elseif($t === T_CURLY_OPEN) {
|
||||
if(strlen($_str) > 1) {
|
||||
$_str .= '".';
|
||||
} else {
|
||||
$_str = "";
|
||||
}
|
||||
$tokens->getNext(T_VARIABLE);
|
||||
$_str .= '".('.$this->parseExp($tokens).')."';
|
||||
$_str .= '('.$this->parseExp($tokens).')';
|
||||
/*if(!$tokens->valid()) {
|
||||
$more = $this->_getMoreSubstr($stop);
|
||||
//var_dump($more); exit;
|
||||
$tokens->append("}".$more, $p);
|
||||
var_dump("Curly", $more, $tokens->getSnippetAsString());
|
||||
exit;
|
||||
}*/
|
||||
|
||||
//$tokens->skip('}');
|
||||
if($tokens->is($stop)) {
|
||||
$tokens->next();
|
||||
return $_str;
|
||||
} else {
|
||||
$_str .= '."';
|
||||
}
|
||||
} elseif($t === "}") {
|
||||
$tokens->next();
|
||||
} elseif($t === $stop) {
|
||||
|
@ -1,4 +1,12 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Aspect.
|
||||
*
|
||||
* (c) 2013 Ivan Shalganov
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Aspect;
|
||||
|
||||
defined('T_INSTEADOF') || define('T_INSTEADOF', 341);
|
||||
@ -16,6 +24,9 @@ defined('T_TRAIT_C') || define('T_TRAIT_C', 365);
|
||||
* @property array $prev the previous token
|
||||
* @property array $curr the current token
|
||||
* @property array $next the next token
|
||||
*
|
||||
* @package aspect
|
||||
* @author Ivan Shalganov <owner@bzick.net>
|
||||
*/
|
||||
class Tokenizer {
|
||||
const TOKEN = 0;
|
||||
@ -363,6 +374,10 @@ class Tokenizer {
|
||||
}
|
||||
}
|
||||
|
||||
public function count() {
|
||||
return $this->_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key of the current element
|
||||
* @return mixed scalar on success, or null on failure.
|
||||
@ -522,8 +537,9 @@ class Tokenizer {
|
||||
|
||||
/**
|
||||
* Parse code and append tokens. This method move pointer to offset.
|
||||
*
|
||||
* @param string $code
|
||||
* @param int $offset
|
||||
* @param int $offset if not -1 replace tokens from position $offset
|
||||
* @return Tokenizer
|
||||
*/
|
||||
public function append($code, $offset = -1) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
namespace Aspect;
|
||||
use Aspect;
|
||||
use Aspect, Aspect\FSProvider as FS;
|
||||
|
||||
class TestCase extends \PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
@ -12,7 +12,7 @@ class TestCase extends \PHPUnit_Framework_TestCase {
|
||||
if(!file_exists(ASPECT_RESOURCES.'/compile')) {
|
||||
mkdir(ASPECT_RESOURCES.'/compile', 0777, true);
|
||||
} else {
|
||||
Misc::clean(ASPECT_RESOURCES.'/compile/');
|
||||
FS::clean(ASPECT_RESOURCES.'/compile/');
|
||||
}
|
||||
$this->aspect = Aspect::factory(ASPECT_RESOURCES.'/template', ASPECT_RESOURCES.'/compile');
|
||||
}
|
||||
@ -21,7 +21,7 @@ class TestCase extends \PHPUnit_Framework_TestCase {
|
||||
if(!file_exists(ASPECT_RESOURCES.'/template')) {
|
||||
mkdir(ASPECT_RESOURCES.'/template', 0777, true);
|
||||
} else {
|
||||
Misc::clean(ASPECT_RESOURCES.'/template/');
|
||||
FS::clean(ASPECT_RESOURCES.'/template/');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ class ExtendsTemplateTest extends TestCase {
|
||||
* @param $vars
|
||||
* @param $result
|
||||
*/
|
||||
public function testDynamicExtends($name, $code, $vars, $result) {
|
||||
public function _testDynamicExtends($name, $code, $vars, $result) {
|
||||
static $i = 0;
|
||||
$vars["iteration"] = $i++;
|
||||
$this->execTpl($name, $code, $vars, $result);
|
||||
@ -60,7 +60,7 @@ class ExtendsTemplateTest extends TestCase {
|
||||
/**
|
||||
* @group extends
|
||||
*/
|
||||
public function _testChildLevel1() {
|
||||
public function testChildLevel1() {
|
||||
//echo($this->aspect->fetch("child1.tpl", array("a" => "a char"))); exit;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
<?php
|
||||
namespace Aspect\Provider;
|
||||
namespace Aspect;
|
||||
use Aspect;
|
||||
|
||||
class FSTest extends \Aspect\TestCase {
|
||||
class FSProviderTest extends \Aspect\TestCase {
|
||||
/**
|
||||
* @var Provider
|
||||
* @var FSProvider
|
||||
*/
|
||||
public $provider;
|
||||
|
||||
@ -12,7 +12,7 @@ class FSTest extends \Aspect\TestCase {
|
||||
parent::setUp();
|
||||
$this->tpl("template1.tpl", 'Template 1 {$a}');
|
||||
$this->tpl("template2.tpl", 'Template 2 {$a}');
|
||||
$this->provider = new FS(ASPECT_RESOURCES.'/template');
|
||||
$this->provider = new FSProvider(ASPECT_RESOURCES.'/template');
|
||||
}
|
||||
|
||||
public function testIsTemplateExists() {
|
@ -15,6 +15,10 @@ class TemplateTest extends TestCase {
|
||||
)));
|
||||
}
|
||||
|
||||
/*public function testSandbox() {
|
||||
var_dump($this->aspect->compileCode('{"$s:{$b+1}f d {$d}"}')->_body);
|
||||
exit;
|
||||
}*/
|
||||
|
||||
public static function providerVars() {
|
||||
$a = array("a" => "World");
|
||||
@ -69,6 +73,42 @@ class TemplateTest extends TestCase {
|
||||
);
|
||||
}
|
||||
|
||||
public static function providerScalars() {
|
||||
return array(
|
||||
array('77', 77),
|
||||
array('-33', -33),
|
||||
array('0.2', 0.2),
|
||||
array('-0.3', -0.3),
|
||||
array('1e6', 1e6),
|
||||
array('-2e6', -2e6),
|
||||
array('"str"', 'str'),
|
||||
array('"str\nand\nmany\nlines"', "str\nand\nmany\nlines"),
|
||||
array('"str and \'substr\'"', "str and 'substr'"),
|
||||
array('"str and \"substr\""', 'str and "substr"'),
|
||||
array("'str'", 'str'),
|
||||
array("'str\\nin\\none\\nline'", 'str\nin\none\nline'),
|
||||
array("'str and \"substr\"'", 'str and "substr"'),
|
||||
array("'str and \'substr\''", "str and 'substr'"),
|
||||
array('"$one"', '1'),
|
||||
array('"$one $two"', '1 2'),
|
||||
array('"$one and $two"', '1 and 2'),
|
||||
array('"a $one and $two b"', 'a 1 and 2 b'),
|
||||
array('"{$one}"', '1'),
|
||||
array('"a {$one} b"', 'a 1 b'),
|
||||
array('"{$one + 2}"', '3'),
|
||||
array('"{$one * $two + 1}"', '3'),
|
||||
array('"{$one} and {$two}"', '1 and 2'),
|
||||
array('"$one and {$two}"', '1 and 2'),
|
||||
array('"{$one} and $two"', '1 and 2'),
|
||||
array('"a {$one} and {$two} b"', 'a 1 and 2 b'),
|
||||
array('"{$one+1} and {$two-1}"', '2 and 1'),
|
||||
array('"a {$one+1} and {$two-1} b"', 'a 2 and 1 b'),
|
||||
array('"a {$one|dots} and {$two|dots} b"', 'a 1... and 2... b'),
|
||||
array('"a {$one|dots} and $two b"', 'a 1... and 2 b'),
|
||||
array('"a $one and {$two|dots} b"', 'a 1 and 2... b'),
|
||||
);
|
||||
}
|
||||
|
||||
public static function providerVarsInvalid() {
|
||||
return array(
|
||||
array('hello, {$a.}!', 'Aspect\CompileException', "Unexpected end of expression"),
|
||||
|
Loading…
Reference in New Issue
Block a user