Completed
Push — 2.0.x ( f85be6...e30486 )
by Andrew
02:32
created

HTMLRenderer::getTemplatePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 7
rs 9.4286
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
/**
3
 * @author     Andrew Coulton <[email protected]>
4
 * @copyright  2015 inGenerator Ltd
5
 * @license    http://kohanaframework.org/license
6
 */
7
8
namespace Ingenerator\KohanaView\Renderer;
9
10
11
use Ingenerator\KohanaView\Exception\TemplateNotFoundException;
12
use Ingenerator\KohanaView\Renderer;
13
use Ingenerator\KohanaView\TemplateManager;
14
use Ingenerator\KohanaView\ViewModel;
15
use Ingenerator\KohanaView\ViewTemplateSelector;
16
17
/**
18
 * Renders a ViewModel to an HTML string for return to the user. The template is rendered with an anonymous scope
19
 * which only has access to the ViewModel, the Renderer (for rendering any subviews) and the template file path.
20
 *
21
 * @package Ingenerator\KohanaView\Renderer
22
 */
23
class HTMLRenderer implements Renderer
24
{
25
26
    /**
27
     * @var TemplateManager
28
     */
29
    protected $template_manager;
30
31
    /**
32
     * @var ViewTemplateSelector
33
     */
34
    protected $template_selector;
35
36
    public function __construct(ViewTemplateSelector $template_selector, TemplateManager $template_manager)
37
    {
38
        $this->template_selector = $template_selector;
39
        $this->template_manager  = $template_manager;
40
    }
41
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function render(ViewModel $view)
47
    {
48
        $template_path = $this->getTemplatePath($view);
49
50
        ob_start();
51
        try {
52
            $this->includeWithAnonymousScope($view, $template_path);
53
        } finally {
54
            $output = ob_get_clean();
55
        }
56
57
        return $output;
58
    }
59
60
    /**
61
     * @param ViewModel $view
62
     *
63
     * @return string
64
     */
65
    protected function getTemplatePath(ViewModel $view)
66
    {
67
        $template_name = $this->template_selector->getTemplateName($view);
68
        $template      = $this->template_manager->getPath($template_name);
69
70
        return $template;
71
    }
72
73
    /**
74
     * @param ViewModel $view
75
     * @param string    $template_path
76
     */
77
    protected function includeWithAnonymousScope(ViewModel $view, $template_path)
78
    {
79
        /** @noinspection PhpUnusedParameterInspection */
80
        /** @noinspection PhpDocSignatureInspection */
81
        $bound_capture = function (ViewModel $view, Renderer $renderer, $template) {
82
            /** @noinspection PhpIncludeInspection */
83
            return include $template;
84
        };
85
        $anon_capture  = $bound_capture->bindTo(NULL);
86
87
        // A user's own error handler may throw an exception here if the include fails - which we will bubble as-is.
88
        // If they have not configured an error handler, we need to throw an exception of our own.
89
        if ($anon_capture($view, $this, $template_path) === FALSE) {
90
            throw TemplateNotFoundException::forFullPath($template_path);
91
        }
92
    }
93
94
}
95