Completed
Push — master ( 487f16...65527d )
by Cees-Jan
25s
created

TwigView::_render()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 32
ccs 16
cts 16
cp 1
rs 8.7857
c 0
b 0
f 0
cc 6
nc 8
nop 2
crap 6
1
<?php
2
declare(strict_types=1);
3
/**
4
 * This file is part of TwigView.
5
 *
6
 ** (c) 2014 Cees-Jan Kiewiet
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WyriHaximus\TwigView\View;
13
14
use Cake\Core\Configure;
15
use Cake\View\View;
16
use Exception;
17
use Twig\Environment;
18
use WyriHaximus\TwigView\Event\ConstructEvent;
19
use WyriHaximus\TwigView\Event\EnvironmentConfigEvent;
20
use WyriHaximus\TwigView\Event\LoaderEvent;
21
use WyriHaximus\TwigView\Lib\Twig\Loader;
22
23
/**
24
 * Class TwigView.
25
 * @package WyriHaximus\TwigView\View
26
 */
27
class TwigView extends View
28
{
29
    public const EXT = '.twig';
30
31
    public const ENV_CONFIG = 'WyriHaximus.TwigView.environment';
32
33
    /**
34
     * Extension to use.
35
     *
36
     * @var string
37
     */
38
    protected $_ext = self::EXT;
39
40
    /**
41
     * @var array
42
     */
43
    protected $extensions = [
44
        self::EXT,
45
        '.php',
46
    ];
47
48
    /**
49
     * Twig instance.
50
     *
51
     * @var \Twig\Environment
52
     */
53
    protected $twig;
54
55
    /**
56
     * Return empty string when View instance is cast to string.
57
     *
58
     * @return string
59
     */
60
    public function __toString(): string
61
    {
62
        return '';
63
    }
64
65
    /**
66
     * Initialize view.
67
     *
68
     */
69 17
    public function initialize(): void
70
    {
71 17
        $this->twig = new Environment($this->getLoader(), $this->resolveConfig());
72
73 17
        $this->getEventManager()->dispatch(ConstructEvent::create($this, $this->twig));
74
75 17
        $this->_ext = self::EXT;
76
77 17
        parent::initialize();
78 17
    }
79
80
    /**
81
     * @param string $extension
82
     */
83
    public function unshiftExtension($extension)
84
    {
85
        array_unshift($this->extensions, $extension);
86
    }
87
88
    /**
89
     * Get twig environment instance.
90
     *
91
     * @return \Twig\Environment
92
     */
93 5
    public function getTwig(): Environment
94
    {
95 5
        return $this->twig;
96
    }
97
98
    /**
99
     * @internal
100
     */
101 4
    public function setTwig(Environment $twig): void
102
    {
103 4
        $this->twig = $twig;
104 4
    }
105
106
    /**
107
     * @return array
108
     */
109 17
    protected function resolveConfig(): array
110
    {
111 17
        $charset = 'utf-8';
112 17
        if (Configure::read('App.encoding') !== null) {
113
            $charset = strtolower(Configure::read('App.encoding'));
114
        }
115 17
        $debugFlag = false;
116 17
        if (Configure::read('App.encoding') === true) {
117
            $debugFlag = true;
118
        }
119
        $config = [
120 17
            'cache' => CACHE . 'twigView' . DS,
121 17
            'charset' => $charset,
122 17
            'auto_reload' => $debugFlag,
123 17
            'debug' => $debugFlag,
124
        ];
125
126 17
        $config = array_replace($config, $this->readConfig());
127
128 17
        $configEvent = EnvironmentConfigEvent::create($config);
129 17
        $this->getEventManager()->dispatch($configEvent);
130
131 17
        return $configEvent->getConfig();
132
    }
133
134
    /**
135
     * @return array
136
     */
137 17
    protected function readConfig(): array
138
    {
139 17
        if (!Configure::check(static::ENV_CONFIG)) {
140 16
            return [];
141
        }
142
143 1
        $config = Configure::read(static::ENV_CONFIG);
144 1
        if (!is_array($config)) {
145
            return [];
146
        }
147
148 1
        return $config;
149
    }
150
151
    /**
152
     * Create the template loader.
153
     *
154
     * @return \WyriHaximus\TwigView\Lib\Twig\Loader
155
     */
156 17
    protected function getLoader(): Loader
157
    {
158 17
        $event = LoaderEvent::create(new Loader());
159 17
        $this->getEventManager()->dispatch($event);
160
161 17
        return $event->getResultLoader();
162
    }
163
164
    /**
165
     * Render the template.
166
     *
167
     * @param string $viewFile Template file.
168
     * @param array  $data     Data that can be used by the template.
169
     *
170
     * @throws \Exception
171
     * @return string
172
     */
173 3
    protected function _render(string $viewFile, array $data = []): string
174
    {
175 3
        if (empty($data)) {
176 3
            $data = $this->viewVars;
177
        }
178
179 3
        if (substr($viewFile, -3) === 'php') {
180 1
            $out = parent::_render($viewFile, $data);
181
        } else {
182 2
            $data = array_merge(
183 2
                $data,
184 2
                iterator_to_array($this->helpers()->getIterator()),
185
                [
186 2
                    '_view' => $this,
187
                ]
188
            );
189
190
            try {
191 2
                $out = $this->getTwig()->loadTemplate($viewFile)->render($data);
192 2
            } catch (Exception $e) {
193 2
                $previous = $e->getPrevious();
194
195 2
                if ($previous !== null && $previous instanceof Exception) {
196 1
                    throw $previous;
197
                } else {
198 1
                    throw $e;
199
                }
200
            }
201
        }
202
203 1
        return $out;
204
    }
205
206
    /**
207
     * @param  string|null $name
208
     * @throws \Exception
209
     * @return string
210
     */
211 3
    protected function _getTemplateFileName(?string $name = null): string
212
    {
213 3
        $rethrow = new Exception('You\'re not supposed to get here');
214 3
        foreach ($this->extensions as $extension) {
215 3
            $this->_ext = $extension;
216
            try {
217 3
                return parent::_getTemplateFileName($name);
218 1
            } catch (Exception $exception) {
219 1
                $rethrow = $exception;
220
            }
221
        }
222
223
        throw $rethrow;
224
    }
225
226
    /**
227
     * @param  string|null $name
228
     * @throws \Exception
229
     * @return string
230
     */
231 1
    protected function _getLayoutFileName(?string $name = null): string
232
    {
233 1
        $rethrow = new Exception('You\'re not supposed to get here');
234 1
        foreach ($this->extensions as $extension) {
235 1
            $this->_ext = $extension;
236
            try {
237 1
                return parent::_getLayoutFileName($name);
238 1
            } catch (Exception $exception) {
239 1
                $rethrow = $exception;
240
            }
241
        }
242
243
        throw $rethrow;
244
    }
245
246
    /**
247
     * @param  string      $name
248
     * @param  bool        $pluginCheck
249
     * @return string|bool
250
     */
251
    protected function _getElementFileName(string $name, bool $pluginCheck = true)
252
    {
253
        foreach ($this->extensions as $extension) {
254
            $this->_ext = $extension;
255
            $result = parent::_getElementFileName($name, $pluginCheck);
256
            if ($result !== false) {
257
                return $result;
258
            }
259
        }
260
261
        return false;
262
    }
263
}
264