Guest User

Untitled

a guest
Jul 3rd, 2018
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.72 KB | None | 0 0
  1. <?php
  2. /**
  3. * Template para o Spaghetti
  4. *
  5. * Sistema de templates para ser trocado pelas Views do Framework Spaghetti
  6. *
  7. * @author Victoremberg Feitoza <vfeitoza@gmail.com>
  8. * @version 0.3
  9. */
  10. class TemplateComponent extends Template {
  11. public $controller = null;
  12. public $data = array();
  13. public $params = array();
  14.  
  15. /**
  16. * Inicialização da classe pelo Spaghetti
  17. *
  18. * @param resource $controller
  19. */
  20. public function initialize(&$controller) {
  21. $this->controller = $controller;
  22. $this->params = $controller->params;
  23.  
  24. $this->loadFile(".", APP . DS .'layouts'. DS . $this->controller->layout.'.phtm');
  25. $this->addFile('CONTEUDO', APP . DS .'views'. DS . $this->params['controller']. DS .$this->params['action'].'.phtm');
  26. }
  27. /**
  28. * Repassa um array POST para re-enviar aos seus referidos campos
  29. * @author Victor Feitoza <vfeitoza@gmail.com>
  30. *
  31. * @param array $data
  32. */
  33. public function arrayVal($data) {
  34. foreach ($data as $chave => $valor) {
  35. $variavel = strtoupper($chave);
  36. if (is_array($valor)) {
  37. foreach ($valor as $chave => $valor) {
  38. if ($chave == 'id') {
  39. $chave = $variavel .'_ID';
  40. }
  41. $this->setValue(strtoupper($chave), $valor);
  42. }
  43. }
  44. $this->setValue($variavel, $valor);
  45. }
  46. }
  47. }
  48. ?>
  49.  
  50.  
  51. <?php
  52. /**
  53. * Mecanismo de Template para PHP5
  54. *
  55. * Mecanismos de Template permitem manter o código HTML em arquivos externos
  56. * que ficam completamente livres de código PHP. Dessa forma, consegue-se manter
  57. * a lógica de programação (PHP) separada da estrutura visual (HTML ou XML, CSS, etc).
  58. *
  59. * Se você já é familiar ao uso de mecanismos de template PHP, esta classe inclui
  60. * algumas melhorias: suporte à objetos, automaticamente detecta blocos, mantém uma
  61. * lista interna das variáveis que existem, limpa automaticamente blocos "filhos",
  62. * avisando quando tentamos chamar blocos ou variáveis que são existem, avisando quando
  63. * criamos blocos "mal formados", e outras pequenas ajudas.
  64. *
  65. * @author Rael G.C. (rael.gc@gmail.com)
  66. * @version 1.6
  67. */
  68. class Template {
  69.  
  70. /**
  71. * A list of existent document variables.
  72. *
  73. * @var array
  74. */
  75. private $vars = array();
  76.  
  77. /**
  78. * A hash with vars and values setted by the user.
  79. *
  80. * @var array
  81. */
  82. private $values = array();
  83.  
  84. /**
  85. * A hash of existent object properties variables in the document.
  86. *
  87. * @var array
  88. */
  89. private $properties = array();
  90.  
  91. /**
  92. * A hash of the object instances setted by the user.
  93. *
  94. * @var array
  95. */
  96. private $instances = array();
  97.  
  98. /**
  99. * A list of all automatic recognized blocks.
  100. *
  101. * @var array
  102. */
  103. private $blocks = array();
  104.  
  105. /**
  106. * A list of all blocks that contains at least a "child" block.
  107. *
  108. * @var array
  109. */
  110. private $parents = array();
  111.  
  112. /**
  113. * Describes the replace method for blocks. See the Template::setFile()
  114. * method for more details.
  115. *
  116. * @var boolean
  117. */
  118. private $accurate;
  119.  
  120. /**
  121. * Regular expression to find var and block names.
  122. * Only alfa-numeric chars and the underscore char are allowed.
  123. *
  124. * @var string
  125. */
  126. private static $REG_NAME = "([[:alnum:]]|_)+";
  127.  
  128. /**
  129. * Cria um novo template, usando $filename como arquivo principal
  130. *
  131. * Quando o parâmetro $accurate é true, a substituição dos blocos no arquivo
  132. * final será perfeitamente fiel ao arquivo original, isto é, todas as tabulações
  133. * serão removidas. Isso vai ter um pequeno prejuízo na performance, que pode variar
  134. * de acordo com a versão do PHP em uso. Mas é útil quando estamos usando tags HTML
  135. * como <pre> ou <code>. Em outros casos, ou melhor, quase sempre,
  136. * nunca se mexe no valor de $accurate.
  137. *
  138. * @param string $filename caminho do arquivo que será lido
  139. * @param booelan $accurate true para fazer substituição fiel das tabulações
  140. */
  141. public function construct($filename = null, $accurate = false){
  142. $this->accurate = $accurate;
  143. $this->loadfile(".", $filename);
  144. }
  145.  
  146. /**
  147. * Adiciona o conteúdo do arquivo identificado por $filename na variável de template
  148. * identificada por $varname
  149. *
  150. * @param string $varname uma variável de template existente
  151. * @param string $filename arquivo a ser carregado
  152. */
  153. public function addFile($varname, $filename){
  154. if(!in_array($varname, $this->vars)) throw new InvalidArgumentException("addFile: var $varname não existe");
  155. $this->loadfile($varname, $filename);
  156. }
  157.  
  158. /**
  159. * Não use este método, ele serve apenas para podemos acessar as variáveis
  160. * de template diretamente.
  161. *
  162. * @param string $varname template var name
  163. * @param mixed $value template var value
  164. */
  165. public function __set($varname, $value){
  166. //if(!in_array($varname, $this->vars)) throw new RuntimeException("var $varname não existe");
  167. $stringValue = $value;
  168. if(is_object($value)){
  169. $this->instances[$varname] = $value;
  170. if(!array_key_exists($varname, $this->properties)) $this->properties[$varname] = array();
  171. if(method_exists($value, "__toString")) $stringValue = $value->__toString();
  172. else $stringValue = "Object";
  173. }
  174. $this->setValue($varname, $stringValue);
  175. return $value;
  176. }
  177.  
  178. /**
  179. * Não use este método, ele serve apenas para podemos acessar as variáveis
  180. * de template diretamente.
  181. *
  182. * @param string $varname template var name
  183. */
  184. public function __get($varname){
  185. if (isset($this->values["{".$varname."}"])) return $this->values["{".$varname."}"];
  186. throw new RuntimeException("var $varname não existe");
  187. }
  188.  
  189. /**
  190. * Loads a file identified by $filename.
  191. *
  192. * The file will be loaded and the file's contents will be assigned as the
  193. * variable's value.
  194. * Additionally, this method call Template::recognize() that identifies
  195. * all blocks and variables automatically.
  196. *
  197. * @param string $varname contains the name of a variable to load
  198. * @param string $filename file name to be loaded
  199. *
  200. * @return void
  201. */
  202. public function loadfile($varname, $filename) {
  203. //if (!file_exists($filename)) throw new InvalidArgumentException("arquivo $filename não existe");
  204. if (!file_exists($filename)) $filename = APP .'/layouts/null.phtm';
  205. $file_array = file($filename);
  206. $blocks = $this->recognize($file_array, $varname);
  207. $str = implode("", $file_array);
  208. //if (empty($str)) throw new InvalidArgumentException("arquivo $filename está vazio");
  209. $this->setValue($varname, $str);
  210. $this->createBlocks($blocks);
  211. }
  212.  
  213. /**
  214. * Identify all blocks and variables automatically and return them.
  215. *
  216. * All variables and blocks are already identified at the moment when
  217. * user calls Template::setFile(). This method calls Template::identifyVars()
  218. * and Template::identifyBlocks() methods to do the job.
  219. *
  220. * @param array $file_array contains all lines from the content file
  221. * @param string $varname contains the variable name of the file
  222. *
  223. * @return array an array where the key is the block name and the value is an
  224. * array with the children block names.
  225. */
  226. private function recognize(&$file_array, $varname){
  227. $blocks = array();
  228. $queued_blocks = array();
  229. foreach ($file_array as $line) {
  230. if (strpos($line, "{")!==false) $this->identifyVars($line);
  231. if (strpos($line, "<!--")!==false) $this->identifyBlocks($line, $varname, $queued_blocks, $blocks);
  232. }
  233. return $blocks;
  234. }
  235.  
  236. /**
  237. * Identify all user defined blocks automatically.
  238. *
  239. * @param string $line contains one line of the content file
  240. * @param string $varname contains the filename variable identifier
  241. * @param string $queued_blocks contains a list of the current queued blocks
  242. * @param string $blocks contains a list of all identified blocks in the current file
  243. *
  244. * @return void
  245. */
  246. private function identifyBlocks(&$line, $varname, &$queued_blocks, &$blocks){
  247. $reg = "/<!--\s*BEGIN\s+(".self::$REG_NAME.")\s*-->/sm";
  248. preg_match($reg, $line, $m);
  249. if (1==preg_match($reg, $line, $m)){
  250. if (0==sizeof($queued_blocks)) $parent = $varname;
  251. else $parent = end($queued_blocks);
  252. if (!isset($blocks[$parent])){
  253. $blocks[$parent] = array();
  254. }
  255. $blocks[$parent][] = $m[1];
  256. $queued_blocks[] = $m[1];
  257. }
  258. $reg = "/<!--\s*END\s+(".self::$REG_NAME.")\s*-->/sm";
  259. if (1==preg_match($reg, $line)) array_pop($queued_blocks);
  260. }
  261.  
  262. /**
  263. * Identifies all variables defined in the document.
  264. *
  265. * @param string $line contains one line of the content file
  266. */
  267. private function identifyVars(&$line){
  268. $reg = "/{(".self::$REG_NAME.")(\-\>)?(".self::$REG_NAME.")?}/";
  269. $r = preg_match_all($reg, $line, $m);
  270. if ($r>0){
  271. for($i=0; $i<$r; $i++){
  272. // Object var detected
  273. if($m[4][$i]) $this->properties[$m[1][$i]][] = $m[4][$i];
  274. $this->vars[] = $m[1][$i];
  275. }
  276. }
  277. }
  278.  
  279. /**
  280. * Create all identified blocks given by Template::identifyBlocks().
  281. *
  282. * @param array $blocks contains all identified block names
  283. * @return void
  284. */
  285. private function createBlocks(&$blocks) {
  286. $this->parents = array_merge($this->parents, $blocks);
  287. foreach($blocks as $parent => $block){
  288. foreach($block as $chield){
  289. if(in_array($chield, $this->blocks)) throw new UnexpectedValueException("bloco duplicado: $chield");
  290. $this->blocks[] = $chield;
  291. $this->setBlock($parent, $chield);
  292. }
  293. }
  294. }
  295.  
  296. /**
  297. * A variable $parent may contain a variable block defined by:
  298. * <!-- BEGIN $varname --> content <!-- END $varname -->.
  299. *
  300. * This method removes that block from $parent and replaces it with a variable
  301. * reference named $block. The block is inserted into the varKeys and varValues
  302. * hashes.
  303. * Blocks may be nested.
  304. *
  305. * @param string $parent contains the name of the parent variable
  306. * @param string $block contains the name of the block to be replaced
  307. * @return void
  308. */
  309. private function setBlock($parent, $block) {
  310. $name = "B_".$block;
  311. $str = $this->getVar($parent);
  312. if($this->accurate){
  313. $str = str_replace("\r\n", "\n", $str);
  314. $reg = "/\t*<!--\s*BEGIN\s+$block\s+-->\n*(\s*.*?\n?)\t*<!--\s+END\s+$block\s*-->\n?/sm";
  315. }
  316. else $reg = "/<!--\s*BEGIN\s+$block\s+-->\n*(\s*.*?\n?)<!--\s+END\s+$block\s*-->\n?/sm";
  317. if(1!==preg_match($reg, $str, $m)) throw new UnexpectedValueException("bloco $block está mal formado");
  318. $this->setValue($name, '');
  319. $this->setValue($block, $m[1]);
  320. $this->setValue($parent, preg_replace($reg, "{".$name."}", $str));
  321. }
  322.  
  323. /**
  324. * Internal setValue() method.
  325. *
  326. * The main difference between this and Template::__set() method is this
  327. * method cannot be called by the user, and can be called using variables or
  328. * blocks as parameters.
  329. *
  330. * @param string $varname constains a varname
  331. * @param string $value constains the new value for the variable
  332. * @return void
  333. */
  334. private function setValue($varname, $value) {
  335. $this->values["{".$varname."}"] = $value;
  336. }
  337.  
  338. /**
  339. * Returns the value of the variable identified by $varname.
  340. *
  341. * @param string $varname the name of the variable to get the value of
  342. * @return string the value of the variable passed as argument
  343. */
  344. private function getVar($varname) {
  345. return $this->values['{'.$varname.'}'];
  346. }
  347.  
  348. /**
  349. * Limpa o valor de uma variável
  350. *
  351. * O mesmo que $this->setValue($varname, "");
  352. *
  353. * @param string $varname nome da variável
  354. */
  355. public function clear($varname) {
  356. $this->setValue($varname, "");
  357. }
  358.  
  359. /**
  360. * Fill in all the variables contained within the variable named
  361. * $varname. The resulting value is returned as the function result and the
  362. * original value of the variable varname is not changed. The resulting string
  363. * is not "finished", that is, the unresolved variable name policy has not been
  364. * applied yet.
  365. *
  366. * @param string $varname the name of the variable within which variables are to be substituted
  367. * @return string the value of the variable $varname with all variables substituted.
  368. */
  369. private function subst($varname) {
  370. $s = $this->getVar($varname);
  371. // Common variables replacement
  372. $s = str_replace(array_keys($this->values), $this->values, $s);
  373. // Object variables replacement
  374. foreach($this->instances as $varname => $inst) foreach($this->properties[$varname] as $p){
  375. // Non boolean accessor
  376. $method = str_replace('_', '', $p);
  377. if(method_exists($inst, "get$method")) $s = str_replace("{".$varname.'->'.$p."}", $inst->{"get".$method}(), $s);
  378. // Boolean accessor
  379. elseif(method_exists($inst, "is$method")) $s = str_replace("{".$varname.'->'.$p."}", $inst->{"is".$method}(), $s);
  380. // Magic __get accessor
  381. elseif(method_exists($inst, "__get")) $s = str_replace("{".$varname.'->'.$p."}", $inst->__get($p), $s);
  382. else throw new BadMethodCallException("não existe método na classe ".get_class($inst)." para acessar ".$varname."->".$p);
  383. }
  384. return $s;
  385. }
  386.  
  387. /**
  388. * Clear all child blocks of a given block.
  389. *
  390. * @param string $block a block with chield blocks.
  391. */
  392. private function clearBlocks($block) {
  393. if (isset($this->parents[$block])){
  394. $chields = $this->parents[$block];
  395. foreach($chields as $chield){
  396. $this->clear("B_".$chield);
  397. }
  398. }
  399. }
  400.  
  401. /**
  402. * Mostra um bloco.
  403. *
  404. * Esse método deve ser chamado quando um bloco deve ser mostrado.
  405. * Sem isso, o bloco não irá aparecer no conteúdo final.
  406. *
  407. * Se o parâmetro $append for true, o conteúdo do bloco será
  408. * adicionado ao conteúdo que já existia antes. Ou seja, use true
  409. * quando quiser que o bloco seja duplicado.
  410. *
  411. * @param string $block nome do bloco que deve ser mostrado
  412. * @param boolean $append true se o conteúdo anterior deve ser mantido (ou seja, para duplicar o bloco)
  413. */
  414. public function block($block, $append = true) {
  415. if(!in_array($block, $this->blocks)) throw new InvalidArgumentException("bloco $block não existe");
  416. if ($append) $this->setValue("B_".$block, $this->getVar("B_".$block) . $this->subst($block));
  417. else $this->setValue("B_".$block, $this->subst($block));
  418. $this->clearBlocks($block);
  419. }
  420.  
  421. /**
  422. * Retorna o conteúdo final, sem mostrá-lo na tela.
  423. * Se você quer mostrá-lo na tela, use o método Template::show().
  424. *
  425. * @return string
  426. */
  427. public function parse() {
  428. // After subst, remove empty vars
  429. return preg_replace("/{(".self::$REG_NAME.")(\-\>)?(".self::$REG_NAME.")?}/", "", $this->subst("."));
  430. }
  431.  
  432. /**
  433. * Mostra na tela o conteúdo final.
  434. */
  435. public function show() {
  436. echo $this->parse();
  437. }
  438.  
  439. }
  440. ?>
Add Comment
Please, Sign In to add comment