Passed
Push — feature/twig-extention-support ( d885a4...c2be84 )
by IWASAKI
02:13
created

TwigRenderer::buildBody()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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