TwigRenderer::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 3
nc 2
nop 2
crap 2
1
<?php
2
/**
3
 * This file is part of the Madapaja.TwigModule package.
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace Madapaja\TwigModule;
8
9
use BEAR\Resource\Code;
10
use BEAR\Resource\RenderInterface;
11
use BEAR\Resource\ResourceObject;
12
use Ray\Aop\WeavedInterface;
13
use Twig_Environment;
14
15
class TwigRenderer implements RenderInterface
16
{
17
    /**
18
     * File extension
19
     *
20
     * @var string
21
     */
22
    const EXT = '.html.twig';
23
24
    /**
25
     * @var Twig_Environment
26
     */
27
    public $twig;
28
29
    /**
30
     * @var TemplateFinderInterface
31
     */
32
    private $templateFinder;
33
34 22
    public function __construct(Twig_Environment $twig, TemplateFinderInterface $templateFinder = null)
35
    {
36 22
        $this->twig = $twig;
37 22
        $this->templateFinder = $templateFinder ?: new TemplateFinder;
38 22
    }
39
40 14
    public function render(ResourceObject $ro)
41
    {
42 14
        $this->beforeRender($ro);
43 14
        $ro->view = $this->isNoContent($ro) ? '' : $this->renderView($ro);
44
45 12
        return $ro->view;
46
    }
47
48 14
    private function beforeRender(ResourceObject $ro)
49
    {
50 14
        if (! isset($ro->headers['content-type'])) {
51 14
            $ro->headers['content-type'] = 'text/html; charset=utf-8';
52
        }
53 14
    }
54
55 13
    private function renderView(ResourceObject $ro)
56
    {
57 13
        $template = $this->load($ro);
58
59 11
        return $template ? $template->render($this->buildBody($ro)) : '';
60
    }
61
62 13
    private function load(ResourceObject $ro)
63
    {
64
        try {
65 13
            return $this->loadTemplate($ro);
66 3
        } catch (\Twig_Error_Loader $e) {
67 3
            if ($ro->code !== 200) {
68 1
                return false;
69
            }
70
        }
71
72 2
        throw new Exception\TemplateNotFound($e->getMessage(), 500, $e);
73
    }
74
75 14
    private function isNoContent(ResourceObject $ro)
76
    {
77 14
        return $ro->code === Code::NO_CONTENT || $ro->view === '';
78
    }
79
80
    /**
81
     * @return \Twig_TemplateWrapper
82
     */
83 13
    private function loadTemplate(ResourceObject $ro)
84
    {
85 13
        $loader = $this->twig->getLoader();
86 13
        if ($loader instanceof \Twig_Loader_Filesystem) {
87 9
            list($file, $dir) = $this->getTemplate($ro, $loader->getPaths());
88 9
            if ($dir) {
89
                // if the file not in paths, register the directory
90 1
                $loader->prependPath($dir);
91
            }
92
93 9
            return $this->twig->load($file);
94
        }
95
96 4
        return $this->twig->load($this->getReflection($ro)->name . self::EXT);
97
    }
98
99
    /**
100
     * @return \ReflectionClass
101
     */
102 13
    private function getReflection(ResourceObject $ro)
103
    {
104 13
        if ($ro instanceof WeavedInterface) {
105 1
            return (new \ReflectionClass($ro))->getParentClass();
106
        }
107
108 12
        return new \ReflectionClass($ro);
109
    }
110
111
    /**
112
     * return template file full path
113
     *
114
     * @return string
115
     */
116 9
    private function getTemplatePath(ResourceObject $ro)
117
    {
118 9
        $file = $this->getReflection($ro)->getFileName();
119
120 9
        return $this->templateFinder->__invoke($file);
121
    }
122
123
    /**
124
     * return template path and directory
125
     *
126
     * @return array
127
     */
128 9
    private function getTemplate(ResourceObject $ro, array $paths = [])
129
    {
130 9
        $file = $this->getTemplatePath($ro);
131
132 9
        foreach ($paths as $path) {
133 8
            if (strpos($file, $path . '/') === 0) {
134 8
                return [substr($file, strlen($path . '/')), null];
135
            }
136
        }
137
138 1
        return [basename($file), dirname($file)];
139
    }
140
141 10
    private function buildBody(ResourceObject $ro)
142
    {
143 10
        $body = is_array($ro->body) ? $ro->body : [];
144 10
        $body += ['_code' => $ro->code, '_headers' => $ro->headers];
145
146 10
        return $body;
147
    }
148
}
149