PHP::getExt()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Jasny\View;
4
5
use Jasny\ViewInterface;
6
use Psr\Http\Message\ResponseInterface;
7
8
/**
9
 * Abstraction use PHP templates as views with PSR-7
10
 */
11
class PHP implements ViewInterface
12
{
13
    /**
14
     * @var string
15
     */
16
    protected $path;
17
18
    /**
19
     * @var string
20
     */
21
    protected $ext = 'php';
22
    
23
    /**
24
     * Class constructor
25
     * 
26
     * @param array $options
27
     */
28 14
    public function __construct(array $options)
29
    {
30 14
        if (!isset($options['path'])) {
31 1
            throw new \BadMethodCallException("'path' option is required");
32
        }
33
            
34 14
        $this->path = $options['path'];
35
        
36 14
        if (isset($options['ext'])) {
37 2
            $this->ext = $options['ext'];
38 2
        }
39 14
    }
40
    
41
    /**
42
     * Get directory path.
43
     * 
44
     * @return string
45
     */
46 2
    public function getPath()
47
    {
48 2
       return $this->path; 
49
    }
50
    
51
    /**
52
     * Get the default file extension
53
     * 
54
     * @return string
55
     */
56 7
    public function getExt()
57
    {
58 7
        return $this->ext;
59
    }
60
    
61
    
62
    /**
63
     * Expose a function to the view.
64
     *
65
     * @param string        $name      Function name in template
66
     * @param callable|null $function
67
     * @return $this
68
     * @throws \BadMethodCallException if function can't be exposed
69
     */
70 4
    public function expose($name, $function = null)
71
    {
72 4
        if (function_exists($name) && (!isset($function) || $name === $function)) {
73 2
            return $this;
74
        }
75
        
76 2
        throw new \BadMethodCallException("Exposing functions under an alias isn't supported with PHP views");
77
    }
78
    
79
    
80
    /**
81
     * Get the path to a view file
82
     * 
83
     * @param string $name
84
     * @return string
85
     */
86 6
    protected function getFilePath($name)
87
    {
88 6
        if (pathinfo($name, PATHINFO_EXTENSION) === '') {
89 5
            $name .= (substr($name, -1) === '/' ? 'index' : '') . '.' . $this->getExt();
90 5
        }
91
        
92 6
        return rtrim($this->path, '/') . '/' . ltrim($name, '/');
93
    }
94
    
95
    /**
96
     * Assert the filename and that the file exists
97
     * 
98
     * @param string $name
99
     * @throws \InvalidArgumentException
100
     */
101 7
    protected function assertFile($name)
102
    {
103 7
        if (strpos($name, '..') !== false) {
104 1
            throw new \InvalidArgumentException("File name '$name' isn't valid");
105
        }
106
        
107 6
        $file = $this->getFilePath($name);
108
        
109 6
        if (!file_exists($file)) {
110 1
            throw new \RuntimeException("View file '$file' doesn't exist");
111
        }
112 5
    }
113
    
114
    /**
115
     * Run the PHP script
116
     * 
117
     * @param string $name
118
     * @param array  $context
119
     */
120 5
    protected function runScript($name, array $context)
121
    {
122
        // Prevent $name and $context being available in the view script
123 5
        $___ = $this->getFilePath($name); 
124 5
        $_context_ = $context;
125 5
        unset($name, $context);
126
        
127
        /** @see http://php.net/extract */
128 5
        extract($_context_);
129 5
        unset($_context_);
130
        
131 5
        include $___;
132 5
    }
133
    
134
    /**
135
     * Render and output template
136
     *
137
     * @param ResponseInterface $response
138
     * @param string            $name      Template name
139
     * @param array             $context   Template context as associated array
140
     * @return ResponseInterface
141
     */
142 7
    public function render(ResponseInterface $response, $name, array $context = [])
143
    {
144 7
        $this->assertFile($name);
145
146 5
        if (!$response->hasHeader('Content-Type')) {
147 5
            $response = $response->withHeader('Content-Type', 'text/html');
148 5
        }
149
        
150 5
        $body = $response->getBody();
151
        
152 5
        ob_start(function ($buffer) use ($body) {
153 5
            $body->write($buffer);
154 5
        });
155
        
156
        try {
157 5
            $this->runScript($name, $context);
158 5
        } finally {
159 5
            ob_end_clean();
160
        }
161
        
162 5
        return $response;
163
    }
164
}
165