1 : <?php
2 :
3 : /**
4 : * XSLT Benchmarking
5 : * @link https://github.com/masicek/XSLT-Benchmarking
6 : * @author Viktor Mašíček <viktor@masicek.net>
7 : * @license "New" BSD License
8 : */
9 :
10 : namespace XSLTBenchmarking\TestsGenerator;
11 :
12 : require_once LIBS . '/Smarty/Smarty.class.php';
13 : require_once LIBS . '/PhpPath/PhpPath.min.php';
14 : require_once __DIR__ . '/ITemplatingDriver.php';
15 : require_once ROOT . '/Exceptions.php';
16 :
17 :
18 : use PhpPath\P;
19 :
20 : /**
21 : * Extend of Smarty for generating XSLT files from template.
22 : *
23 : * @author Viktor Mašíček <viktor@masicek.net>
24 : */
25 : class SmartyTemplatingDriver extends \Smarty implements ITemplatingDriver
26 : {
27 :
28 :
29 : /**
30 : * Object configuration
31 : *
32 : * @param string $tmpDirectory The path of the temporary directory
33 : */
34 : public function __construct($tmpDirectory)
35 : {
36 5 : parent::__construct();
37 5 : $this->debugging = FALSE;
38 5 : $this->caching = FALSE;
39 5 : $this->compile_dir = P::mcd($tmpDirectory, '/');
40 :
41 4 : $this->registerPlugin('modifier', 'pathEnd', array($this, 'pathEnd'));
42 4 : $this->registerPlugin('modifier', 'timeNicer', array($this, 'timeNicer'));
43 4 : $this->registerPlugin('modifier', 'memoryNicer', array($this, 'memoryNicer'));
44 4 : }
45 :
46 :
47 : /**
48 : * Generate the template with specifis variable and save the content into the file
49 : *
50 : * @param string $templatePath Path of template for generating
51 : * @param string $outputPath Path output file
52 : * @param array $settings Array of variables for template
53 : *
54 : * @throws \XSLTBenchmarking\GenerateTemplateException Problem with generating
55 : * @return void
56 : */
57 : public function generate($templatePath, $outputPath, array $settings)
58 : {
59 3 : P::cf($templatePath);
60 :
61 : // set variables
62 2 : $this->assign('templateDir', pathinfo($templatePath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR);
63 2 : foreach ($settings as $name => $value)
64 : {
65 2 : $this->assign($name, $value);
66 2 : }
67 :
68 : // generate xslt
69 2 : ob_start();
70 : try {
71 2 : $this->display($templatePath);
72 2 : } catch (\Exception $e) {
73 1 : throw new \XSLTBenchmarking\GenerateTemplateException('Cannot generate template by Smarty Driver (' . $e->getMessage() . ')', 0, $e);
74 : }
75 1 : $content = ob_get_clean();
76 :
77 : // filtering of output
78 : // indent = default
79 : // linearize
80 : // nothing
81 1 : $indent = TRUE;
82 1 : $linearize = TRUE;
83 1 : if (isset($settings['outputFiler']))
84 1 : {
85 0 : switch ($settings['outputFiler'])
86 : {
87 0 : case 'linearize':
88 0 : $indent = FALSE;
89 0 : $linearize = TRUE;
90 0 : break;
91 0 : case 'nothing':
92 0 : $indent = FALSE;
93 0 : $linearize = FALSE;
94 0 : break;
95 0 : }
96 0 : }
97 : if ($linearize)
98 1 : {
99 1 : $content = $this->repareIndent($content, $indent);
100 1 : }
101 :
102 1 : if (!file_put_contents($outputPath, $content))
103 : {// @codeCoverageIgnoreStart
104 : throw new \XSLTBenchmarking\GenerateTemplateException('Cannot create file "' . $outputFile . '".');
105 : }// @codeCoverageIgnoreEnd
106 1 : }
107 :
108 :
109 : /**
110 : * Repare indent of output content, for better human reading.
111 : *
112 : * @param string $content Repared content
113 : * @param bool $indent Flag, if we want indent of the content
114 : *
115 : * @return string
116 : */
117 : public function repareIndent($content, $indent)
118 : {
119 : // linearize
120 1 : $content = preg_replace('/>[\s]*</', '><', $content);
121 :
122 1 : if (!$indent)
123 1 : {
124 0 : return $content;
125 : }
126 :
127 : // make indent
128 1 : $contentSimpleXml = new \SimpleXMLElement($content);
129 1 : $contentDomXml = dom_import_simplexml($contentSimpleXml)->ownerDocument;
130 1 : $contentDomXml->formatOutput = TRUE;
131 1 : $content = $contentDomXml->saveXml();
132 :
133 : // better indent
134 1 : $content = str_replace("\r\n", "\n", $content);
135 1 : $lines = explode("\n", $content);
136 1 : $linesNew = array();
137 1 : foreach ($lines as $line)
138 : {
139 1 : $indentEndPos = strpos($line, '<');
140 1 : $linesNew[] = str_repeat("\t", $indentEndPos / 2) . substr($line, $indentEndPos);
141 1 : }
142 1 : $content = implode(PHP_EOL, $linesNew);
143 :
144 : // separate each template
145 1 : $content = preg_replace('/(\t*<xsl:template)/', PHP_EOL . '$0', $content);
146 1 : $content = str_replace('</xsl:stylesheet>', PHP_EOL . '</xsl:stylesheet>', $content);
147 :
148 1 : return $content;
149 : }
150 :
151 :
152 : //---- SMARTY MODIFIERS ----
153 :
154 :
155 : /**
156 : * Return last $parts parts of path.
157 : *
158 : * @param string $path Modified path
159 : * @param int $partsNumber Number of last parts
160 : *
161 : * @return string
162 : */
163 : public function pathEnd($path, $partsNumber = 1)
164 : {
165 0 : $parts = explode('/', $path);
166 0 : $separator = '/';
167 0 : if (count($parts) == 1)
168 0 : {
169 0 : $parts = explode('\\', $path);
170 0 : $separator = '\\';
171 0 : }
172 0 : $parts = array_slice($parts, -$partsNumber);
173 0 : return implode($separator, $parts);
174 : }
175 :
176 :
177 : /**
178 : * Return round time.
179 : *
180 : * @param string $time Modified time
181 : *
182 : * @return string
183 : */
184 : public function timeNicer($time)
185 : {
186 0 : if ($time === '')
187 0 : {
188 0 : return '';
189 : }
190 0 : return substr($time, 0, -3) . ' sec';
191 : }
192 :
193 :
194 : /**
195 : * Return round memory with unit.
196 : *
197 : * @param string $memory Modified memory in bytes
198 : *
199 : * @return string
200 : */
201 : public function memoryNicer($memory)
202 : {
203 0 : if ($memory === '')
204 0 : {
205 0 : return '';
206 : }
207 :
208 : $units = array(
209 0 : 'GB' => 1000000000,
210 0 : 'MB' => 1000000,
211 0 : 'KB' => 1000,
212 0 : 'B' => 1,
213 0 : );
214 :
215 0 : $number = (int)$memory;
216 0 : foreach ($units as $unit => $limit)
217 : {
218 0 : if ($number > $limit)
219 0 : {
220 0 : $rounded = number_format($number / $limit, 1) . ' ' . $unit;
221 0 : break;
222 : }
223 0 : }
224 :
225 0 : return $rounded;
226 : }
227 :
228 :
229 : }
|