PageRenderTime 39ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/src/SimpleTemplate/SimpleTemplateAbstract.php

https://gitlab.com/php.bjoernbartels.earth/simpletemplate
PHP | 288 lines | 124 code | 34 blank | 130 comment | 15 complexity | 38c84ad9bc619f93de8662a5065c1f88 MD5 | raw file
  1. <?php
  2. /**
  3. * simple template engine class abstract
  4. *
  5. * @package SimpleTemplate
  6. * @author Björn Bartels <coding@bjoernbartels.earth>
  7. * @link https://gitlab.bjoernbartels.earth/groups/zf2
  8. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  9. * @copyright copyright (c) 2016 Björn Bartels <coding@bjoernbartels.earth>
  10. */
  11. namespace SimpleTemplate;
  12. /**
  13. * light template mechanism abstract
  14. */
  15. abstract class SimpleTemplateAbstract implements SimpleTemplateInterface
  16. {
  17. /**
  18. * Needles (static)
  19. *
  20. * @var array
  21. */
  22. public $needles = array();
  23. /**
  24. * Replacements (static)
  25. *
  26. * @var array
  27. */
  28. public $replacements = array();
  29. /**
  30. * dynamicNeedles (dynamic)
  31. *
  32. * @var array
  33. */
  34. public $dynamicNeedles = array();
  35. /**
  36. * dynamicReplacements (dynamic)
  37. *
  38. * @var array
  39. */
  40. public $dynamicReplacements = array();
  41. /**
  42. * Dynamic counter
  43. *
  44. * @var int
  45. */
  46. public $dynamicContent = 0;
  47. /**
  48. * Tags array (for dynamic blocks);
  49. *
  50. * @var array
  51. */
  52. public $tags = array(
  53. 'static' => '{%s}',
  54. 'start' => '<!-- BEGIN:BLOCK -->',
  55. 'end' => '<!-- END:BLOCK -->'
  56. );
  57. /**
  58. * gettext domain (default: 'default')
  59. *
  60. * @var string
  61. */
  62. public $_sDomain = "default";
  63. /**
  64. * text encoding (default: '')
  65. *
  66. * @var string
  67. */
  68. public $_encoding = "";
  69. /**
  70. * Constructor function
  71. *
  72. * @param array|null $tags
  73. */
  74. public function __construct($tags = null)
  75. {
  76. if (is_array($tags)) {
  77. $this->tags = array_merge($this->tags, $tags);
  78. }
  79. $this->setEncoding("");
  80. }
  81. /**
  82. * setDomain
  83. *
  84. * Sets the gettext domain to use for translations in a template
  85. *
  86. * @param $sDomain string Sets the domain to use for template translations
  87. * @return self
  88. */
  89. public function setDomain($sDomain)
  90. {
  91. $this->_sDomain = $sDomain;
  92. return $this;
  93. }
  94. /**
  95. * getDomain
  96. *
  97. * Gets the gettext domain to use for translations in a template
  98. *
  99. * @return string
  100. */
  101. public function getDomain()
  102. {
  103. return $this->_sDomain;
  104. }
  105. /**
  106. * Set Templates placeholders and values
  107. *
  108. * With this method you can replace the placeholders
  109. * in the static templates with dynamic data.
  110. *
  111. * @param $which String 's' for Static or else dynamic
  112. * @param $needle String Placeholder
  113. * @param $replacement String Replacement String
  114. *
  115. * @return self
  116. */
  117. public function set($which = 's', $needle, $replacement)
  118. {
  119. if ($which == 's') { // static
  120. $this->needles[] = sprintf($this->tags['static'], $needle);
  121. $this->replacements[] = $replacement;
  122. } else
  123. { // dynamic
  124. $this->dynamicNeedles[$this->dynamicContent][] = sprintf($this->tags['static'], $needle);
  125. $this->dynamicReplacements[$this->dynamicContent][] = $replacement;
  126. }
  127. return $this;
  128. }
  129. /**
  130. * Sets an encoding for the template's head block.
  131. *
  132. * @param $encoding string Encoding to set
  133. * @return self
  134. */
  135. public function setEncoding($encoding)
  136. {
  137. $this->_encoding = $encoding;
  138. return $this;
  139. }
  140. /**
  141. * Iterate internal counter by one
  142. *
  143. * @return self
  144. */
  145. public function next()
  146. {
  147. $this->dynamicContent++;
  148. return $this;
  149. }
  150. /**
  151. * Reset template data
  152. *
  153. * @return self
  154. */
  155. public function reset()
  156. {
  157. $this->dynamicContent = 0;
  158. $this->needles = array();
  159. $this->replacements = array();
  160. $this->dynamicNeedles = array();
  161. $this->dynamicReplacements = array();
  162. return $this;
  163. }
  164. /**
  165. * Generate the template and print/return it.
  166. *
  167. * @param $template string/file Template
  168. * @param $return bool Return or print template
  169. *
  170. * @return string complete Template string
  171. */
  172. public function generate($template, $return = 0)
  173. {
  174. //check if the template is a file or a string
  175. if (!@ is_file($template)) {
  176. $content = & $template; //template is a string (it is a reference to save memory!!!)
  177. } else {
  178. $content = implode("", file($template)); //template is a file
  179. }
  180. $pieces = array();
  181. //replace i18n strings before replacing other placeholders
  182. $this->replacei18n($content, "i18n");
  183. $this->replacei18n($content, "translate");
  184. //if content has dynamic blocks
  185. if (preg_match("/^.*".preg_quote($this->tags['start'], "/").".*?".preg_quote($this->tags['end'], "/").".*$/s", $content)) {
  186. //split everything into an array
  187. preg_match_all("/^(.*)".preg_quote($this->tags['start'], "/")."(.*?)".preg_quote($this->tags['end'], "/")."(.*)$/s", $content, $pieces);
  188. //safe some memory
  189. array_shift($pieces);
  190. $content = "";
  191. //now combine pieces together
  192. //start block
  193. $content .= str_replace($this->needles, $this->replacements, $pieces[0][0]);
  194. unset($pieces[0][0]);
  195. //generate dynamic blocks
  196. for ($a = 0; $a < $this->dynamicContent; $a++) {
  197. $content .= str_replace($this->dynamicNeedles[$a], $this->dynamicReplacements[$a], $pieces[1][0]);
  198. }
  199. unset($pieces[1][0]);
  200. //end block
  201. $content .= str_replace($this->needles, $this->replacements, $pieces[2][0]);
  202. unset($pieces[2][0]);
  203. } else {
  204. $content = str_replace($this->needles, $this->replacements, $content);
  205. }
  206. if ($this->_encoding != "") {
  207. $content = '<meta http-equiv="Content-Type" content="text/html; charset='.$this->_encoding.'">'."\n".$content;
  208. }
  209. if ($return) {
  210. return $content;
  211. } else {
  212. echo $content;
  213. }
  214. }
  215. /**
  216. * replacei18n()
  217. *
  218. * Replaces a named function with the translated variant
  219. *
  220. * @param $template string Contents of the template to translate (it is reference to save memory!!!)
  221. * @param $functionName string Name of the translation function (e.g. i18n)
  222. * @return self
  223. */
  224. public function replacei18n(& $template, $functionName)
  225. {
  226. // Be sure that php code stays unchanged
  227. $php_matches = array();
  228. $container = array();
  229. if (preg_match_all('/<\?(php)?((.)|(\s))*?\?>/i', $template, $php_matches)) {
  230. $x = 0;
  231. foreach ($php_matches[0] as $php_match) {
  232. $x++;
  233. $template = str_replace($php_match, "{PHP#".$x."#PHP}", $template);
  234. $container[$x] = $php_match;
  235. }
  236. }
  237. // If template contains functionName + parameter store all matches
  238. $matches = array();
  239. preg_match_all("/".preg_quote($functionName, "/")."\\(([\\\"\\'])(.*?)\\1\\)/s", $template, $matches);
  240. $matches = array_values(array_unique($matches[2]));
  241. $matchcount = count($matches);
  242. for ($a = 0; $a < $matchcount; $a++) {
  243. $template = preg_replace("/".preg_quote($functionName, "/")."\\([\\\"\\']".preg_quote($matches[$a], "/")."[\\\"\\']\\)/s", gettext($matches[$a]), $template);
  244. }
  245. // , this->_sDomain
  246. // Change back php placeholder
  247. if (is_array($container)) {
  248. foreach ($container as $x => $php_match) {
  249. $template = str_replace("{PHP#".$x."#PHP}", $php_match, $template);
  250. }
  251. }
  252. return $this;
  253. }
  254. }