Completed
Push — master ( 571822...c5142e )
by Cheren
09:31
created

DocumentHelper   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 302
Duplicated Lines 8.28 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 9
dl 25
loc 302
rs 8.8
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A afterLayout() 0 7 3
A afterRender() 9 9 3
A afterRenderFile() 7 7 3
A assets() 0 10 2
A beforeLayout() 0 7 3
A beforeRender() 9 9 3
A beforeRenderFile() 0 7 3
A getBodyClasses() 0 20 3
A head() 0 11 1
A initialize() 0 10 3
A lang() 0 5 2
A meta() 0 16 3
A type() 0 18 1
A _assignMeta() 0 8 2
A _setupMetaData() 0 7 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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) {
0 ignored issues
show
Bug introduced by
The expression $assets of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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