View::clear()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 16
nc 1
nop 0
1
<?php
2
/**
3
 * This file is part of the fangface/yii2-concord package
4
 *
5
 * For the full copyright and license information, please view
6
 * the file LICENSE.md that was distributed with this source code.
7
 *
8
 * @package fangface/yii2-concord
9
 * @author Fangface <[email protected]>
10
 * @copyright Copyright (c) 2014 Fangface <[email protected]>
11
 * @license https://github.com/fangface/yii2-concord/blob/master/LICENSE.md MIT License
12
 *
13
 */
14
15
namespace fangface\web;
16
17
use yii\helpers\ArrayHelper;
18
use yii\helpers\Html;
19
20
class View extends \yii\web\View
21
{
22
23
    /**
24
     * @event \yii\base\Event an event that is triggered by [[endAjax()]].
25
     */
26
    const EVENT_END_AJAX_DEBUG = 'endAjax';
27
28
    /**
29
     * The location of registered JavaScript code block or files.
30
     * This means the location is in the head section.
31
     */
32
    const POS_JS_BLOCK = 6;
33
34
    /**
35
     * This is internally used as the placeholder for receiving the content registered for the js block section.
36
     */
37
    const PH_JS_BLOCK = '<![CDATA[APP-JS-BLOCK]]>';
38
39
    /**
40
     * @var array Body html tag parameters
41
     */
42
    public $bodyOptions = [];
43
44
    /**
45
     * @var array general options for this view
46
     */
47
    public $Opts = [];
48
49
    /**
50
     * @var boolean allow idle timeout of user session
51
     */
52
    public $enableIdleTimeout = true;
53
54
    /**
55
     * @var string simple single page style sheet
56
     */
57
    public $pageStyle = '';
58
59
    /**
60
     * @var array list of style sheets to be added to the view
61
     */
62
    public $pageStyles = [];
63
64
    /**
65
     * @var array list of style sheets to be added to the view after all other styles
66
     */
67
    public $pageStylesFinal = [];
68
69
    /**
70
     * @var string simple single page javascript file to be added to the view
71
     */
72
    public $pagePlugin = '';
73
74
    /**
75
     * @var array list of javascript files to be added to the view
76
     */
77
    public $pagePlugins = [];
78
79
    /**
80
     * @var string simple single javascript function to call on jQuery page ready
81
     */
82
    public $pageReadyJS = '';
83
84
    /**
85
     * @var array list of javascript functions to call on jQuery page ready
86
     */
87
    public $pageReadyJSs = [];
88
89
    /**
90
     * @var array list of javascript functions to call on jQuery page ready (before pageReadyJSs)
91
     */
92
    public $pageReadyPriorityJSs = [];
93
94
    /**
95
     * @var array list of javascript functions to call on jQuery page ready (after other page ready js)
96
     */
97
    public $pageReadyFinalJSs = [];
98
99
    /**
100
     * @var string simple single javascript function to call on jQuery page loaded
101
     */
102
    public $pageLoadJS = '';
103
104
    /**
105
     * @var array list of javascript functions to call on jQuery page loaded
106
     */
107
    public $pageLoadJSs = [];
108
109
    /**
110
     * @var array list of javascript functions to call on jQuery page ready (before pageLoadJSs)
111
     */
112
    public $pageLoadPriorityJSs = [];
113
114
    /**
115
     * @var array list of javascript functions to call on jQuery page load (after other page load js)
116
     */
117
    public $pageLoadFinalJSs = [];
118
119
    /**
120
     * @var array the registered base tag
121
     * @see registerBaseTag()
122
     */
123
    public $baseTag;
124
125
    /**
126
     * @var string Code for active menu item
127
     */
128
    public $activeMenuCode = '';
129
130
    /**
131
     * Add in some controller parameters that we want to make available to all
132
     * views without needing to pass them explicitly
133
     *
134
     * (non-PHPdoc)
135
     * @see \yii\base\View::renderFile($viewFile, $params, $context)
136
     */
137
    public function renderFile($viewFile, $params = [], $context = null)
138
    {
139
        if (!$params) {
140
            $params = [];
141
        }
142
        if (method_exists(\Yii::$app->controller, 'getParameters')) {
143
            if (\Yii::$app->controller->getParameters()) {
144
                $params = array_merge(\Yii::$app->controller->getParameters(), $params);
145
            }
146
        }
147
        return parent::renderFile($viewFile, $params, $context);
148
    }
149
150
    /**
151
     * Renders a view in response to an AJAX request.
152
     *
153
     * Identical to \yii\web\View for renderAjax but clears out unwanted jsFiles from being repeated within the ajax request
154
     *
155
     * @param string $view the view name. Please refer to [[render()]] on how to specify this parameter.
156
     * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
157
     * @param object $context the context that the view should use for rendering the view. If null,
158
     * existing [[context]] will be used.
159
     * @return string the rendering result
160
     * @see render()
161
     */
162
    public function renderAjaxLocal($view, $params = [], $context = null)
163
    {
164
        $viewFile = $this->findViewFile($view, $context);
165
        ob_start();
166
        ob_implicit_flush(false);
167
168
        $this->beginPage();
169
        $this->head();
170
        $this->beginBody();
171
        echo $this->renderFile($viewFile, $params, $context);
172
        $this->jsBlock();
173
        $this->endBody();
174
        //$this->jsFiles = array();
175
        $this->renderPageReadyJS(true);
176
        $this->renderPageLoadJS(true);
177
        $this->endPage(true);
178
        $this->clear();
179
180
        return ob_get_clean();
181
    }
182
183
    /**
184
     * Renders the content to be inserted in the head section.
185
     * The content is rendered using the registered meta tags, link tags, CSS/JS code blocks and files.
186
     * @return string the rendered content
187
     */
188
    protected function renderHeadHtml()
189
    {
190
        $lines = [];
191
        if (!empty($this->metaTags)) {
192
            $lines[] = implode("\n\t", $this->metaTags);
193
        }
194
195
        if (!empty($this->baseTag)) {
196
            $lines[] = $this->baseTag;
197
        }
198
199
        if (!empty($this->linkTags)) {
200
            $lines[] = implode("\n\t", $this->linkTags);
201
        }
202
203
        if (empty($this->cssFiles)) {
204
            $this->cssFiles = [];
205
        }
206
207
        if ($this->pageStyle) {
208
            $this->addPageStyle($this->pageStyle, true);
209
            $this->pageStyle = '';
210
        }
211
212
        if ($this->pageStyles) {
213
            foreach ($this->pageStyles as $pageStyle) {
214
                $this->cssFiles[] = '<link href="' . (substr($pageStyle, 0, 1) == '.' || substr($pageStyle, 0, 1) == '/' ? $pageStyle : './css/pages/' . $pageStyle) . (substr($pageStyle, -4, 4) != '.css' ? '.css' : '')  . '" rel="stylesheet">';
215
            }
216
            $this->pageStyles = [];
217
        }
218
219
        if ($this->pageStylesFinal) {
220
            foreach ($this->pageStylesFinal as $pageStyle) {
221
                $this->cssFiles[] = '<link href="' . (substr($pageStyle, 0, 1) == '.' || substr($pageStyle, 0, 1) == '/' ? $pageStyle : './css/pages/' . $pageStyle) . (substr($pageStyle, -4, 4) != '.css' ? '.css' : '')  . '" rel="stylesheet">';
222
            }
223
            $this->pageStylesFinal = [];
224
        }
225
226
        if (!empty($this->cssFiles)) {
227
            $lines[] = implode("\n\t", $this->cssFiles);
228
        }
229
230
        if (!empty($this->css)) {
231
            $lines[] = implode("\n\t", $this->css);
232
        }
233
234
        if (!empty($this->jsFiles[self::POS_HEAD])) {
235
            $lines[] = implode("\n\t", $this->jsFiles[self::POS_HEAD]);
236
        }
237
238
        if (!empty($this->js[self::POS_HEAD])) {
239
            $lines[] = Html::script("\n\t\t" . implode("\t\t", $this->js[self::POS_HEAD]) . "\t", ['type' => 'text/javascript']);
240
        }
241
242
        return empty($lines) ? '' : "\t" . implode("\n\t", $lines);
243
    }
244
245
    /**
246
     * Marks the ending of an HTML page.
247
     * @param boolean $ajaxMode whether the view is rendering in AJAX mode.
248
     * If true, the JS scripts registered at [[POS_READY]] and [[POS_LOAD]] positions
249
     * will be rendered at the end of the view like normal scripts.
250
     */
251
    public function endPage($ajaxMode = false)
252
    {
253
        $this->trigger(self::EVENT_END_PAGE);
254
        $content = ob_get_clean();
255
        echo strtr($content, [
256
            self::PH_HEAD => $this->renderHeadHtml(),
257
            self::PH_BODY_BEGIN => $this->renderBodyBeginHtml(),
258
            self::PH_JS_BLOCK => $this->renderJsBlockHtml($ajaxMode),
259
            self::PH_BODY_END => $this->renderBodyEndHtml($ajaxMode),
260
        ]);
261
262
        $this->clear();
263
    }
264
265
    /**
266
     * Marks the position of the JS Block section.
267
     */
268
    public function jsBlock()
269
    {
270
        echo self::PH_JS_BLOCK;
271
    }
272
273
    /**
274
     * Renders the content to be inserted within the default js block
275
     * The content is rendered using the registered JS code blocks and files.
276
     * @param boolean $ajaxMode whether the view is rendering in AJAX mode.
277
     * @return string the rendered content
278
     */
279
    protected function renderJsBlockHtml($ajaxMode = false)
280
    {
281
        $lines = [];
282
        if (true) {
283
284
            if (!empty($this->jsFiles[self::POS_JS_BLOCK])) {
285
                $lines[] = implode("\n\t", $this->jsFiles[self::POS_JS_BLOCK]);
286
                $this->jsFiles[self::POS_JS_BLOCK] = [];
287
            }
288
289
            if ($this->pagePlugin) {
290
                $this->addPagePlugin($this->pagePlugin, true);
291
                $this->pagePlugin = '';
292
            }
293
294
            if ($this->pagePlugins) {
295
                foreach ($this->pagePlugins as $pagePlugin) {
296
                    $lines[] = Html::jsFile($pagePlugin);
297
                }
298
                $this->pagePlugins = [];
299
            }
300
301
            if (!empty($this->jsFiles[self::POS_END])) {
302
                $lines[] = implode("\n\t", $this->jsFiles[self::POS_END]);
303
                $this->jsFiles[self::POS_END] = [];
304
            }
305
306
            if (empty($this->js[self::POS_READY])) {
307
                $this->js[self::POS_READY] = [];
308
            }
309
310
            if ($this->pageReadyJS) {
311
                array_unshift($this->js[self::POS_READY], $this->pageReadyJS);
312
                $this->pageReadyJS = '';
313
            }
314
315
            if ($this->pageReadyJSs) {
316
                $this->js[self::POS_READY] = array_merge($this->pageReadyJSs, $this->js[self::POS_READY]);
317
                $this->pageReadyJSs = [];
318
            }
319
320
            if ($this->pageReadyPriorityJSs) {
321
                $this->js[self::POS_READY] = array_merge($this->pageReadyPriorityJSs, $this->js[self::POS_READY]);
322
                $this->pageReadyPriorityJSs = [];
323
            }
324
325
            if ($this->pageReadyFinalJSs) {
326
                $this->js[self::POS_READY] = array_merge($this->js[self::POS_READY], $this->pageReadyFinalJSs);
327
                $this->pageReadyFinalJSs = [];
328
            }
329
330
331
            if (!empty($this->js[self::POS_READY])) {
332
                if ($ajaxMode) {
333
                    $js = "\n\t\t" . implode("\n\t\t", $this->js[self::POS_READY]) . "\n\t";
334
                } else {
335
                    $js = "\n\t\tjQuery(document).ready(function () {\n\t\t\t" . implode("\n\t\t\t", $this->js[self::POS_READY]) . "\n\t\t});\n\t";
336
                }
337
                $this->js[self::POS_READY] = [];
338
                $lines[] = Html::script($js, ['type' => 'text/javascript']);
339
            }
340
341
            if (empty($this->js[self::POS_LOAD])) {
342
                $this->js[self::POS_LOAD] = [];
343
            }
344
345
            if ($this->pageLoadJS) {
346
                array_unshift($this->js[self::POS_LOAD], $this->pageLoadJS);
347
                $this->pageLoadJS = '';
348
            }
349
350
            if ($this->pageLoadJSs) {
351
                $this->js[self::POS_LOAD] = array_merge($this->pageLoadJSs, $this->js[self::POS_READY]);
352
                $this->pageLoadJSs = [];
353
            }
354
355
            if ($this->pageLoadPriorityJSs) {
356
                $this->js[self::POS_LOAD] = array_merge($this->pageLoadPriorityJSs, $this->js[self::POS_LOAD]);
357
                $this->pageLoadPriorityJSs = [];
358
            }
359
360
            if ($this->pageLoadFinalJSs) {
361
                $this->js[self::POS_LOAD] = array_merge($this->js[self::POS_LOAD], $this->pageLoadFinalJSs);
362
                $this->pageLoadFinalJSs = [];
363
            }
364
            if (!empty($this->js[self::POS_LOAD])) {
365
                if ($ajaxMode) {
366
                    $js = "\n\t\t" . implode("\n\t\t", $this->js[self::POS_LOAD]) . "\n\t";
367
                } else {
368
                    $js = "\n\t\tjQuery(window).load(function () {\n\t\t\t" . implode("\n\t\t\t", $this->js[self::POS_LOAD]) . "\n\t\t});\n\t";
369
                }
370
                $this->js[self::POS_LOAD] = [];
371
                $lines[] = Html::script($js, ['type' => 'text/javascript']);
372
            }
373
        }
374
        return empty($lines) ? '' : "\t" . implode("\n\t", $lines) . "\n";
375
    }
376
377
    /**
378
     * Add a page style for rendering later
379
     *
380
     * @param string $style
381
     * @param boolean $start [optional] should style be added to start of existing page styles
382
     */
383
    public function addPageStyle($style, $start = false)
384
    {
385
        if ($start) {
386
            array_unshift($this->pageStyles, \Yii::getAlias($style));
387
        } else {
388
            $this->pageStyles[] = \Yii::getAlias($style);
389
        }
390
    }
391
392
    /**
393
     * Add a page style for rendering later (after all other styles)
394
     *
395
     * @param string $style
396
     * @param boolean $start [optional] add to start of existing array
397
     */
398
    public function addFinalPageStyle($style, $start = false)
399
    {
400
        if ($start) {
401
            array_unshift($this->pageStylesFinal, \Yii::getAlias($style));
402
        } else {
403
            $this->pageStylesFinal[] = \Yii::getAlias($style);
404
        }
405
    }
406
407
    /**
408
     * Add a page javascript plugin for rendering later
409
     *
410
     * @param string $style
411
     * @param boolean $start [optional] add to start of existing array
412
     */
413
    public function addPagePlugin($plugin, $start = false)
414
    {
415
        if ($start) {
416
            array_unshift($this->pagePlugins, \Yii::getAlias($plugin));
417
        } else {
418
            $this->pagePlugins[] = \Yii::getAlias($plugin);
419
        }
420
    }
421
422
    /**
423
     * Add js function to execute on jQuery page ready
424
     *
425
     * @param string $js
426
     * @param boolean $start [optional] add to start of existing array
427
     */
428
    public function addPageReadyJS($js, $start = false)
429
    {
430
        if ($start) {
431
            array_unshift($this->pageReadyJSs, $js);
432
        } else {
433
            $this->pageReadyJSs[] = $js;
434
        }
435
    }
436
437
    /**
438
     * Add priority js function to execute on jQuery page ready
439
     *
440
     * @param string $js
441
     * @param boolean $start [optional] add to start of existing array
442
     */
443
    public function addPageReadyPriorityJS($js, $start = false)
444
    {
445
        if ($start) {
446
            array_unshift($this->pageReadyPriorityJSs, $js);
447
        } else {
448
            $this->pageReadyPriorityJSs[] = $js;
449
        }
450
    }
451
452
    /**
453
     * Add priority js function to execute on jQuery page ready
454
     *
455
     * @param string $js
456
     * @param boolean $start [optional] add to start of existing array
457
     */
458
    public function addPageReadyFinalJS($js, $start = false)
459
    {
460
        if ($start) {
461
            array_unshift($this->pageReadyFinalJSs, $js);
462
        } else {
463
            $this->pageReadyFinalJSs[] = $js;
464
        }
465
    }
466
467
    /**
468
     * Add js function to execute on jQuery page loaded
469
     *
470
     * @param string $js
471
     * @param boolean $start [optional] add to start of existing array
472
     */
473
    public function addPageLoadJS($js, $start = false)
474
    {
475
        if ($start) {
476
            array_unshift($this->pageLoadJSs, $js);
477
        } else {
478
            $this->pageLoadJSs[] = $js;
479
        }
480
    }
481
482
    /**
483
     * Add priority js function to execute on jQuery page loaded
484
     *
485
     * @param string $js
486
     * @param boolean $start [optional] add to start of existing array
487
     */
488
    public function addPageLoadPriorityJS($js, $start = false)
489
    {
490
        if ($start) {
491
            array_unshift($this->pageLoadPriorityJSs, $js);
492
        } else {
493
            $this->pageLoadPriorityJSs[] = $js;
494
        }
495
    }
496
497
    /**
498
     * Add priority js function to execute on jQuery page loaded
499
     *
500
     * @param string $js
501
     * @param boolean $start [optional] add to start of existing array
502
     */
503
    public function addPageLoadFinalJS($js, $start = false)
504
    {
505
        if ($start) {
506
            array_unshift($this->pageLoadFinalJSs, $js);
507
        } else {
508
            $this->pageLoadFinalJSs[] = $js;
509
        }
510
    }
511
512
    /**
513
     * Render stylesheet tags for the current view
514
     */
515
    public function renderPageStyles()
516
    {
517
        if ($this->pageStyle) {
518
            $this->addPageStyle($this->pageStyle, true);
519
            $this->pageStyle = '';
520
        }
521
522
        foreach ($this->pageStyles as $pageStyle) {
523
            echo "\t" . '<link href="' . (substr($pageStyle, 0, 1) == '.' || substr($pageStyle, 0, 1) == '/' ? $pageStyle : './css/pages/' . $pageStyle) . (substr($pageStyle, -4, 4) != '.css' ? '.css' : '')  . '" rel="stylesheet" type="text/css"/>' . "\n";
524
        }
525
526
        foreach ($this->pageStylesFinal as $pageStyle) {
527
            echo "\t" . '<link href="' . (substr($pageStyle, 0, 1) == '.' || substr($pageStyle, 0, 1) == '/' ? $pageStyle : './css/pages/' . $pageStyle) . (substr($pageStyle, -4, 4) != '.css' ? '.css' : '')  . '" rel="stylesheet" type="text/css"/>' . "\n";
528
        }
529
    }
530
531
    /**
532
     * Render plugin javascript script tags for the current view
533
     */
534
    public function renderPagePlugins()
535
    {
536
        if ($this->pagePlugin) {
537
            $this->addPagePlugin($this->pagePlugin, true);
538
            $this->pagePlugin = '';
539
        }
540
541
        foreach ($this->pagePlugins as $pagePlugin) {
542
            echo "\t" . '<script src="' . (substr($pagePlugin, 0, 1) == '.' || substr($pagePlugin, 0, 1) == '/' ? $pagePlugin : './js/pages/' . $pagePlugin) . (substr($pagePlugin, -3, 3) != '.js' ? '.js' : '') . '"></script>' . "\n";
543
        }
544
545
    }
546
547
    /**
548
     * Render jQuery page ready js function calls
549
     *
550
     * @param boolean $ajax is function being called as a result of rendering an ajax page
551
     */
552
    public function renderPageReadyJS($ajax = false)
553
    {
554
555
        // note non ajax output is already rendered in a jQuery document ready wrapper
556
557
        if ($ajax) {
558
            echo '<script>jQuery(document).ready(function() {' . "\n";
559
        }
560
561
        if ($this->pageReadyJS) {
562
            echo "\t\t" . $this->pageReadyJS . "\n";
563
        }
564
565
        foreach ($this->pageReadyPriorityJSs as $pageReadyJS) {
566
            echo "\t\t" . $pageReadyJS . "\n";
567
        }
568
569
        foreach ($this->pageReadyJSs as $pageReadyJS) {
570
            echo "\t\t" . $pageReadyJS . "\n";
571
        }
572
573
        foreach ($this->pageReadyFinalJSs as $pageReadyJS) {
574
            echo "\t\t" . $pageReadyJS . "\n";
575
        }
576
577
        if ($ajax) {
578
            echo '});</script>' . "\n";
579
        }
580
581
    }
582
583
    /**
584
     * Render jQuery page loaded js function calls
585
     *
586
     * @param boolean $ajax is function being called as a result of rendering an ajax page
587
     */
588
    public function renderPageLoadJS($ajax = false)
589
    {
590
591
        // note non ajax output is already rendered in a jQuery window load wrapper
592
593
        if ($ajax) {
594
            echo '<script>jQuery(window).load(function() {' . "\n";
595
        }
596
597
        if ($this->pageLoadJS) {
598
            echo "\t\t" . $this->pageLoadJS . "\n";
599
        }
600
601
        foreach ($this->pageLoadPriorityJSs as $pageLoadJS) {
602
            echo "\t\t" . $pageLoadJS . "\n";
603
        }
604
605
        foreach ($this->pageLoadJSs as $pageLoadJS) {
606
            echo "\t\t" . $pageLoadJS . "\n";
607
        }
608
609
        foreach ($this->pageLoadFinalJSs as $pageLoadJS) {
610
            echo "\t\t" . $pageLoadJS . "\n";
611
        }
612
613
        if ($ajax) {
614
            echo '});</script>' . "\n";
615
        }
616
617
    }
618
619
    /**
620
     * Called at the end of an ajax request by Controller::endAjaxResponse()
621
     */
622
    public function endAjax()
623
    {
624
        ob_start();
625
        ob_implicit_flush(false);
626
        $this->trigger(self::EVENT_END_AJAX_DEBUG);
627
        return ob_get_clean();
628
    }
629
630
    /**
631
     * Registers a base tag.
632
     * @param string $url
633
     * @param array $options the HTML attributes for the base tag.
634
     */
635
    public function registerBaseTag($url, $options = [])
636
    {
637
        $options['href'] = \Yii::getAlias($url);
638
        $this->baseTag = Html::tag('base', '', $options);
639
    }
640
641
    /**
642
     * (non-PHPdoc)
643
     * @see \yii\web\View::registerLinkTag()
644
     */
645
    public function registerLinkTag($options, $key = null)
646
    {
647
        if (ArrayHelper::keyExists('href', $options)) {
648
            $options['href'] = \Yii::getAlias($options['href']);
649
        }
650
        parent::registerLinkTag($options, $key);
651
    }
652
653
    /**
654
     * (non-PHPdoc)
655
     * @see \yii\web\View::clear()
656
     */
657
    public function clear()
658
    {
659
        $this->pageStyle = '';
660
        $this->pageStyles = [];
661
        $this->pageStylesFinal = [];
662
        $this->pagePlugin = '';
663
        $this->pagePlugins = [];
664
        $this->pageReadyJS = '';
665
        $this->pageReadyPriorityJSs = [];
666
        $this->pageReadyJSs = [];
667
        $this->pageReadyFinalJSs = [];
668
        $this->pageLoadJS = '';
669
        $this->pageLoadPriorityJSs = [];
670
        $this->pageLoadJSs = [];
671
        $this->pageLoadFinalJSs = [];
672
        $this->baseTag = [];
673
        parent::clear();
674
    }
675
676
}
677