Test Failed
Push — main ( 88b8ff...27a594 )
by Dimitri
03:42
created

NativeAdapter::endSection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 1
cp 0
crap 2
rs 10
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\View\Adapters;
13
14
use BlitzPHP\Debug\Toolbar\Collectors\ViewsCollector;
15
use BlitzPHP\Exceptions\ViewException;
16
use BlitzPHP\Utilities\Helpers;
17
use RuntimeException;
18
19
/**
20
 * Class View
21
 */
22
class NativeAdapter extends AbstractAdapter
23
{
24
    /**
25
     * {@inheritDoc}
26
     */
27
    protected string $ext = 'php';
28
29
    /**
30
     * Fusionner les données enregistrées et les données utilisateur
31
     */
32
    protected $tempData;
33
34
    /**
35
     * Indique si les données doivent être enregistrées entre les rendus.
36
     *
37
     * @var bool
38
     */
39
    protected $saveData;
40
41
    /**
42
     * Nombre de vues chargées
43
     */
44
    protected int $viewsCount = 0;
45
46
    /**
47
     * Contient les sections et leurs données.
48
     */
49
    protected array $sections = [];
50
51
    /**
52
     * Le nom de la section actuelle en cours de rendu, le cas échéant.
53
     *
54
     * @var string[]
55
     */
56
    protected array $sectionStack = [];
57
58
    /**
59
     * Contient les css charges a partie de la section actuelle en cours de rendu
60
     */
61
    protected array $_styles = [];
62
63
    /**
64
     * Contient les librairies css charges a partie de la section actuelle en cours de rendu
65
     */
66
    protected array $_lib_styles = [];
67
68
    /**
69
     * Contient les scripts js charges a partie de la section actuelle en cours de rendu
70
     */
71
    protected array $_scripts = [];
72
73
    /**
74
     * Contient les scripts js des librairies charges a partie de la section actuelle en cours de rendu
75
     */
76
    protected array $_lib_scripts = [];
77
78
    /**
79
     * {@inheritDoc}
80
     */
81
    public function __construct(protected array $config, $viewPathLocator = null, protected bool $debug = BLITZ_DEBUG)
82
    {
83 2
        parent::__construct($config, $viewPathLocator, $debug);
84
85 2
        $this->saveData = (bool) ($config['save_data'] ?? true);
86
    }
87
88
    /**
89
     * {@inheritDoc}
90
     */
91
    public function render(string $view, ?array $options = null, ?bool $saveData = null): string
92
    {
93
        $this->renderVars['start']   = microtime(true);
94
        $this->renderVars['view']    = $view;
95
        $this->renderVars['options'] = $options ?? [];
96
97
        // Stocke les résultats ici donc même si
98
        // plusieurs vues sont appelées dans une vue, ce ne sera pas le cas
99
        // nettoyez-le sauf si nous le voulons.
100
        $saveData ??= $this->saveData;
101
102
        // A-t-il été mis en cache ?
103
        if (isset($this->renderVars['options']['cache'])) {
104
            $cacheName = $this->renderVars['options']['cache_name'] ?? str_replace('.' . $this->ext, '', $this->renderVars['view']);
105
            $cacheName = str_replace(['\\', '/'], '', $cacheName);
106
107
            $this->renderVars['cacheName'] = $cacheName;
108
109
            if ($output = cache($this->renderVars['cacheName'])) {
110
                $this->logPerformance($this->renderVars['start'], microtime(true), $this->renderVars['view']);
0 ignored issues
show
Bug introduced by
It seems like $this->renderVars['start'] can also be of type string; however, parameter $start of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, 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

110
                $this->logPerformance(/** @scrutinizer ignore-type */ $this->renderVars['start'], microtime(true), $this->renderVars['view']);
Loading history...
Bug introduced by
It seems like microtime(true) can also be of type string; however, parameter $end of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, 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

110
                $this->logPerformance($this->renderVars['start'], /** @scrutinizer ignore-type */ microtime(true), $this->renderVars['view']);
Loading history...
111
112
                return $output;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $output returns the type BlitzPHP\Cache\Cache|true which is incompatible with the type-hinted return string.
Loading history...
113
            }
114
        }
115
116
        $this->renderVars['file'] = $this->getRenderedFile($this->renderVars['options'], $this->renderVars['view'], $this->ext);
117
118
        // Rendre nos données de vue disponibles pour la vue.
119
        $this->prepareTemplateData($saveData);
120
121
        // Enregistrer les variables actuelles
122
        $renderVars = $this->renderVars;
123
124
        $output = (function (): string {
125
            extract($this->tempData);
126
            ob_start();
127
            include $this->renderVars['file'];
128
129
            return ob_get_clean() ?: '';
130
        })();
131
132
        // Lors de l'utilisation de mises en page, les données ont déjà été stockées
133
        // dans $this->sections, et aucune autre sortie valide
134
        // est autorisé dans $output donc nous allons l'écraser.
135
        if ($this->layout !== null && $this->sectionStack === []) {
136
            $layoutView   = $this->layout;
137
            $this->layout = null;
138
            // Enregistrer les variables actuelles
139
            $renderVars = $this->renderVars;
140
            $output     = $this->render($layoutView, array_merge($options ?? [], ['viewPath' => LAYOUT_PATH]), $saveData);
141
        }
142
143
        $this->logPerformance($this->renderVars['start'], microtime(true), $this->renderVars['view']);
144
145
        if (($this->debug && (! isset($options['debug']) || $options['debug'] === true))) {
146
            if (in_array(ViewsCollector::class, config('toolbar.collectors'), true)) {
0 ignored issues
show
Bug introduced by
config('toolbar.collectors') of type BlitzPHP\Config\Config|null is incompatible with the type array expected by parameter $haystack of in_array(). ( Ignorable by Annotation )

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

146
            if (in_array(ViewsCollector::class, /** @scrutinizer ignore-type */ config('toolbar.collectors'), true)) {
Loading history...
147
                // Nettoyer nos noms de chemins pour les rendre un peu plus propres
148
                $this->renderVars['file'] = clean_path($this->renderVars['file']);
149
                $this->renderVars['file'] = ++$this->viewsCount . ' ' . $this->renderVars['file'];
150
151
                $output = '<!-- DEBUG-VIEW START ' . $this->renderVars['file'] . ' -->' . PHP_EOL
152
                    . $output . PHP_EOL
153
                    . '<!-- DEBUG-VIEW ENDED ' . $this->renderVars['file'] . ' -->' . PHP_EOL;
154
            }
155
        }
156
157
        $output = $this->decorate($output);
158
159
        // Faut-il mettre en cache ?
160
        if (isset($this->renderVars['options']['cache'])) {
161
            cache()->write($this->renderVars['cacheName'], $output, (int) $this->renderVars['options']['cache']);
162
        }
163
164
        $this->tempData = null;
165
166
        // Récupère les variables actuelles
167
        $this->renderVars = $renderVars;
168
169
        return $output;
170
    }
171
172
    /**
173
     * {@inheritDoc}
174
     */
175
    public function renderString(string $view, ?array $options = null, ?bool $saveData = null): string
176
    {
177
        $start = microtime(true);
178
        $saveData ??= $this->saveData;
179
        $this->prepareTemplateData($saveData);
180
181
        $output = (function (string $view): string {
182
            extract($this->tempData);
183
            ob_start();
184
            eval('?>' . $view);
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
185
186
            return ob_get_clean() ?: '';
187
        })($view);
188
189
        $this->logPerformance($start, microtime(true), $this->excerpt($view));
0 ignored issues
show
Bug introduced by
It seems like microtime(true) can also be of type string; however, parameter $end of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, 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

189
        $this->logPerformance($start, /** @scrutinizer ignore-type */ microtime(true), $this->excerpt($view));
Loading history...
Bug introduced by
It seems like $start can also be of type string; however, parameter $start of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, 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

189
        $this->logPerformance(/** @scrutinizer ignore-type */ $start, microtime(true), $this->excerpt($view));
Loading history...
190
        $this->tempData = null;
191
192
        return $output;
193
    }
194
195
    /**
196
     * Extraire le premier bit d'une longue chaîne et ajouter des points de suspension
197
     */
198
    public function excerpt(string $string, int $length = 20): string
199
    {
200
        return (strlen($string) > $length) ? substr($string, 0, $length - 3) . '...' : $string;
201
    }
202
203
    /**
204
     * {@inheritDoc}
205
     */
206
    public function setData(array $data = [], ?string $context = null): self
207
    {
208
        if ($context) {
209
            $data = esc($data, $context);
210
        }
211
212
        $this->tempData = $data;
213
214
        return $this;
215
    }
216
217
    /**
218
     * {@inheritDoc}
219
     */
220
    public function addData(array $data = [], ?string $context = null): self
221
    {
222
        if ($context) {
223
            $data = esc($data, $context);
224
        }
225
226
        $this->tempData ??= $this->data;
227
        $this->tempData = array_merge($this->tempData, $data);
228
229
        return $this;
230
    }
231
232
    /**
233
     * {@inheritDoc}
234
     */
235
    public function setVar(string $name, $value = null, ?string $context = null): self
236
    {
237
        if ($context) {
238
            $value = esc($value, $context);
239
        }
240
241
        $this->tempData ??= $this->data;
242
        $this->tempData[$name] = $value;
243
244
        return $this;
245
    }
246
247
    /**
248
     * {@inheritDoc}
249
     */
250
    public function getData(): array
251
    {
252
        return $this->tempData ?? $this->data;
253
    }
254
255
    /**
256
     * {@inheritDoc}
257
     */
258
    public function resetData(): self
259
    {
260
        $this->data     = [];
261
        $this->tempData = [];
262
263
        return $this;
264
    }
265
266
    /**
267
     * Spécifie que la vue actuelle doit étendre une mise en page existante.
268
     */
269
    public function extend(string $layout)
270
    {
271
        $this->setLayout($layout);
272
    }
273
274
    /**
275
     * Commence le contenu d'une section dans la mise en page.
276
     */
277
    public function start(string $name, ?string $content = null)
278
    {
279
        if (null === $content) {
280
            $this->sectionStack[] = $name;
281
282
            ob_start();
283
        } else {
284
            $this->sections[$name] = [$content];
285
        }
286
    }
287
288
    /**
289
     * Commence le contenu d'une section dans la mise en page.
290
     *
291
     * @alias self::start()
292
     */
293
    public function section(string $name, ?string $content = null): void
294
    {
295
        $this->start($name, $content);
296
    }
297
298
    /**
299
     * Commence le contenu d'une section dans la mise en page.
300
     *
301
     * @alias self::start()
302
     */
303
    public function begin(string $name, ?string $content = null): void
304
    {
305
        $this->start($name, $content);
306
    }
307
308
    /**
309
     * Capture la dernière section
310
     *
311
     * @throws RuntimeException
312
     */
313
    public function stop()
314
    {
315
        $contents = ob_get_clean();
316
317
        if ($this->sectionStack === []) {
318
            throw new RuntimeException('View themes, no current section.');
319
        }
320
321
        $section = array_pop($this->sectionStack);
322
323
        // Assurez-vous qu'un tableau existe afin que nous puissions stocker plusieurs entrées pour cela.
324
        if (! array_key_exists($section, $this->sections)) {
325
            $this->sections[$section] = [];
326
        }
327
328
        $this->sections[$section][] = $contents;
329
    }
330
331
    /**
332
     * Capture la dernière section
333
     *
334
     * @throws RuntimeException
335
     *
336
     * @alias self::stop()
337
     */
338
    public function endSection(): void
339
    {
340
        $this->stop();
341
    }
342
343
    /**
344
     * Capture la dernière section
345
     *
346
     * @throws RuntimeException
347
     *
348
     * @alias self::stop()
349
     */
350
    public function end(): void
351
    {
352
        $this->stop();
353
    }
354
355
    /**
356
     * Restitue le contenu d'une section.
357
     */
358
    public function show(string $sectionName, bool $preserve = false)
359
    {
360
        if (! isset($this->sections[$sectionName])) {
361
            echo '';
362
363
            return;
364
        }
365
366
        foreach ($this->sections[$sectionName] as $key => $contents) {
367
            echo $contents;
368
369
            if (false === $preserve) {
370
                unset($this->sections[$sectionName][$key]);
371
            }
372
        }
373
    }
374
375
    /**
376
     * Affichage rapide du contenu principal
377
     */
378
    public function renderView(): void
379
    {
380
        $this->show('content');
381
    }
382
383
    /**
384
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires.
385
     */
386
    public function insert(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
387
    {
388
        $view = Helpers::ensureExt($view, $this->ext);
389
        $view = str_replace(' ', '', $view);
390
391
        if ($view[0] !== '/') {
392
            $view = $this->retrievePartialPath($view);
393
        }
394
395
        return $this->addData($data)->render($view, $options, $saveData);
396
    }
397
398
    /**
399
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires.
400
     *
401
     * @alias self::insert()
402
     */
403
    public function include(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
404
    {
405
        return $this->insert($view, $data, $options, $saveData);
406
    }
407
408
    /**
409
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition est remplie.
410
     */
411
    public function insertWhen(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
412
    {
413
        if (is_callable($condition)) {
414
            $condition = $condition();
415
        }
416
417
        if (true === $condition) {
418
            return $this->insert($view, $data, $options, $saveData);
419
        }
420
421
        return '';
422
    }
423
424
    /**
425
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition est remplie.
426
     *
427
     * @alias self::insertWhen()
428
     */
429
    public function includeWhen(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
430
    {
431
        return $this->insertWhen($condition, $view, $data, $options, $saveData);
432
    }
433
434
    /**
435
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition n'est pas remplie.
436
     */
437
    public function insertUnless(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
438
    {
439
        if (is_callable($condition)) {
440
            $condition = $condition();
441
        }
442
443
        return $this->insertWhen(false === $condition, $view, $data, $options, $saveData);
444
    }
445
446
    /**
447
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition n'est pas remplie.
448
     *
449
     * @alias self::insertUnless()
450
     */
451
    public function includeUnless(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
452
    {
453
        return $this->insertUnless($condition, $view, $data, $options, $saveData);
454
    }
455
456
    /**
457
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires si elle existe.
458
     *
459
     * @alias self::insertIf()
460
     */
461
    public function includeIf(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
462
    {
463
        return $this->insertIf($view, $data, $options, $saveData);
464
    }
465
466
    /**
467
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires si elle existe.
468
     */
469
    public function insertIf(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
470
    {
471
        $view = Helpers::ensureExt($view, $this->ext);
472
        $view = str_replace(' ', '', $view);
473
474
        if ($view[0] !== '/') {
475
            $view = $this->retrievePartialPath($view);
476
        }
477
478
        if (is_file($view)) {
479
            return $this->addData($data)->render($view, $options, $saveData);
480
        }
481
482
        return '';
483
    }
484
485
    /**
486
     * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires si elle existe.
487
     */
488
    public function insertFirst(array $views, ?array $data = [], ?array $options = null, ?bool $saveData = null): string
489
    {
490
        foreach ($views as $view) {
491
            $view = Helpers::ensureExt($view, $this->ext);
492
            $view = str_replace(' ', '', $view);
493
494
            if ($view[0] !== '/') {
495
                $view = $this->retrievePartialPath($view);
496
            }
497
498
            if (is_file($view)) {
499
                return $this->addData($data)->render($view, $options, $saveData);
500
            }
501
        }
502
503
        throw ViewException::invalidFile(implode(' OR ', $views));
504
    }
505
506
    /**
507
     * Compile de manière conditionnelle une chaîne de classe CSS.
508
     */
509
    public function class(array $classes): string
510
    {
511
        if ($classes === []) {
512
            return '';
513
        }
514
515
        $class = [];
516
517
        foreach ($classes as $key => $value) {
518
            if (is_int($key)) {
519
                $class[] = $value;
520
            } elseif (true === $value) {
521
                $class[] = $key;
522
            }
523
        }
524
525
        return 'class="' . implode(' ', $class) . '"';
526
    }
527
528
    /**
529
     * Ajoute conditionnellement des styles CSS en ligne à un élément HTML
530
     */
531
    public function style(array $styles): string
532
    {
533
        if ($styles === []) {
534
            return '';
535
        }
536
537
        $style = [];
538
539
        foreach ($styles as $key => $value) {
540
            if (is_int($key)) {
541
                $style[] = $value . ';';
542
            } elseif (true === $value) {
543
                $style[] = $key . ';';
544
            }
545
        }
546
547
        return 'style="' . implode(' ', $style) . '"';
548
    }
549
550
    /**
551
     * Utiliser pour indiquer facilement si une case à cocher HTML donnée est "cochée".
552
     * Indiquera que la case est cochée si la condition fournie est évaluée à true.
553
     */
554
    public function checked(bool|string $condition): string
555
    {
556
        return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'checked="checked"' : '';
557
    }
558
559
    /**
560
     * Utiliser pour indiquer si une option de sélection donnée doit être "sélectionnée".
561
     */
562
    public function selected(bool|string $condition): string
563
    {
564
        return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'selected="selected"' : '';
565
    }
566
567
    /**
568
     * Utiliser pour indiquer si un élément donné doit être "désactivé".
569
     */
570
    public function disabled(bool|string $condition): string
571
    {
572
        return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'disabled' : '';
573
    }
574
575
    /**
576
     * Utiliser pour indiquer si un élément donné doit être "readonly".
577
     */
578
    public function readonly(bool|string $condition): string
579
    {
580
        return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'readonly' : '';
581
    }
582
583
    /**
584
     * Utiliser pour indiquer si un élément donné doit être "obligatoire".
585
     */
586
    public function required(bool|string $condition): string
587
    {
588
        return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
589
    }
590
591
    /**
592
     * Génère un champ input caché à utiliser dans les formulaires générés manuellement.
593
     */
594
    public function csrf(?string $id): string
595
    {
596
        return csrf_field($id);
597
    }
598
599
    /**
600
     * Générer un champ de formulaire pour usurper le verbe HTTP utilisé par les formulaires.
601
     */
602
    public function method(string $method): string
603
    {
604
        return method_field($method);
605
    }
606
607
    /**
608
     * Ajoute un fichier css de librairie a la vue
609
     */
610
    public function addLibCss(string ...$src): self
611
    {
612
        $this->_lib_styles = array_merge($this->_lib_styles, $src);
613
614
        return $this;
615
    }
616
617
    /**
618
     * Ajoute un fichier css a la vue
619
     */
620
    public function addCss(string ...$src): self
621
    {
622
        $this->_styles = array_merge($this->_styles, $src);
623
624
        return $this;
625
    }
626
627
    /**
628
     * Compile les fichiers de style de l'instance et genere les link:href vers ceux-ci
629
     */
630
    public function stylesBundle(): void
631
    {
632
        if (! empty($this->_lib_styles)) {
633
            lib_styles(array_unique($this->_lib_styles));
634
        }
635
636
        if (! empty($this->_styles)) {
637
            styles(array_unique($this->_styles));
638
        }
639
640
        $this->show('css');
641
    }
642
643
    /**
644
     * Ajoute un fichier js de librairie a la vue
645
     */
646
    public function addLibJs(string ...$src): self
647
    {
648
        $this->_lib_scripts = array_merge($this->_lib_scripts, $src);
649
650
        return $this;
651
    }
652
653
    /**
654
     * Ajoute un fichier js a la vue
655
     */
656
    public function addJs(string ...$src): self
657
    {
658
        $this->_scripts = array_merge($this->_scripts, $src);
659
660
        return $this;
661
    }
662
663
    /**
664
     * Compile les fichiers de script de l'instance et genere les link:href vers ceux-ci
665
     */
666
    public function scriptsBundle(): void
667
    {
668
        if (! empty($this->_lib_scripts)) {
669
            lib_scripts(array_unique($this->_lib_scripts));
670
        }
671
672
        if (! empty($this->_scripts)) {
673
            scripts(array_unique($this->_scripts));
674
        }
675
676
        $this->show('js');
677
    }
678
679
    protected function prepareTemplateData(bool $saveData): void
680
    {
681
        $this->tempData ??= $this->data;
682
683
        if ($saveData) {
684
            $this->data = $this->tempData;
685
        }
686
    }
687
688
    private function retrievePartialPath(string $view): string
689
    {
690
        $current_dir = pathinfo($this->renderVars['file'] ?? '', PATHINFO_DIRNAME);
691
        if (file_exists(rtrim($current_dir, DS) . DS . $view)) {
0 ignored issues
show
Bug introduced by
It seems like $current_dir can also be of type array; however, parameter $string of rtrim() 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

691
        if (file_exists(rtrim(/** @scrutinizer ignore-type */ $current_dir, DS) . DS . $view)) {
Loading history...
692
            $view = rtrim($current_dir, DS) . DS . $view;
693
        } elseif (file_exists(rtrim($current_dir, DS) . DS . 'partials' . DS . $view)) {
694
            $view = rtrim($current_dir, DS) . DS . 'partials' . DS . $view;
695
        } elseif (file_exists($this->viewPath . 'partials' . DS . $view)) {
696
            $view = $this->viewPath . 'partials' . DS . $view;
697
        } elseif (file_exists($this->viewPath . trim(dirname($current_dir), '/\\') . DS . $view)) {
0 ignored issues
show
Bug introduced by
It seems like $current_dir can also be of type array; however, parameter $path of dirname() 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

697
        } elseif (file_exists($this->viewPath . trim(dirname(/** @scrutinizer ignore-type */ $current_dir), '/\\') . DS . $view)) {
Loading history...
698
            $view = $this->viewPath . trim(dirname($current_dir), '/\\') . DS . $view;
699
        } elseif (file_exists(VIEW_PATH . 'partials' . DS . $view)) {
700
            $view = VIEW_PATH . 'partials' . DS . $view;
701
        } elseif (file_exists(VIEW_PATH . trim(dirname($current_dir), '/\\') . DS . $view)) {
702
            $view = VIEW_PATH . trim(dirname($current_dir), '/\\') . DS . $view;
703
        }
704
705
        return $view;
706
    }
707
}
708