Completed
Push — master ( 16ac8a...063067 )
by Jonathan
02:25
created

Template::section()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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