Completed
Pull Request — master (#58)
by
unknown
08:40
created

TwigView::resolveConfig()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.1406

Importance

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