| 7 |
14 |
! BC Break: Changed the function signature of Dwoo_Block_Plugin::postProcessing |
| 8 |
15 |
it only affects you if you had any custom block plugins, see UPGRADE_NOTES |
| 9 |
16 |
for more details |
| 10 |
|
-! BC Break: Dwoo_ITemplate::cache() must now return the cached file name or false if |
| 11 |
|
- caching failed, only affects you if you had a custom template class and |
| 12 |
|
- implemented cache() yourself |
|
17 |
+! BC Break: Dwoo_ITemplate::cache() must now return the cached file name or |
|
18 |
+ false if caching failed, only affects you if you had a custom template class |
|
19 |
+ and implemented cache() yourself |
| 13 |
20 |
! BC Break: Dwoo_Loader is not static anymore so anything you did on it directly |
| 14 |
21 |
will break. Use $dwoo->getLoader()->addDirectory() instead of |
| 15 |
22 |
Dwoo_Loader::addDirectory() for example |
| 2 |
|
------------------------------------------------------------------------------ |
| 3 |
|
--- 0.9.2 |
| 4 |
|
------------------------------------------------------------------------------ |
| 5 |
|
- |
| 6 |
|
-1. Block plugins |
| 7 |
|
------------------ |
| 8 |
|
- |
| 9 |
|
-This version introduced a backward compatibility break with block plugins, this |
| 10 |
|
-was needed to allow compile-time access to the block's (parsed) content, be |
| 11 |
|
-very careful if you manipulate this content since it is php code and should remain |
| 12 |
|
-so if you don't want syntax errors (which are fatal) during template run. |
| 13 |
|
- |
| 14 |
|
-Error message : |
| 15 |
|
- |
| 16 |
|
- Strict Standards: Declaration of Dwoo_Plugin_*::postProcessing() should be compatible with that of Dwoo_Block_Plugin::postProcessing() |
| 17 |
|
- |
| 18 |
|
-Solution : |
| 19 |
|
- |
| 20 |
|
- * Change your block plugins postProcessing method declaration to the following : |
| 21 |
|
- |
| 22 |
|
- public static function postProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $content) |
| 23 |
|
- |
| 24 |
|
- * Then add "$content" to the beginning of your return value, or modify it if required |
| 25 |
|
- |
| 26 |
|
-2. Strip modifier |
| 27 |
|
------------------ |
| 28 |
|
- |
| 29 |
|
-The strip modifier had the same name as the strip block, this worked when the block |
| 30 |
|
-was hard coded within the compiler, but with the API change (see above) I was able |
| 31 |
|
-to move it to a plugin. Since both plugins don't have the same purpose, there was |
| 32 |
|
-a real problem and I had to rename it. The renaming will be handled by the smarty compatibility |
| 33 |
|
-layer, but if you used it without smarty compatibility, you should edit your templates. |
| 34 |
|
- |
| 35 |
|
-3. DWOO_COMPILE_DIRECTORY and DWOO_CACHE_DIRECTORY constants |
| 36 |
|
------------------------------------------------------------- |
| 37 |
|
- |
| 38 |
|
-If you used those before, you will now get an exception when loading Dwoo. This is done |
| 39 |
|
-on purpose to help people to make the transition to the new method of doing it : |
| 40 |
|
- |
|
2 |
+----------------------------------------------------------------------------- |
|
3 |
+-- 0.9.2 |
|
4 |
+----------------------------------------------------------------------------- |
|
5 |
+ |
|
6 |
+1. Block plugins |
|
7 |
+----------------- |
|
8 |
+ |
|
9 |
+This version introduced a backward compatibility break with block plugins, this |
|
10 |
+was needed to allow compile-time access to the block's (parsed) content, be |
|
11 |
+very careful if you manipulate this content since it is php code and should remain |
|
12 |
+so if you don't want syntax errors (which are fatal) during template run. |
|
13 |
+ |
|
14 |
+Error message : |
|
15 |
+ |
|
16 |
+ Strict Standards: Declaration of Dwoo_Plugin_*::postProcessing() should be compatible with that of Dwoo_Block_Plugin::postProcessing() |
|
17 |
+ |
|
18 |
+Solution : |
|
19 |
+ |
|
20 |
+ * Change your block plugins postProcessing method declaration to the following : |
|
21 |
+ |
|
22 |
+ public static function postProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $content) |
|
23 |
+ |
|
24 |
+ * Then add "$content" to the beginning of your return value, or modify it if required |
|
25 |
+ |
|
26 |
+2. Strip modifier |
|
27 |
+----------------- |
|
28 |
+ |
|
29 |
+The strip modifier had the same name as the strip block, this worked when the block |
|
30 |
+was hard coded within the compiler, but with the API change (see above) I was able |
|
31 |
+to move it to a plugin. Since both plugins don't have the same purpose, there was |
|
32 |
+a real problem and I had to rename it. The renaming will be handled by the smarty compatibility |
|
33 |
+layer, but if you used it without smarty compatibility, you should edit your templates. |
|
34 |
+ |
|
35 |
+3. DWOO_COMPILE_DIRECTORY and DWOO_CACHE_DIRECTORY constants |
|
36 |
+------------------------------------------------------------ |
|
37 |
+ |
|
38 |
+If you used those before, you will now get an exception when loading Dwoo. This is done |
|
39 |
+on purpose to help people to make the transition to the new method of doing it : |
|
40 |
+ |
| 41 |
41 |
$dwoo = new Dwoo('myCompileDir', 'myCacheDir'); |
| 648 |
650 |
} |
| 649 |
651 |
} |
| 650 |
652 |
|
| 651 |
|
- $endpos = strpos($tpl, $this->rd, $pos); |
| 652 |
|
- |
| 653 |
|
- if ($endpos===false) { |
| 654 |
|
- throw new Dwoo_Compilation_Exception($this, 'A template tag was not closed, started with <em>'.substr($tpl, $pos, 20).'</em>'); |
| 655 |
|
- } |
| 656 |
|
- |
| 657 |
|
- while (substr($tpl, $endpos-1, 1) === '\\') { |
| 658 |
|
- $tpl = substr_replace($tpl, $this->rd, $endpos-1, 1+strlen($this->rd)); |
| 659 |
|
- $endpos = strpos($tpl, $this->rd, $endpos); |
|
653 |
+ // check that there is an end tag present |
|
654 |
+ if (strpos($tpl, $this->rd, $pos) === false) { |
|
655 |
+ throw new Dwoo_Compilation_Exception($this, 'A template tag was not closed, started with "'.substr($tpl, $ptr, 30).'"'); |
| 660 |
656 |
} |
| 661 |
657 |
|
| 662 |
|
- $ptr = $endpos+strlen($this->rd); |
| 663 |
658 |
|
| 664 |
|
- $lines = substr_count(substr($tpl, $pos, $endpos-$pos), "\n"); |
|
659 |
+ $ptr += strlen($this->ld); |
|
660 |
+ $subptr = $ptr; |
|
661 |
+ $subparse = ''; |
| 665 |
662 |
|
| 666 |
|
- if (substr($tpl, $pos, 1)==='/') { |
| 667 |
|
- if (substr($tpl, $pos, $endpos-$pos) === '/') { |
| 668 |
|
- $this->push($this->removeTopBlock(), $lines); |
|
663 |
+ while (true) { |
|
664 |
+ $parsed = $this->parse($tpl, $subptr, null, false, 'root', $subptr); |
|
665 |
+ if ($parsed === false) { |
|
666 |
+ break; |
| 669 |
667 |
} else { |
| 670 |
|
- $this->push($this->removeBlock(substr($tpl, $pos+1, $endpos-$pos-1)), $lines); |
|
668 |
+ $subparse .= $parsed; |
|
669 |
+ } |
|
670 |
+ // reload loop if the compiler was reset |
|
671 |
+ if ($ptr === 0) { |
|
672 |
+ continue 2; |
| 671 |
673 |
} |
| 672 |
|
- } else { |
| 673 |
|
- $this->push($this->parse($tpl, $pos, $endpos, false, 'root'), $lines); |
| 674 |
674 |
} |
| 675 |
675 |
|
|
676 |
+ $len = $subptr - $ptr + strlen($this->rd); |
|
677 |
+ $this->push($subparse, substr_count(substr($tpl, $ptr, $len), "\n")); |
|
678 |
+ $ptr += $len; |
|
679 |
+ |
| 676 |
680 |
// adds additional line breaks between php closing and opening tags because the php parser removes those if there is just a single line break |
| 677 |
681 |
if (substr($this->curBlock['buffer'], -2) === '?>' && preg_match('{^(([\r\n])([\r\n]?))}', substr($tpl, $ptr, 3), $m)) { |
| 678 |
682 |
if ($m[3] === '') { |
| 1061 |
1065 |
if ($to === null) { |
| 1062 |
1066 |
$to = strlen($in); |
| 1063 |
1067 |
} |
| 1064 |
|
- $first = $in[$from]; |
|
1068 |
+ $first = substr($in, $from, 1); |
|
1069 |
+ |
|
1070 |
+ if ($first === false) { |
|
1071 |
+ throw new Dwoo_Compilation_Exception($this, 'Unexpected EOF, a template tag was not closed'); |
|
1072 |
+ } |
|
1073 |
+ |
|
1074 |
+ while ($first===" " || $first==="\n" || $first==="\t" || $first==="\r") { |
|
1075 |
+ if ($curBlock === 'root' && substr($in, $from, strlen($this->rd)) === $this->rd) { |
|
1076 |
+ // end template tag |
|
1077 |
+ if ($this->debug) echo 'TEMPLATE PARSING ENDED<br />'; |
|
1078 |
+ return false; |
|
1079 |
+ } |
|
1080 |
+ $from++; |
|
1081 |
+ if ($pointer !== null) { |
|
1082 |
+ $pointer++; |
|
1083 |
+ } |
|
1084 |
+ if ($from >= $to) { |
|
1085 |
+ if (is_array($parsingParams)) { |
|
1086 |
+ return $parsingParams; |
|
1087 |
+ } else { |
|
1088 |
+ return ''; |
|
1089 |
+ } |
|
1090 |
+ } |
|
1091 |
+ $first = $in[$from]; |
|
1092 |
+ } |
|
1093 |
+ |
| 1065 |
1094 |
$substr = substr($in, $from, $to-$from); |
| 1066 |
1095 |
|
| 1067 |
|
- if ($this->debug) echo '<br />PARSE CALL : PARSING "<b>'.htmlentities(substr($in, $from, $to-$from)).'</b>" @ '.$from.':'.$to.' in '.$curBlock.' : pointer='.$pointer.'<br/>'; |
|
1096 |
+ if ($this->debug) echo '<br />PARSE CALL : PARSING "<b>'.htmlentities(substr($in, $from, min($to-$from, 50))).(($to-$from) > 50 ? '...':'').'</b>" @ '.$from.':'.$to.' in '.$curBlock.' : pointer='.$pointer.'<br/>'; |
| 1068 |
1097 |
|
| 1069 |
1098 |
if ($first==='$') { |
| 1070 |
1099 |
// var |
| 1075 |
1104 |
} elseif ($first==='"' || $first==="'") { |
| 1076 |
1105 |
// string |
| 1077 |
1106 |
$out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer); |
| 1078 |
|
- } elseif (preg_match('#^[a-z][a-z0-9_]*('.(is_array($parsingParams)||$curBlock!='root'?'':'\s+[^(]|').'\s*\(|$)#i', $substr)) { |
|
1107 |
+ } elseif (preg_match('/^[a-z][a-z0-9_]*('.(is_array($parsingParams)||$curBlock!='root'?'':'\s+[^(]|').'\s*\(|\s*'.$this->rdr.'|\s*;)/i', $substr)) { |
| 1079 |
1108 |
// func |
| 1080 |
1109 |
$out = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1110 |
+ } elseif ($first === ';') { |
|
1111 |
+ // instruction end |
|
1112 |
+ if ($this->debug) echo 'END OF INSTRUCTION<br />'; |
|
1113 |
+ if ($pointer !== null) { |
|
1114 |
+ $pointer++; |
|
1115 |
+ } |
|
1116 |
+ return $this->parse($in, $from+1, $to, false, 'root', $pointer); |
|
1117 |
+ } elseif ($curBlock === 'root' && preg_match('#^/([a-z][a-z0-9_]*)?#i', $substr, $match)) { |
|
1118 |
+ // close block |
|
1119 |
+ if ($pointer !== null) { |
|
1120 |
+ $pointer += strlen($match[0]); |
|
1121 |
+ } |
|
1122 |
+ if (empty($match[1])) { |
|
1123 |
+ if ($this->debug) echo 'TOP BLOCK CLOSED<br />'; |
|
1124 |
+ return $this->removeTopBlock(); |
|
1125 |
+ } else { |
|
1126 |
+ if ($this->debug) echo 'BLOCK OF TYPE '.$match[1].' CLOSED<br />'; |
|
1127 |
+ return $this->removeBlock($match[1]); |
|
1128 |
+ } |
|
1129 |
+ } elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) { |
|
1130 |
+ // end template tag |
|
1131 |
+ if ($this->debug) echo 'TAG PARSING ENDED<br />'; |
|
1132 |
+ return false; |
| 1081 |
1133 |
} elseif (is_array($parsingParams) && preg_match('#^([a-z0-9_]+\s*=)(?:\s+|[^=]).*#i', $substr, $match)) { |
| 1082 |
1134 |
// named parameter |
| 1083 |
1135 |
if ($this->debug) echo 'NAMED PARAM FOUND<br />'; |
| 1188 |
1245 |
if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') { |
| 1189 |
1246 |
if ($this->debug) echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT '.$ptr.'<br/>'; |
| 1190 |
1247 |
break 2; |
|
1248 |
+ } elseif ($paramstr[$ptr] === ';') { |
|
1249 |
+ $ptr++; |
|
1250 |
+ if ($this->debug) echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT '.$ptr.'<br/>'; |
|
1251 |
+ break 2; |
|
1252 |
+ } elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) { |
|
1253 |
+ if ($this->debug) echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT '.$ptr.'<br/>'; |
|
1254 |
+ break 2; |
| 1191 |
1255 |
} |
| 1192 |
1256 |
|
| 1193 |
1257 |
if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") { |
| 1935 |
1997 |
$end = strlen($substr); |
| 1936 |
1998 |
|
| 1937 |
1999 |
if ($curBlock === 'condition') { |
| 1938 |
|
- $breakChars = array('(', ')', ' ', '||', '&&', '|', '&', '>=', '<=', '===', '==', '=', '!==', '!=', '<<', '<', '>>', '>', '^', '~', ',', '+', '-', '*', '/', '%', '!', '?', ':'); |
|
2000 |
+ $breakChars = array('(', ')', ' ', '||', '&&', '|', '&', '>=', '<=', '===', '==', '=', '!==', '!=', '<<', '<', '>>', '>', '^', '~', ',', '+', '-', '*', '/', '%', '!', '?', ':', $this->rd, ';'); |
| 1939 |
2001 |
} elseif ($curBlock === 'modifier') { |
| 1940 |
|
- $breakChars = array(' ', ',', ')', ':', '|', "\r", "\n", "\t"); |
|
2002 |
+ $breakChars = array(' ', ',', ')', ':', '|', "\r", "\n", "\t", ";", $this->rd); |
| 1941 |
2003 |
} else { |
| 1942 |
|
- $breakChars = array(' ', ',', ')', "\r", "\n", "\t"); |
|
2004 |
+ $breakChars = array(' ', ',', ')', "\r", "\n", "\t", ";", $this->rd); |
| 1943 |
2005 |
} |
| 1944 |
2006 |
|
| 1945 |
2007 |
$breaker = false; |
| 1977 |
2039 |
if ($this->debug) echo 'NULL PARSED<br />'; |
| 1978 |
2040 |
$substr = 'null'; |
| 1979 |
2041 |
} elseif (is_numeric($substr)) { |
| 1980 |
|
- if ($this->debug) echo 'NUMBER PARSED<br />'; |
| 1981 |
2042 |
$substr = (float) $substr; |
| 1982 |
2043 |
if ((int) $substr == $substr) { |
| 1983 |
2044 |
$substr = (int) $substr; |
| 1984 |
2045 |
} |
|
2046 |
+ if ($this->debug) echo 'NUMBER ('.$substr.') PARSED<br />'; |
| 1985 |
2047 |
} elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) { |
| 1986 |
2048 |
if ($this->debug) echo 'SIMPLE MATH PARSED<br />'; |
| 1987 |
2049 |
$substr = '('.$substr.')'; |
| 1988 |
2050 |
} elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) { |
| 1989 |
|
- if ($this->debug) echo 'BREAKCHAR PARSED<br />'; |
|
2051 |
+ if ($this->debug) echo 'BREAKCHAR ('.$substr.') PARSED<br />'; |
| 1990 |
2052 |
//$substr = '"'.$substr.'"'; |
| 1991 |
2053 |
} else { |
| 1992 |
|
- if ($this->debug) echo 'BLABBER CASTED AS STRING<br />'; |
| 1993 |
|
- |
| 1994 |
2054 |
$substr = $this->replaceStringVars('"'.str_replace('"', '\\"', $substr).'"', '"', $curBlock); |
|
2055 |
+ |
|
2056 |
+ if ($this->debug) echo 'BLABBER ('.$substr.') CASTED AS STRING<br />'; |
| 1995 |
2057 |
} |
| 1996 |
2058 |
|
| 1997 |
2059 |
if (is_array($parsingParams)) { |
| 2090 |
2164 |
|
| 2091 |
2165 |
$state = 0; |
| 2092 |
2166 |
if ($paramspos === false) { |
| 2093 |
|
- $func = $cmdstr; |
| 2094 |
|
- $cmdstrsrc = substr($cmdstrsrc, strlen($func)+1); |
|
2167 |
+ if (!preg_match('/^(@{0,2}[a-z][a-z0-9_]*)/', $cmdstr, $match)) { |
|
2168 |
+ throw new Dwoo_Compilation_Exception($this, 'Invalid modifier name, started with : '.substr($cmdstr, 0, 10)); |
|
2169 |
+ } |
|
2170 |
+ $func = $match[1]; |
|
2171 |
+ $cmdstrsrc = substr($cmdstrsrc, strlen($func)); |
| 2095 |
2172 |
$params = array(); |
|
2173 |
+ if ($this->debug) echo 'MODIFIER ('.$func.') CALLED WITH NO PARAMS<br/>'; |
| 2096 |
2174 |
} else { |
| 2097 |
2175 |
$func = substr($cmdstr, 0, $paramspos); |
| 2098 |
2176 |
$paramstr = substr($cmdstr, $paramspos+1); |
| 132 |
132 |
|
| 133 |
133 |
$this->assertEquals('true', $this->dwoo->get($tpl, array('foo'=>'bar'), $this->compiler)); |
| 134 |
134 |
|
|
135 |
+ // fixes the init call not being called (which is normal) |
|
136 |
+ $fixCall = new Dwoo_Plugin_if ($this->dwoo); |
|
137 |
+ $fixCall->init(array()); |
|
138 |
+ } |
|
139 |
+ |
|
140 |
+ public function testIfVariation2 () |
|
141 |
+ { |
| 135 |
142 |
$tpl = new Dwoo_Template_String('{if 4/2==2 && 2!=1 && 3>0 && 4<5 && 5<=5 && 6>=3 && 3===3 && "3"!==3}true{/if}'); |
| 136 |
143 |
$tpl->forceCompilation(); |
| 137 |
144 |
|
| 138 |
145 |
$this->assertEquals('true', $this->dwoo->get($tpl, array(), $this->compiler)); |
| 139 |
|
- |
|
146 |
+ } |
|
147 |
+ |
|
148 |
+ public function testIfVariation3 () |
|
149 |
+ { |
| 140 |
150 |
$tpl = new Dwoo_Template_String('{if 5%2==1 && !isset($foo)}true{/if}'); |
| 141 |
151 |
$tpl->forceCompilation(); |
| 142 |
152 |
|
| 143 |
153 |
$this->assertEquals('true', $this->dwoo->get($tpl, array(), $this->compiler)); |
| 144 |
|
- |
|
154 |
+ } |
|
155 |
+ |
|
156 |
+ public function testIfVariation4 () |
|
157 |
+ { |
| 145 |
158 |
$tpl = new Dwoo_Template_String('{if 5 is not div by 2 && 4 is div by 2 && 6 is even && 6 is not even by 5 && (3 is odd && 9 is odd by 3)}true{/if}'); |
| 146 |
159 |
$tpl->forceCompilation(); |
| 147 |
160 |
|
| 148 |
161 |
$this->assertEquals('true', $this->dwoo->get($tpl, array(), $this->compiler)); |
| 149 |
|
- |
|
162 |
+ } |
|
163 |
+ |
|
164 |
+ public function testIfVariation5 () |
|
165 |
+ { |
| 150 |
166 |
$tpl = new Dwoo_Template_String('{if (3==4 && 5==5) || 3==3}true{/if}'); |
| 151 |
167 |
$tpl->forceCompilation(); |
| 152 |
168 |
|
| 153 |
169 |
$this->assertEquals('true', $this->dwoo->get($tpl, array(), $this->compiler)); |
| 154 |
|
- |
| 155 |
|
- // fixes the init call not being called (which is normal) |
| 156 |
|
- $fixCall = new Dwoo_Plugin_if ($this->dwoo); |
| 157 |
|
- $fixCall->init(array()); |
| 158 |
170 |
} |
| 159 |
171 |
|
| 160 |
172 |
public function testIfElseif () |
| 480 |
480 |
$tpl = new Dwoo_Template_String('{upper foo=bar}'); |
| 481 |
481 |
$tpl->forceCompilation(); |
| 482 |
482 |
|
| 483 |
|
- $this->dwoo->get($tpl, array('foo'=>0), $this->compiler); |
|
483 |
+ $this->dwoo->get($tpl, array(), $this->compiler); |
|
484 |
+ } |
|
485 |
+ |
|
486 |
+ /** |
|
487 |
+ * @expectedException Dwoo_Compilation_Exception |
|
488 |
+ */ |
|
489 |
+ public function testUnclosedTemplateTag() |
|
490 |
+ { |
|
491 |
+ $tpl = new Dwoo_Template_String('aa{upper foo=bar'); |
|
492 |
+ $tpl->forceCompilation(); |
|
493 |
+ |
|
494 |
+ $this->dwoo->get($tpl, array(), $this->compiler); |
| 484 |
495 |
} |
| 485 |
496 |
|
| 486 |
497 |
public function testAutoEscape() |