PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/tag/TemplateParser.php

http://rhaco.googlecode.com/
PHP | 438 lines | 393 code | 10 blank | 35 comment | 27 complexity | ca5b959432420270cf126825d09e6186 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. Rhaco::import("tag.model.SimpleTag");
  3. Rhaco::import("tag.TagParser");
  4. Rhaco::import("exception.ExceptionTrigger");
  5. Rhaco::import("network.Url");
  6. Rhaco::import("lang.ArrayUtil");
  7. Rhaco::import("util.Logger");
  8. Rhaco::import("tag.model.TemplateFormatter");
  9. /**
  10. * ???????????????
  11. *
  12. * @author Kazutaka Tokushima
  13. * @license New BSD License
  14. * @copyright Copyright 2005- rhaco project. All rights reserved.
  15. */
  16. class TemplateParser extends TagParser{
  17. var $replaceList = array();
  18. var $blockList = array();
  19. var $blocRead = array();
  20. var $blocParts = array();
  21. /**
  22. * ???????
  23. * @param string $template ??????????
  24. * @param string $path ????????
  25. * @param string $url ?????????URL
  26. */
  27. function TemplateParser($template=null,$path=null,$url=null){
  28. parent::TagParser($template,$path,$url);
  29. }
  30. /**
  31. * ??????????????
  32. * @param string/array $arrayOrSource
  33. * @param string $dest
  34. */
  35. function setReplace($arrayOrSource,$dest=""){
  36. if(!is_array($arrayOrSource)) $arrayOrSource = array($arrayOrSource=>$dest);
  37. foreach($arrayOrSource as $key => $value) $this->replaceList[$key] = $value;
  38. }
  39. /**
  40. * ????????????????
  41. * @param string/array $templateFileName
  42. * @param string/array ...
  43. */
  44. function setBlock(){
  45. foreach(func_get_args() as $templateFileName){
  46. if(is_array($templateFileName)){
  47. foreach($templateFileName as $value) $this->blockList[] = $value;
  48. }else if(is_string($templateFileName)){
  49. $this->blockList[] = $templateFileName;
  50. }
  51. }
  52. }
  53. function _syntaxCheck($src){
  54. if(preg_match_all("/(Notice|Fatal).+/",$src,$match)){
  55. foreach($match[0] as $key => $m) Logger::error($m);
  56. }
  57. if(preg_match_all("/({\\$|".preg_quote(TemplateParser::withNamespace("")).").+/m",$src,$match)){
  58. foreach($match[0] as $key => $m) Logger::warning($m);
  59. }
  60. return $src;
  61. }
  62. function _cs1001_Comment($src){
  63. /*** unit("tag.TemplateParserTest"); */
  64. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("comment"))){
  65. $src = str_replace($tag->getPlain(),"",$src);
  66. }
  67. return $src;
  68. }
  69. function _cs1002_Template($src){
  70. /*** unit("tag.TemplateParserTest"); */
  71. $value = "";
  72. $bool = false;
  73. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("template"))){
  74. $value .= $tag->getRawValue();
  75. $bool = true;
  76. $src = str_replace($tag->getPlain(),"",$src);
  77. }
  78. return ($bool) ? $value : $src;
  79. }
  80. function _cs1003_Include($src,$filename=""){
  81. /*** unit("tag.TemplateParserTest"); */
  82. $base = (empty($filename)) ? Url::parseAbsolute($this->path,$this->filename) : $filename;
  83. $bool = false;
  84. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("include"))){
  85. $path = Url::parseAbsolute(dirname($base),$tag->getParameter("href"));
  86. $includeTemplateSrc = $this->_getTemplateSource($path);
  87. $read = "";
  88. if(empty($includeTemplateSrc)){
  89. Logger::warning(Message::_("fails in read include template file [{1}]",$path));
  90. $src = str_replace($tag->getPlain(),"",$src);
  91. }else{
  92. Logger::deep_debug(Message::_("read include template file [{1}]",$path));
  93. $read = $this->_callFilter("init",$includeTemplateSrc);
  94. $src = str_replace($tag->getPlain(),$this->_cs1003_Include($read,$path),$src);
  95. }
  96. $bool = true;
  97. }
  98. if($bool) $src = $this->_callFilter("before",$src);
  99. return $src;
  100. }
  101. function _cs1003_Extends($src){
  102. /*** unit("tag.TemplateParserTest"); */
  103. $blockList = array($this->filename);
  104. $path = Url::parseAbsolute($this->path,$this->filename);
  105. $bool = false;
  106. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("extends"))){
  107. $path = Url::parseAbsolute(dirname($path),$tag->getParameter("href"));
  108. $blockList[] = $path;
  109. $src = $this->_getTemplateSource($path);
  110. $bool = true;
  111. }
  112. if($bool){
  113. $this->setTemplate($path);
  114. array_pop($blockList);
  115. $this->blockList = array_reverse(ArrayUtil::arrays($blockList));
  116. }
  117. return $src;
  118. }
  119. function _cs1005_Block($src){
  120. /*** unit("tag.TemplateParserTest"); */
  121. $tmpsrc = $src;
  122. $this->blockList = ArrayUtil::arrays($this->blockList);
  123. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("setblock"))){
  124. $this->setBlock(Url::parseAbsolute(dirname(Url::parseAbsolute($this->path,$this->filename)),$tag->getParameter("href")));
  125. $src = str_replace($tag->getPlain(),"",$src);
  126. }
  127. foreach($this->blockList as $key => $blockTemplateFile){
  128. $blockTemplateFile = Url::parseAbsolute($this->path,$blockTemplateFile);
  129. $tmpurl = Url::parseAbsolute($this->url,Url::parseRelative($this->path,$blockTemplateFile));
  130. if(!isset($this->blocRead[$blockTemplateFile])){
  131. $blockTemplateSrc = $this->_getTemplateSource($blockTemplateFile);
  132. $this->blocRead[$blockTemplateFile] = true;
  133. if(empty($blockTemplateSrc)){
  134. Logger::warning(Message::_("fails in read block template file [{1}]",$blockTemplateFile));
  135. }else{
  136. $incvalue = $this->_cs1003_Include($blockTemplateSrc,$blockTemplateFile);
  137. $newtag = new SimpleTag("template",$incvalue);
  138. foreach($newtag->getIn(TemplateParser::withNamespace("block")) as $blocktag){
  139. $this->blocParts[strtolower($blocktag->getParameter("name","name"))] = Url::parse($blocktag->getRawValue(),$tmpurl);
  140. }
  141. Logger::deep_debug(Message::_("read block template file [{1}]",$blockTemplateFile));
  142. }
  143. }
  144. }
  145. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("block"))){
  146. $id = strtolower($tag->getParameter("name","name"));
  147. $value = $tag->getRawValue();
  148. if(array_key_exists($id,$this->blocParts)) $value = $this->blocParts[$id];
  149. $src = str_replace($tag->getPlain(),$this->_call($value,"_cs"),$src);
  150. }
  151. if(sizeof($this->blockList) > 0) $src = $this->_callFilter("before",$src);
  152. return $src;
  153. }
  154. function _cs1006_Replace($src){
  155. /*** unit("tag.TemplateParserTest"); */
  156. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("replace"))){
  157. if($tag->getParameter("src") != "") $this->replaceList[$tag->getParameter("src")] = $tag->getParameter("dest");
  158. $src = str_replace($tag->getPlain(),"",$src);
  159. }
  160. krsort($this->replaceList);
  161. foreach($this->replaceList as $source => $dest){
  162. $src = str_replace($source,$dest,$src);
  163. }
  164. return $src;
  165. }
  166. /**
  167. * ???????????
  168. *
  169. * @param unknown_type $src
  170. * @return unknown
  171. */
  172. function _exec1006_ReplaceContent($src){
  173. if(preg_match_all("/<([\w:_-]+)[\s][^>]*?content[s]{0,1}=([\"\'])[^\\2]*?\\2[^>]*?>/i",$src,$tagList)){
  174. foreach($tagList[0] as $id => $plain){
  175. $tag = new SimpleTag();
  176. $tag->set(substr($src,strpos($src,$plain)),$tagList[1][$id]);
  177. if($tag->isParameter(TemplateParser::withNamespace("content"))){
  178. $plain = $tag->getPlain();
  179. $var = $tag->getParameter(TemplateParser::withNamespace("content"));
  180. $tag->removeParameter(TemplateParser::withNamespace("content"));
  181. $tag->setValue($var);
  182. $src = str_replace($plain,$tag->get(),$src);
  183. }
  184. }
  185. }
  186. return $src;
  187. }
  188. /**
  189. * ???????????????????
  190. *
  191. * @param unknown_type $src
  192. * @return unknown
  193. */
  194. function _exec1007_Message($src){
  195. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("plural"))){
  196. $param = $tag->getParameter("param","param");
  197. $single = $tag->getParameter("single");
  198. $plural = trim(str_replace(array("\r\n","\r","\n"),"",$tag->getValue()));
  199. if(!is_int($param) && $param[0] != "{" && !preg_match("/^[\d]+$/",$param)) $param = "{\$".$param."}";
  200. $src = str_replace($tag->getPlain(),"_p(\"".$single."\",\"".$plural."\",".$param.")",$src);
  201. }
  202. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("trans"))){
  203. $trans = trim(str_replace(array("\r\n","\r","\n"),"",$tag->getValue()));
  204. $src = str_replace($tag->getPlain(),"_(\"".$trans."\")",$src);
  205. }
  206. return $src;
  207. }
  208. function _exec1008_invalid($src){
  209. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("invalid"))){
  210. $name = $this->_parsePlainVariable($tag->getParameter("name","exceptions"));
  211. if(substr($name,0,1) != "$") $name = "\"".$name."\"";
  212. $var = $this->_parsePlainVariable($tag->getParameter("var","errors"));
  213. $type = $this->_parsePlainVariable($tag->getParameter("type","ul"));
  214. $value = $tag->getRawValue();
  215. $function = sprintf("%sif(ExceptionTrigger::invalid(%s)):%s",$this->_pts(),$name,$this->_pte());
  216. $function .= sprintf("%s\$_INVALID_ = array();%s",$this->_pts(),$this->_pte());
  217. $function .= sprintf("%sforeach(ExceptionTrigger::get(%s) as \$_INVALID_EXCEPTION):%s",$this->_pts(),$name,$this->_pte());
  218. $function .= sprintf("%s\$_INVALID_[] = \$_INVALID_EXCEPTION->getMessage();%s",$this->_pts(),$this->_pte());
  219. $function .= sprintf("%sendforeach;%s",$this->_pts(),$this->_pte());
  220. $function .= sprintf("%s%s = \$_INVALID_; %s",$this->_pts(),$this->_getVariableString($var),$this->_pte());
  221. if(!empty($value)){
  222. $function .= $value;
  223. }else{
  224. switch(strtolower($type)){
  225. case "ul":
  226. $function .= sprintf("<ul class=\"exceptions\">\n").
  227. sprintf("<%s param=\"%s\" var=\"msg\">\n",TemplateParser::withNamespace("loop"),$this->_getVariableString($var)).
  228. "<li>{\$msg}</li>\n".
  229. sprintf("</%s>\n",TemplateParser::withNamespace("loop")).
  230. "</ul>\n";
  231. break;
  232. case "plain":
  233. $function .= sprintf("<%s param=\"%s\" var=\"msg\">\n",TemplateParser::withNamespace("loop"),$this->_getVariableString($var)).
  234. "{\$msg}\n".
  235. sprintf("</%s>\n",TemplateParser::withNamespace("loop"));
  236. break;
  237. }
  238. }
  239. $function .= sprintf("%sendif;%s",$this->_pts(),$this->_pte());
  240. $src = str_replace($tag->getPlain(),$function,$src);
  241. unset($function);
  242. }
  243. return $src;
  244. }
  245. function _exec2001_include($src){
  246. return $this->_cs1003_Include($src);
  247. }
  248. function _exec2002_Loop($src){
  249. /*** unit("tag.TemplateParserTest"); */
  250. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("loop"))){
  251. $class = $this->_parsePlainVariable($tag->getParameter("param","param"));
  252. $id = $tag->getParameter("var","var");
  253. $classnm = $this->_variableQuote($class);
  254. $counter = $this->_getVariableString($tag->getParameter("counter","counter"));
  255. $first = $this->_getVariableString($tag->getParameter("first","first"));
  256. $last = $this->_getVariableString($tag->getParameter("last","last"));
  257. $key = $tag->getParameter("key","key");
  258. $count = $this->_getVariableString("counter_".$classnm);
  259. $offset = $tag->getParameter("offset","1");
  260. $limit = $tag->getParameter("limit","0");
  261. $offsetName = sprintf("\$_OFFSET_%s",$classnm);
  262. $limitName = sprintf("\$_LIMIT_%s",$classnm);
  263. $varName = sprintf("\$_".Variable::uniqid("RHACO_LOOP"));
  264. $function = "";
  265. $function .= sprintf("%s%s = 1;%s",$this->_pts(),$count,$this->_pte());
  266. $function .= sprintf("%s %s = %d;%s",$this->_pts(),$offsetName,$offset,$this->_pte());
  267. $function .= sprintf("%s %s = %d;%s",$this->_pts(),$limitName,(($limit>0)?($offset + $limit):0),$this->_pte());
  268. $function .= sprintf("%s%s=%s%s",$this->_pts(),$varName,$this->_getVariableString($class),$this->_pte());
  269. $function .= sprintf("%sif(is_array(%s)):%s",$this->_pts(),$varName,$this->_pte());
  270. $function .= sprintf("%sforeach(%s as %s => %s):%s",$this->_pts(),$varName,$this->_getVariableString($key),$this->_getVariableString($id),$this->_pte());
  271. $function .= sprintf("%sif(%s <= %s):%s",$this->_pts(),$offsetName,$count,$this->_pte());
  272. $function .= sprintf("%s%s = %s;%s",$this->_pts(),$counter,$count,$this->_pte());
  273. $function .= sprintf("%s%s = (1 == %s);%s",$this->_pts(),$first,$count,$this->_pte());
  274. $function .= sprintf("%s%s = (sizeof(%s) == %s);%s",$this->_pts(),$last,$varName,$count,$this->_pte());
  275. $function .= sprintf("%s",$tag->getRawValue());
  276. $function .= sprintf("%sendif;%s",$this->_pts(),$this->_pte());
  277. $function .= sprintf("%s%s++;%s",$this->_pts(),$count,$this->_pte());
  278. $function .= sprintf("%sif(%s > 0 && %s >= %s){break;}%s",$this->_pts(),$limitName,$count,$limitName,$this->_pte());
  279. $function .= sprintf("%sendforeach;%s",$this->_pts(),$this->_pte());
  280. $function .= sprintf("%sendif;%s",$this->_pts(),$this->_pte());
  281. $function .= sprintf("%sunset(%s);%s",$this->_pts(),$varName,$this->_pte());
  282. $src = str_replace($tag->getPlain(),$function,$src);
  283. unset($function);
  284. }
  285. return $src;
  286. }
  287. function _exec2003_For($src){
  288. /*** unit("tag.TemplateParserTest"); */
  289. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("for"))){
  290. $counterName = $this->_getVariableString($tag->getParameter("counter","counter"));
  291. $start = $this->_parsePlainVariable($tag->getParameter("start",0));
  292. $end = $this->_parsePlainVariable($tag->getParameter("end",10));
  293. $step = $this->_parsePlainVariable($tag->getParameter("step",1));
  294. $function = sprintf("%s for(%s=%s;%s<=%s;%s+=%s): %s",
  295. $this->_pts(),$counterName,$start,$counterName,$end,$counterName,$step,$this->_pte());
  296. $function .= $tag->getRawValue();
  297. $function .= sprintf("%s endfor; %s",$this->_pts(),$this->_pte());
  298. $src = str_replace($tag->getPlain(),$function,$src);
  299. unset($function);
  300. }
  301. return $src;
  302. }
  303. function _exec2004_If($src){
  304. /*** unit("tag.TemplateParserTest"); */
  305. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("if"))){
  306. $pattern = "";
  307. $parse = array();
  308. $value = $tag->getRawValue();
  309. $arg1 = $tag->getParameter("param",false);
  310. $arg1 = (preg_match("/^[a-zA-Z_][\w]*$/",$arg1)) ? "$".$arg1 : $this->_parsePlainVariable($arg1);
  311. $isarg1 = (preg_match("/^[\$\'\"]/",$arg1)) ? true : false;
  312. $arg1 = (!is_bool($arg1) && !$isarg1) ? sprintf("'%s'",$arg1) : $arg1;
  313. $pattern = ($isarg1 && $arg1[0] == "\$" && strpos($arg1,"->") === false) ? sprintf("isset(%s) && ",$arg1) : "";
  314. if($tag->isParameter("value")){
  315. $arg2 = $this->_parsePlainVariable($tag->getParameter("value"));
  316. $isarg2 = (preg_match("/^[\$\'\"]/",$arg2)) ? true : false;
  317. $arg2 = (!is_bool($arg2) && !$isarg2) ? sprintf("'%s'",$arg2) : $arg2;
  318. $pattern .= ($isarg2 && $arg2[0] == "\$" && strpos($arg2,"->") === false) ? sprintf("isset(%s) && ",$arg2) : "";
  319. $pattern .= sprintf("%s == %s",$arg1,$arg2);
  320. }else{
  321. $pattern .= sprintf("%s",$arg1);
  322. }
  323. $function = sprintf("%s if(%s): %s",$this->_pts(),$pattern,$this->_pte());
  324. if(preg_match("/(<[\s]*".TemplateParser::withNamespace("else")."[^>]*[\s]*\/>)/i",$tag->getRawValue(),$parse)){
  325. $value = str_replace($parse[1],sprintf("%s else: %s",$this->_pts(),$this->_pte()),$value);
  326. }
  327. $function .= sprintf("%s",$value);
  328. $function .= sprintf("%s endif; %s",$this->_pts(),$this->_pte());
  329. $src = str_replace($tag->getPlain(),$function,$src);
  330. unset($function);
  331. }
  332. return $src;
  333. }
  334. function _exec2005_IfNot($src){
  335. /*** unit("tag.TemplateParserTest"); */
  336. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("ifnot"))){
  337. $pattern = "";
  338. $parse = array();
  339. $value = $tag->getRawValue();
  340. $arg1 = $tag->getParameter("param",false);
  341. $arg1 = (preg_match("/^[a-zA-Z_][\w]*$/",$arg1)) ? "$".$arg1 : $this->_parsePlainVariable($arg1);
  342. $isarg1 = (preg_match("/^[\$\'\"]/",$arg1)) ? true : false;
  343. $arg1 = (!is_bool($arg1) && !$isarg1) ? sprintf("'%s'",$arg1) : $arg1;
  344. $pattern = ($isarg1 && $arg1[0] == "\$" && strpos($arg1,"->") === false) ? sprintf("isset(%s) && ",$arg1) : "";
  345. if($tag->isParameter("value")){
  346. $arg2 = $this->_parsePlainVariable($tag->getParameter("value"));
  347. $isarg2 = (preg_match("/^[\$\'\"]/",$arg2)) ? true : false;
  348. $arg2 = (!is_bool($arg2) && !$isarg2) ? sprintf("'%s'",$arg2) : $arg2;
  349. $pattern .= ($isarg2 && $arg2[0] == "\$" && strpos($arg2,"->") === false) ? sprintf("isset(%s) && ",$arg2) : "";
  350. $pattern .= sprintf("%s != %s",$arg1,$arg2);
  351. }else{
  352. $pattern .= sprintf("!%s",$arg1);
  353. }
  354. $function = sprintf("%s if(%s): %s",$this->_pts(),$pattern,$this->_pte());
  355. if(preg_match("/(<[\s]*".TemplateParser::withNamespace("else")."[^>]*[\s]*\/>)/i",$tag->getRawValue(),$parse)){
  356. $value = str_replace($parse[1],sprintf("%s else: %s",$this->_pts(),$this->_pte()),$value);
  357. }
  358. $function .= sprintf("%s",$value);
  359. $function .= sprintf("%s endif; %s",$this->_pts(),$this->_pte());
  360. $src = str_replace($tag->getPlain(),$function,$src);
  361. unset($function);
  362. }
  363. return $src;
  364. }
  365. function _exec2006_hasnot($src){
  366. //array(),null,""?hasnot
  367. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("hasnot"))){
  368. $param = $this->_parsePlainVariable($tag->getParameter("param","param"));
  369. $varName = sprintf("\$_".Variable::uniqid("RHACO_LOOP"));
  370. $function = "";
  371. $function .= sprintf("%s%s=%s%s",$this->_pts(),$varName,$this->_getVariableString($param),$this->_pte());
  372. $function .= sprintf("%sif(%s === null || (is_array(%s) && empty(%s)) || %s === \"\" ):%s",$this->_pts(),$varName,$varName,$varName,$varName,$this->_pte());
  373. $function .= $tag->getRawValue();
  374. $function .= sprintf("%s endif; %s",$this->_pts(),$this->_pte());
  375. $src = str_replace($tag->getPlain(),$function,$src);
  376. unset($function);
  377. }
  378. return $src;
  379. }
  380. function _exec2006_has($src){
  381. while(SimpleTag::setof($tag,$src,TemplateParser::withNamespace("has"))){
  382. $param = $this->_parsePlainVariable($tag->getParameter("param","param"));
  383. $varName = sprintf("\$_".Variable::uniqid("RHACO_LOOP"));
  384. $function = "";
  385. $function .= sprintf("%s%s=%s%s",$this->_pts(),$varName,$this->_getVariableString($param),$this->_pte());
  386. $function .= sprintf("%sif(%s !== null && ( (!is_string(%s) && !is_array(%s)) || (is_string(%s) && %s !== \"\") || (is_array(%s) && !empty(%s)) ) ):%s",$this->_pts(),$varName,$varName,$varName,$varName,$varName,$varName,$varName,$this->_pte());
  387. $function .= $tag->getRawValue();
  388. $function .= sprintf("%s endif; %s",$this->_pts(),$this->_pte());
  389. $src = str_replace($tag->getPlain(),$function,$src);
  390. unset($function);
  391. }
  392. return $src;
  393. }
  394. /**
  395. * ???????
  396. * @param string $value
  397. * @return string
  398. */
  399. function withNamespace($value){
  400. /***
  401. * $parser = new TemplateParser();
  402. * eq("rt:hoge",$parser->withNamespace("hoge"));
  403. */
  404. return "rt:".$value;
  405. }
  406. function _getCacheUrl($templateFileName){
  407. return parent::_getCacheUrl(implode("-",array_merge(ArrayUtil::arrays($templateFileName),ArrayUtil::arrays($this->blockList))));
  408. }
  409. function _replaceSpecialVariables($src){
  410. return $this->_toStaticVariable("TemplateFormatter","f",parent::_replaceSpecialVariables($src));
  411. }
  412. }
  413. ?>