Completed
Pull Request — 2.x (#29)
by Akihito
01:35
created

TwigRenderer::load()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 0
cts 6
cp 0
rs 9.4285
cc 3
eloc 7
nc 3
nop 1
crap 12
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
    public function __construct(Twig_Environment $twig, TemplateFinderInterface $templateFinder = null)
35
    {
36
        $this->twig = $twig;
37
        $this->templateFinder = $templateFinder ?: new TemplateFinder;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function render(ResourceObject $ro)
44
    {
45
        $this->setContentType($ro);
46
        $ro->view = $this->isNoContent($ro) ? '' : $this->renderView($ro);
47
48
        return $ro->view;
49
    }
50
51
    private function setContentType(ResourceObject $ro)
52
    {
53
        if (! isset($ro->headers['content-type'])) {
54
            $ro->headers['content-type'] = 'text/html; charset=utf-8';
55
        }
56
    }
57
58
    private function renderView(ResourceObject $ro)
59
    {
60
        $template = $this->load($ro);
61
62
        return $template ? $template->render($this->buildBody($ro)) : '';
63
    }
64
65
    /**
66
     * @return null|\Twig_TemplateWrapper
67
     */
68
    private function load(ResourceObject $ro)
69
    {
70
        try {
71
            return $this->loadTemplate($ro);
72
        } catch (\Twig_Error_Loader $e) {
73
            if ($ro->code !== 200) {
74
                return;
75
            }
76
        }
77
78
        throw new Exception\TemplateNotFound($e->getMessage(), 500, $e);
79
    }
80
81
    private function isNoContent(ResourceObject $ro) : bool
82
    {
83
        return $ro->code === Code::NO_CONTENT || $ro->view === '';
84
    }
85
86
    private function loadTemplate(ResourceObject $ro) : \Twig_TemplateWrapper
87
    {
88
        $loader = $this->twig->getLoader();
89
        if ($loader instanceof \Twig_Loader_Filesystem) {
90
            $classFile = $this->getReflection($ro)->getFileName();
91
            $templateFile = $this->templateFinder->__invoke($classFile);
92
93
            return $this->twig->load($templateFile);
94
        }
95
96
        return $this->twig->load($this->getReflection($ro)->name . self::EXT);
97
    }
98
99
    private function getReflection(ResourceObject $ro) : \ReflectionClass
100
    {
101
        if ($ro instanceof WeavedInterface) {
102
            return (new \ReflectionClass($ro))->getParentClass();
103
        }
104
105
        return new \ReflectionClass($ro);
106
    }
107
108
    private function buildBody(ResourceObject $ro) : array
109
    {
110
        $body = \is_array($ro->body) ? $ro->body : [];
111
        $body += ['_ro' => $ro];
112
113
        return $body;
114
    }
115
}
116