1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* CakeCMS Core |
4
|
|
|
* |
5
|
|
|
* This file is part of the of the simple cms based on CakePHP 3. |
6
|
|
|
* For the full copyright and license information, please view the LICENSE |
7
|
|
|
* file that was distributed with this source code. |
8
|
|
|
* |
9
|
|
|
* @package Core |
10
|
|
|
* @license MIT |
11
|
|
|
* @copyright MIT License http://www.opensource.org/licenses/mit-license.php |
12
|
|
|
* @link https://github.com/CakeCMS/Core". |
13
|
|
|
* @author Sergey Kalistratov <[email protected]> |
14
|
|
|
*/ |
15
|
|
|
|
16
|
|
|
namespace Core\View\Helper; |
17
|
|
|
|
18
|
|
|
use Core\Plugin; |
19
|
|
|
use JBZoo\Utils\Arr; |
20
|
|
|
use JBZoo\Utils\Str; |
21
|
|
|
use Cake\Event\Event; |
22
|
|
|
use Cake\Core\Configure; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Class DocumentHelper |
26
|
|
|
* |
27
|
|
|
* @package Core\View\Helper |
28
|
|
|
* @property \Core\View\Helper\HtmlHelper $Html |
29
|
|
|
* @property \Core\View\Helper\AssetsHelper $Assets |
30
|
|
|
* |
31
|
|
|
* @SuppressWarnings(PHPMD.TooManyPublicMethods) |
32
|
|
|
*/ |
33
|
|
|
class DocumentHelper extends AppHelper |
34
|
|
|
{ |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Init vars. |
38
|
|
|
* |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
public $charset; |
42
|
|
|
public $dir; |
43
|
|
|
public $eol; |
44
|
|
|
public $locale; |
45
|
|
|
public $tab; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Uses helpers. |
49
|
|
|
* |
50
|
|
|
* @var array |
51
|
|
|
*/ |
52
|
|
|
public $helpers = [ |
53
|
|
|
'Core.Html', |
54
|
|
|
'Core.Assets' |
55
|
|
|
]; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Is called after layout rendering is complete. Receives the layout filename as an argument. |
59
|
|
|
* |
60
|
|
|
* @param Event $event |
61
|
|
|
* @param string $layoutFile |
62
|
|
|
* @return void |
63
|
|
|
* |
64
|
|
|
* @throws \JBZoo\Utils\Exception |
65
|
|
|
*/ |
66
|
|
|
public function afterLayout(Event $event, $layoutFile) |
67
|
|
|
{ |
68
|
|
|
$pluginEvent = Plugin::getData('Core', 'View.afterLayout'); |
69
|
|
|
if (is_callable($pluginEvent->find(0)) && Plugin::hasManifestEvent('View.afterLayout')) { |
70
|
|
|
call_user_func_array($pluginEvent->find(0), [$this->_View, $event, $layoutFile]); |
71
|
|
|
} |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Is called after the view has been rendered but before layout rendering has started. |
76
|
|
|
* |
77
|
|
|
* @param Event $event |
78
|
|
|
* @param string $viewFile |
79
|
|
|
* @return void |
80
|
|
|
* |
81
|
|
|
* @throws \JBZoo\Utils\Exception |
82
|
|
|
*/ |
83
|
|
View Code Duplication |
public function afterRender(Event $event, $viewFile) |
|
|
|
|
84
|
|
|
{ |
85
|
|
|
$this->_setupMetaData(); |
86
|
|
|
|
87
|
|
|
$pluginEvent = Plugin::getData('Core', 'View.afterRender'); |
88
|
|
|
if (is_callable($pluginEvent->find(0)) && Plugin::hasManifestEvent('View.afterRender')) { |
89
|
|
|
call_user_func_array($pluginEvent->find(0), [$this->_View, $event, $viewFile]); |
90
|
|
|
} |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Is called after each view file is rendered. This includes elements, views, parent views and layouts. |
95
|
|
|
* A callback can modify and return $content to change how the rendered content will be displayed in the browser. |
96
|
|
|
* |
97
|
|
|
* @param Event $event |
98
|
|
|
* @param string $viewFile |
99
|
|
|
* @param string $content |
100
|
|
|
* @return void |
101
|
|
|
* |
102
|
|
|
* @throws \JBZoo\Utils\Exception |
103
|
|
|
*/ |
104
|
|
View Code Duplication |
public function afterRenderFile(Event $event, $viewFile, $content) |
|
|
|
|
105
|
|
|
{ |
106
|
|
|
$pluginEvent = Plugin::getData('Core', 'View.afterRenderFile'); |
107
|
|
|
if (is_callable($pluginEvent->find(0)) && Plugin::hasManifestEvent('View.afterRenderFile')) { |
108
|
|
|
call_user_func_array($pluginEvent->find(0), [$this->_View, $event, $viewFile, $content]); |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Get assets fot layout render. |
114
|
|
|
* |
115
|
|
|
* @param string $type |
116
|
|
|
* @return string |
117
|
|
|
*/ |
118
|
|
|
public function assets($type = 'css') |
119
|
|
|
{ |
120
|
|
|
$output = []; |
121
|
|
|
$assets = $this->Assets->getAssets($type); |
122
|
|
|
foreach ($assets as $asset) { |
|
|
|
|
123
|
|
|
$output[] = $asset['output']; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
return implode($this->eol, $output); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Is called before layout rendering starts. Receives the layout filename as an argument. |
131
|
|
|
* |
132
|
|
|
* @param Event $event |
133
|
|
|
* @param string $layoutFile |
134
|
|
|
* @return void |
135
|
|
|
* |
136
|
|
|
* @throws \JBZoo\Utils\Exception |
137
|
|
|
*/ |
138
|
|
|
public function beforeLayout(Event $event, $layoutFile) |
139
|
|
|
{ |
140
|
|
|
$pluginEvent = Plugin::getData('Core', 'View.beforeLayout'); |
141
|
|
|
if (is_callable($pluginEvent->find(0)) && Plugin::hasManifestEvent('View.beforeLayout')) { |
142
|
|
|
call_user_func_array($pluginEvent->find(0), [$this->_View, $event, $layoutFile]); |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* Is called after the controller’s beforeRender method but before the controller renders view and layout. |
148
|
|
|
* Receives the file being rendered as an argument. |
149
|
|
|
* |
150
|
|
|
* @param Event $event |
151
|
|
|
* @param string $viewFile |
152
|
|
|
* @return void |
153
|
|
|
* |
154
|
|
|
* @throws \JBZoo\Less\Exception |
155
|
|
|
* @throws \JBZoo\Utils\Exception |
156
|
|
|
*/ |
157
|
|
View Code Duplication |
public function beforeRender(Event $event, $viewFile) |
|
|
|
|
158
|
|
|
{ |
159
|
|
|
$this->Assets->loadPluginAssets(); |
160
|
|
|
|
161
|
|
|
$pluginEvent = Plugin::getData('Core', 'View.beforeRender'); |
162
|
|
|
if (is_callable($pluginEvent->find(0)) && Plugin::hasManifestEvent('View.beforeRender')) { |
163
|
|
|
call_user_func_array($pluginEvent->find(0), [$this->_View, $event, $viewFile]); |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Is called before each view file is rendered. This includes elements, views, parent views and layouts. |
169
|
|
|
* |
170
|
|
|
* @param Event $event |
171
|
|
|
* @param string $viewFile |
172
|
|
|
* @return void |
173
|
|
|
* |
174
|
|
|
* @throws \JBZoo\Utils\Exception |
175
|
|
|
*/ |
176
|
|
|
public function beforeRenderFile(Event $event, $viewFile) |
177
|
|
|
{ |
178
|
|
|
$pluginEvent = Plugin::getData('Core', 'View.beforeRenderFile'); |
179
|
|
|
if (is_callable($pluginEvent->find(0)) && Plugin::hasManifestEvent('View.beforeRenderFile')) { |
180
|
|
|
call_user_func_array($pluginEvent->find(0), [$this->_View, $event, $viewFile]); |
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Get body classes by view data. |
186
|
|
|
* |
187
|
|
|
* @return string |
188
|
|
|
*/ |
189
|
|
|
public function getBodyClasses() |
190
|
|
|
{ |
191
|
|
|
$prefix = ($this->request->getParam('prefix')) ? 'prefix-' . $this->request->getParam('prefix') : 'prefix-site'; |
192
|
|
|
|
193
|
|
|
$classes = [ |
194
|
|
|
$prefix, |
195
|
|
|
'theme-' . Str::low($this->_View->theme), |
196
|
|
|
'plugin-' . Str::low($this->_View->plugin), |
197
|
|
|
'view-' . Str::low($this->_View->name), |
198
|
|
|
'tmpl-' . Str::low($this->_View->template), |
199
|
|
|
'layout-' . Str::low($this->_View->layout) |
200
|
|
|
]; |
201
|
|
|
|
202
|
|
|
$pass = (array) $this->request->getParam('pass'); |
203
|
|
|
if (count($pass)) { |
204
|
|
|
$classes[] = 'item-id-' . array_shift($pass); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
return implode(' ', $classes); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Create head for layout. |
212
|
|
|
* |
213
|
|
|
* @return string |
214
|
|
|
*/ |
215
|
|
|
public function head() |
216
|
|
|
{ |
217
|
|
|
$output = [ |
218
|
|
|
'meta' => $this->_View->fetch('meta'), |
219
|
|
|
'assets' => $this->assets('css'), |
220
|
|
|
'fetch_css' => $this->_View->fetch('css'), |
221
|
|
|
'fetch_css_bottom' => $this->_View->fetch('css_bottom'), |
222
|
|
|
]; |
223
|
|
|
|
224
|
|
|
return implode('', $output); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* Constructor hook method. |
229
|
|
|
* |
230
|
|
|
* @param array $config |
231
|
|
|
*/ |
232
|
|
|
public function initialize(array $config) |
233
|
|
|
{ |
234
|
|
|
parent::initialize($config); |
235
|
|
|
|
236
|
|
|
$this->dir = Configure::read('Cms.docDir'); |
237
|
|
|
$this->locale = Configure::read('App.defaultLocale'); |
238
|
|
|
$this->charset = Str::low(Configure::read('App.encoding')); |
239
|
|
|
$this->eol = (Configure::read('debug')) ? PHP_EOL : ''; |
240
|
|
|
$this->tab = (Configure::read('debug')) ? Configure::read('Cms.lineTab') : ''; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* Site language. |
245
|
|
|
* |
246
|
|
|
* @param bool|true $isLang |
247
|
|
|
* @return string |
248
|
|
|
* |
249
|
|
|
* @throws \Exception |
250
|
|
|
*/ |
251
|
|
|
public function lang($isLang = true) |
252
|
|
|
{ |
253
|
|
|
list($lang, $region) = explode('_', $this->locale); |
254
|
|
|
return ($isLang) ? Str::low($lang) : Str::low($region); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Creates a link to an external resource and handles basic meta tags. |
259
|
|
|
* |
260
|
|
|
* @param array $rows |
261
|
|
|
* @param null $block |
262
|
|
|
* @return null|string |
263
|
|
|
*/ |
264
|
|
|
public function meta(array $rows, $block = null) |
265
|
|
|
{ |
266
|
|
|
$output = []; |
267
|
|
|
foreach ($rows as $row) { |
268
|
|
|
$output[] = trim($row); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
$output = implode($this->eol, $output) . $this->eol; |
272
|
|
|
|
273
|
|
|
if ($block !== null) { |
274
|
|
|
$this->_View->append($block, $output); |
275
|
|
|
return null; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
return $output; |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Create html 5 document type. |
283
|
|
|
* |
284
|
|
|
* @return string |
285
|
|
|
* |
286
|
|
|
* @throws \Exception |
287
|
|
|
*/ |
288
|
|
|
public function type() |
289
|
|
|
{ |
290
|
|
|
$lang = $this->lang(); |
291
|
|
|
$html = [ |
292
|
|
|
'<!doctype html>', |
293
|
|
|
'<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7 ie6" ' |
294
|
|
|
. 'lang="' . $lang . '" dir="' . $this->dir . '"> <![endif]-->', |
295
|
|
|
'<!--[if IE 7]><html class="no-js lt-ie9 lt-ie8 ie7" ' |
296
|
|
|
. 'lang="' . $lang . '" dir="' . $this->dir . '"> <![endif]-->', |
297
|
|
|
'<!--[if IE 8]><html class="no-js lt-ie9 ie8" ' |
298
|
|
|
. 'lang="' . $lang . '" dir="' . $this->dir . '"> <![endif]-->', |
299
|
|
|
'<!--[if gt IE 8]><!--><html class="no-js" xmlns="http://www.w3.org/1999/xhtml" ' |
300
|
|
|
. 'lang="' . $lang . '" dir="' . $this->dir . '" ' |
301
|
|
|
. 'prefix="og: http://ogp.me/ns#" ' |
302
|
|
|
. '> <!--<![endif]-->', |
303
|
|
|
]; |
304
|
|
|
return implode($this->eol, $html) . $this->eol; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* Assign data from view vars. |
309
|
|
|
* |
310
|
|
|
* @param string $key |
311
|
|
|
* @return $this |
312
|
|
|
*/ |
313
|
|
|
protected function _assignMeta($key) |
314
|
|
|
{ |
315
|
|
|
if (Arr::key($key, $this->_View->viewVars)) { |
316
|
|
|
$this->_View->assign($key, $this->_View->viewVars[$key]); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
return $this; |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* Setup view meta data. |
324
|
|
|
* |
325
|
|
|
* @return void |
326
|
|
|
*/ |
327
|
|
|
protected function _setupMetaData() |
328
|
|
|
{ |
329
|
|
|
$this |
330
|
|
|
->_assignMeta('page_title') |
331
|
|
|
->_assignMeta('meta_keywords') |
332
|
|
|
->_assignMeta('meta_description'); |
333
|
|
|
} |
334
|
|
|
} |
335
|
|
|
|
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.