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.

Blade::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
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\Parser\Template\Engines;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Parser\Template\Abstracts\AbstractEngine;
19
use O2System\Spl\Traits\Collectors\ConfigCollectorTrait;
20
21
/**
22
 * Class Blade
23
 *
24
 * @package O2System\Parser\Template\Engines
25
 *
26
 * @todo    :
27
 *      1. @include (done)
28
 *      2. @each (done)
29
 *      3. @inject
30
 *      4. @stack
31
 *      5. @push
32
 *      6. @verbatim
33
 */
34
class Blade extends AbstractEngine
35
{
36
    use ConfigCollectorTrait;
37
38
    /**
39
     * Blade::$extensions
40
     *
41
     * List of blade file extensions.
42
     *
43
     * @var array
44
     */
45
    protected $extensions = [
46
        '.php',
47
        '.blade.php',
48
        '.phtml',
49
    ];
50
51
    /**
52
     * Blade::$vars
53
     *
54
     * Blade variables
55
     *
56
     * @var array
57
     */
58
    protected $vars = [];
59
60
    /**
61
     * Blade::$sections
62
     *
63
     * List of blade sections.
64
     *
65
     * @var array
66
     */
67
    protected $sections = [];
68
69
    // ------------------------------------------------------------------------
70
71
    /**
72
     * Blade::__construct
73
     *
74
     * @param array $config
75
     */
76
    public function __construct(array $config = [])
77
    {
78
        $this->config = array_merge([
79
            'allowPhpGlobals'   => true,
80
            'allowPhpFunctions' => true,
81
            'allowPhpConstants' => true,
82
        ], $config);
83
    }
84
85
    // ------------------------------------------------------------------------
86
87
    /**
88
     * Blade::parseString
89
     *
90
     * @param string  $string
91
     * @param array   $vars
92
     *
93
     * @return bool|string
94
     */
95
    public function parseString($string, array $vars = [])
96
    {
97
        $this->vars =& $vars;
98
99
        // Collect sections with no closing
100
        $string = preg_replace_callback('/@section((.*),(.*))/', [&$this, 'collectSection'], $string);
101
102
        // Collect sections with @show closing
103
        $string = preg_replace_callback(
104
            '/@section(.*)\s+(.*)\s+@show/',
105
            [&$this, 'collectSectionWithShow'],
106
            $string
107
        );
108
109
        // Collect sections with @endsection closing
110
        $string = preg_replace_callback(
111
            '/@section(.*)\s+(.*)\s+@endsection/',
112
            [&$this, 'collectSectionWithEnd'],
113
            $string
114
        );
115
116
        // Collect sections with @stop closing
117
        $string = preg_replace_callback(
118
            '/@section(.*)\s+(.*)\s+@stop/',
119
            [&$this, 'collectSectionWithEnd'],
120
            $string
121
        );
122
123
        // Collect sections with @overwrite closing
124
        $string = preg_replace_callback(
125
            '/@section(.*)\s+(.*)\s+@overwrite/',
126
            [&$this, 'collectSectionWithEnd'],
127
            $string
128
        );
129
130
        // Collect sections with @parent
131
        $string = preg_replace_callback(
132
            '/@section(.*)\s+@parent\s+(.*)\s+@endsection/',
133
            [&$this, 'collectSectionWithParent'],
134
            $string
135
        );
136
137
        // Remove blank lines
138
        $string = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $string);
139
140
        return $this->replaceString($string);
141
    }
142
143
    // ------------------------------------------------------------------------
144
145
    /**
146
     * Blade::replaceString
147
     *
148
     * @param string $string
149
     *
150
     * @return bool|string
151
     */
152
    private function replaceString($string)
153
    {
154
        if ($this->config[ 'allowPhpGlobals' ] === false) {
155
            $string = str_replace(
156
                [
157
                    '{{$GLOBALS}}',
158
                    '{{$GLOBALS[%%]}}',
159
                    '{{$_SERVER}}',
160
                    '{{$_SERVER[%%]}}',
161
                    '{{$_GET}}',
162
                    '{{$_GET[%%]}}',
163
                    '{{$_POST}}',
164
                    '{{$_POST[%%]}}',
165
                    '{{$_FILES}}',
166
                    '{{$_FILES[%%]}}',
167
                    '{{$_COOKIE}}',
168
                    '{{$_COOKIE[%%]}}',
169
                    '{{$_SESSION}}',
170
                    '{{$_SESSION[%%]}}',
171
                    '{{$_REQUEST}}',
172
                    '{{$_REQUEST[%%]}}',
173
                    '{{$_ENV}}',
174
                    '{{$_ENV[%%]}}',
175
176
                    // with spaces
177
                    '{{ $GLOBALS }}',
178
                    '{{ $GLOBALS[%%] }}',
179
                    '{{ $GLOBALS.%% }}',
180
                    '{{ $_SERVER }}',
181
                    '{{ $_SERVER[%%] }}',
182
                    '{{ $_SERVER.%% }}',
183
                    '{{ $_GET }}',
184
                    '{{ $_GET[%%] }}',
185
                    '{{ $_GET.%% }}',
186
                    '{{ $_POST }}',
187
                    '{{ $_POST[%%] }}',
188
                    '{{ $_POST.%% }}',
189
                    '{{ $_FILES }}',
190
                    '{{ $_FILES[%%] }}',
191
                    '{{ $_FILES.%% }}',
192
                    '{{ $_COOKIE }}',
193
                    '{{ $_COOKIE[%%] }}',
194
                    '{{ $_COOKIE.%% }}',
195
                    '{{ $_SESSION }}',
196
                    '{{ $_SESSION[%%] }}',
197
                    '{{ $_SESSION.%% }}',
198
                    '{{ $_REQUEST }}',
199
                    '{{ $_REQUEST[%%] }}',
200
                    '{{ $_REQUEST.%% }}',
201
                    '{{ $_ENV }}',
202
                    '{{ $_ENV[%%] }}',
203
                    '{{ $_ENV.%% }}',
204
                ],
205
                '',
206
                $string
207
            );
208
        }
209
210
        // php logical codes
211
        $logicalCodes = [
212
            '@if(%%)'        => '<?php if(\1): ?>',
213
            '@elseif(%%)'    => '<?php elseif(\1): ?>',
214
            '@endif'         => '<?php endif; ?>',
215
            '@else'          => '<?php else: ?>',
216
            '@unless(%%)'    => '<?php if(\1): ?>',
217
            '@endunless'     => '<?php endif; ?>',
218
219
            // with spaces
220
            '@if( %% )'      => '<?php if(\1): ?>',
221
            '@elseif( %% )'  => '<?php elseif(\1): ?>',
222
            '@unless( %% )'  => '<?php if(\1): ?>',
223
            '@if (%%)'       => '<?php if(\1): ?>',
224
            '@elseif (%%)'   => '<?php elseif(\1): ?>',
225
            '@unless (%%)'   => '<?php if(\1): ?>',
226
            '@if ( %% )'     => '<?php if(\1): ?>',
227
            '@elseif ( %% )' => '<?php elseif(\1): ?>',
228
            '@unless ( %% )' => '<?php if(\1): ?>',
229
        ];
230
231
        // php loop codes
232
        $loopCodes = [
233
            '@foreach(%%)'  => '<?php foreach(\1): ?>',
234
            '@endforeach'   => '<?php endforeach; ?>',
235
            '@for(%%)'      => '<?php for(\1): ?>',
236
            '@endfor'       => '<?php endfor; ?>',
237
            '@while(%%)'    => '<?php while(\1): ?>',
238
            '@endwhile'     => '<?php endwhile; ?>',
239
            '@continue'     => '<?php continue; ?>',
240
            '@break'        => '<?php break; ?>',
241
242
            // with spaces
243
            '@foreach (%%)' => '<?php foreach(\1): ?>',
244
            '@for (%%)'     => '<?php for(\1): ?>',
245
            '@while (%%)'   => '<?php while(\1): ?>',
246
        ];
247
248
        // php function codes
249
        $functionsCodes = [
250
            '@lang(%%)'           => '<?php echo $language->getLine(\1); ?>',
251
            '@include(%%)'        => '<?php echo $this->parseFile(\1); ?>',
252
            '@include(%%, %%)'    => '<?php echo $this->parseFile(\1, \2); ?>',
253
            '@yield(%%)'          => '<?php echo $this->sections[\1]; ?>',
254
            '@each(%%, %%, %%)'   => '<?php echo $this->parsePartials(\1, \2, \3); ?>',
255
            '@extends(%%)'        => '@extends not supported',
256
            '@choice(%%,%%)'      => '@choice not supported',
257
258
            // with spaces
259
            '@lang (%%)'          => '<?php echo $language->getLine(\1); ?>',
260
            '@include (%%)'       => '<?php echo $this->parseFile(\1); ?>',
261
            '@include (%%, %%)'   => '<?php echo $this->parseFile(\1, \2); ?>',
262
            '@yield (%%)'         => '<?php echo $this->sections[\1]; ?>',
263
            '@each (%%, %%, %%)'  => '<?php echo $this->parsePartials(\1, \2, \3); ?>',
264
            '@extends (%%)'       => '@extends not supported',
265
            '@choice (%%,%%)'     => '@choice not supported',
266
            '@lang( %% )'         => '<?php echo $language->getLine(\1); ?>',
267
            '@include( %% )'      => '<?php echo $this->parseFile(\1); ?>',
268
            '@include( %%, %% )'  => '<?php echo $this->parseFile(\1, \2); ?>',
269
            '@yield( %% )'        => '<?php echo $this->sections[\1]; ?>',
270
            '@each( %%, %%, %% )' => '<?php echo $this->parsePartials(\1, \2, \3); ?>',
271
            '@extends( %% )'      => '@extends not supported',
272
            '@choice( %%,%% )'    => '@choice not supported',
273
        ];
274
275
        if ($this->config[ 'allowPhpFunctions' ] === false) {
276
            $functionsCodes[ '@%%(%%)' ] = '';
277
        } elseif (is_array($this->config[ 'allowPhpFunctions' ]) AND count(
278
                $this->config[ 'allowPhpFunctions' ]
279
            ) > 0
280
        ) {
281
            foreach ($this->config[ 'allowPhpFunctions' ] as $functionName) {
282
                $functionsCodes[ '@' . $functionName . '(%%)' ] = '<?php echo ' . $functionName . '(\1); ?>';
283
            }
284
        }
285
286
        // php variables codes
287
        $variablesCodes = [
288
            '{{%% ? %% : %%}}'   => '<?php echo (\1 ? \2 : \3); ?>',
289
            '{{%% or %%}}'       => '<?php echo ( empty(\1) ? \2 : \1 ); ?>',
290
            '{{%% || %%}}'       => '<?php echo ( empty(\1) ? \2 : \1 ); ?>',
291
            '{{$%%->%%(%%)}}'    => '<?php echo $\1->\2(\3); ?>',
292
            '{{$%%->%%}}'        => '<?php echo @$\1->\2; ?>',
293
            '{{$%%[%%]}}'        => '<?php echo @$\1[\2]; ?>',
294
            '{{$%%.%%}}'         => '<?php echo @$\1[\2]; ?>',
295
            '{{$%% = %%}}'       => '<?php $\1 = \2; ?>',
296
            '{{$%%++}}'          => '<?php $\1++; ?>',
297
            '{{$%%--}}'          => '<?php $\1--; ?>',
298
            '{{$%%}}'            => '<?php echo (!empty($\1) ? $\1 : ""); ?>',
299
            '{{/*}}'             => '<?php /*',
300
            '{{*/}}'             => '*/ ?>',
301
            '{{%%}}'             => '<?php echo (\1); ?>',
302
            '{{!! $%% !!}}'      => '<?php echo htmlentities($\1, ENT_HTML5); ?>',
303
            '{{-- %% --}}'       => '',
304
305
            // with spaces
306
            '{{ %% ? %% : %% }}' => '<?php echo (\1 ? \2 : \3); ?>',
307
            '{{ %% or %% }}'     => '<?php echo ( empty(\1) ? \2 : \1 ); ?>',
308
            '{{ %% || %% }}'     => '<?php echo ( empty(\1) ? \2 : \1 ); ?>',
309
            '{{ $%%->%%(%%) }}'  => '<?php echo $\1->\2(\3); ?>',
310
            '{{ $%%->%% }}'      => '<?php echo @$\1->\2; ?>',
311
            '{{ $%%[%%] }}'      => '<?php echo @$\1[\2]; ?>',
312
            '{{ $%%.%% }}'       => '<?php echo @$\1[\2]; ?>',
313
            '{{ $%% = %% }}'     => '<?php $\1 = \2; ?>',
314
            '{{ $%%++ }}'        => '<?php $\1++; ?>',
315
            '{{ $%%-- }}'        => '<?php $\1--; ?>',
316
            '{{ $%% }}'          => '<?php echo (!empty($\1) ? $\1 : ""); ?>',
317
            '{{ /* }}'           => '<?php /*',
318
            '{{ */ }}'           => '*/ ?>',
319
            '{{ %% }}'           => '<?php echo (\1); ?>',
320
        ];
321
322
        if ($this->config[ 'allowPhpConstants' ] === true) {
323
            $constantsVariables = get_defined_constants(true);
324
325
            if ( ! empty($constantsVariables[ 'user' ])) {
326
                foreach ($constantsVariables[ 'user' ] as $constant => $value) {
327
                    $variablesCodes[ '{{ ' . $constant . ' }}' ] = '<?php echo ' . $constant . '; ?>';
328
                }
329
            }
330
        }
331
332
        $phpCodes = array_merge($logicalCodes, $loopCodes, $functionsCodes, $variablesCodes);
333
334
        $patterns = $replace = [];
335
        foreach ($phpCodes as $tplCode => $phpCode) {
336
            $patterns[] = '#' . str_replace('%%', '(.+)', preg_quote($tplCode, '#')) . '#U';
337
            $replace[] = $phpCode;
338
        }
339
340
        /*replace our pseudo language in template with php code*/
341
        $string = preg_replace($patterns, $replace, $string);
342
343
        extract($this->vars);
344
345
        /*
346
         * Buffer the output
347
         *
348
         * We buffer the output for two reasons:
349
         * 1. Speed. You get a significant speed boost.
350
         * 2. So that the final rendered template can be post-processed by
351
         *  the output class. Why do we need post processing? For one thing,
352
         *  in order to show the elapsed page load time. Unless we can
353
         *  intercept the content right before it's sent to the browser and
354
         *  then stop the timer it won't be accurate.
355
         */
356
        ob_start();
357
358
        echo eval('?>' . preg_replace('/;*\s*\?>/', '; ?>', $string));
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
359
360
        $output = ob_get_contents();
361
        @ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ob_end_clean(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

361
        /** @scrutinizer ignore-unhandled */ @ob_end_clean();

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
362
363
        return $output;
364
    }
365
366
    // ------------------------------------------------------------------------
367
368
    /**
369
     * Blade::collectSection
370
     *
371
     * @param string $match
372
     *
373
     * @return string
374
     */
375
    private function collectSection($match)
376
    {
377
        $section = str_replace(['\'', '(', ')'], '', trim($match[ 1 ]));
378
        $xSection = explode(',', $section);
379
        $xSection = array_map('trim', $xSection);
380
381
        $this->sections[ $xSection[ 0 ] ] = $this->replaceString($xSection[ 1 ]);
382
383
        return '';
384
    }
385
386
    // ------------------------------------------------------------------------
387
388
    /**
389
     * Blade::collectSectionWithShow
390
     *
391
     * @param string $match
392
     *
393
     * @return string
394
     */
395
    private function collectSectionWithShow($match)
396
    {
397
        $offset = str_replace(['(\'', '\')'], '', trim($match[ 1 ]));
398
        $this->sections[ $offset ] = $this->replaceString($match[ 2 ]);
399
400
        return '@yield(\'' . $offset . '\')';
401
    }
402
403
    // ------------------------------------------------------------------------
404
405
    /**
406
     * Blade::collectSectionWithEnd
407
     *
408
     * @param string $match
409
     *
410
     * @return string
411
     */
412
    private function collectSectionWithEnd($match)
413
    {
414
        $offset = str_replace(['(\'', '\')'], '', trim($match[ 1 ]));
415
        $content = trim($match[ 2 ]);
416
417
        $this->sections[ $offset ] = $this->replaceString($content);
418
419
        return '';
420
    }
421
422
    // ------------------------------------------------------------------------
423
424
    /**
425
     * Blade::collectSectionWithParent
426
     *
427
     * @param string $match
428
     *
429
     * @return string
430
     */
431
    private function collectSectionWithParent($match)
432
    {
433
        $offset = str_replace(['(\'', '\')'], '', trim($match[ 1 ]));
434
        $content = $this->replaceString($match[ 2 ]);
435
436
        if (isset($this->sections[ $offset ])) {
437
            $this->sections[ $offset ] .= PHP_EOL . $content;
438
        } else {
439
            $this->sections[ $offset ] = $content;
440
        }
441
442
        return '';
443
    }
444
}