1414 */
1515class TextTemplate
1616{
17- /** @var array */
17+ /**
18+ * comments: {* comments ... *}
19+ */
20+ const MATCH_COMMENT = '#\{\*.*?\*\}#sm ' ;
21+
22+ /**
23+ * {#include 'text-0.tpl'}
24+ */
25+ const MATCH_INCLUDE = '#\{\#include (.*)\}# ' ;
26+
27+ /** @var array */
1828 private $ vars = [];
1929
20- /** @var string */
30+ /** @var string */
2131 private $ openChar = '{$ ' ;
2232
23- /** @var string */
33+ /** @var string */
2434 private $ closeChar = '} ' ;
2535
36+ /** @var string */
37+ private $ basePath ;
38+
39+ /** @var bool clear first and last space. */
40+ private $ clearFLSpace = true ;
41+
2642 /**
2743 * TextTemplate constructor.
2844 * @param array $vars
@@ -34,6 +50,11 @@ public function __construct(array $vars = [])
3450 }
3551 }
3652
53+ public function reset ()
54+ {
55+ $ this ->vars = [];
56+ }
57+
3758 /**
3859 * @param string $tplFile
3960 * @param array $vars
@@ -46,6 +67,10 @@ public function renderFile(string $tplFile, array $vars = [], $saveAs = null)
4667 throw new \InvalidArgumentException ("Template file not exists. FILE: $ tplFile " );
4768 }
4869
70+ if (!$ this ->basePath ) {
71+ $ this ->basePath = \dirname ($ tplFile );
72+ }
73+
4974 return $ this ->render (file_get_contents ($ tplFile ), $ vars , $ saveAs );
5075 }
5176
@@ -73,9 +98,23 @@ public function render(string $template, array $vars = [], $saveAs = null)
7398 $ pairs [$ key ] = $ value ;
7499 }
75100
101+ // has include tag
102+ if ($ this ->basePath && false !== strpos ($ template , '{#include ' )) {
103+ $ template = (string )preg_replace_callback (self ::MATCH_INCLUDE , function ($ m ) use ($ pairs ) {
104+ return $ this ->renderInclude ($ m , $ pairs );
105+ }, $ template );
106+ }
107+
108+ // remove comments
109+ $ template = $ this ->removeComments ($ template );
110+
76111 // replace vars to values.
77112 $ rendered = strtr ($ template , $ pairs );
78113
114+ if ($ this ->clearFLSpace ) {
115+ $ rendered = trim ($ rendered );
116+ }
117+
79118 if (!$ saveAs ) {
80119 return $ rendered ;
81120 }
@@ -89,6 +128,45 @@ public function render(string $template, array $vars = [], $saveAs = null)
89128 return (bool )file_put_contents ($ saveAs , $ rendered );
90129 }
91130
131+ /**
132+ * @param array $matches
133+ * @param array $data
134+ * @return string
135+ */
136+ protected function renderInclude (array $ matches , array $ data )
137+ {
138+ if (!isset ($ matches [1 ]) || !($ include = trim ($ matches [1 ], ' \'" ' ))) {
139+ return '!!CANNOT INCLUDE EMPTY FILE!! ' ;
140+ }
141+
142+ $ include = $ this ->basePath . '/ ' . $ include ;
143+
144+ if (!\is_file ($ include )) {
145+ return '!!THE INCLUDE FILE NOT FOUND!! ' ;
146+ }
147+
148+ $ rendered = strtr (file_get_contents ($ include ), $ data );
149+
150+ if ($ this ->clearFLSpace ) {
151+ $ rendered = trim ($ rendered );
152+ }
153+
154+ return $ rendered ;
155+ }
156+
157+ /**
158+ * @param string $input
159+ * @return string
160+ */
161+ protected function removeComments (string $ input )
162+ {
163+ return preg_replace (
164+ self ::MATCH_COMMENT ,
165+ '' ,
166+ $ input = str_replace ("\r\n" , "\n" , $ input )
167+ );
168+ }
169+
92170 /**
93171 * Multidimensional array expansion to one dimension array
94172 * @param array $vars
@@ -197,4 +275,31 @@ public function setCloseChar(string $closeChar)
197275 $ this ->closeChar = $ closeChar ;
198276 }
199277 }
278+
279+ /**
280+ * @return string
281+ */
282+ public function getBasePath ()
283+ {
284+ return $ this ->basePath ;
285+ }
286+
287+ /**
288+ * @param string $basePath
289+ */
290+ public function setBasePath (string $ basePath )
291+ {
292+ $ this ->basePath = $ basePath ;
293+ }
294+
295+ /**
296+ * @param bool $clearFLSpace
297+ * @return TextTemplate
298+ */
299+ public function setClearFLSpace (bool $ clearFLSpace ): TextTemplate
300+ {
301+ $ this ->clearFLSpace = $ clearFLSpace ;
302+
303+ return $ this ;
304+ }
200305}
0 commit comments