"require": {
"pear/archive_tar": "1.3.*",
"mustangostang/spyc": "0.5.*",
- "andy128k/routeexpression": "dev-master"
+ "andy128k/routeexpression": "dev-master",
+ "andy128k/ipf-template": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
- "hash": "e0cb33c2f8ad49fa19a176a18d6a2285",
+ "hash": "e5ea80198a9aa0bc5288cbdbe34949e7",
"packages": [
+ {
+ "name": "andy128k/ipf-template",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/andy128k/ipf-template.git",
+ "reference": "9b00d636be5db7b6147fd6f6899068f26b8e17b1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/andy128k/ipf-template/zipball/9b00d636be5db7b6147fd6f6899068f26b8e17b1",
+ "reference": "9b00d636be5db7b6147fd6f6899068f26b8e17b1",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpunit/phpunit": "3.7.*"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "lib"
+ ]
+ },
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alex Litovchenko",
+ "email": "alex.litovchenko@gmail.com"
+ },
+ {
+ "name": "Andrey Kutejko",
+ "email": "andy128k@gmail.com"
+ }
+ ],
+ "description": "Template Engine extracted from IPF Web Framework",
+ "support": {
+ "source": "https://github.com/andy128k/ipf-template/tree/master",
+ "issues": "https://github.com/andy128k/ipf-template/issues"
+ },
+ "time": "2013-07-30 22:13:38"
+ },
{
"name": "andy128k/routeexpression",
"version": "dev-master",
},
{
"name": "phpunit/php-token-stream",
- "version": "1.1.5",
+ "version": "1.1.7",
"source": {
"type": "git",
- "url": "git://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "1.1.5"
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "1.1.7"
},
"dist": {
"type": "zip",
- "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5",
- "reference": "1.1.5",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1.1.7",
+ "reference": "1.1.7",
"shasum": ""
},
"require": {
}
],
"description": "Wrapper around PHP's tokenizer extension.",
- "homepage": "http://www.phpunit.de/",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
"tokenizer"
],
- "time": "2012-10-11 04:47:14"
+ "time": "2013-07-29 14:27:06"
},
{
"name": "phpunit/phpunit",
],
"minimum-stability": "stable",
"stability-flags": {
- "andy128k/routeexpression": 20
+ "andy128k/routeexpression": 20,
+ "andy128k/ipf-template": 20
},
"platform": [
** Tags
-*** print
- Syntax: ={<expr>[modifiers]?}=
-
- Outputs expression.
-
-*** if/elseif/else
- Syntax: ={if <condition>}= <body> [ ={elseif <condition>}= <body> ]* [ ={else}= <body> ]? ={/if}=
-
-*** while
- Syntax: ={while <condition>}= <body> ={/while}=
-
-*** foreach
- Syntax: ~{foreach <collection> as [<key> =>]? <value>}~ <body> ~{/foreach}~
-
- Iterate over collection.
-
- Following variables are defined in a loop body:
- + =foreach_counter0= -- zero based iteration counter
- + =foreach_counter1= -- unit based iteration counter
- + =foreach_first= -- is true on first iteration and false on the rest ones.
-
-*** assign
- Syntax: ={assign <var> <eq-op> <expr>}=
-
- Example: ~{assing $v += 1}~
-
-*** literal
- Syntax: ={literal}= <body> ={/literal}=
-
- Literally output enclosed text. Mostly used to wrap inlined JavaScript.
-
-*** include
- Syntax: ={include "<filename>"}=
-
- Example: ={include "pagination.html"}=
-
- Substitutes another template.
-
-*** block
- Syntax: ={block <name>}= <body> ={/block}=
-
- Defines or redefines named block.
-
-*** superblock
- Syntax: ={superblock}=
-
- Placeholder for content of inherited block.
-
-*** extends
- Syntax: ={extends "<filename>"}=
-
- Example: ={extends "base.html"}=
-
- Declares current template as defived one. Top level blocks are substituted into corresponding blocks of base template.
-
-*** ldelim, rdelim
- Syntax: ={ldelim}=, ={rdelim}=
-
- Output '{' and '}'.
-
-*** trans, plural, blocktrans
- No information about these tags
-
-** Predefined custom tags
-
*** url
Syntax: ={url '<view-name>'[, array([<arg>]*)]?}=
Prints SQL statistics.
-** Modifiers
-
- Modifier is a transformation applied to a printed value.
- Some modifiers have one or more parameters. All parameters have default values and can be omitted.
-
- ={<expr> [|<modifier>[:<params>]?]*}=
-
- Where =<params>= is a comma-separated list of parameters.
-
- Examples: ={$content|safe}=, ={$content|strip_tags|limit_words:10}=
-
-*** Predefined modifiers
-
- + =upper=
- + =lower=
- + =capitalize=
- + =trim=
-
- + =limit_words:<count>,<end>= -- Limits text to specified number of words (default is 100). Text is terminted by <end> string (default is ellipsis character).
-
- + =date:<format>= -- format date. Default format is '%b %e, %Y'
- + =time:<format>= -- format date and time. Default format is 'Y-m-d H:i:s'
-
- + =floatformat:<decimals>,<point><thousands>= -- format float value. Default parameters are 2, '.', ','.
-
- + =count= -- number of elements in collection
-
- + =escxml= -- escape XM
- + =escape= -- escape HTML
- + =escurl= -- escape URL
- + =strip_tags= -- remove all tags
- + =nl2br= -- replaces all new line characters with '<br>' tags
- + =unsafe=, =safe= -- outputs text unescaped
-
- + =debug= -- print_r
- + =fulldebug= -- var_export
-
** Configuration
+ =template_tags= -- additional template tags
+++ /dev/null
-<?php
-
-class IPF_Exception_Template extends IPF_Exception{}
+++ /dev/null
-<?php
-
-abstract class IPF_Template
-{
- protected $environment;
-
- public function __construct(IPF_Template_Environment $environment)
- {
- $this->environment = $environment;
- }
-
- abstract public function __toString();
-
- abstract protected function content();
-
- public function compile()
- {
- $compiler = new IPF_Template_Compiler($this->content(), $this->environment);
- return $compiler->getCompiledTemplate();
- }
-
- public function render($c=null)
- {
- $compiled_template = $this->environment->getCompiledTemplateName($this);
- ob_start();
- $t = $c;
- try {
- include $compiled_template;
- } catch (Exception $e) {
- ob_clean();
- throw $e;
- }
- $a = ob_get_contents();
- ob_end_clean();
- return $a;
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_Template_Compiler
-{
- private static $allowedInVar = null,
- $allowedInExpr = null,
- $allowedAssign = null,
- $allowedForeach = null;
-
- public static function init()
- {
- $vartype = array(T_CHARACTER, T_CONSTANT_ENCAPSED_STRING, T_DNUMBER,
- T_ENCAPSED_AND_WHITESPACE, T_LNUMBER, T_OBJECT_OPERATOR, T_STRING,
- T_WHITESPACE, T_ARRAY, T_VARIABLE);
-
- $assignOp = array(T_AND_EQUAL, T_DIV_EQUAL, T_MINUS_EQUAL, T_MOD_EQUAL,
- T_MUL_EQUAL, T_OR_EQUAL, T_PLUS_EQUAL, T_PLUS_EQUAL, T_SL_EQUAL,
- T_SR_EQUAL, T_XOR_EQUAL);
-
- $op = array(T_BOOLEAN_AND, T_BOOLEAN_OR, T_EMPTY, T_INC, T_ISSET,
- T_IS_EQUAL, T_IS_GREATER_OR_EQUAL, T_IS_IDENTICAL, T_IS_NOT_EQUAL,
- T_IS_NOT_IDENTICAL, T_IS_SMALLER_OR_EQUAL, T_LOGICAL_AND,
- T_LOGICAL_OR, T_LOGICAL_XOR, T_SR, T_SL, T_DOUBLE_ARROW);
-
- self::$allowedInVar = array_merge($vartype, $op);
- self::$allowedInExpr = array_merge($vartype, $op);
- self::$allowedAssign = array_merge($vartype, $op, $assignOp);
- self::$allowedForeach = array_merge(self::$allowedInExpr, array(T_AS));
- }
-
- protected $_literals;
-
- protected $_blockStack = array();
-
- protected $_transStack = array();
- protected $_transPlural = false;
-
- private $environment;
-
- public $templateContent = '';
-
- public $_extendBlocks = array();
-
- function __construct($templateContent, $environment)
- {
- $this->templateContent = $templateContent;
- $this->environment = $environment;
- }
-
- private function compile()
- {
- $this->compileBlocks();
- $tplcontent = $this->templateContent;
- $tplcontent = preg_replace('!{\*(.*?)\*}!s', '', $tplcontent);
- $tplcontent = preg_replace('!<\?php(.*?)\?>!s', '', $tplcontent);
- preg_match_all('!{literal}(.*?){/literal}!s', $tplcontent, $_match);
- $this->_literals = $_match[1];
- $tplcontent = preg_replace("!{literal}(.*?){/literal}!s", '{literal}', $tplcontent);
- // Core regex to parse the template
- $result = preg_replace_callback('/{((.).*?)}/s',
- array($this, '_callback'),
- $tplcontent);
- if (count($this->_blockStack)) {
- trigger_error(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack)), E_USER_ERROR);
- }
- return $result;
- }
-
- public function getCompiledTemplate()
- {
- $result = $this->compile();
- $result = str_replace(array('?><?php', '<?php ?>', '<?php ?>'), '', $result);
- $result = str_replace("?>\n", "?>\n\n", $result);
- return $result;
- }
-
- private static function toplevelBlocks($content)
- {
- preg_match_all("!{block\s*([^} \r\t\n]*)}|{/block}!", $content, $tags, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
-
- $count = 0;
- $result = array();
- foreach ($tags as $tag) {
- $text = $tag[0][0];
-
- if (substr($text, 0, 6) === '{block') {
- if ($count == 0) {
- $result[] = array(
- 'name' => $tag[1][0],
- 'start' => $tag[1][1] + strlen($tag[1][0]) + 1,
- );
- }
- $count++;
- } elseif (substr($text, 0, 7) === '{/block') {
- $count--;
- if ($count == 0) {
- $result[count($result)-1]['finish'] = $tag[0][1];
- }
- }
- }
-
- if ($count != 0)
- throw new IPF_Exception(sprintf(__('Blocks are not nested properly.')));
-
- return $result;
- }
-
- function compileBlocks()
- {
- $tplcontent = $this->templateContent;
- $extendedTemplate = '';
- // Match extends on the first line of the template
- if (preg_match("!{extends\s['\"](.*?)['\"]}!", $tplcontent, $_match)) {
- $extendedTemplate = $_match[1];
- }
- // Get the blocks in the current template
- $blocks = self::toplevelBlocks($this->templateContent);
- $cnt = count($blocks);
- // Compile the blocks
- for ($i=0; $i<$cnt; $i++) {
- $blockName = $blocks[$i]['name'];
- if (!isset($this->_extendBlocks[$blockName]) or false !== strpos($this->_extendBlocks[$blockName], '~~{~~superblock~~}~~')) {
- $compiler = clone($this);
- $compiler->templateContent = substr($this->templateContent, $blocks[$i]['start'], $blocks[$i]['finish'] - $blocks[$i]['start']);
- $_tmp = $compiler->compile();
- if (!isset($this->_extendBlocks[$blockName])) {
- $this->_extendBlocks[$blockName] = $_tmp;
- } else {
- $this->_extendBlocks[$blockName] = str_replace('~~{~~superblock~~}~~', $_tmp, $this->_extendBlocks[$blockName]);
- }
- }
- }
- if (strlen($extendedTemplate) > 0) {
- // The template of interest is now the extended template
- // as we are not in a base template
- $this->templateContent = $this->environment->loadTemplateFile($extendedTemplate);
- $this->compileBlocks(); //It will recurse to the base template.
- } else {
- // Replace the current blocks by a place holder
- if ($cnt) {
- $this->templateContent = preg_replace("!{block\s(\S+?)}(.*?){/block}!s", "{block $1}", $tplcontent, -1);
- }
- }
- }
-
- private function _callback($matches)
- {
- list(,$tag, $firstcar) = $matches;
- if (!preg_match('/^\$|[\'"]|[a-zA-Z\/]$/', $firstcar)) {
- trigger_error(sprintf(__('Invalid tag syntax: %s'), $tag), E_USER_ERROR);
- return '';
- }
- if (in_array($firstcar, array('$', '\'', '"'))) {
- if ('blocktrans' !== end($this->_blockStack)) {
- return '<?php echo IPF_Template_SafeString::value('.$this->_parseVariable($tag).'); ?>';
- } else {
- $tok = explode('|', $tag);
- $this->_transStack[substr($tok[0], 1)] = $this->_parseVariable($tag);
- return '%%'.substr($tok[0], 1).'%%';
- }
- } else {
- if (!preg_match('/^(\/?[a-zA-Z0-9_]+)(?:(?:\s+(.*))|(?:\((.*)\)))?$/', $tag, $m)) {
- trigger_error(sprintf(__('Invalid function syntax: %s'), $tag), E_USER_ERROR);
- return '';
- }
- if (count($m) == 4){
- $m[2] = $m[3];
- }
- if (!isset($m[2])) $m[2] = '';
- if($m[1] == 'ldelim') return '{';
- if($m[1] == 'rdelim') return '}';
- if ($m[1] != 'include') {
- return '<?php '.$this->_parseFunction($m[1], $m[2]).'?>';
- } else {
- return $this->_parseFunction($m[1], $m[2]);
- }
- }
- }
-
- private function _parseVariable($expr)
- {
- $tok = explode('|', $expr);
- $res = $this->_parseFinal(array_shift($tok), self::$allowedInVar);
- foreach ($tok as $modifier) {
- if (!preg_match('/^(\w+)(?:\:(.*))?$/', $modifier, $m)) {
- trigger_error(sprintf(__('Invalid modifier syntax: (%s) %s'), $expr, $modifier), E_USER_ERROR);
- return '';
- }
-
- if ($this->environment->hasModifier($m[1])) {
- trigger_error(sprintf(__('Unknown modifier: (%s) %s'), $expr, $m[1]), E_USER_ERROR);
- return '';
- }
-
- $mod = $this->environment->getModifier($m[1]);
-
- if (isset($m[2])) {
- $res = $mod.'('.$res.','.$m[2].')';
- } else {
- $res = $mod.'('.$res.')';
- }
- }
- return $res;
- }
-
- private function _parseFunction($name, $args)
- {
- switch ($name) {
- case 'if':
- $res = 'if ('.$this->_parseFinal($args, self::$allowedInExpr).'): ';
- $this->_blockStack[] = 'if';
- break;
- case 'else':
- if (end($this->_blockStack) != 'if') {
- trigger_error(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack)), E_USER_ERROR);
- }
- $res = 'else: ';
- break;
- case 'elseif':
- if (end($this->_blockStack) != 'if') {
- trigger_error(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack)), E_USER_ERROR);
- }
- $res = 'elseif('.$this->_parseFinal($args, self::$allowedInExpr).'):';
- break;
- case 'foreach':
- $tokens = $this->tokenize($args, self::$allowedForeach, array(';'));
- $asFound = false;
- $scopeVars = array('foreach_counter0', 'foreach_counter', 'foreach_first');
- foreach ($tokens as $token) {
- if (!is_array($token))
- continue;
- if ($asFound) {
- if ($token[0] == T_VARIABLE)
- $scopeVars[] = substr($token[1], 1);
- } else {
- if ($token[0] == T_AS)
- $asFound = true;
- }
- }
- $res =
- '$t->push(\'' . implode('\', \'', $scopeVars) . '\'); ' .
- '$t->_vars[\'foreach_counter0\'] = 0;' .
- '$t->_vars[\'foreach_counter\'] = 1;' .
- '$t->_vars[\'foreach_first\'] = true;' .
- 'foreach ('.$this->compileExpression($tokens).'): ';
- $this->_blockStack[] = 'foreach';
- break;
- case 'while':
- $res = 'while('.$this->_parseFinal($args, self::$allowedInExpr).'):';
- $this->_blockStack[] = 'while';
- break;
- case '/foreach':
- if(end($this->_blockStack) != 'foreach'){
- trigger_error(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack)), E_USER_ERROR);
- }
- array_pop($this->_blockStack);
- $res =
- '$t->_vars[\'foreach_counter0\'] = $t->_vars[\'foreach_counter0\'] + 1;' .
- '$t->_vars[\'foreach_counter\'] = $t->_vars[\'foreach_counter\'] + 1;' .
- '$t->_vars[\'foreach_first\'] = false;' .
- 'endforeach; ' .
- '$t->pop(); ';
- break;
- case '/if':
- case '/while':
- $short = substr($name,1);
- if(end($this->_blockStack) != $short){
- trigger_error(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack)), E_USER_ERROR);
- }
- array_pop($this->_blockStack);
- $res = 'end'.$short.'; ';
- break;
- case 'assign':
- $res = $this->_parseFinal($args, self::$allowedAssign).'; ';
- break;
- case 'literal':
- if (count($this->_literals)) {
- $res = '?>'.array_shift($this->_literals).'<?php ';
- } else {
- trigger_error(__('End tag of a block missing: literal'), E_USER_ERROR);
- }
- break;
- case '/literal':
- trigger_error(__('Start tag of a block missing: literal'), E_USER_ERROR);
- break;
- case 'block':
- if (isset($this->_extendBlocks[$args]))
- $res = '?>'.$this->_extendBlocks[$args].'<?php ';
- else
- $res = '';
- break;
- case 'superblock':
- $res = '?>~~{~~superblock~~}~~<?php ';
- break;
- case 'trans':
- $argfct = $this->_parseFinal($args, self::$allowedAssign);
- $res = 'echo(__('.$argfct.'));';
- break;
- case 'blocktrans':
- $this->_blockStack[] = 'blocktrans';
- $res = '';
- $this->_transStack = array();
- if ($args) {
- $this->_transPlural = true;
- $_args = $this->_parseFinal($args, self::$allowedAssign, array(';', '[', ']'));
- $res .= '$_b_t_c='.trim($_args).'; ';
- }
- $res .= 'ob_start(); ';
- break;
- case '/blocktrans':
- $short = substr($name,1);
- if(end($this->_blockStack) != $short){
- trigger_error(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack)), E_USER_ERROR);
- }
- $res = '';
- if ($this->_transPlural) {
- $res .= '$_b_t_p=ob_get_contents(); ob_end_clean(); echo(';
- $res .= 'IPF_Translation::sprintf(_n($_b_t_s, $_b_t_p, $_b_t_c), array(';
- $_tmp = array();
- foreach ($this->_transStack as $key=>$_trans) {
- $_tmp[] = '\''.addslashes($key).'\' => IPF_Template_SafeString::value('.$_trans.')';
- }
- $res .= implode(', ', $_tmp);
- unset($_trans, $_tmp);
- $res .= ')));';
- $this->_transStack = array();
- } else {
- $res .= '$_b_t_s=ob_get_contents(); ob_end_clean(); ';
- if (count($this->_transStack) == 0) {
- $res .= 'echo(__($_b_t_s)); ';
- } else {
- $res .= 'echo(IPF_Translation::sprintf(__($_b_t_s), array(';
- $_tmp = array();
- foreach ($this->_transStack as $key=>$_trans) {
- $_tmp[] = '\''.addslashes($key).'\' => IPF_Template_SafeString::value('.$_trans.')';
- }
- $res .= implode(', ', $_tmp);
- unset($_trans, $_tmp);
- $res .= '))); ';
- $this->_transStack = array();
- }
- }
- $this->_transPlural = false;
- array_pop($this->_blockStack);
- break;
- case 'plural':
- $res = '$_b_t_s=ob_get_contents(); ob_end_clean(); ob_start(); ';
- break;
- case 'include':
- $argfct = preg_replace('!^[\'"](.*)[\'"]$!', '$1', $args);
- $includedTemplateContent = $this->environment->loadTemplateFile($argfct);
- $_comp = new IPF_Template_Compiler($includedTemplateContent, $this->environment);
- $res = $_comp->compile();
- break;
- default:
- $_start = true;
- $oname = $name;
- if (substr($name, 0, 1) == '/') {
- $_start = false;
- $name = substr($name, 1);
- }
- // Here we should allow custom blocks.
-
- // Here we start the template tag calls at the template tag
- // {tag ...} is not a block, so it must be a function.
- if (!$this->environment->isTagAllowed($name)) {
- trigger_error(sprintf(__('The function tag "%s" is not allowed.'), $name), E_USER_ERROR);
- }
- // $argfct is a string that can be copy/pasted in the PHP code
- // but we need the array of args.
- $argfct = $this->_parseFinal($args, self::$allowedAssign);
-
- $res = '$_extra_tag = new '.$this->environment->getTag($name).'($t);';
- if ($_start) {
- $res .= '$_extra_tag->start('.$argfct.'); ';
- } else {
- $res .= '$_extra_tag->end('.$argfct.'); ';
- }
- }
- return $res;
- }
-
- private function _parseFinal($string, &$allowed, $exceptchar=array(';'))
- {
- $tokens = $this->tokenize($string, $allowed, $exceptchar);
- return $this->compileExpression($tokens);
- }
-
- private function tokenize($string, $allowed, $exceptchar)
- {
- $tokens = token_get_all('<?php '.$string.'?>');
- $result = array();
- foreach ($tokens as $tok) {
- if (is_array($tok)) {
- list($type, $str) = $tok;
- if ($type == T_OPEN_TAG || $type == T_CLOSE_TAG) {
- // skip
- } elseif (in_array($type, $allowed)) {
- $result[] = $tok;
- } else {
- throw new IPF_Exception_Template(sprintf(__('Invalid syntax: (%s) %s.'), $string, $str));
- }
- } else {
- if (in_array($tok, $exceptchar)) {
- trigger_error(sprintf(__('Invalid character: (%s) %s.'), $string, $tok), E_USER_ERROR);
- } else {
- $result[] = $tok;
- }
- }
- }
- return $result;
- }
-
- private function compileExpression($tokens)
- {
- $result = '';
- foreach ($tokens as $tok) {
- if (is_array($tok)) {
- list($type, $str) = $tok;
- if ($type == T_VARIABLE) {
- $result .= '$t->_vars[\''.substr($str, 1).'\']';
- } else {
- $result .= $str;
- }
- } else {
- if ($tok == '.') {
- $result .= '->';
- } elseif ($tok == '~') {
- $result .= '.';
- } else {
- $result .= $tok;
- }
- }
- }
- return $result;
- }
-}
-
-IPF_Template_Compiler::init();
-
+++ /dev/null
-<?php
-
-class IPF_Template_Context
-{
- public $_vars;
- private $stack = array();
-
- function __construct($vars=array())
- {
- $this->_vars = new IPF_Template_ContextVars($vars);
- }
-
- function get($var)
- {
- if (isset($this->_vars[$var])) {
- return $this->_vars[$var];
- }
- return '';
- }
-
- function set($var, $value)
- {
- $this->_vars[$var] = $value;
- }
-
- public function push()
- {
- $vars = func_get_args();
- $frame = array();
- foreach ($vars as $var) {
- $frame[$var] = $this->get($var);
- }
- $this->stack[] = $frame;
- }
-
- public function pop()
- {
- $frame = array_pop($this->stack);
- foreach ($frame as $var => $val)
- $this->set($var, $val);
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_Template_ContextVars extends ArrayObject
-{
- function offsetGet($prop)
- {
- if (!$this->offsetExists($prop)) {
- return '';
- }
- return parent::offsetGet($prop);
- }
-
- function __get($prop)
- {
- if (isset($this->$prop)) {
- return $this->$prop;
- } else {
- return $this->offsetGet($prop);
- }
- }
-
- function __toString()
- {
- return var_export($this, true);
- }
-}
+++ /dev/null
-<?php
-
-abstract class IPF_Template_Environment
-{
- abstract public function loadTemplateFile($filename);
-
- abstract public function getCompiledTemplateName($template);
-
- // Dictionary of allowed tags (tag name => class)
- public $tags = array();
-
- public function isTagAllowed($name)
- {
- return isset($this->tags[$name]);
- }
-
- public function getTag($name)
- {
- if (isset($this->tags[$name]))
- return $this->tags[$name];
- else
- throw new IPF_Exception_Template('Tag '.$name.' is not defined.');
- }
-
- // Dictionary of modifiers (modifier name => function)
- public $modifiers = array(
- 'upper' => 'strtoupper',
- 'lower' => 'strtolower',
- 'escxml' => 'htmlspecialchars',
- 'escape' => 'IPF_Template_Modifier::escape',
- 'strip_tags' => 'strip_tags',
- 'escurl' => 'rawurlencode',
- 'capitalize' => 'ucwords',
- 'debug' => 'print_r', // Not var_export because of recursive issues.
- 'fulldebug' => 'var_export',
- 'count' => 'count',
- 'nl2br' => 'nl2br',
- 'trim' => 'trim',
- 'unsafe' => 'IPF_Template_SafeString::markSafe',
- 'safe' => 'IPF_Template_SafeString::markSafe',
- 'date' => 'IPF_Template_Modifier::dateFormat',
- 'time' => 'IPF_Template_Modifier::timeFormat',
- 'floatformat' => 'IPF_Template_Modifier::floatFormat',
- 'limit_words' => 'IPF_Template_Modifier::limitWords',
- 'limit_chars' => 'IPF_Template_Modifier::limitCharacters',
- );
-
- public function hasModifier($name)
- {
- return isset($this->modifiers[$name]);
- }
-
- public function getModifier($name)
- {
- if (isset($this->modifiers[$name]))
- return $this->modifiers[$name];
- else
- throw new IPF_Exception_Template('Modifier '.$name.' is not defined.');
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_Template_Environment_FileSystem extends IPF_Template_Environment
-{
- public $folders = array();
- public $cache = '/tmp';
- public $debug = false;
-
- public function loadTemplateFile($filename)
- {
- // FIXME: Very small security check, could be better.
- if (strpos($filename, '..') !== false) {
- throw new IPF_Exception(sprintf(__('Template file contains invalid characters: %s'), $filename));
- }
- foreach ($this->folders as $folder) {
- if (file_exists($folder.'/'.$filename)) {
- return file_get_contents($folder.'/'.$filename);
- }
- }
- throw new IPF_Exception(sprintf(__('Template file not found: %s'), $filename));
- }
-
- public function getCompiledTemplateName($template)
- {
- $_tmp = var_export($this->folders, true);
- $filename = $this->cache.'/IPF_Template-'.md5($_tmp.(string)$template).'.phps';
- if ($this->debug or !file_exists($filename)) {
- $this->write($filename, $template->compile());
- }
- return $filename;
- }
-
- private function write($filename, $content)
- {
- $fp = @fopen($filename, 'a');
- if ($fp !== false) {
- flock($fp, LOCK_EX);
- ftruncate($fp, 0);
- rewind($fp);
- fwrite($fp, $content, strlen($content));
- flock($fp, LOCK_UN);
- fclose($fp);
- @chmod($filename, 0777);
- return true;
- } else {
- throw new IPF_Exception_Template(sprintf(__('Cannot write the compiled template: %s'), $filename));
- }
- return false;
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_Template_File extends IPF_Template
-{
- private $tpl;
-
- function __construct($template, IPF_Template_Environment $environment)
- {
- parent::__construct($environment);
- $this->tpl = $template;
- }
-
- public function __toString()
- {
- return $this->tpl;
- }
-
- protected function content()
- {
- return $this->environment->loadTemplateFile($this->tpl);
- }
-}
-
+++ /dev/null
-<?php
-
-final class IPF_Template_Modifier
-{
- public static function escape($string)
- {
- return htmlspecialchars((string)$string, ENT_COMPAT, 'UTF-8');
- }
-
- public static function dateFormat($date, $format='%b %e, %Y')
- {
- if (substr(PHP_OS,0,3) == 'WIN') {
- $_win_from = array ('%e', '%T', '%D');
- $_win_to = array ('%#d', '%H:%M:%S', '%m/%d/%y');
- $format = str_replace($_win_from, $_win_to, $format);
- }
- $date = date('Y-m-d H:i:s', strtotime($date.' GMT'));
- return strftime($format, strtotime($date));
- }
-
- public static function timeFormat($time, $format='Y-m-d H:i:s')
- {
- return date($format, $time);
- }
-
- public static function floatFormat($number, $decimals=2, $dec_point='.', $thousands_sep=',')
- {
- return number_format($number, $decimals, $dec_point, $thousands_sep);
- }
-
- /**
- * Word Limiter
- *
- * Limits a string to X number of words.
- *
- * @param string
- * @param integer
- * @param string the end character. Usually an ellipsis
- * @return string
- */
- public static function limitWords($str, $limit=100, $end_char='…')
- {
- if (trim($str) == '')
- return $str;
- preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);
- if (strlen($str) == strlen($matches[0]))
- $end_char = '';
- return rtrim($matches[0]).$end_char;
- }
-
- /**
- * Character Limiter
- *
- * Limits the string based on the character count. Preserves complete words
- * so the character count may not be exactly as specified.
- *
- * @param string
- * @param integer
- * @param string the end character. Usually an ellipsis
- * @return string
- */
- function limitCharacters($str, $n=500, $end_char='…')
- {
- if (strlen($str) < $n)
- return $str;
-
- $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
-
- if (strlen($str) <= $n)
- return $str;
-
- $out = "";
- foreach (explode(' ', trim($str)) as $val) {
- $out .= $val.' ';
- if (strlen($out) >= $n) {
- $out = trim($out);
- return (strlen($out) == strlen($str)) ? $out : $out.$end_char;
- }
- }
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_Template_SafeString
-{
- public $value = '';
-
- public static function value($mixed, $safe=false)
- {
- if (is_object($mixed) and 'IPF_Template_SafeString' == get_class($mixed))
- return $mixed->value;
- if ($safe)
- return $mixed;
- return htmlspecialchars($mixed, ENT_COMPAT, 'UTF-8');
- }
-
- function __construct($mixed, $safe=false)
- {
- $this->value = self::value($mixed, $safe);
- }
-
- function __toString()
- {
- return $this->value;
- }
-
- public static function markSafe($string)
- {
- return new IPF_Template_SafeString($string, true);
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_Template_String extends IPF_Template
-{
- private $tpl;
-
- function __construct($template, IPF_Template_Environment $environment)
- {
- parent::__construct($environment);
- $this->tpl = $template;
- }
-
- public function __toString()
- {
- return $this->tpl;
- }
-
- protected function content()
- {
- return $this->tpl;
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_Template_Tag
-{
- protected $context;
-
- function __construct($context=null)
- {
- $this->context = $context;
- }
-
- // variable list of arguments
- function start()
- {
- }
-
- // variable list of arguments
- function end()
- {
- }
-}
-
+++ /dev/null
-<?php
-
-class Template_Test extends PHPUnit_Framework_TestCase
-{
- public function testStringTemplate()
- {
- $environment = new IPF_Template_Environment_FileSystem(array(), IPF::get('tmp'));
- $template = new IPF_Template_String('Hello, {$name}!', $environment);
-
- $this->assertEquals('Hello, World!', $template->render(new IPF_Template_Context(array('name' => 'World'))));
- $this->assertEquals('Hello, (>.<)!', $template->render(new IPF_Template_Context(array('name' => '(>.<)'))));
- }
-
- public function testLimitWords()
- {
- $lipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
- $this->assertEquals('Lorem ipsum dolor…', IPF_Utils::limitWords($lipsum, 3));
- }
-}