/includes/templateView.php

https://gitlab.com/billyprice1/Addon-Frontend · PHP · 218 lines · 115 code · 28 blank · 75 comment · 27 complexity · ce0c0904f9cf374905d99bb09000712a MD5 · raw file

  1. <?php
  2. require_once('markerManager.php');
  3. class TemplateView {
  4. /**
  5. * The page template to use
  6. *
  7. * @var string
  8. */
  9. protected $template;
  10. /**
  11. * RenderCache
  12. *
  13. * @var array
  14. */
  15. protected $renderCache = array();
  16. /**
  17. * Internal instance of the markerManager
  18. *
  19. * @var MarkerManager
  20. */
  21. protected $markerManager;
  22. public function __construct() {
  23. global $markerManager;
  24. if (isset($markerManager)) {
  25. $this->markerManager = &$markerManager;
  26. } else {
  27. $this->markerManager = new MarkerManager();
  28. }
  29. }
  30. /**
  31. * Setter for the template to use
  32. *
  33. * @param string $template
  34. * @return void
  35. */
  36. public function setTemplate($template) {
  37. $this->template = $template;
  38. }
  39. /**
  40. * Setter for the markers to replace in the template
  41. *
  42. * @param array $marker
  43. * @return void
  44. */
  45. public function setMarker(array $marker) {
  46. foreach ($marker as $name => $value) {
  47. $this->markerManager->setMarker($name, $value);
  48. }
  49. }
  50. /**
  51. * Registers a additional marker handler to resolve missing markers
  52. *
  53. * @param mixed $className Either Classname or Instance
  54. * @return void
  55. */
  56. public function addMarkerHandler($className) {
  57. $this->markerManager->registerHandler($className);
  58. }
  59. /**
  60. * Renders the final page output
  61. *
  62. * @param string $templateName The template to render
  63. * @return string The rendered page;
  64. */
  65. public function render($templateName = NULL) {
  66. if ($templateName === NULL) $templateName = $this->template;
  67. if (isset($this->renderCache['content'][$templateName])) {
  68. return $this->renderCache['content'][$templateName];
  69. }
  70. // add template to processed list in order to prevent endless recursive nesting of template when rendering subtemplates
  71. if (isset($this->renderCache['processed']) && in_array($templateName, $this->renderCache['processed'])) {
  72. throw new Exception( sprintf('Recursive template rendering detected. Nesting path: %s', implode(' -> ', $this->renderCache['processed'])) );
  73. }
  74. $this->renderCache['processed'][] = $templateName;
  75. $templateCode = $this->getTemplate($templateName);
  76. $marker = $this->resolveUsedMarkers($templateCode);
  77. $output = $this->replaceMarker($marker, $templateCode);
  78. $this->renderCache['content'][$templateName] = $output;
  79. return $output;
  80. }
  81. /**
  82. * Replaces a collection of markers in a template
  83. *
  84. * @param array $marker
  85. * @param string $template
  86. * @return string
  87. */
  88. protected function replaceMarker(array $marker, $template) {
  89. return strtr($template, $marker);
  90. }
  91. /**
  92. * Reads the content of a template and returns it
  93. *
  94. * @param string $templateName
  95. * @param string $extension The file extension
  96. * @return string
  97. */
  98. protected function getTemplate($templateName, $extension = 'html') {
  99. if (!strlen($templateName)) throw new Exception('Empty template name given - can\'t render template!');
  100. $pathInfo = pathinfo($templateName);
  101. $templatePath = $this->getTemplatePath();
  102. $templateFile = $templateName;
  103. if (!isset($pathInfo['extension'])) {
  104. $templateFile .= '.' . $extension;
  105. } else {
  106. $extension = $pathInfo['extension'];
  107. }
  108. if (!is_file($templatePath . $templateFile)) throw new Exception(sprintf('Template file &quot;%s&quot; not found in the template path', $templateFile) );
  109. if ($extension == 'php') {
  110. ob_flush();
  111. ob_start();
  112. include($templatePath . $templateFile);
  113. $output = ob_get_contents();
  114. ob_end_clean();
  115. return $output;
  116. } else {
  117. return file_get_contents($templatePath . $templateFile);
  118. }
  119. }
  120. /**
  121. * Resolves the markers used in the template
  122. *
  123. * @param string $tempalteCode The raw template code (not the template name)
  124. * @return array Array with ###MARKER### => 'Replacement value' pairs
  125. */
  126. protected function resolveUsedMarkers($templateCode) {
  127. if (!strlen($templateCode)) return array();
  128. $markerArray = array();
  129. // find placeholders/markers for content
  130. if (preg_match_all('!(###|%%%)([A-Za-z0-9\._-|]*)\1!is', $templateCode, $matches)) {
  131. $usedMarkers = array_unique($matches[2]);
  132. if (count($usedMarkers)) {
  133. foreach ($usedMarkers as $key => $markerName) {
  134. $wrapper = $matches[1][$key];
  135. $marker = $wrapper . $markerName . $wrapper;
  136. // predefined? don't resolve new content for it
  137. if (isset($this->marker[$marker])) continue;
  138. // try to find the replacement content
  139. $replacement = $this->getMarkerContent($markerName, $wrapper);
  140. if($replacement == '' && isset($markerArray[$marker])) {
  141. $replacement = $markerArray[$marker];
  142. }
  143. $markerArray[$marker] = $replacement;
  144. }
  145. }
  146. }
  147. return $markerArray;
  148. }
  149. /**
  150. * Resolves the placeholders/markers of nested templates
  151. *
  152. * @param string $markerName The name of the marker
  153. * @param string $wrapper The wrapping string of the marker, like '###' or '%%%' that determins the type of marker
  154. * @return string The rendered marker if available
  155. */
  156. protected function getMarkerContent($markerName, $wrapper) {
  157. $content = '';
  158. switch ($wrapper) {
  159. default:
  160. case '###':
  161. if ($this->markerManager->hasMarker($markerName, $wrapper)) {
  162. $content = $this->markerManager->getMarker($markerName, $wrapper);
  163. }
  164. break;
  165. case '%%%';
  166. $templatePath = $this->getTemplatePath();
  167. $templateInfo = pathinfo($markerName);
  168. if (isset($templateInfo['extension'])) {
  169. $content = $this->render($markerName);
  170. } else if (@is_file($templatePath . $markerName . '.html')) {
  171. $content = $this->render($markerName . '.html');
  172. } else if (@is_file($templatePath . $markerName . '.php')) {
  173. $content = $this->getTemplate($markerName . '.php');
  174. }
  175. break;
  176. }
  177. return $content;
  178. }
  179. /**
  180. * Returns the absolute template path
  181. *
  182. * @return string
  183. */
  184. protected function getTemplatePath() {
  185. global $configuration;
  186. $root = getcwd();
  187. return $root . DIRECTORY_SEPARATOR . $configuration['templatePath'] . DIRECTORY_SEPARATOR;
  188. }
  189. }
  190. ?>