Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
42 / 42 |
|
100.00% |
15 / 15 |
CRAP | |
100.00% |
1 / 1 |
View | |
100.00% |
42 / 42 |
|
100.00% |
15 / 15 |
32 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
5 | |||
hasTemplate | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getTemplate | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getOutput | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isFile | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
isStream | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
getData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setTemplate | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
7 | |||
setData | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
set | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
merge | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
filter | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
render | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
__toString | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\View; |
15 | |
16 | use Pop\Filter\FilterableTrait; |
17 | use Pop\Utils; |
18 | |
19 | /** |
20 | * View class |
21 | * |
22 | * @category Pop |
23 | * @package Pop\View |
24 | * @author Nick Sagona, III <dev@nolainteractive.com> |
25 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
26 | * @license http://www.popphp.org/license New BSD License |
27 | * @version 4.0.0 |
28 | */ |
29 | class View extends Utils\ArrayObject |
30 | { |
31 | |
32 | use FilterableTrait; |
33 | |
34 | /** |
35 | * View template object |
36 | * @var ?Template\TemplateInterface |
37 | */ |
38 | protected ?Template\TemplateInterface $template = null; |
39 | |
40 | /** |
41 | * Model data |
42 | * @var mixed |
43 | */ |
44 | protected mixed $data = []; |
45 | |
46 | /** |
47 | * View output string |
48 | * @var ?string |
49 | */ |
50 | protected ?string $output = null; |
51 | |
52 | /** |
53 | * Constructor |
54 | * |
55 | * Instantiate the view object |
56 | * |
57 | * @param mixed $template |
58 | * @param ?array $data |
59 | * @param mixed $filters |
60 | */ |
61 | public function __construct(mixed $template = null, ?array $data = null, mixed $filters = null) |
62 | { |
63 | if ($template !== null) { |
64 | $this->setTemplate($template); |
65 | } |
66 | if ($data !== null) { |
67 | parent::__construct($data); |
68 | } |
69 | if ($filters !== null) { |
70 | if (is_array($filters)) { |
71 | $this->addFilters($filters); |
72 | } else { |
73 | $this->addFilter($filters); |
74 | } |
75 | } |
76 | } |
77 | |
78 | /** |
79 | * Has a view template |
80 | * |
81 | * @return bool |
82 | */ |
83 | public function hasTemplate(): bool |
84 | { |
85 | return ($this->template !== null); |
86 | } |
87 | |
88 | /** |
89 | * Get view template |
90 | * |
91 | * @return Template\TemplateInterface |
92 | */ |
93 | public function getTemplate(): Template\TemplateInterface |
94 | { |
95 | return $this->template; |
96 | } |
97 | |
98 | /** |
99 | * Get rendered output |
100 | * |
101 | * @return string |
102 | */ |
103 | public function getOutput(): string |
104 | { |
105 | return $this->output; |
106 | } |
107 | |
108 | /** |
109 | * Is view template a file |
110 | * |
111 | * @return bool |
112 | */ |
113 | public function isFile(): bool |
114 | { |
115 | return (($this->template !== null) && ($this->template instanceof Template\File)); |
116 | } |
117 | |
118 | /** |
119 | * Is view template a stream |
120 | * |
121 | * @return bool |
122 | */ |
123 | public function isStream(): bool |
124 | { |
125 | return (($this->template !== null) && ($this->template instanceof Template\Stream)); |
126 | } |
127 | |
128 | /** |
129 | * Get all model data |
130 | * |
131 | * @return array |
132 | */ |
133 | public function getData(): array |
134 | { |
135 | return $this->data; |
136 | } |
137 | |
138 | /** |
139 | * Get data |
140 | * |
141 | * @param string $key |
142 | * @return mixed |
143 | */ |
144 | public function get(string $key): mixed |
145 | { |
146 | return $this->data[$key] ?? null; |
147 | } |
148 | |
149 | /** |
150 | * Set view template |
151 | * |
152 | * @param mixed $template |
153 | * @return static |
154 | */ |
155 | public function setTemplate(mixed $template): static |
156 | { |
157 | if (!($template instanceof Template\TemplateInterface)) { |
158 | // If a native PHP file template |
159 | if (((str_ends_with($template, '.phtml')) || |
160 | (substr($template, -5, 4) == '.php') || |
161 | (str_ends_with($template, '.php'))) && (strlen($template) <= 255) && (file_exists($template))) { |
162 | $template = new Template\File($template); |
163 | // If a string template, or a string template from a non-PHP file |
164 | } else { |
165 | $template = new Template\Stream($template); |
166 | } |
167 | } |
168 | $this->template = $template; |
169 | return $this; |
170 | } |
171 | |
172 | /** |
173 | * Set all model data |
174 | * |
175 | * @param array $data |
176 | * @return static |
177 | */ |
178 | public function setData(array $data = []): static |
179 | { |
180 | $this->data = $data; |
181 | return $this; |
182 | } |
183 | |
184 | /** |
185 | * Set model data |
186 | * |
187 | * @param string $name |
188 | * @param mixed $value |
189 | * @return static |
190 | */ |
191 | public function set(string $name, mixed $value): static |
192 | { |
193 | $this->data[$name] = $value; |
194 | return $this; |
195 | } |
196 | |
197 | /** |
198 | * Merge new model data |
199 | * |
200 | * @param array $data |
201 | * @return static |
202 | */ |
203 | public function merge(array $data): static |
204 | { |
205 | $this->data = array_merge($this->data, $data); |
206 | return $this; |
207 | } |
208 | |
209 | /** |
210 | * Filter values |
211 | * |
212 | * @param mixed $values |
213 | * @return mixed |
214 | */ |
215 | public function filter(mixed $values): mixed |
216 | { |
217 | foreach ($this->filters as $filter) { |
218 | if (is_array($values)) { |
219 | foreach ($values as $key => $value) { |
220 | $values[$key] = $filter->filter($value, $key); |
221 | } |
222 | } else { |
223 | $values = [$filter->filter($values)]; |
224 | } |
225 | } |
226 | |
227 | return $values; |
228 | } |
229 | |
230 | /** |
231 | * Render the view |
232 | * |
233 | * @throws Exception|Template\Exception |
234 | * @return ?string |
235 | */ |
236 | public function render(): ?string |
237 | { |
238 | if ($this->template === null) { |
239 | throw new Exception('A template asset has not been assigned.'); |
240 | } |
241 | |
242 | if ($this->hasFilters()) { |
243 | $this->data = $this->filter($this->data); |
244 | } |
245 | |
246 | $this->output = $this->template->render($this->data); |
247 | return $this->output; |
248 | } |
249 | |
250 | /** |
251 | * Return rendered view as string |
252 | * |
253 | * @return string |
254 | */ |
255 | public function __toString(): string |
256 | { |
257 | return $this->render(); |
258 | } |
259 | |
260 | } |