PageRenderTime 50ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/Module/Template/Template.php

https://github.com/DerDu/AIO-System
PHP | 253 lines | 150 code | 3 blank | 100 comment | 20 complexity | 78fadab2ba698f7739f11bbfeaffdc6e MD5 | raw file
Possible License(s): GPL-2.0, MIT, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * Template
  4. *
  5. // ---------------------------------------------------------------------------------------
  6. * LICENSE (BSD)
  7. *
  8. * Copyright (c) 2011, Gerd Christian Kunze
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are
  13. * met:
  14. *
  15. * * Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. *
  18. * * Redistributions in binary form must reproduce the above copyright
  19. * notice, this list of conditions and the following disclaimer in the
  20. * documentation and/or other materials provided with the distribution.
  21. *
  22. * * Neither the name of Gerd Christian Kunze nor the names of the
  23. * contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  27. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  28. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  29. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  30. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  31. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  32. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  33. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  34. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  35. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. // ---------------------------------------------------------------------------------------
  38. *
  39. * @package AIOSystem\Module
  40. * @subpackage Template
  41. */
  42. namespace AIOSystem\Module\Template;
  43. use \AIOSystem\Api\System;
  44. use \AIOSystem\Api\Stack;
  45. use \AIOSystem\Api\Cache;
  46. use \AIOSystem\Api\Event;
  47. /**
  48. * @package AIOSystem\Module
  49. * @subpackage Template
  50. */
  51. interface InterfaceTemplate {
  52. public static function Instance( $File, $ParsePhp = true );
  53. public function Content();
  54. public function Parse();
  55. public function Assign( $Template, $Value = null );
  56. public function Repeat( $Template, $Array );
  57. }
  58. /**
  59. * @package AIOSystem\Module
  60. * @subpackage Template
  61. */
  62. class ClassTemplate implements InterfaceTemplate {
  63. /** @var \AIOSystem\Core\ClassSystemFile $propertyTemplateFile */
  64. private $propertyTemplateFile = null;
  65. /** @var null|string $propertyTemplateContent */
  66. private $propertyTemplateContent = null;
  67. /** @var \AIOSystem\Core\ClassStackQueue $propertyAssignContent */
  68. private $propertyAssignContent = array();
  69. /** @var \AIOSystem\Core\ClassStackQueue $propertyAssignRepeat */
  70. private $propertyAssignRepeat = array();
  71. /** @var bool $ParseAfterContent */
  72. private $ParsePhpAfterContent = false;
  73. /** @var bool $isTemplateContent */
  74. private $isTemplateContent = false;
  75. /** @var array $EscapePattern */
  76. private $EscapePattern = array(
  77. '('=>'\(',')'=>'\)',
  78. '['=>'\[',']'=>'\]',
  79. '/'=>'\/',
  80. );
  81. /**
  82. * @static
  83. * @throws \Exception
  84. * @param string $File
  85. * @return ClassTemplate
  86. */
  87. public static function Instance( $File, $ParsePhp = true, $ParsePhpAfterContent = false, $isTemplateContent = false ) {
  88. return new ClassTemplate( $File, $ParsePhp, $ParsePhpAfterContent, $isTemplateContent );
  89. }
  90. public function __construct( $File, $ParsePhp = true, $ParsePhpAfterContent = false, $isTemplateContent = false ) {
  91. $this->propertyAssignContent = Stack::Queue();
  92. $this->propertyAssignRepeat = Stack::Queue();
  93. if( !$isTemplateContent && file_exists( $File ) ) {
  94. $this->propertyTemplateFile = System::File( $File );
  95. //var_dump( 'Load: '.$File );
  96. } else if( $isTemplateContent ) {
  97. $this->isTemplateContent = $isTemplateContent;
  98. } else {
  99. Event::Message('Load Template: '.$File);
  100. throw new \Exception( 'Template not available!' );
  101. }
  102. if( $this->isTemplateContent ) {
  103. if( $ParsePhpAfterContent ) {
  104. // TODO: Parse PHP not available
  105. $this->Content( $File );
  106. $this->ParsePhpAfterContent = true;
  107. } else {
  108. $this->Content( $File );
  109. }
  110. } else {
  111. if( $ParsePhpAfterContent ) {
  112. $this->Content( $this->propertyTemplateFile->readFile( false ) );
  113. $this->ParsePhpAfterContent = true;
  114. } else {
  115. $this->Content( $this->propertyTemplateFile->readFile( $ParsePhp ) );
  116. }
  117. }
  118. }
  119. /**
  120. * @param null|string $Content
  121. * @return string
  122. */
  123. public function Content( $Content = null ) {
  124. if( $Content !== null ) {
  125. $this->propertyTemplateContent = $Content;
  126. } return $this->propertyTemplateContent;
  127. }
  128. /**
  129. * @return array
  130. */
  131. public function MapAssign() {
  132. return $this->propertyAssignContent->listData();
  133. }
  134. /**
  135. * @return array
  136. */
  137. public function MapRepeat() {
  138. return $this->propertyAssignRepeat->listData();
  139. }
  140. /**
  141. * @param string $RepeatKey
  142. * @param array $DataArray
  143. * @param string $Content
  144. * @return string
  145. */
  146. private function ParseRepeat( $RepeatKey, $DataArray, $Content ) {
  147. preg_match_all( '!{'.$RepeatKey.'}(.*?){\/'.$RepeatKey.'}!is', $Content , $Matches );
  148. foreach( (array)$Matches[1] as $TemplateIndex => $TemplateContent ) {
  149. $TemplateRepeat = '';
  150. foreach( (array)$DataArray as $RowIndex => $ValueList ) {
  151. $TemplateContentRow = $TemplateContent;
  152. foreach( (array)$ValueList as $Key => $Value ) {
  153. if( is_array( $Value ) ) {
  154. $TemplateContentRow = $this->ParseRepeat( $Key, $Value, $TemplateContentRow );
  155. } else {
  156. $Key = str_replace( array_keys( $this->EscapePattern ), array_values( $this->EscapePattern ), $Key );
  157. $TemplateContentRow = preg_replace( '!{'.$Key.'}!is', $Value, $TemplateContentRow );
  158. }
  159. }
  160. $TemplateRepeat .= $TemplateContentRow;
  161. }
  162. $Content = preg_replace( '!{'.$RepeatKey.'}(.*?){\/'.$RepeatKey.'}!is', $TemplateRepeat, $Content, 1 );
  163. }
  164. return $Content;
  165. }
  166. /**
  167. * Parse Template
  168. *
  169. * @param boolean $doCleanup
  170. * @return string
  171. */
  172. public function Parse( $doCleanup = false ) {
  173. // LeftOver -> Empty String
  174. if( true === $doCleanup ) {
  175. $PlaceholderList = $this->Fetch('.*?');
  176. foreach( $PlaceholderList[0] as $Placeholder ) {
  177. $this->Assign( $Placeholder, '' );
  178. }
  179. }
  180. while( $this->propertyAssignRepeat->peekData() !== null ) {
  181. $Repeat = $this->propertyAssignRepeat->popData();
  182. $Content = $this->Content();
  183. preg_match_all( '!{'.$Repeat[0].'}(.*?){\/'.$Repeat[0].'}!is', $Content , $Matches );
  184. foreach( (array)$Matches[1] as $TemplateIndex => $TemplateContent ) {
  185. $TemplateRepeat = '';
  186. foreach( (array)$Repeat[1] as $RowIndex => $ValueList ) {
  187. $TemplateContentRow = $TemplateContent;
  188. foreach( (array)$ValueList as $Key => $Value ) {
  189. if( is_array( $Value ) ) {
  190. $TemplateContentRow = $this->ParseRepeat( $Key, $Value, $TemplateContentRow );
  191. } else {
  192. $Key = str_replace( array_keys( $this->EscapePattern ), array_values( $this->EscapePattern ), $Key );
  193. $TemplateContentRow = preg_replace( '!{'.$Key.'}!is', $Value, $TemplateContentRow );
  194. }
  195. }
  196. $TemplateRepeat .= $TemplateContentRow;
  197. }
  198. $Content = preg_replace( '!{'.$Repeat[0].'}(.*?){\/'.$Repeat[0].'}!is', $TemplateRepeat, $Content, 1 );
  199. }
  200. $this->Content( $Content );
  201. }
  202. $Content = $this->Content();
  203. while( $this->propertyAssignContent->peekData() !== null ) {
  204. $Replace = $this->propertyAssignContent->popData();
  205. $Content = preg_replace( '!{'.$Replace[0].'}!is', $Replace[1], $Content );
  206. }
  207. $this->Content( $Content );
  208. if( $this->ParsePhpAfterContent ) {
  209. Cache::Set( $this->Content(), $this->Content(), 'Template', false, 10 );
  210. ob_start(); include( Cache::GetLocation( $this->Content(), 'Template', false ) );
  211. $this->Content( ob_get_clean() );
  212. }
  213. return $this->Content();
  214. }
  215. /**
  216. * @param string|array $Template
  217. * @param string|null $Value
  218. * @return void
  219. */
  220. public function Assign( $Template, $Value = null ) {
  221. if( is_array( $Template ) ) {
  222. $this->_assignArray( $Template );
  223. } else {
  224. $this->propertyAssignContent->pushData( array( $Template, $Value ) );
  225. }
  226. }
  227. public function Fetch( $TemplateRegExp ) {
  228. $Matches = array();
  229. preg_match_all( '!(?<={)'.str_replace('!','\!',$TemplateRegExp).'(?=})!is', $this->Content(), $Matches );
  230. return $Matches;
  231. }
  232. /**
  233. * @param string $Template
  234. * @param array $Array array( array( 'Template'=>'Value or Sub-Repeat-Array', ... ), ... )
  235. * @return void
  236. */
  237. public function Repeat( $Template, $Array ) {
  238. $this->propertyAssignRepeat->pushData( array( $Template, $Array ) );
  239. }
  240. /**
  241. * @param array $Array
  242. * @return void
  243. */
  244. private function _AssignArray( $Array ) {
  245. foreach( (array)$Array as $Template => $Value ) {
  246. $this->Assign( $Template, $Value );
  247. }
  248. }
  249. }
  250. ?>