Completed
Push — master ( 208f8f...277583 )
by Jonathan
01:43
created

Template   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 273
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 97.7%

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 3
dl 0
loc 273
ccs 85
cts 87
cp 0.977
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A __call() 0 4 1
A data() 0 4 1
A exists() 0 4 1
A path() 0 4 1
B render() 0 36 5
A layout() 0 5 1
A start() 0 12 2
A stop() 0 12 2
A section() 0 8 2
A fetch() 0 4 1
A insert() 0 4 1
A batch() 0 16 4
A escape() 0 14 4
A e() 0 4 1
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 = [];
32
33
    /**
34
     * An array of section content.
35
     * @var array
36
     */
37
    protected $sections = [];
38
39
    /**
40
     * The name of the template layout.
41
     * @var string
42
     */
43
    protected $layoutName;
44
45
    /**
46
     * The data assigned to the template layout.
47
     * @var array
48
     */
49
    protected $layoutData;
50
51
    /**
52
     * Create new Template instance.
53
     * @param Engine $engine
54 100
     * @param string $name
55
     */
56 100
    public function __construct(Engine $engine, $name)
57 100
    {
58
        $this->engine = $engine;
59 100
        $this->name = new Name($engine, $name);
60 100
61
        $this->data($this->engine->getData($name));
62
    }
63
64
    /**
65
     * Magic method used to call extension functions.
66
     * @param  string $name
67
     * @param  array  $arguments
68 8
     * @return mixed
69
     */
70 8
    public function __call($name, $arguments)
71
    {
72
        return $this->engine->getFunction($name)->call($this, $arguments);
73
    }
74
75
    /**
76
     * Assign data to template object.
77
     * @param  array $data
78 100
     * @return null
79
     */
80 100
    public function data(array $data)
81 100
    {
82
        $this->data = array_merge($this->data, $data);
83
    }
84
85
    /**
86
     * Check if the template exists.
87 88
     * @return boolean
88
     */
89 88
    public function exists()
90
    {
91
        return $this->name->doesPathExist();
92
    }
93
94
    /**
95
     * Get the template path.
96 84
     * @return string
97
     */
98 84
    public function path()
99
    {
100
        return $this->name->getPath();
101
    }
102
103
    /**
104
     * Render the template and layout.
105
     * @param  array      $data
106
     * @throws \Throwable
107
     * @throws \Exception
108 80
     * @return string
109
     */
110
    public function render(array $data = [])
111 80
    {
112
        try {
113 80
            $this->data($data);
114
115 80
            unset($data);
116
117 80
            extract($this->data);
118
119 80
            ob_start();
120 4
121 4
            if (!$this->exists()) {
122 4
                throw new LogicException(
123
                    'The template "'.$this->name->getName().'" could not be found at "'.$this->path().'".'
124
                );
125 76
            }
126
127 60
            include $this->path();
128
129 60
            $content = ob_get_clean();
130 12
131 12
            if (isset($this->layoutName)) {
132 12
                $layout = $this->engine->make($this->layoutName);
133 12
                $layout->sections = array_merge($this->sections, ['content' => $content]);
134
                $content = $layout->render($this->layoutData);
135 60
            }
136 20
137
            return $content;
138 20
        } catch (Throwable $e) {
0 ignored issues
show
Bug introduced by
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...
139 20
            ob_end_clean();
140
            throw $e;
141
        } catch (Exception $e) {
142
            ob_end_clean();
143
            throw $e;
144
        }
145
    }
146
147
    /**
148 20
     * Set the template's layout.
149
     * @param  string $name
150 20
     * @param  array  $data
151 20
     * @return null
152
     */
153
    protected function layout($name, array $data = [])
154
    {
155
        $this->layoutName = $name;
156
        $this->layoutData = $data;
157
    }
158
159
    /**
160 12
     * Start a new section block.
161
     * @param  string $name
162 12
     * @return null
163 12
     */
164 12
    protected function start($name)
165
    {
166
        if ($name === 'content') {
167
            throw new LogicException(
168
                'The section name "content" is reserved.'
169
            );
170
        }
171 8
172
        $this->sections[$name] = '';
173 8
174 4
        ob_start();
175
    }
176 4
177
    /**
178
     * Stop the current section block.
179 4
     * @return null
180
     */
181 4
    protected function stop()
182 4
    {
183
        if (empty($this->sections)) {
184
            throw new LogicException(
185
                'You must start a section before you can stop it.'
186
            );
187
        }
188 8
189
        end($this->sections);
190 8
191 4
        $this->sections[key($this->sections)] = ob_get_clean();
192
    }
193 4
194
    /**
195
     * Returns the content for a section block.
196 4
     * @param  string      $name    Section name
197
     * @param  string      $default Default section content
198 4
     * @return string|null
199 4
     */
200
    protected function section($name, $default = null)
201
    {
202
        if (!isset($this->sections[$name])) {
203
            return $default;
204
        }
205
206
        return $this->sections[$name];
207 12
    }
208
209 12
    /**
210 8
     * Fetch a rendered template.
211
     * @param  string $name
212
     * @param  array  $data
213 4
     * @return string
214
     */
215
    protected function fetch($name, array $data = [])
216
    {
217
        return $this->engine->render($name, $data);
218
    }
219
220
    /**
221
     * Output a rendered template.
222 4
     * @param  string $name
223
     * @param  array  $data
224 4
     * @return null
225
     */
226
    protected function insert($name, array $data = [])
227
    {
228
        echo $this->engine->render($name, $data);
229
    }
230
231
    /**
232
     * Apply multiple functions to variable.
233 4
     * @param  mixed  $var
234
     * @param  string $functions
235 4
     * @return mixed
236 4
     */
237
    protected function batch($var, $functions)
238
    {
239
        foreach (explode('|', $functions) as $function) {
240
            if ($this->engine->doesFunctionExist($function)) {
241
                $var = call_user_func([$this, $function], $var);
242
            } elseif (is_callable($function)) {
243
                $var = call_user_func($function, $var);
244 12
            } else {
245
                throw new LogicException(
246 12
                    'The batch function could not find the "'.$function.'" function.'
247 12
                );
248 4
            }
249 12
        }
250 8
251 8
        return $var;
252 4
    }
253 4
254 4
    /**
255
     * Escape string.
256 8
     * @param  string      $string
257
     * @param  null|string $functions
258 8
     * @return string
259
     */
260
    protected function escape($string, $functions = null)
261
    {
262
        static $flags;
263
264
        if (!isset($flags)) {
265
            $flags = ENT_QUOTES | (defined('ENT_SUBSTITUTE') ? ENT_SUBSTITUTE : 0);
266
        }
267 12
268
        if ($functions) {
269 12
            $string = $this->batch($string, $functions);
270
        }
271 12
272 4
        return htmlspecialchars($string, $flags, 'UTF-8');
273 4
    }
274
275 12
    /**
276 4
     * Alias to escape function.
277 4
     * @param  string      $string
278
     * @param  null|string $functions
279 12
     * @return string
280
     */
281
    protected function e($string, $functions = null)
282
    {
283
        return $this->escape($string, $functions);
284
    }
285
}
286