Completed
Push — master ( 92fdfc...c3dd6e )
by
unknown
18s queued 13s
created

src/Template/Template.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace League\Plates\Template;
4
5
use Exception;
6
use League\Plates\Engine;
7
use LogicException;
8
use Throwable;
9
10
/**
11
 * Container which holds template data and provides access to template functions.
12
 */
13
class Template
14
{
15
    /**
16
     * Instance of the template engine.
17
     * @var Engine
18
     */
19
    protected $engine;
20
21
    /**
22
     * The name of the template.
23
     * @var Name
24
     */
25
    protected $name;
26
27
    /**
28
     * The data assigned to the template.
29
     * @var array
30
     */
31
    protected $data = array();
32
33
    /**
34
     * An array of section content.
35
     * @var array
36
     */
37
    protected $sections = array();
38
39
    /**
40
     * The name of the section currently being rendered.
41
     * @var string
42
     */
43
    protected $sectionName;
44
45
    /**
46
     * Whether the section should be appended or not.
47
     * @var boolean
48
     */
49
    protected $appendSection;
50
51
    /**
52
     * The name of the template layout.
53
     * @var string
54
     */
55
    protected $layoutName;
56
57
    /**
58
     * The data assigned to the template layout.
59
     * @var array
60
     */
61
    protected $layoutData;
62
63
    /**
64
     * Create new Template instance.
65
     * @param Engine $engine
66
     * @param string $name
67
     */
68 62
    public function __construct(Engine $engine, $name)
69
    {
70 62
        $this->engine = $engine;
71 62
        $this->name = new Name($engine, $name);
72
73 62
        $this->data($this->engine->getData($name));
74 62
    }
75
76
    /**
77
     * Magic method used to call extension functions.
78
     * @param  string $name
79
     * @param  array  $arguments
80
     * @return mixed
81
     */
82 4
    public function __call($name, $arguments)
83
    {
84 4
        return $this->engine->getFunction($name)->call($this, $arguments);
85
    }
86
87
    /**
88
     * Alias for render() method.
89
     * @throws \Throwable
90
     * @throws \Exception
91
     * @return string
92
     */
93 2
    public function __toString()
94
    {
95 2
        return $this->render();
96
    }
97
98
    /**
99
     * Assign or get template data.
100
     * @param  array $data
101
     * @return mixed
102
     */
103 62
    public function data(array $data = null)
104
    {
105 62
        if (is_null($data)) {
106 2
            return $this->data;
107
        }
108
109 62
        $this->data = array_merge($this->data, $data);
110 62
    }
111
112
    /**
113
     * Check if the template exists.
114
     * @return boolean
115
     */
116 54
    public function exists()
117
    {
118 54
        return $this->name->doesPathExist();
119
    }
120
121
    /**
122
     * Get the template path.
123
     * @return string
124
     */
125 52
    public function path()
126
    {
127 52
        return $this->name->getPath();
128
    }
129
130
    /**
131
     * Render the template and layout.
132
     * @param  array  $data
133
     * @throws \Throwable
134
     * @throws \Exception
135
     * @return string
136
     */
137 50
    public function render(array $data = array())
138
    {
139 50
        $this->data($data);
140 50
        unset($data);
141 50
        extract($this->data);
142
143 50
        if (!$this->exists()) {
144 2
            throw new LogicException(
145 2
                'The template "' . $this->name->getName() . '" could not be found at "' . $this->path() . '".'
146 2
            );
147
        }
148
149
        try {
150 48
            $level = ob_get_level();
151 48
            ob_start();
152
153 48
            include $this->path();
154
155 38
            $content = ob_get_clean();
156
157 38
            if (isset($this->layoutName)) {
158 12
                $layout = $this->engine->make($this->layoutName);
159 12
                $layout->sections = array_merge($this->sections, array('content' => $content));
160 12
                $content = $layout->render($this->layoutData);
161 12
            }
162
163 38
            return $content;
164 10
        } catch (Throwable $e) {
0 ignored issues
show
The class Throwable does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
165
            while (ob_get_level() > $level) {
166
                ob_end_clean();
167
            }
168
169
            throw $e;
170 10
        } catch (Exception $e) {
171 10
            while (ob_get_level() > $level) {
172 10
                ob_end_clean();
173 10
            }
174
175 10
            throw $e;
176
        }
177
    }
178
179
    /**
180
     * Set the template's layout.
181
     * @param  string $name
182
     * @param  array  $data
183
     * @return null
184
     */
185 12
    public function layout($name, array $data = array())
186
    {
187 12
        $this->layoutName = $name;
188 12
        $this->layoutData = $data;
189 12
    }
190
191
    /**
192
     * Start a new section block.
193
     * @param  string  $name
194
     * @return null
195
     */
196 12
    public function start($name)
197
    {
198 12
        if ($name === 'content') {
199 2
            throw new LogicException(
200
                'The section name "content" is reserved.'
201 2
            );
202
        }
203
204 10
        if ($this->sectionName) {
205 2
            throw new LogicException('You cannot nest sections within other sections.');
206
        }
207
208 10
        $this->sectionName = $name;
209
210 10
        ob_start();
211 10
    }
212
213
    /**
214
     * Start a new append section block.
215
     * @param  string $name
216
     * @return null
217
     */
218 4
    public function push($name)
219
    {
220 4
        $this->appendSection = true;
221
222 4
        $this->start($name);
223 4
    }
224
225
    /**
226
     * Stop the current section block.
227
     * @return null
228
     */
229 10
    public function stop()
230
    {
231 10
        if (is_null($this->sectionName)) {
232 2
            throw new LogicException(
233
                'You must start a section before you can stop it.'
234 2
            );
235
        }
236
237 8
        if (!isset($this->sections[$this->sectionName])) {
238 8
            $this->sections[$this->sectionName] = '';
239 8
        }
240
241 8
        $this->sections[$this->sectionName] = $this->appendSection ? $this->sections[$this->sectionName] . ob_get_clean() : ob_get_clean();
242 8
        $this->sectionName = null;
243 8
        $this->appendSection = false;
244 8
    }
245
246
    /**
247
     * Alias of stop().
248
     * @return null
249
     */
250 4
    public function end()
251
    {
252 4
        $this->stop();
253 4
    }
254
255
    /**
256
     * Returns the content for a section block.
257
     * @param  string      $name    Section name
258
     * @param  string      $default Default section content
259
     * @return string|null
260
     */
261 12
    public function section($name, $default = null)
262
    {
263 12
        if (!isset($this->sections[$name])) {
264 4
            return $default;
265
        }
266
267 8
        return $this->sections[$name];
268
    }
269
270
    /**
271
     * Fetch a rendered template.
272
     * @param  string $name
273
     * @param  array  $data
274
     * @return string
275
     */
276 2
    public function fetch($name, array $data = array())
277
    {
278 2
        return $this->engine->render($name, $data);
279
    }
280
281
    /**
282
     * Output a rendered template.
283
     * @param  string $name
284
     * @param  array  $data
285
     * @return null
286
     */
287 2
    public function insert($name, array $data = array())
288
    {
289 2
        echo $this->engine->render($name, $data);
290 2
    }
291
292
    /**
293
     * Apply multiple functions to variable.
294
     * @param  mixed  $var
295
     * @param  string $functions
296
     * @return mixed
297
     */
298 6
    public function batch($var, $functions)
299
    {
300 6
        foreach (explode('|', $functions) as $function) {
301 6
            if ($this->engine->doesFunctionExist($function)) {
302 2
                $var = call_user_func(array($this, $function), $var);
303 6
            } elseif (is_callable($function)) {
304 4
                $var = call_user_func($function, $var);
305 4
            } else {
306 2
                throw new LogicException(
307 2
                    'The batch function could not find the "' . $function . '" function.'
308 2
                );
309
            }
310 4
        }
311
312 4
        return $var;
313
    }
314
315
    /**
316
     * Escape string.
317
     * @param  string      $string
318
     * @param  null|string $functions
319
     * @return string
320
     */
321 6
    public function escape($string, $functions = null)
322
    {
323 6
        static $flags;
324
325 6
        if (!isset($flags)) {
326 2
            $flags = ENT_QUOTES | (defined('ENT_SUBSTITUTE') ? ENT_SUBSTITUTE : 0);
327 2
        }
328
329 6
        if ($functions) {
330 2
            $string = $this->batch($string, $functions);
331 2
        }
332
333 6
        return htmlspecialchars($string, $flags, 'UTF-8');
334
    }
335
336
    /**
337
     * Alias to escape function.
338
     * @param  string      $string
339
     * @param  null|string $functions
340
     * @return string
341
     */
342 2
    public function e($string, $functions = null)
343
    {
344 2
        return $this->escape($string, $functions);
345
    }
346
}
347