Passed
Pull Request — master (#48)
by Arman
03:56
created

QtView::defaultRenderer()   A

Complexity

Conditions 3
Paths 9

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
nc 9
nop 2
dl 0
loc 16
rs 9.9332
c 6
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A QtView::cleaner() 0 6 2
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.6.0
13
 */
14
15
namespace Quantum\Mvc;
16
17
use Quantum\Exceptions\ViewException;
18
use Quantum\Renderer\DefaultRenderer;
19
use Quantum\Renderer\TwigRenderer;
20
use Quantum\Factory\ViewFactory;
21
use Quantum\Debugger\Debugger;
22
use Psr\Log\LogLevel;
23
24
/**
25
 * Class QtView
26
 * @package Quantum\Mvc
27
 */
28
class QtView
29
{
30
31
    /**
32
     * Layout file
33
     * @var string
34
     */
35
    private $layout = null;
36
37
    /**
38
     * Rendered view
39
     * @var string
40
     */
41
    private $view = null;
42
43
    /**
44
     * View params
45
     * @var array
46
     */
47
    private $params = [];
48
49
    /**
50
     * QtView constructor.
51
     * @throws \Quantum\Exceptions\ViewException
52
     */
53
    public function __construct()
54
    {
55
        if (get_caller_class() != ViewFactory::class) {
56
            throw ViewException::directInstantiation(ViewFactory::class);
57
        }
58
    }
59
60
    /**
61
     * Sets a layout
62
     * @param string|null $layout
63
     */
64
    public function setLayout(?string $layout)
65
    {
66
        $this->layout = $layout;
67
    }
68
69
    /**
70
     * Gets the layout
71
     * @return string|null
72
     */
73
    public function getLayout(): ?string
74
    {
75
        return $this->layout;
76
    }
77
78
    /**
79
     * Sets view parameter
80
     * @param string $key
81
     * @param mixed $value
82
     */
83
    public function setParam(string $key, $value)
84
    {
85
        $this->params[$key] = $value;
86
    }
87
88
    /**
89
     * Gets the view parameter
90
     * @param string $key
91
     * @return mixed|null
92
     */
93
    public function getParam(string $key)
94
    {
95
        return $this->params[$key] ?? null;
96
    }
97
98
    /**
99
     * Sets multiple view parameters
100
     * @param array $params
101
     */
102
    public function setParams(array $params)
103
    {
104
        foreach ($params as $key => $value) {
105
            $this->setParam($key, $value);
106
        }
107
    }
108
109
    /**
110
     * Gets all view parameters
111
     * @return array
112
     */
113
    public function getParams(): array
114
    {
115
        return $this->params;
116
    }
117
118
    /**
119
     * Flushes the view params
120
     */
121
    public function flushParams()
122
    {
123
        $this->params = [];
124
    }
125
126
    /**
127
     * Renders the view
128
     * @param string $view
129
     * @param array $params
130
     * @return string|null
131
     * @throws \Quantum\Exceptions\DiException
132
     * @throws \Quantum\Exceptions\ViewException
133
     * @throws \ReflectionException
134
     * @throws \Twig\Error\LoaderError
135
     * @throws \Twig\Error\RuntimeError
136
     * @throws \Twig\Error\SyntaxError
137
     */
138
    public function render(string $view, array $params = []): ?string
139
    {
140
        if (!$this->layout) {
141
            throw ViewException::noLayoutSet();
142
        }
143
144
        if (!empty($params)) {
145
            $this->params = array_merge($this->params, $params);
146
        }
147
148
        $this->view = $this->renderFile($view);
149
150
        if (filter_var(config()->get('debug'), FILTER_VALIDATE_BOOLEAN)) {
151
            Debugger::updateStoreCell(Debugger::ROUTES, LogLevel::INFO, ['View' => current_module() . '/Views/' . $view]);
152
        }
153
154
        return $this->renderFile($this->layout);
155
    }
156
157
    /**
158
     * Renders partial view
159
     * @param string $view
160
     * @param array $params
161
     * @return string|null
162
     * @throws \Quantum\Exceptions\DiException
163
     * @throws \Quantum\Exceptions\ViewException
164
     * @throws \ReflectionException
165
     * @throws \Twig\Error\LoaderError
166
     * @throws \Twig\Error\RuntimeError
167
     * @throws \Twig\Error\SyntaxError
168
     */
169
    public function renderPartial(string $view, array $params = []): ?string
170
    {
171
        if (!empty($params)) {
172
            $this->params = array_merge($this->params, $params);
173
        }
174
175
        return $this->renderFile($view);
176
    }
177
178
    /**
179
     * Gets the rendered view
180
     * @return string|null
181
     */
182
    public function getView(): ?string
183
    {
184
        return $this->view;
185
    }
186
187
    /**
188
     * Renders the view
189
     * @param string $view
190
     * @return string
191
     * @throws \Quantum\Exceptions\DiException
192
     * @throws \Quantum\Exceptions\ViewException
193
     * @throws \ReflectionException
194
     * @throws \Twig\Error\LoaderError
195
     * @throws \Twig\Error\RuntimeError
196
     * @throws \Twig\Error\SyntaxError
197
     */
198
    private function renderFile(string $view): string
199
    {
200
        $params = $this->xssFilter($this->params);
201
202
        $templateEngine = config()->get('template_engine');
203
204
        if ($templateEngine) {
205
            $configs = config()->get('template_engine.' . key($templateEngine));
206
207
            if (!$configs) {
208
                throw ViewException::missingTemplateEngineConfigs();
209
            }
210
211
            return (new TwigRenderer())->render($view, $params, $configs);
212
        } else {
213
            return (new DefaultRenderer())->render($view, $params);
214
        }
215
    }
216
217
    /**
218
     * XSS Filter
219
     * @param mixed $params
220
     * @return mixed
221
     */
222
    private function xssFilter($params)
223
    {
224
        if (is_string($params)) {
225
            $this->cleaner($params);
226
            $params = [$params];
227
        } else {
228
            array_walk_recursive($params, [$this, 'cleaner']);
229
        }
230
231
        return $params;
232
    }
233
234
    /**
235
     * Cleaner
236
     * @param mixed $value
237
     */
238
    private function cleaner(&$value)
239
    {
240
        if (is_object($value)) {
241
            $this->xssFilter($value);
242
        } else {
243
            $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
244
        }
245
    }
246
247
}
248