Completed
Push — master ( 5da106...cd03ca )
by Cees-Jan
02:11
created

TwigView::_getElementFileName()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
271
    {
272
        $rethrow = new Exception('You\'re not supposed to get here');
273
        foreach ($this->extensions as $extension) {
274
            $this->_ext = $extension;
275
            try {
276
                return parent::_getLayoutFileName($name);
277
            } catch (Exception $exception) {
278
                $rethrow = $exception;
279
            }
280
        }
281
282
        throw $rethrow;
283
    }
284
285
    /**
286
     * @param  string      $name
287
     * @param  bool        $pluginCheck
288
     * @return string|bool
289
     */
290
    protected function _getElementFileName($name, $pluginCheck = true)
291
    {
292
        foreach ($this->extensions as $extension) {
293
            $this->_ext = $extension;
294
            $result = parent::_getElementFileName($name, $pluginCheck);
295
            if ($result !== false) {
296
                return $result;
297
            }
298
        }
299
300
        return false;
301
    }
302
}
303