|
1
|
|
|
<?php /** MicroView */ |
|
2
|
|
|
|
|
3
|
|
|
namespace Micro\Mvc\Views; |
|
4
|
|
|
|
|
5
|
|
|
use Micro\Base\Exception; |
|
6
|
|
|
use Micro\Mvc\Module; |
|
7
|
|
|
use Micro\Mvc\Widget; |
|
8
|
|
|
use Micro\Web\Html\Html; |
|
9
|
|
|
|
|
10
|
|
|
/** |
|
11
|
|
|
* Class View |
|
12
|
|
|
* |
|
13
|
|
|
* @author Oleg Lunegov <[email protected]> |
|
14
|
|
|
* @link https://github.com/linpax/microphp-framework |
|
15
|
|
|
* @copyright Copyright (c) 2013 Oleg Lunegov |
|
16
|
|
|
* @license https://github.com/linpax/microphp-framework/blob/master/LICENSE |
|
17
|
|
|
* @package Micro |
|
18
|
|
|
* @subpackage Mvc/Views |
|
19
|
|
|
* @version 1.0 |
|
20
|
|
|
* @since 1.0 |
|
21
|
|
|
*/ |
|
22
|
|
|
abstract class View implements IView |
|
23
|
|
|
{ |
|
24
|
|
|
/** @var array $styleScripts */ |
|
25
|
|
|
public $styleScripts = []; |
|
26
|
|
|
/** @var bool $asWidget */ |
|
27
|
|
|
public $asWidget = false; |
|
28
|
|
|
/** @var array $params */ |
|
29
|
|
|
public $params = []; |
|
30
|
|
|
/** @var array $stack */ |
|
31
|
|
|
public $stack = []; |
|
32
|
|
|
/** @var Module $module */ |
|
33
|
|
|
public $module; |
|
34
|
|
|
|
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* @access public |
|
38
|
|
|
* @result void |
|
39
|
|
|
*/ |
|
40
|
|
|
public function __construct() |
|
41
|
|
|
{ |
|
42
|
|
|
} |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* Add parameter into view |
|
46
|
|
|
* |
|
47
|
|
|
* @access public |
|
48
|
|
|
* |
|
49
|
|
|
* @param string $name parameter name |
|
50
|
|
|
* @param mixed $value parameter value |
|
51
|
|
|
* |
|
52
|
|
|
* @return void |
|
53
|
|
|
*/ |
|
54
|
|
|
public function addParameter($name, $value) |
|
55
|
|
|
{ |
|
56
|
|
|
$this->params[$name] = $value; |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* Widget |
|
61
|
|
|
* |
|
62
|
|
|
* @access public |
|
63
|
|
|
* |
|
64
|
|
|
* @param string $name widget name |
|
65
|
|
|
* @param array $options options array |
|
66
|
|
|
* @param bool $capture capture output |
|
67
|
|
|
* |
|
68
|
|
|
* @return string |
|
69
|
|
|
* @throws Exception |
|
70
|
|
|
*/ |
|
71
|
|
|
public function widget($name, array $options = [], $capture = false) |
|
72
|
|
|
{ |
|
73
|
|
|
if (!class_exists($name)) { |
|
74
|
|
|
throw new Exception('Widget '.$name.' not found.'); |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
/** @var \Micro\mvc\Widget $widget widget */ |
|
78
|
|
|
$widget = new $name($options); |
|
79
|
|
|
$widget->init(); |
|
80
|
|
|
|
|
81
|
|
|
if ($capture) { |
|
82
|
|
|
ob_start(); |
|
83
|
|
|
$widget->run(); |
|
84
|
|
|
$result = ob_get_clean(); |
|
85
|
|
|
} else { |
|
86
|
|
|
$result = $widget->run(); |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
View Code Duplication |
if ($result instanceof PhpView) { |
|
|
|
|
|
|
90
|
|
|
$result->asWidget = true; |
|
91
|
|
|
$result->path = get_class($widget); |
|
92
|
|
|
|
|
93
|
|
|
$result = $result->render(); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
unset($widget); |
|
97
|
|
|
|
|
98
|
|
|
if ($capture) { |
|
99
|
|
|
return $result; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
echo $result; |
|
103
|
|
|
|
|
104
|
|
|
return ''; |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
/** |
|
108
|
|
|
* Begin widget |
|
109
|
|
|
* |
|
110
|
|
|
* @access public |
|
111
|
|
|
* |
|
112
|
|
|
* @param string $name widget name |
|
113
|
|
|
* @param array $options options array |
|
114
|
|
|
* |
|
115
|
|
|
* @return mixed |
|
116
|
|
|
* @throws Exception |
|
117
|
|
|
*/ |
|
118
|
|
|
public function beginWidget($name, array $options = []) |
|
|
|
|
|
|
119
|
|
|
{ |
|
120
|
|
|
if (!class_exists($name)) { |
|
121
|
|
|
throw new Exception('Widget `'.$name.'` not found.'); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
View Code Duplication |
if (!empty($GLOBALS['widgetStack'][$name])) { |
|
|
|
|
|
|
125
|
|
|
throw new Exception('This widget `'.$name.'` already started!'); |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
$GLOBALS['widgetStack'][$name] = new $name($options); |
|
129
|
|
|
|
|
130
|
|
|
/** @noinspection PhpUndefinedMethodInspection */ |
|
131
|
|
|
|
|
132
|
|
|
return $GLOBALS['widgetStack'][$name]->init(); |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
/** |
|
136
|
|
|
* Ending widget |
|
137
|
|
|
* |
|
138
|
|
|
* @access public |
|
139
|
|
|
* |
|
140
|
|
|
* @param string $name widget name |
|
141
|
|
|
* |
|
142
|
|
|
* @throws Exception |
|
143
|
|
|
*/ |
|
144
|
|
|
public function endWidget($name = '') |
|
|
|
|
|
|
145
|
|
|
{ |
|
146
|
|
|
if (!$name && $GLOBALS['widgetStack']) { |
|
147
|
|
|
/** @var Widget $widget */ |
|
148
|
|
|
$widget = array_pop($GLOBALS['widgetStack']); |
|
149
|
|
|
$v = $widget->run(); |
|
150
|
|
|
|
|
151
|
|
View Code Duplication |
if ($v instanceof PhpView) { |
|
|
|
|
|
|
152
|
|
|
$v->asWidget = true; |
|
153
|
|
|
$v->path = get_class($widget); |
|
154
|
|
|
|
|
155
|
|
|
$v = $v->render(); |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
unset($widget); |
|
159
|
|
|
echo $v; |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
if (empty($GLOBALS['widgetStack'][$name]) && !class_exists($name)) { |
|
163
|
|
|
throw new Exception('Widget `'.$name.'` not started.'); |
|
164
|
|
|
} |
|
165
|
|
|
|
|
166
|
|
|
/** @var \Micro\mvc\Widget $widget widget */ |
|
167
|
|
|
$widget = $GLOBALS['widgetStack'][$name]; |
|
168
|
|
|
unset($GLOBALS['widgetStack'][$name]); |
|
169
|
|
|
|
|
170
|
|
|
$v = $widget->run(); |
|
171
|
|
|
|
|
172
|
|
View Code Duplication |
if ($v instanceof PhpView) { |
|
|
|
|
|
|
173
|
|
|
$v->asWidget = true; |
|
174
|
|
|
$v->path = get_class($widget); |
|
175
|
|
|
|
|
176
|
|
|
$v = $v->render(); |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
unset($widget); |
|
180
|
|
|
echo $v; |
|
181
|
|
|
} |
|
182
|
|
|
|
|
183
|
|
|
/** |
|
184
|
|
|
* Register JS script |
|
185
|
|
|
* |
|
186
|
|
|
* @access public |
|
187
|
|
|
* |
|
188
|
|
|
* @param string $source file name |
|
189
|
|
|
* @param bool $isHead is head block |
|
190
|
|
|
* |
|
191
|
|
|
* @return void |
|
192
|
|
|
*/ |
|
193
|
|
|
public function registerScript($source, $isHead = true) |
|
194
|
|
|
{ |
|
195
|
|
|
$this->styleScripts[] = [ |
|
196
|
|
|
'isHead' => $isHead, |
|
197
|
|
|
'body' => Html::script($source) |
|
198
|
|
|
]; |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
/** |
|
202
|
|
|
* Register JS file |
|
203
|
|
|
* |
|
204
|
|
|
* @access public |
|
205
|
|
|
* |
|
206
|
|
|
* @param string $source file name |
|
207
|
|
|
* @param bool $isHead is head block |
|
208
|
|
|
* |
|
209
|
|
|
* @return void |
|
210
|
|
|
*/ |
|
211
|
|
|
public function registerScriptFile($source, $isHead = true) |
|
212
|
|
|
{ |
|
213
|
|
|
$this->styleScripts[] = [ |
|
214
|
|
|
'isHead' => $isHead, |
|
215
|
|
|
'body' => Html::scriptFile($source) |
|
216
|
|
|
]; |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
|
|
/** |
|
220
|
|
|
* Register CSS code |
|
221
|
|
|
* |
|
222
|
|
|
* @access public |
|
223
|
|
|
* |
|
224
|
|
|
* @param string $source file name |
|
225
|
|
|
* @param bool $isHead is head block |
|
226
|
|
|
* |
|
227
|
|
|
* @return void |
|
228
|
|
|
*/ |
|
229
|
|
|
public function registerCss($source, $isHead = true) |
|
230
|
|
|
{ |
|
231
|
|
|
$this->styleScripts[] = [ |
|
232
|
|
|
'isHead' => $isHead, |
|
233
|
|
|
'body' => Html::css($source) |
|
234
|
|
|
]; |
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
/** |
|
238
|
|
|
* Register CSS file |
|
239
|
|
|
* |
|
240
|
|
|
* @access public |
|
241
|
|
|
* |
|
242
|
|
|
* @param string $source file name |
|
243
|
|
|
* @param bool $isHead is head block |
|
244
|
|
|
* |
|
245
|
|
|
* @return void |
|
246
|
|
|
*/ |
|
247
|
|
|
public function registerCssFile($source, $isHead = true) |
|
248
|
|
|
{ |
|
249
|
|
|
$this->styleScripts[] = [ |
|
250
|
|
|
'isHead' => $isHead, |
|
251
|
|
|
'body' => Html::cssFile($source) |
|
252
|
|
|
]; |
|
253
|
|
|
} |
|
254
|
|
|
|
|
255
|
|
|
/** |
|
256
|
|
|
* Insert styles and scripts into cache |
|
257
|
|
|
* |
|
258
|
|
|
* @access protected |
|
259
|
|
|
* |
|
260
|
|
|
* @param string $cache cache of generated page |
|
261
|
|
|
* |
|
262
|
|
|
* @return string |
|
263
|
|
|
*/ |
|
264
|
|
|
protected function insertStyleScripts($cache) |
|
265
|
|
|
{ |
|
266
|
|
|
$heads = ''; |
|
267
|
|
|
$ends = ''; |
|
268
|
|
|
$result = ''; |
|
269
|
|
|
|
|
270
|
|
|
foreach ($this->styleScripts AS $element) { |
|
271
|
|
|
if ($element['isHead']) { |
|
272
|
|
|
$heads .= $element['body']; |
|
273
|
|
|
} else { |
|
274
|
|
|
$ends .= $element['body']; |
|
275
|
|
|
} |
|
276
|
|
|
} |
|
277
|
|
|
|
|
278
|
|
|
$positionHead = strpos($cache, Html::closeTag('head')); |
|
279
|
|
|
$positionBody = strpos($cache, Html::closeTag('body'), $positionHead); |
|
280
|
|
|
|
|
281
|
|
|
$result .= substr($cache, 0, $positionHead); |
|
282
|
|
|
$result .= $heads; |
|
283
|
|
|
$result .= substr($cache, $positionHead, $positionBody); |
|
284
|
|
|
$result .= $ends; |
|
285
|
|
|
$result .= substr($cache, $positionHead + $positionBody); |
|
286
|
|
|
|
|
287
|
|
|
return $result; |
|
288
|
|
|
} |
|
289
|
|
|
} |
|
290
|
|
|
|
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.