Completed
Push — 2.x ( e76563...657ecc )
by Akihito
02:35
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
 * 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 23
    public function __construct(Twig_Environment $twig, TemplateFinderInterface $templateFinder = null)
35
    {
36 23
        $this->twig = $twig;
37 23
        $this->templateFinder = $templateFinder ?: new TemplateFinder;
38 23
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 15
    public function render(ResourceObject $ro)
44
    {
45 15
        $this->setContentType($ro);
46 15
        $ro->view = $this->isNoContent($ro) ? '' : $this->renderView($ro);
47
48 13
        return $ro->view;
49
    }
50
51 15
    private function setContentType(ResourceObject $ro)
52
    {
53 15
        if (! isset($ro->headers['content-type'])) {
54 15
            $ro->headers['content-type'] = 'text/html; charset=utf-8';
55
        }
56 15
    }
57
58 14
    private function renderView(ResourceObject $ro)
59
    {
60 14
        $template = $this->load($ro);
61
62 12
        return $template ? $template->render($this->buildBody($ro)) : '';
63
    }
64
65
    /**
66
     * @return null|\Twig_TemplateWrapper
67
     */
68 14
    private function load(ResourceObject $ro)
69
    {
70
        try {
71 14
            return $this->loadTemplate($ro);
72 3
        } catch (\Twig_Error_Loader $e) {
73 3
            if ($ro->code !== 200) {
74 1
                return null;
75
            }
76
        }
77
78 2
        throw new Exception\TemplateNotFound($e->getMessage(), 500, $e);
79
    }
80
81 15
    private function isNoContent(ResourceObject $ro) : bool
82
    {
83 15
        return $ro->code === Code::NO_CONTENT || $ro->view === '';
84
    }
85
86 14
    private function loadTemplate(ResourceObject $ro) : \Twig_TemplateWrapper
87
    {
88 14
        $loader = $this->twig->getLoader();
89 14
        if ($loader instanceof \Twig_Loader_Filesystem) {
90 10
            $file = $this->getTemplatePath($ro);
91
92 10
            return $this->twig->load($file);
93
        }
94
95 4
        return $this->twig->load($this->getReflection($ro)->name . self::EXT);
96
    }
97
98 14
    private function getReflection(ResourceObject $ro) : \ReflectionClass
99
    {
100 14
        if ($ro instanceof WeavedInterface) {
101 1
            return (new \ReflectionClass($ro))->getParentClass();
102
        }
103
104 13
        return new \ReflectionClass($ro);
105
    }
106
107
    /**
108
     * return template file full path
109
     */
110 10
    private function getTemplatePath(ResourceObject $ro) : string
111
    {
112 10
        $file = $this->getReflection($ro)->getFileName();
113
114 10
        return $this->templateFinder->__invoke($file);
115
    }
116
117 11
    private function buildBody(ResourceObject $ro) : array
118
    {
119 11
        $body = is_array($ro->body) ? $ro->body : [];
120 11
        $body += ['_ro' => $ro,];
121
122 11
        return $body;
123
    }
124
}
125