1
|
|
|
<?php |
2
|
|
|
namespace Zewa; |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* Abstract class for model extension |
6
|
|
|
* |
7
|
|
|
* @author Zechariah Walden<zech @ zewadesign.com> |
8
|
|
|
*/ |
9
|
|
|
class View |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* System configuration |
13
|
|
|
* |
14
|
|
|
* @var object |
15
|
|
|
*/ |
16
|
|
|
protected $configuration; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Instantiated request class pointer |
20
|
|
|
* |
21
|
|
|
* @var object |
22
|
|
|
*/ |
23
|
|
|
protected $request; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Active layout for view |
27
|
|
|
* |
28
|
|
|
* @var string|bool |
29
|
|
|
*/ |
30
|
|
|
protected $layout = false; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Active module for view |
34
|
|
|
* |
35
|
|
|
* @var string|bool |
36
|
|
|
*/ |
37
|
|
|
protected $module = false; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Rendered view content |
41
|
|
|
* |
42
|
|
|
* @var string |
43
|
|
|
*/ |
44
|
|
|
protected $view = false; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Data object for view |
48
|
|
|
* |
49
|
|
|
* @var object |
50
|
|
|
*/ |
51
|
|
|
protected $properties; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Router object for view injection |
55
|
|
|
* |
56
|
|
|
* @var object |
57
|
|
|
*/ |
58
|
|
|
protected $router; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Load up some basic configuration settings. |
62
|
|
|
*/ |
63
|
|
View Code Duplication |
public function __construct() |
|
|
|
|
64
|
|
|
{ |
65
|
|
|
// This abstract is strictly to establish inheritance from a global registery. |
66
|
|
|
$app = App::getInstance(); |
67
|
|
|
$this->configuration = $app->getConfiguration(); |
68
|
|
|
$this->request = App::getService('request'); |
69
|
|
|
$this->router = App::getService('router'); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
private function baseURL($path = '') |
73
|
|
|
{ |
74
|
|
|
return $this->router->baseURL($path); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
private function currentURL($params = false) |
|
|
|
|
78
|
|
|
{ |
79
|
|
|
return $this->router->currentURL($params); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
|
83
|
|
|
private function currentURI() |
|
|
|
|
84
|
|
|
{ |
85
|
|
|
return $this->router->uri; |
86
|
|
|
} |
87
|
|
|
/** |
88
|
|
|
* Loads a view |
89
|
|
|
* |
90
|
|
|
* @access public |
91
|
|
|
* |
92
|
|
|
* @param string $requestedView relative path for the view |
|
|
|
|
93
|
|
|
* @param string $renderName array of data to expose to view |
|
|
|
|
94
|
|
|
* |
95
|
|
|
* @throws \Exception when a view can not be found |
96
|
|
|
*/ |
97
|
|
|
public function render() |
98
|
|
|
{ |
99
|
|
|
if ($this->view !== false) { |
100
|
|
|
$this->view = $this->process($this->view); |
101
|
|
|
} |
102
|
|
|
if ($this->layout === false) { |
103
|
|
|
$this->setLayout($this->configuration->layouts->default); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if (is_null($this->layout)) { |
107
|
|
|
return $this->view; |
108
|
|
|
} else { |
109
|
|
|
return $this->process($this->layout); |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
public function setView($requestedView) |
114
|
|
|
{ |
115
|
|
|
|
116
|
|
|
if ($this->module === false) { |
117
|
|
|
$this->module = $this->configuration->router->module; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$view = APP_PATH |
121
|
|
|
. DIRECTORY_SEPARATOR |
122
|
|
|
. 'Modules' |
123
|
|
|
. DIRECTORY_SEPARATOR |
124
|
|
|
. $this->module |
125
|
|
|
. DIRECTORY_SEPARATOR |
126
|
|
|
. 'Views' |
127
|
|
|
. DIRECTORY_SEPARATOR |
128
|
|
|
. strtolower($requestedView) |
129
|
|
|
. '.php'; |
130
|
|
|
|
131
|
|
|
if (!file_exists($view)) { |
132
|
|
|
throw new Exception\LookupException('View: "' . $view . '" could not be found.'); |
133
|
|
|
} |
134
|
|
|
$this->view = $view; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
public function setProperty($property, $value = false) |
138
|
|
|
{ |
139
|
|
|
if ($value !== false) { |
140
|
|
|
$this->properties[$property] = $value; |
141
|
|
|
} elseif (!empty($property)) { |
142
|
|
|
$this->properties = $property; |
143
|
|
|
} |
144
|
|
|
return false; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
public function setLayout($layout) |
148
|
|
|
{ |
149
|
|
|
|
150
|
|
|
if ($layout === false) { |
151
|
|
|
$this->layout = null; |
152
|
|
|
} else { |
153
|
|
|
$layout = APP_PATH . DIRECTORY_SEPARATOR . 'Layouts' . DIRECTORY_SEPARATOR . strtolower($layout) . '.php'; |
154
|
|
|
|
155
|
|
|
if (!file_exists($layout)) { |
156
|
|
|
throw new Exception\LookupException('Layout: "' . $layout . '" could not be found.'); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
$this->layout = $layout; |
160
|
|
|
|
161
|
|
|
return true; |
162
|
|
|
} |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
public function setModule($module = false) |
166
|
|
|
{ |
167
|
|
|
if ($module === false) { |
168
|
|
|
$this->module = $this->configuration->router->module; |
169
|
|
|
} else { |
170
|
|
|
$this->module = ucfirst($module); |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
/** |
174
|
|
|
* Processes view/layouts and exposes variables to the view/layout |
175
|
|
|
* |
176
|
|
|
* @access private |
177
|
|
|
* |
178
|
|
|
* @param string $file file being rendered |
179
|
|
|
* |
180
|
|
|
* @return string processed content |
181
|
|
|
*/ |
182
|
|
|
//@TODO: come back and clean up this and the way the view receives stuff |
183
|
|
|
private function process($file) |
184
|
|
|
{ |
185
|
|
|
ob_start(); |
186
|
|
|
|
187
|
|
|
if (is_array($this->properties)) { |
188
|
|
|
extract($this->properties); // yuck. could produce undeclared errors. hmm.. |
189
|
|
|
} |
190
|
|
|
//should i set $this->data in abstract controller, and provide all access vars ? seems bad practice.. |
191
|
|
|
|
192
|
|
|
include($file); |
193
|
|
|
|
194
|
|
|
$return = ob_get_contents(); |
195
|
|
|
|
196
|
|
|
ob_end_clean(); |
197
|
|
|
|
198
|
|
|
return $return; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
// private function verifyResource($resource) { |
|
|
|
|
202
|
|
|
// |
203
|
|
|
// $path = PUBLIC_PATH . DIRECTORY_SEPARATOR . $resource; |
204
|
|
|
// |
205
|
|
|
// if (!file_exists($path)) { |
206
|
|
|
// return false; |
207
|
|
|
// } |
208
|
|
|
// |
209
|
|
|
// return true; |
210
|
|
|
// } |
211
|
|
|
|
212
|
|
View Code Duplication |
protected function fetchCSS() |
|
|
|
|
213
|
|
|
{ |
214
|
|
|
$app = App::getInstance(); |
215
|
|
|
$sheets = $app->getConfiguration('view::css'); |
216
|
|
|
|
217
|
|
|
$string = ""; |
218
|
|
|
|
219
|
|
|
if (empty($sheets)) { |
220
|
|
|
return $string; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
foreach ($sheets as $sheet) { |
224
|
|
|
$string .= '<link rel="stylesheet" href="' . $sheet .'">' . "\r\n"; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
return $string; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
View Code Duplication |
protected function fetchJS() |
|
|
|
|
231
|
|
|
{ |
232
|
|
|
|
233
|
|
|
$app = App::getInstance(); |
234
|
|
|
$scripts = $app->getConfiguration('view::js'); |
235
|
|
|
$string = "<script>baseURL = '" . $this->baseURL() . "/'</script>"; |
236
|
|
|
|
237
|
|
|
if (empty($scripts)) { |
238
|
|
|
return $string; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
foreach ($scripts as $script) { |
242
|
|
|
$string .= '<script src="' . $script . '"></script>' . "\r\n"; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
return $string; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
View Code Duplication |
public function addCSS($sheets = [], $place = 'append') |
|
|
|
|
249
|
|
|
{ |
250
|
|
|
$app = App::getInstance(); |
251
|
|
|
$existingCSS = $app->getConfiguration('view::css'); |
252
|
|
|
|
253
|
|
|
if ($existingCSS === false) { |
254
|
|
|
$existingCSS = []; |
255
|
|
|
} else { |
256
|
|
|
$existingCSS = (array)$existingCSS; |
257
|
|
|
} |
258
|
|
|
if (empty($sheets)) { |
259
|
|
|
throw new Exception\LookupException('You must provide a valid CSS Resource.'); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
$files = []; |
263
|
|
|
|
264
|
|
|
foreach ($sheets as $file) { |
265
|
|
|
$files[] = $file; |
266
|
|
|
// if ($this->verifyResource($file)) { |
267
|
|
|
// } else { |
268
|
|
|
// throw new Exception\LookupException('The CSS Resource you\'ve specified does not exist.'); |
269
|
|
|
// } |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
if ($place === 'prepend') { |
273
|
|
|
$existingCSS = array_merge($files, $existingCSS); |
274
|
|
|
} else { |
275
|
|
|
$existingCSS = array_merge($existingCSS, $files); |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
$app = App::getInstance(); |
279
|
|
|
$app->setConfiguration('view::css', (object)$existingCSS); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
View Code Duplication |
public function addJS($scripts = [], $place = 'append') |
|
|
|
|
283
|
|
|
{ |
284
|
|
|
|
285
|
|
|
$app = App::getInstance(); |
286
|
|
|
$existingJS = $app->getConfiguration('view::js'); |
287
|
|
|
|
288
|
|
|
if ($existingJS === false) { |
289
|
|
|
$existingJS = []; |
290
|
|
|
} else { |
291
|
|
|
$existingJS = (array)$existingJS; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
if (!empty($scripts)) { |
295
|
|
|
$files = []; |
296
|
|
|
|
297
|
|
|
foreach ($scripts as $file) { |
298
|
|
|
$files[] = $file; |
299
|
|
|
// if ($this->verifyResource($file)) { |
300
|
|
|
// } else { |
301
|
|
|
// throw new Exception\LookupException('The JS Resource you\'ve specified does not exist: ' . $file); |
302
|
|
|
// } |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
if ($place === 'prepend') { |
306
|
|
|
$existingJS = array_merge($files, $existingJS); |
307
|
|
|
} else { |
308
|
|
|
$existingJS = array_merge($existingJS, $files); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
$app = App::getInstance(); |
312
|
|
|
$app->setConfiguration('view::js', (object)$existingJS); |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
|
317
|
|
|
/** |
318
|
|
|
* Set 401 header, and return noaccess view contents |
319
|
|
|
* |
320
|
|
|
* @access public |
321
|
|
|
* @return string |
322
|
|
|
*/ |
323
|
|
|
public function renderNoAccess($data) |
324
|
|
|
{ |
325
|
|
|
header('HTTP/1.1 401 Access Denied'); |
326
|
|
|
$this->setProperty($data); |
327
|
|
|
$this->setLayout('no-access'); |
328
|
|
|
return $this->render(); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
/** |
332
|
|
|
* Set 404 header, and return 404 view contents |
333
|
|
|
* |
334
|
|
|
* @access public |
335
|
|
|
* @param $module string |
336
|
|
|
* @param $data array |
337
|
|
|
* @return string |
338
|
|
|
*/ |
339
|
|
|
public function render404($data = []) |
340
|
|
|
{ |
341
|
|
|
header('HTTP/1.1 404 Not Found'); |
342
|
|
|
$this->setProperty($data); |
343
|
|
|
$this->setLayout('404'); |
344
|
|
|
return $this->render(); |
345
|
|
|
} |
346
|
|
|
} |
347
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.