Completed
Push — fallback-order-correction ( 0364a8 )
by Cees-Jan
02:13
created

TwigView::_getLayoutFileName()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 29
Code Lines 16

Duplication

Lines 5
Ratio 17.24 %

Code Coverage

Tests 13
CRAP Score 10.3549

Importance

Changes 0
Metric Value
dl 5
loc 29
ccs 13
cts 22
cp 0.5909
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 16
nc 20
nop 1
crap 10.3549
1
<?php
2
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
namespace WyriHaximus\TwigView\View;
12
13
use Cake\Core\Configure;
14
use Cake\View\Exception\MissingLayoutException;
15
use Cake\View\Exception\MissingTemplateException;
16
use Cake\View\View;
17
use Exception;
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
// @codingStandardsIgnoreStart
28
class TwigView extends View
29
// @codingStandardsIgnoreEnd
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
    // @codingStandardsIgnoreStart
41
    protected $_ext = self::EXT;
42
    // @codingStandardsIgnoreEnd
43
44
    /**
45
     * @var array
46
     */
47
    protected $extensions = [
48
        self::EXT,
49
        '.tpl',
50
        '.ctp',
51
    ];
52
53
    /**
54
     * Twig instance.
55
     *
56
     * @var \Twig_Environment
57
     */
58
    protected $twig;
59
60
    /**
61
     * Initialize view.
62
     *
63
     * @return void
64
     */
65 16
    public function initialize()
66
    {
67 16
        $this->twig = new \Twig_Environment($this->getLoader(), $this->resolveConfig());
68
69 16
        $this->eventManager()->dispatch(ConstructEvent::create($this, $this->twig));
70
71 16
        $this->_ext = self::EXT;
72
73 16
        parent::initialize();
74 16
    }
75
76
    /**
77
     * @return array
78
     */
79 16
    protected function resolveConfig()
80
    {
81
        $config = [
82 16
            'cache' => CACHE . 'twigView' . DS,
83 16
            'charset' => strtolower(Configure::read('App.encoding')),
84 16
            'auto_reload' => Configure::read('debug'),
85 16
            'debug' => Configure::read('debug'),
86 16
        ];
87
88 16
        $config = array_replace($config, $this->readConfig());
89
90 16
        $configEvent = EnvironmentConfigEvent::create($config);
91 16
        $this->eventManager()->dispatch($configEvent);
92 16
        return $configEvent->getConfig();
93
    }
94
95
    /**
96
     * @return array
97
     */
98 16
    protected function readConfig()
99
    {
100 16
        if (!Configure::check(static::ENV_CONFIG)) {
101 15
            return [];
102
        }
103
104 1
        $config = Configure::read(static::ENV_CONFIG);
105 1
        if (!is_array($config)) {
106
            return [];
107
        }
108
109 1
        return $config;
110
    }
111
112
    /**
113
     * @param string $extension
114
     */
115
    public function unshiftExtension($extension)
116
    {
117
        array_unshift($this->extensions, $extension);
118
    }
119
120
    /**
121
     * Create the template loader.
122
     *
123
     * @return \Twig_LoaderInterface
124
     */
125 16
    protected function getLoader()
126
    {
127 16
        $event = LoaderEvent::create(new Loader());
128 16
        $this->eventManager()->dispatch($event);
129 16
        return $event->getResultLoader();
130 1
    }
131
132
    /**
133
     * Get helper list.
134
     *
135
     * @return \Cake\View\Helper[]
136
     */
137 7
    protected function generateHelperList()
138
    {
139 7
        $registry = $this->helpers();
140 7
        $helperList = [];
141
142 7
        foreach ($registry->loaded() as $alias) {
143 6
            $helperList[$alias] = $registry->get($alias);
144 7
        }
145
146 7
        return $helperList;
147
    }
148
    /**
149
     * Render the template.
150
     *
151
     * @param string $viewFile Template file.
152
     * @param array  $data     Data that can be used by the template.
153
     *
154
     * @throws \Exception
155
     * @return string
156
     */
157
    // @codingStandardsIgnoreStart
158 10
    protected function _render($viewFile, $data = array())
159
    {
160
        // @codingStandardsIgnoreEnd
161 10
        if (empty($data)) {
162 10
            $data = $this->viewVars;
163 10
        }
164
165 10
        if (substr($viewFile, -3) === 'ctp') {
166 4
            $out = parent::_render($viewFile, $data);
167
            // @codingStandardsIgnoreStart
168 4
        } else {
169
            // @codingStandardsIgnoreEnd
170 6
            $data = array_merge(
171 6
                $data,
172 6
                $this->generateHelperList(),
173
                [
174 6
                    '_view' => $this,
175
                ]
176 6
            );
177
178
            // @codingStandardsIgnoreStart
179
            try {
180 6
                $out = $this->getTwig()->loadTemplate($viewFile)->render($data);
181 6
            } catch (Exception $e) {
182 2
                $previous = $e->getPrevious();
183
184 2
                if ($previous !== null && $previous instanceof Exception) {
185 1
                    throw $previous;
186
                } else {
187 1
                    throw $e;
188
                }
189
            }
190
            // @codingStandardsIgnoreEnd
191
        }
192
193 8
        return $out;
194
    }
195
196
    /**
197
     * @param string|null $name
198
     * @return string
199
     * @throws \Exception
200
     */
201
    // @codingStandardsIgnoreStart
202 6
    protected function _getViewFileName($name = null)
203
    {
204
        // @codingStandardsIgnoreEnd
205 6
        $templatePath = $subDir = '';
206
207 6
        if ($this->subDir !== null) {
208
            $subDir = $this->subDir . DIRECTORY_SEPARATOR;
209
        }
210 6
        if ($this->templatePath) {
211
            $templatePath = $this->templatePath . DIRECTORY_SEPARATOR;
212
        }
213
214 6
        if ($name === null) {
215
            $name = $this->template;
216
        }
217
218 6
        list($plugin, $name) = $this->pluginSplit($name);
219 6
        $name = str_replace('/', DIRECTORY_SEPARATOR, $name);
220
221 6
        if (strpos($name, DIRECTORY_SEPARATOR) === false && $name[0] !== '.') {
222 2
            $name = $templatePath . $subDir . $this->_inflectViewFileName($name);
223 6
        } elseif (strpos($name, DIRECTORY_SEPARATOR) !== false) {
224 4
            if ($name[0] === DIRECTORY_SEPARATOR || $name[1] === ':') {
225
                $name = trim($name, DIRECTORY_SEPARATOR);
226 4
            } elseif (!$plugin || $this->templatePath !== $this->name) {
227 4
                $name = $templatePath . $subDir . $name;
228 4
            } else {
229
                $name = DIRECTORY_SEPARATOR . $subDir . $name;
230
            }
231 4
        }
232
233 6 View Code Duplication
        foreach ($this->_paths($plugin) as $path) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
234 6
            foreach ($this->extensions as $extension) {
235 6
                if (file_exists($path . $name . $extension)) {
236 6
                    return $this->_checkFilePath($path . $name . $extension, $path);
237
                }
238 2
            }
239
        }
240
241
        throw new MissingTemplateException(['file' => $name . $this->_ext]);
242
    }
243
244
    /**
245
     * @param string|null $name
246
     * @return string
247
     * @throws \Exception
248
     */
249
    // @codingStandardsIgnoreStart
250 2
    protected function _getLayoutFileName($name = null)
251
    {
252
        // @codingStandardsIgnoreEnd
253 2
        if ($name === null) {
254
            $name = $this->layout;
255
        }
256 2
        $subDir = null;
257
258 2
        if ($this->layoutPath) {
259
            $subDir = $this->layoutPath . DIRECTORY_SEPARATOR;
260
        }
261 2
        list($plugin, $name) = $this->pluginSplit($name);
262
263 2
        $layoutPaths = $this->_getSubPaths('Layout' . DIRECTORY_SEPARATOR . $subDir);
264
265 2
        foreach ($this->_paths($plugin) as $path) {
266 2
            foreach ($layoutPaths as $layoutPath) {
267 2
                $currentPath = $path . $layoutPath;
268 2 View Code Duplication
                foreach ($this->extensions as $extension) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
269 2
                    if (file_exists($currentPath . $name . $extension)) {
270 2
                        return $this->_checkFilePath($currentPath . $name . $extension, $currentPath);
271
                    }
272 1
                }
273
            }
274
        }
275
        throw new MissingLayoutException([
276
            'file' => $layoutPaths[0] . $name . $this->_ext
277
        ]);
278
    }
279
280
    /**
281
     * @param string $name
282
     * @param bool $pluginCheck
283
     * @return string
284
     * @throws \Exception
285
     */
286
    // @codingStandardsIgnoreStart
287 2
    protected function _getElementFileName($name, $pluginCheck = true)
288
    {
289
        // @codingStandardsIgnoreEnd
290 2
        list($plugin, $name) = $this->pluginSplit($name, $pluginCheck);
291
292 2
        $paths = $this->_paths($plugin);
293 2
        $elementPaths = $this->_getSubPaths('Element');
294
295 2
        foreach ($paths as $path) {
296 2
            foreach ($elementPaths as $elementPath) {
297 2
                foreach ($this->extensions as $extension) {
298 2
                    if (file_exists($path . $elementPath . DIRECTORY_SEPARATOR . $name . $extension)) {
299 2
                        return $path . $elementPath . DIRECTORY_SEPARATOR . $name . $extension;
300
                    }
301 1
                }
302
            }
303
        }
304
305
        return false;
306
    }
307
308
    /**
309
     * Get twig environment instance.
310
     *
311
     * @return \Twig_Environment
312
     */
313 6
    public function getTwig()
314
    {
315 6
        return $this->twig;
316
    }
317
318
    /**
319
     * Return empty string when View instance is cast to string.
320
     *
321
     * @return string
322
     */
323
    public function __toString()
324
    {
325
        return '';
326
    }
327
}
328