GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 890c9c...35b399 )
by
unknown
02:03
created

View   F

Complexity

Total Complexity 84

Size/Duplication

Total Lines 599
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 259
dl 0
loc 599
rs 2
c 0
b 0
f 0
wmc 84

9 Methods

Rating   Name   Duplication   Size   Complexity  
A with() 0 9 2
A parse() 0 5 1
A __construct() 0 22 2
A __get() 0 9 2
A modal() 0 14 4
F render() 0 271 45
B load() 0 53 8
C getFilePath() 0 69 12
B page() 0 26 8

How to fix   Complexity   

Complex Class

Complex classes like View often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use View, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Framework\Http;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Framework\Containers\Modules\DataStructures\Module\Theme;
19
use O2System\Framework\Http\Presenter\Meta;
20
use O2System\Gear\Toolbar;
21
use O2System\Html;
22
use O2System\Psr\Patterns\Structural\Composite\RenderableInterface;
23
use O2System\Spl\Exceptions\ErrorException;
24
use O2System\Spl\Traits\Collectors\FileExtensionCollectorTrait;
25
use O2System\Spl\Traits\Collectors\FilePathCollectorTrait;
26
27
/**
28
 * Class View
29
 *
30
 * @package O2System
31
 */
32
class View implements RenderableInterface
33
{
34
    use FilePathCollectorTrait;
35
    use FileExtensionCollectorTrait;
36
37
    /**
38
     * View Config
39
     *
40
     * @var \O2System\Kernel\DataStructures\Config
41
     */
42
    protected $config;
43
44
    /**
45
     * View HTML Document
46
     *
47
     * @var Html\Document
48
     */
49
    protected $document;
50
51
    // ------------------------------------------------------------------------
52
53
    /**
54
     * View::__construct
55
     *
56
     * @return View
57
     */
58
    public function __construct()
59
    {
60
        $this->setFileDirName('Views');
61
        $this->addFilePath(PATH_APP);
62
63
        output()->addFilePath(PATH_APP);
64
65
        $this->config = config()->loadFile('view', true);
0 ignored issues
show
Documentation Bug introduced by
It seems like config()->loadFile('view', true) can also be of type false. However, the property $config is declared as type O2System\Kernel\DataStructures\Config. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
Bug introduced by
The method loadFile() does not exist on O2System\Kernel\Datastructures\Config. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

65
        $this->config = config()->/** @scrutinizer ignore-call */ loadFile('view', true);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
66
67
        $this->setFileExtensions(
68
            [
69
                '.php',
70
                '.phtml',
71
            ]
72
        );
73
74
        if ($this->config->offsetExists('extensions')) {
75
            $this->setFileExtensions($this->config[ 'extensions' ]);
76
        }
77
78
        $this->document = new Html\Document();
79
        $this->document->formatOutput = (bool)$this->config->beautify;
80
    }
81
82
    /**
83
     * View::__get
84
     *
85
     * @param string $property
86
     *
87
     * @return bool Returns FALSE when property is not set.
88
     */
89
    public function &__get($property)
90
    {
91
        $get[ $property ] = false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$get was never initialized. Although not strictly required by PHP, it is generally a good practice to add $get = array(); before regardless.
Loading history...
92
93
        if (property_exists($this, $property)) {
94
            return $this->{$property};
95
        }
96
97
        return $get[ $property ];
98
    }
99
100
    // ------------------------------------------------------------------------
101
102
    /**
103
     * View::parse
104
     *
105
     * @param string $string
106
     * @param array  $vars
107
     *
108
     * @return bool|string Returns FALSE if failed.
109
     */
110
    public function parse($string, array $vars = [])
111
    {
112
        parser()->loadString($string);
113
114
        return parser()->parse($vars);
115
    }
116
117
    // ------------------------------------------------------------------------
118
119
    /**
120
     * View::with
121
     *
122
     * @param mixed $vars
123
     * @param mixed $value
124
     *
125
     * @return static
126
     */
127
    public function with($vars, $value = null)
128
    {
129
        if (is_string($vars)) {
130
            $vars = [$vars => $value];
131
        }
132
133
        presenter()->merge($vars);
134
135
        return $this;
136
    }
137
138
    // ------------------------------------------------------------------------
139
140
    /**
141
     * View::modal
142
     *
143
     * @param string $filename
144
     * @param array  $vars
145
     */
146
    public function modal($filename, array $vars = [])
147
    {
148
        if (presenter()->theme->hasLayout('modal')) {
0 ignored issues
show
Bug introduced by
The method hasLayout() does not exist on O2System\Framework\Conta...Structures\Module\Theme. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

148
        if (presenter()->theme->/** @scrutinizer ignore-call */ hasLayout('modal')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
149
            if (presenter()->theme->hasLayout('modal')) {
150
                presenter()->theme->setLayout('modal');
151
                echo $this->load($filename, $vars, true);
0 ignored issues
show
Bug introduced by
Are you sure $this->load($filename, $vars, true) of type false|string can be used in echo? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

151
                echo /** @scrutinizer ignore-type */ $this->load($filename, $vars, true);
Loading history...
152
                exit(EXIT_SUCCESS);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
153
            }
154
        }
155
156
        presenter()->merge($vars);
157
158
        if (parser()->loadFile($filename)) {
159
            output()->send(parser()->parse(presenter()->getArrayCopy()));
0 ignored issues
show
Bug introduced by
The method send() does not exist on O2System\Kernel\Cli\Output. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

159
            output()->/** @scrutinizer ignore-call */ send(parser()->parse(presenter()->getArrayCopy()));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
160
        }
161
    }
162
163
    // ------------------------------------------------------------------------
164
165
    /**
166
     * View::load
167
     *
168
     * @param string $filename
169
     * @param array  $vars
170
     * @param bool   $return
171
     *
172
     * @return false|string
173
     */
174
    public function load($filename, array $vars = [], $return = false)
175
    {
176
        if ($filename instanceof \SplFileInfo) {
0 ignored issues
show
introduced by
$filename is never a sub-type of SplFileInfo.
Loading history...
177
            return $this->page($filename->getRealPath(), array_merge($vars, $filename->getVars()));
178
        }
179
180
        if (strpos($filename, 'Pages') !== false) {
181
            return $this->page($filename, $vars, $return);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->page($filename, $vars, $return) also could return the type boolean which is incompatible with the documented return type false|string.
Loading history...
182
        }
183
184
        presenter()->merge($vars);
185
186
        if (false !== ($filePath = $this->getFilePath($filename))) {
187
            if ($return === false) {
188
                if (presenter()->partials->hasPartial('content') === false) {
189
                    presenter()->partials->addPartial('content', $filePath);
190
                } else {
191
                    presenter()->partials->addPartial(pathinfo($filePath, PATHINFO_FILENAME), $filePath);
192
                }
193
            } else {
194
                parser()->loadFile($filePath);
195
196
                return parser()->parse(presenter()->getArrayCopy());
197
            }
198
        } else {
199
            $vars = presenter()->getArrayCopy();
200
            extract($vars);
201
202
            $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
203
204
            $error = new ErrorException(
205
                'E_VIEW_NOT_FOUND',
206
                0,
207
                @$backtrace[ 0 ][ 'file' ],
208
                @$backtrace[ 0 ][ 'line' ],
209
                [trim($filename)]
210
            );
211
212
            unset($backtrace);
213
214
            ob_start();
215
            include output()->getFilePath('error');
0 ignored issues
show
Bug introduced by
The method getFilePath() does not exist on O2System\Kernel\Cli\Output. Did you maybe mean getFilePaths()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

215
            include output()->/** @scrutinizer ignore-call */ getFilePath('error');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
216
            $content = ob_get_contents();
217
            ob_end_clean();
218
219
            if ($return === false) {
220
                if (presenter()->partials->hasPartial('content') === false) {
221
                    presenter()->addPartial('content', $content);
0 ignored issues
show
Bug introduced by
The method addPartial() does not exist on O2System\Framework\Http\Presenter. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

221
                    presenter()->/** @scrutinizer ignore-call */ addPartial('content', $content);
Loading history...
222
                } else {
223
                    presenter()->addPartial(pathinfo($filePath, PATHINFO_FILENAME), $content);
0 ignored issues
show
Bug introduced by
It seems like $filePath can also be of type false; however, parameter $path of pathinfo() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

223
                    presenter()->addPartial(pathinfo(/** @scrutinizer ignore-type */ $filePath, PATHINFO_FILENAME), $content);
Loading history...
224
                }
225
            } else {
226
                return $content;
227
            }
228
        }
229
    }
230
231
    // ------------------------------------------------------------------------
232
233
    /**
234
     * View::page
235
     *
236
     * @param string $filename
237
     * @param array  $vars
238
     * @param bool   $return
239
     *
240
     * @return bool|string Returns FALSE if failed.
241
     */
242
    public function page($filename, array $vars = [], $return = false)
243
    {
244
        if ( ! is_file($filename)) {
245
            $pageDirectories = modules()->getDirs('Pages');
0 ignored issues
show
Bug introduced by
The method getDirs() does not exist on O2System\Framework\Conta...s\DataStructures\Module. Did you maybe mean getDir()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

245
            $pageDirectories = modules()->/** @scrutinizer ignore-call */ getDirs('Pages');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
246
            foreach ($pageDirectories as $pageDirectory) {
247
                if (is_file($pageFilePath = $pageDirectory . $filename . '.phtml')) {
248
                    $filename = $pageFilePath;
249
                    break;
250
                }
251
            }
252
        }
253
254
        if (count($vars)) {
255
            presenter()->merge($vars);
256
        }
257
258
        presenter()->merge(presenter()->page->getVars());
259
260
        if ($return === false) {
261
            if (presenter()->partials->hasPartial('content') === false) {
262
                presenter()->partials->addPartial('content', $filename);
263
            } else {
264
                presenter()->partials->addPartial(pathinfo($filename, PATHINFO_FILENAME), $filename);
265
            }
266
        } elseif (parser()->loadFile($filename)) {
267
            return parser()->parse(presenter()->getArrayCopy());
268
        }
269
    }
270
271
    // ------------------------------------------------------------------------
272
273
    /**
274
     * View::getFilePath
275
     *
276
     * @param string $filename
277
     *
278
     * @return bool|string
279
     */
280
    public function getFilePath($filename)
281
    {
282
        $filename = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $filename);
283
284
        if (is_file($filename)) {
285
            return realpath($filename);
286
        } else {
287
            $viewsFileExtensions = $this->fileExtensions;
288
            $viewsDirectories = modules()->getDirs('Views');
289
            $viewsDirectories = array_merge($viewsDirectories, $this->filePaths);
290
            $viewsDirectories = array_unique($viewsDirectories);
291
292
            $deviceDirectory = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $deviceDirectory is dead and can be removed.
Loading history...
293
            if (services('userAgent')->isMobile()) {
0 ignored issues
show
Bug introduced by
The method isMobile() does not exist on O2System\Kernel\Containers\Services. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

293
            if (services('userAgent')->/** @scrutinizer ignore-call */ isMobile()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
294
                $deviceDirectory = 'mobile';
295
            }
296
297
            if (presenter()->theme) {
298
                $moduleReplacementPath = presenter()->theme->getPathName()
299
                    . DIRECTORY_SEPARATOR
300
                    . 'views'
301
                    . DIRECTORY_SEPARATOR
302
                    . strtolower(
303
                        str_replace(PATH_APP, '', modules()->current()->getRealpath())
0 ignored issues
show
Bug introduced by
The method current() does not exist on O2System\Framework\Conta...s\DataStructures\Module. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

303
                        str_replace(PATH_APP, '', modules()->/** @scrutinizer ignore-call */ current()->getRealpath())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
304
                    );
305
306
                if (is_dir($moduleReplacementPath)) {
307
                    array_unshift($viewsDirectories, $moduleReplacementPath);
308
309
                    // Add Theme File Extensions
310
                    if (presenter()->theme->getPresets()->offsetExists('extension')) {
311
                        array_unshift($viewsFileExtensions,
312
                            presenter()->theme->getPresets()->offsetGet('extension'));
313
                    } elseif (presenter()->theme->getPresets()->offsetExists('extensions')) {
314
                        $viewsFileExtensions = array_merge(
315
                            presenter()->theme->getPresets()->offsetGet('extensions'),
316
                            $viewsFileExtensions
317
                        );
318
                    }
319
320
                    // Add Theme Parser Engine
321
                    if (presenter()->theme->getPresets()->offsetExists('driver')) {
322
                        $parserDriverClassName = '\O2System\Parser\Drivers\\' . camelcase(
323
                                presenter()->theme->getPresets()->offsetGet('driver')
324
                            );
325
326
                        if (class_exists($parserDriverClassName)) {
327
                            parser()->addDriver(
328
                                new $parserDriverClassName(),
329
                                presenter()->theme->getPresets()->offsetGet('driver')
330
                            );
331
                        }
332
                    }
333
                }
334
            }
335
336
            foreach ($viewsDirectories as $viewsDirectory) {
337
                foreach ($viewsFileExtensions as $fileExtension) {
338
                    $filename = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $filename);
339
340
                    if (is_file($filePath = $viewsDirectory . $filename . $fileExtension)) {
341
                        return realpath($filePath);
342
                        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
343
                    }
344
                }
345
            }
346
        }
347
348
        return false;
349
    }
350
351
    // ------------------------------------------------------------------------
352
353
    /**
354
     * View::render
355
     *
356
     * @param array $options
357
     *
358
     * @return string
359
     */
360
    public function render(array $options = [])
361
    {
362
        if (profiler() !== false) {
0 ignored issues
show
introduced by
The condition profiler() !== false is always true.
Loading history...
363
            profiler()->watch('Starting View Rendering');
364
        }
365
366
        parser()->loadVars(presenter()->getArrayCopy());
367
368
        if (false !== ($pagePresets = presenter()->page->getPresets())) {
0 ignored issues
show
introduced by
The condition false !== $pagePresets =...r()->page->getPresets() is always true.
Loading history...
369
            /**
370
             * Sets Page Theme
371
             */
372
            if ($pagePresets->offsetExists('theme')) {
373
                presenter()->setTheme($pagePresets->theme);
374
            } elseif (false !== ($theme = presenter()->getConfig('theme'))) {
375
                if (modules()->current()->hasTheme($theme)) {
376
                    presenter()->setTheme($theme);
0 ignored issues
show
Bug introduced by
It seems like $theme can also be of type array; however, parameter $theme of O2System\Framework\Http\Presenter::setTheme() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

376
                    presenter()->setTheme(/** @scrutinizer ignore-type */ $theme);
Loading history...
377
                }
378
            }
379
380
            /**
381
             * Sets Page Layout
382
             */
383
            if (presenter()->theme !== false) {
384
                if ($pagePresets->offsetExists('layout')) {
385
                    presenter()->theme->setLayout($pagePresets->layout);
386
                }
387
388
                if (false !== ($modulePresets = modules()->current()->getPresets())) {
389
390
                    /**
391
                     * Autoload Module Assets
392
                     */
393
                    if ($modulePresets->offsetExists('assets')) {
394
                        presenter()->assets->autoload($modulePresets->assets);
395
                    }
396
397
                    $moduleAssets = [
398
                        'main',
399
                        modules()->current()->getParameter()
400
                    ];
401
402
                    // Autoload Assets
403
                    presenter()->assets->loadCss($moduleAssets);
404
                    presenter()->assets->loadJs($moduleAssets);
405
406
                    /**
407
                     * Sets Module Meta
408
                     */
409
                    if ($modulePresets->offsetExists('title')) {
410
                        presenter()->meta->title->append(language()->getLine($modulePresets->title));
411
                    }
412
413
                    if ($modulePresets->offsetExists('pageTitle')) {
414
                        presenter()->meta->title->replace(language()->getLine($modulePresets->pageTitle));
415
                    }
416
417
                    if ($modulePresets->offsetExists('browserTitle')) {
418
                        presenter()->meta->title->replace(language()->getLine($modulePresets->browserTitle));
419
                    }
420
421
                    if ($modulePresets->offsetExists('meta')) {
422
                        foreach ($modulePresets->meta as $name => $content) {
423
                            presenter()->meta->store($name, $content);
424
                        }
425
                    }
426
                }
427
428
                /**
429
                 * Autoload Page Assets
430
                 */
431
                if ($pagePresets->offsetExists('assets')) {
432
                    presenter()->assets->autoload($pagePresets->assets);
433
                }
434
435
                if (presenter()->page->file instanceof \SplFileInfo) {
0 ignored issues
show
introduced by
presenter()->page->file is always a sub-type of SplFileInfo.
Loading history...
436
                    $pageAssets[] = presenter()->page->file->getDirectoryInfo()->getDirName();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$pageAssets was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pageAssets = array(); before regardless.
Loading history...
437
                    $pageAssets[] = implode('/', [
438
                        presenter()->page->file->getDirectoryInfo()->getDirName(),
439
                        $pageAssets[] = presenter()->page->file->getFilename(),
440
                    ]);
441
442
                    // Autoload Assets
443
                    presenter()->assets->loadCss($pageAssets);
444
                    presenter()->assets->loadJs($pageAssets);
445
                }
446
447
                /**
448
                 * Sets Page Meta
449
                 */
450
                if ($pagePresets->offsetExists('title')) {
451
                    presenter()->meta->title->append(language()->getLine($pagePresets->title));
452
                }
453
454
                if ($pagePresets->offsetExists('pageTitle')) {
455
                    presenter()->meta->title->replace(language()->getLine($pagePresets->pageTitle));
456
                }
457
458
                if ($pagePresets->offsetExists('browserTitle')) {
459
                    presenter()->meta->title->replace(language()->getLine($pagePresets->browserTitle));
460
                }
461
462
                if ($pagePresets->offsetExists('meta')) {
463
                    foreach ($pagePresets->meta as $name => $content) {
464
                        presenter()->meta->store($name, $content);
465
                    }
466
                }
467
468
                if (false !== ($layout = presenter()->theme->getLayout())) {
0 ignored issues
show
introduced by
The condition false !== $layout = pres...r()->theme->getLayout() is always true.
Loading history...
469
                    parser()->loadFile($layout->getRealPath());
470
471
                    $htmlOutput = parser()->parse();
472
                    $htmlOutput = presenter()->assets->parseSourceCode($htmlOutput);
473
474
                    $this->document->loadHTML($htmlOutput);
475
                }
476
            } else {
477
                output()->sendError(204, language()->getLine('E_THEME_NOT_FOUND', [$theme]));
478
            }
479
        } elseif (presenter()->theme instanceof Theme) {
480
            /**
481
             * Autoload Controller Assets
482
             */
483
            $controllerAssets[] = controller()->getParameter();
484
            $controllerAssets[] = implode('/', [
485
                controller()->getParameter(),
486
                controller()->getRequestMethod(),
487
            ]);
488
489
            if (false !== ($layout = presenter()->theme->getLayout())) {
490
                parser()->loadFile($layout->getRealPath());
491
492
                $htmlOutput = parser()->parse();
493
                $htmlOutput = presenter()->assets->parseSourceCode($htmlOutput);
494
495
                $this->document->loadHTML($htmlOutput);
496
            }
497
        } elseif (false !== ($theme = presenter()->getConfig('theme'))) {
498
            if (modules()->current()->hasTheme($theme)) {
499
                presenter()->setTheme($theme);
500
501
                /**
502
                 * Autoload Controller Assets
503
                 */
504
                $controllerAssets[] = controller()->getParameter();
505
                $controllerAssets[] = implode('/', [
506
                    controller()->getParameter(),
507
                    controller()->getRequestMethod(),
508
                ]);
509
510
                if (false !== ($layout = presenter()->theme->getLayout())) {
511
                    parser()->loadFile($layout->getRealPath());
512
513
                    $htmlOutput = parser()->parse();
514
                    $htmlOutput = presenter()->assets->parseSourceCode($htmlOutput);
515
516
                    $this->document->loadHTML($htmlOutput);
517
                }
518
            } else {
519
                output()->sendError(204, language()->getLine('E_THEME_NOT_FOUND', [$theme]));
520
            }
521
        } else {
522
            $this->document->find('body')->append(presenter()->partials->__get('content'));
523
        }
524
525
        /**
526
         * Set Document Meta Title
527
         */
528
        if (presenter()->meta->title instanceof Meta\Title) {
0 ignored issues
show
introduced by
presenter()->meta->title is always a sub-type of O2System\Framework\Http\Presenter\Meta\Title.
Loading history...
529
            $this->document->title->text(presenter()->meta->title->__toString());
530
        }
531
532
        /**
533
         * Injecting Meta Opengraph
534
         */
535
        if (presenter()->meta->opengraph instanceof Meta\Opengraph) {
0 ignored issues
show
introduced by
presenter()->meta->opengraph is always a sub-type of O2System\Framework\Http\Presenter\Meta\Opengraph.
Loading history...
536
            // set opengraph title
537
            if (presenter()->meta->title instanceof Meta\Title) {
0 ignored issues
show
introduced by
presenter()->meta->title is always a sub-type of O2System\Framework\Http\Presenter\Meta\Title.
Loading history...
538
                presenter()->meta->opengraph->setTitle(presenter()->meta->title->__toString());
539
            }
540
541
            // set opengraph site name
542
            if (presenter()->exists('siteName')) {
543
                presenter()->meta->opengraph->setSiteName(presenter()->offsetGet('siteName'));
544
            }
545
546
            if (presenter()->meta->opengraph->count()) {
547
                $htmlElement = $this->document->getElementsByTagName('html')->item(0);
548
                $htmlElement->setAttribute('prefix', 'og: ' . presenter()->meta->opengraph->prefix);
549
550
                if (presenter()->meta->opengraph->exists('og:type') === false) {
551
                    presenter()->meta->opengraph->setType('website');
552
                }
553
554
                $opengraph = presenter()->meta->opengraph->getArrayCopy();
555
556
                foreach ($opengraph as $tag) {
557
                    $this->document->metaNodes->createElement($tag->attributes->getArrayCopy());
558
                }
559
            }
560
        }
561
562
        if (presenter()->meta->count()) {
563
            $meta = presenter()->meta->getArrayCopy();
564
565
            foreach ($meta as $tag) {
566
                $this->document->metaNodes->createElement($tag->attributes->getArrayCopy());
567
            }
568
        }
569
570
        /**
571
         * Injecting Single Sign-On (SSO) iFrame
572
         */
573
        if (services()->has('user')) {
574
            $iframe = services()->get('user')->getIframeCode();
575
576
            if ( ! empty($iframe)) {
577
                $this->document->find('body')->append($iframe);
578
            }
579
        }
580
581
        if (input()->env('DEBUG_STAGE') === 'DEVELOPER' and
582
            config()->getItem('presenter')->debugToolBar === true and
0 ignored issues
show
Bug introduced by
The method getItem() does not exist on O2System\Kernel\Datastructures\Config. Did you maybe mean getIterator()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

582
            config()->/** @scrutinizer ignore-call */ getItem('presenter')->debugToolBar === true and

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
583
            services()->has('profiler')
584
        ) {
585
            $this->document->find('body')->append((new Toolbar())->__toString());
586
        }
587
588
        /**
589
         * Injecting Progressive Web Application (PWA) Manifest
590
         */
591
        $this->document->linkNodes->createElement([
592
            'rel'  => 'manifest',
593
            'href' => '/manifest.json',
594
        ]);
595
596
        $htmlOutput = $this->document->saveHTML();
597
598
        // Uglify Output
599
        if ($this->config->output[ 'uglify' ] === true) {
600
            $htmlOutput = preg_replace(
601
                [
602
                    '/\>[^\S ]+/s',     // strip whitespaces after tags, except space
603
                    '/[^\S ]+\</s',     // strip whitespaces before tags, except space
604
                    '/(\s)+/s',         // shorten multiple whitespace sequences
605
                    '/<!--(.|\s)*?-->/', // Remove HTML comments
606
                    '/<!--(.*)-->/Uis',
607
                    "/[[:blank:]]+/",
608
                ],
609
                [
610
                    '>',
611
                    '<',
612
                    '\\1',
613
                    '',
614
                    '',
615
                    ' ',
616
                ],
617
                str_replace(["\n", "\r", "\t"], '', $htmlOutput));
618
        }
619
620
        // Beautify Output
621
        if ($this->config->output[ 'beautify' ] === true) {
622
            $beautifier = new Html\Dom\Beautifier();
623
            $htmlOutput = $beautifier->format($htmlOutput);
624
        }
625
626
        if (profiler() !== false) {
0 ignored issues
show
introduced by
The condition profiler() !== false is always true.
Loading history...
627
            profiler()->watch('Ending View Rendering');
628
        }
629
630
        return $htmlOutput;
631
    }
632
}
633