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.
Completed
Push — master ( 4d68fd...6b2287 )
by Zordius
03:13
created

Runtime::sec()   F

Complexity

Conditions 37
Paths > 20000

Size

Total Lines 112
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 74
CRAP Score 37

Importance

Changes 0
Metric Value
dl 0
loc 112
ccs 74
cts 74
cp 1
rs 2
c 0
b 0
f 0
cc 37
eloc 75
nc 22564
nop 7
crap 37

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
4
Copyrights for code authored by Yahoo! Inc. is licensed under the following terms:
5
MIT License
6
Copyright (c) 2013-2016 Yahoo! Inc. All Rights Reserved.
7
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10
11
Origin: https://github.com/zordius/lightncandy
12
*/
13
14
/**
15
 * file to support LightnCandy compiled PHP runtime
16
 *
17
 * @package    LightnCandy
18
 * @author     Zordius <[email protected]>
19
 */
20
21
namespace LightnCandy;
22
use \LightnCandy\Encoder;
23
24
/**
25
 * LightnCandy class for compiled PHP runtime.
26
 */
27
class Runtime extends Encoder
28
{
29
    const DEBUG_ERROR_LOG = 1;
30
    const DEBUG_ERROR_EXCEPTION = 2;
31
    const DEBUG_TAGS = 4;
32
    const DEBUG_TAGS_ANSI = 12;
33
    const DEBUG_TAGS_HTML = 20;
34
35
    /**
36
     * Output debug info.
37
     *
38
     * @param string $v expression
39
     * @param string $f runtime function name
40
     * @param array<string,array|string|integer> $cx render time context for lightncandy
41
     *
42
     * @expect '{{123}}' when input '123', 'miss', array('flags' => array('debug' => Runtime::DEBUG_TAGS), 'runtime' => 'LightnCandy\\Runtime'), ''
43
     * @expect '<!--MISSED((-->{{#123}}<!--))--><!--SKIPPED--><!--MISSED((-->{{/123}}<!--))-->' when input '123', 'wi', array('flags' => array('debug' => Runtime::DEBUG_TAGS_HTML), 'runtime' => 'LightnCandy\\Runtime'), false, null, false, function () {return 'A';}
44
     */
45 9
    public static function debug($v, $f, $cx) {
46
        // Build array of reference for call_user_func_array
47 9
        $P = func_get_args();
48 9
        $params = array();
49 9
        for ($i=2;$i<count($P);$i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
50 9
            $params[] = &$P[$i];
51
        }
52 9
        $r = call_user_func_array((isset($cx['funcs'][$f]) ? $cx['funcs'][$f] : "{$cx['runtime']}::$f"), $params);
53
54 8
        if ($cx['flags']['debug'] & static::DEBUG_TAGS) {
55 5
            $ansi = $cx['flags']['debug'] & (static::DEBUG_TAGS_ANSI - static::DEBUG_TAGS);
56 5
            $html = $cx['flags']['debug'] & (static::DEBUG_TAGS_HTML - static::DEBUG_TAGS);
57 5
            $cs = ($html ? (($r !== '') ? '<!!--OK((-->' : '<!--MISSED((-->') : '')
58 5
                  . ($ansi ? (($r !== '') ? "\033[0;32m" : "\033[0;31m") : '');
59 5
            $ce = ($html ? '<!--))-->' : '')
60 5
                  . ($ansi ? "\033[0m" : '');
61
            switch ($f) {
62 5
                case 'sec':
63 3
                case 'wi':
64 3
                    if ($r == '') {
65 3
                        if ($ansi) {
66 1
                            $r = "\033[0;33mSKIPPED\033[0m";
67
                        }
68 3
                        if ($html) {
69 2
                            $r = '<!--SKIPPED-->';
70
                        }
71
                    }
72 3
                    return "$cs{{#{$v}}}$ce{$r}$cs{{/{$v}}}$ce";
73
                default:
74 3
                    return "$cs{{{$v}}}$ce";
75
            }
76
        } else {
77 3
            return $r;
78
        }
79
    }
80
81
    /**
82
     * Handle error by error_log or throw exception.
83
     *
84
     * @param array<string,array|string|integer> $cx render time context for lightncandy
85
     * @param string $err error message
86
     *
87
     * @throws \Exception
88
     */
89 12
    public static function err($cx, $err) {
90 12
        if ($cx['flags']['debug'] & static::DEBUG_ERROR_LOG) {
91 2
            error_log($err);
92 2
            return;
93
        }
94 10
        if ($cx['flags']['debug'] & static::DEBUG_ERROR_EXCEPTION) {
95 6
            throw new \Exception($err);
96
        }
97 4
    }
98
99
    /**
100
     * Handle missing data error.
101
     *
102
     * @param array<string,array|string|integer> $cx render time context for lightncandy
103
     * @param string $v expression
104
     */
105 5
    public static function miss($cx, $v) {
106 5
        static::err($cx, "Runtime: $v does not exist");
107 4
    }
108
109
    /**
110
     * For {{log}} .
111
     *
112
     * @param array<string,array|string|integer> $cx render time context for lightncandy
113
     * @param string $v expression
114
     */
115
    public static function lo($cx, $v) {
116
        error_log(var_export($v[0], true));
117
        return '';
118
    }
119
120
    /**
121
     * Resursive lookup variable and helpers. This is slow and will only be used for instance property or method detection or lambdas.
122
     *
123
     * @param array<string,array|string|integer> $cx render time context for lightncandy
124
     * @param array|string|boolean|integer|double|null $in current context
125
     * @param array<array|string|integer> $base current variable context
126
     * @param array<string|integer> $path array of names for path
127
     * @param array|null $args extra arguments for lambda
128
     *
129
     * @return null|string Return the value or null when not found
130
     *
131
     * @expect null when input array('scopes' => array(), 'flags' => array('prop' => 0, 'method' => 0, 'mustlok' => 0)), null, 0, array('a', 'b')
132
     * @expect 3 when input array('scopes' => array(), 'flags' => array('prop' => 0, 'method' => 0), 'mustlok' => 0), null, array('a' => array('b' => 3)), array('a', 'b')
133
     * @expect null when input array('scopes' => array(), 'flags' => array('prop' => 0, 'method' => 0, 'mustlok' => 0)), null, (Object) array('a' => array('b' => 3)), array('a', 'b')
134
     * @expect 3 when input array('scopes' => array(), 'flags' => array('prop' => 1, 'method' => 0, 'mustlok' => 0)), null, (Object) array('a' => array('b' => 3)), array('a', 'b')
135
     */
136 387
    public static function v($cx, $in, $base, $path, $args = null) {
137 387
        $count = count($cx['scopes']);
138 387
        $plen = count($path);
139 387
        while ($base) {
140 351
            $v = $base;
141 351
            foreach ($path as $i => $name) {
142 351
                if (is_array($v)) {
143 350
                    if (isset($v[$name])) {
144 346
                        $v = $v[$name];
145 346
                        continue;
146
                    }
147 31
                    if (($i === $plen - 1) && ($name === 'length')) {
148 1
                        return count($v);
149
                    }
150
                }
151 36
                if (is_object($v)) {
152 5
                    if ($cx['flags']['prop'] && !($v instanceof \Closure) && isset($v->$name)) {
153 3
                        $v = $v->$name;
154 3
                        continue;
155
                    }
156 5
                    if ($cx['flags']['method'] && is_callable(array($v, $name))) {
157 4
                        $v = $v->$name();
158 4
                        continue;
159
                    }
160
                }
161 34
                if ($cx['flags']['mustlok']) {
162 31
                    unset($v);
163 31
                    break;
164
                }
165 3
                return null;
166
            }
167 350
            if (isset($v)) {
168 339
                if ($v instanceof \Closure) {
169 29
                    if ($cx['flags']['mustlam'] || $cx['flags']['lambda']) {
170 29
                        if (!$cx['flags']['knohlp'] && ($args || ($args === 0))) {
171 20
                            $A = $args ? $args[0] : array();
172 20
                            $A[] = array('hash' => $args[1], '_this' => $in);
173
                        } else {
174 10
                            $A = array($in);
175
                        }
176 29
                        $v = call_user_func_array($v, $A);
177
                    }
178
                }
179 339
                return $v;
180
            }
181 31
            $count--;
182
            switch ($count) {
183 31
                case -1:
184 30
                    $base = $cx['sp_vars']['root'];
185 30
                    break;
186 30
                case -2:
187 29
                    return null;
188
                default:
189 6
                    $base = $cx['scopes'][$count];
190
            }
191
        }
192 40
        if ($args) {
193 3
            static::err($cx, 'Can not find helper or lambda: "' . implode('.', $path) . '" !');
194
        }
195 40
    }
196
197
    /**
198
     * For {{#if}} .
199
     *
200
     * @param array<string,array|string|integer> $cx render time context for lightncandy
201
     * @param array<array|string|integer>|string|integer|null $v value to be tested
202
     * @param boolean $zero include zero as true
203
     *
204
     * @return boolean Return true when the value is not null nor false.
205
     *
206
     * @expect false when input array(), null, false
207
     * @expect false when input array(), 0, false
208
     * @expect true when input array(), 0, true
209
     * @expect false when input array(), false, false
210
     * @expect true when input array(), true, false
211
     * @expect true when input array(), 1, false
212
     * @expect false when input array(), '', false
213
     * @expect false when input array(), array(), false
214
     * @expect true when input array(), array(''), false
215
     * @expect true when input array(), array(0), false
216
     */
217 74
    public static function ifvar($cx, $v, $zero) {
218 74
        return ($v !== null) && ($v !== false) && ($zero || ($v !== 0) && ($v !== 0.0)) && ($v !== '') && (is_array($v) ? (count($v) > 0) : true);
219
    }
220
221
    /**
222
     * For {{^var}} .
223
     *
224
     * @param array<string,array|string|integer> $cx render time context for lightncandy
225
     * @param array<array|string|integer>|string|integer|null $v value to be tested
226
     *
227
     * @return boolean Return true when the value is not null nor false.
228
     *
229
     * @expect true when input array(), null
230
     * @expect false when input array(), 0
231
     * @expect true when input array(), false
232
     * @expect false when input array(), 'false'
233
     * @expect true when input array(), array()
234
     * @expect false when input array(), array('1')
235
     */
236 37
    public static function isec($cx, $v) {
237 37
        return ($v === null) || ($v === false) || (is_array($v) && (count($v) === 0));
238
    }
239
240
    /**
241
     * For {{var}} .
242
     *
243
     * @param array<string,array|string|integer> $cx render time context for lightncandy
244
     * @param array<array|string|integer>|string|integer|null $var value to be htmlencoded
245
     *
246
     * @return string The htmlencoded value of the specified variable
247
     *
248
     * @expect 'a' when input array('flags' => array('mustlam' => 0, 'lambda' => 0)), 'a'
249
     * @expect 'a&amp;b' when input array('flags' => array('mustlam' => 0, 'lambda' => 0)), 'a&b'
250
     * @expect 'a&#039;b' when input array('flags' => array('mustlam' => 0, 'lambda' => 0)), 'a\'b'
251
     * @expect 'a&b' when input null, new \LightnCandy\SafeString('a&b')
252
     */
253 46
    public static function enc($cx, $var) {
254 46
        if ($var instanceof \LightnCandy\SafeString) {
255 1
            return (string)$var;
256
        }
257
258 46
        return htmlspecialchars(static::raw($cx, $var), ENT_QUOTES, 'UTF-8');
259
    }
260
261
    /**
262
     * For {{var}} , do html encode just like handlebars.js .
263
     *
264
     * @param array<string,array|string|integer> $cx render time context for lightncandy
265
     * @param array<array|string|integer>|string|integer|null $var value to be htmlencoded
266
     *
267
     * @return string The htmlencoded value of the specified variable
268
     *
269
     * @expect 'a' when input array('flags' => array('mustlam' => 0, 'lambda' => 0)), 'a'
270
     * @expect 'a&amp;b' when input array('flags' => array('mustlam' => 0, 'lambda' => 0)), 'a&b'
271
     * @expect 'a&#x27;b' when input array('flags' => array('mustlam' => 0, 'lambda' => 0)), 'a\'b'
272
     * @expect '&#x60;a&#x27;b' when input array('flags' => array('mustlam' => 0, 'lambda' => 0)), '`a\'b'
273
     */
274 335
    public static function encq($cx, $var) {
275 335
        if ($var instanceof \LightnCandy\SafeString) {
276 3
            return (string)$var;
277
        }
278
279 332
        return str_replace(array('=', '`', '&#039;'), array('&#x3D;', '&#x60;', '&#x27;'), htmlspecialchars(static::raw($cx, $var), ENT_QUOTES, 'UTF-8'));
280
    }
281
282
    /**
283
     * For {{#var}} or {{#each}} .
284
     *
285
     * @param array<string,array|string|integer> $cx render time context for lightncandy
286
     * @param array<array|string|integer>|string|integer|null $v value for the section
287
     * @param array<string>|null $bp block parameters
288
     * @param array<array|string|integer>|string|integer|null $in input data with current scope
289
     * @param boolean $each true when rendering #each
290
     * @param Closure $cb callback function to render child context
291
     * @param Closure|null $else callback function to render child context when {{else}}
292
     *
293
     * @return string The rendered string of the section
294
     *
295
     * @expect '' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), false, null, false, false, function () {return 'A';}
296
     * @expect '' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), null, null, null, false, function () {return 'A';}
297
     * @expect 'A' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), true, null, true, false, function () {return 'A';}
298
     * @expect 'A' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), 0, null, 0, false, function () {return 'A';}
299
     * @expect '-a=' when input array('scopes' => array(), 'flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), array('a'), null, array('a'), false, function ($c, $i) {return "-$i=";}
300
     * @expect '-a=-b=' when input array('scopes' => array(), 'flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), array('a','b'), null, array('a','b'), false, function ($c, $i) {return "-$i=";}
301
     * @expect '' when input array('scopes' => array(), 'flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), 'abc', null, 'abc', true, function ($c, $i) {return "-$i=";}
302
     * @expect '-b=' when input array('scopes' => array(), 'flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), array('a' => 'b'), null, array('a' => 'b'), true, function ($c, $i) {return "-$i=";}
303
     * @expect '1' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), 'b', null, 'b', false, function ($c, $i) {return count($i);}
304
     * @expect '1' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), 1, null, 1, false, function ($c, $i) {return print_r($i, true);}
305
     * @expect '0' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), 0, null, 0, false, function ($c, $i) {return print_r($i, true);}
306
     * @expect '{"b":"c"}' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), array('b' => 'c'), null, array('b' => 'c'), false, function ($c, $i) {return json_encode($i);}
307
     * @expect 'inv' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), array(), null, 0, true, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
308
     * @expect 'inv' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), array(), null, 0, false, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
309
     * @expect 'inv' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), false, null, 0, true, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
310
     * @expect 'inv' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), false, null, 0, false, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
311
     * @expect 'inv' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), '', null, 0, true, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
312
     * @expect 'cb' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), '', null, 0, false, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
313
     * @expect 'inv' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), 0, null, 0, true, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
314
     * @expect 'cb' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), 0, null, 0, false, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
315
     * @expect 'inv' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'lambda' => 0)), new stdClass, null, 0, true, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
316
     * @expect 'cb' when input array('flags' => array('spvar' => 0, 'mustlam' => 0, 'mustsec' => 0, 'lambda' => 0)), new stdClass, null, 0, false, function ($c, $i) {return 'cb';}, function ($c, $i) {return 'inv';}
317
     * @expect '268' when input array('scopes' => array(), 'flags' => array('spvar' => 1, 'mustlam' => 0, 'lambda' => 0), 'sp_vars'=>array('root' => 0)), array(1,3,4), null, 0, false, function ($c, $i) {return $i * 2;}
318
     * @expect '038' when input array('scopes' => array(), 'flags' => array('spvar' => 1, 'mustlam' => 0, 'lambda' => 0), 'sp_vars'=>array('root' => 0)), array(1,3,'a'=>4), null, 0, true, function ($c, $i) {return $i * $c['sp_vars']['index'];}
319
     */
320 165
    public static function sec($cx, $v, $bp, $in, $each, $cb, $else = null) {
321 165
        $push = ($in !== $v) || $each;
322
323 165
        $isAry = is_array($v) || ($v instanceof \ArrayObject);
324 165
        $isTrav = $v instanceof \Traversable;
325 165
        $loop = $each;
326 165
        $keys = null;
327 165
        $last = null;
328 165
        $isObj = false;
329
330 165
        if ($isAry && $else !== null && count($v) === 0) {
331 3
            $ret = $else($cx, $in);
332 3
            return $ret;
333
        }
334
335
        // #var, detect input type is object or not
336 163
        if (!$loop && $isAry) {
337 66
            $keys = array_keys($v);
338 66
            $loop = (count(array_diff_key($v, array_keys($keys))) == 0);
339 66
            $isObj = !$loop;
340
        }
341
342 163
        if (($loop && $isAry) || $isTrav) {
343 104
            if ($each && !$isTrav) {
344
                // Detect input type is object or not when never done once
345 48
                if ($keys == null) {
346 48
                    $keys = array_keys($v);
347 48
                    $isObj = (count(array_diff_key($v, array_keys($keys))) > 0);
348
                }
349
            }
350 104
            $ret = array();
351 104
            if ($push) {
352 102
                $cx['scopes'][] = $in;
353
            }
354 104
            $i = 0;
355 104
            if ($cx['flags']['spvar']) {
356 93
                $old_spvar = $cx['sp_vars'];
357 93
                $cx['sp_vars'] = array_merge(array('root' => $old_spvar['root']), $old_spvar, array('_parent' => $old_spvar));
358 93
                if (!$isTrav) {
359 92
                    $last = count($keys) - 1;
360
                }
361
            }
362
363 104
            $isSparceArray = $isObj && (count(array_filter(array_keys($v), 'is_string')) == 0);
364 104
            foreach ($v as $index => $raw) {
365 97
                if ($cx['flags']['spvar']) {
366 87
                    $cx['sp_vars']['first'] = ($i === 0);
367 87
                    $cx['sp_vars']['last'] = ($i == $last);
368 87
                    $cx['sp_vars']['key'] = $index;
369 87
                    $cx['sp_vars']['index'] = $isSparceArray ? $index : $i;
370 87
                    $i++;
371
                }
372 97
                if (isset($bp[0])) {
373 2
                    $raw = static::m($cx, $raw, array($bp[0] => $raw));
374
                }
375 97
                if (isset($bp[1])) {
376 1
                    $raw = static::m($cx, $raw, array($bp[1] => $cx['sp_vars']['index']));
377
                }
378 97
                $ret[] = $cb($cx, $raw);
379
            }
380 103
            if ($cx['flags']['spvar']) {
381 92
                if ($isObj) {
382 14
                    unset($cx['sp_vars']['key']);
383
                } else {
384 80
                    unset($cx['sp_vars']['last']);
385
                }
386 92
                unset($cx['sp_vars']['index']);
387 92
                unset($cx['sp_vars']['first']);
388 92
                $cx['sp_vars'] = $old_spvar;
389
            }
390 103
            if ($push) {
391 101
                array_pop($cx['scopes']);
392
            }
393 103
            return join('', $ret);
394
        }
395 63
        if ($each) {
396 2
            if ($else !== null) {
397 1
                $ret = $else($cx, $v);
398 1
                return $ret;
399
            }
400 2
            return '';
401
        }
402 62
        if ($isAry) {
403 11
            if ($push) {
404 10
                $cx['scopes'][] = $in;
405
            }
406 11
            $ret = $cb($cx, $v);
407 11
            if ($push) {
408 10
                array_pop($cx['scopes']);
409
            }
410 11
            return $ret;
411
        }
412
413 52
        if ($cx['flags']['mustsec']) {
414 20
            return $v ? $cb($cx, $in) : '';
415
        }
416
417 32
        if ($v === true) {
418 9
            return $cb($cx, $in);
419
        }
420
421 25
        if (($v !== null) && ($v !== false)) {
422 7
            return $cb($cx, $v);
423
        }
424
425 20
        if ($else !== null) {
426 10
            $ret = $else($cx, $in);
427 10
            return $ret;
428
        }
429
430 11
        return '';
431
    }
432
433
    /**
434
     * For {{#with}} .
435
     *
436
     * @param array<string,array|string|integer> $cx render time context for lightncandy
437
     * @param array<array|string|integer>|string|integer|null $v value to be the new context
438
     * @param array<array|string|integer>|string|integer|null $in input data with current scope
439
     * @param array<string>|null $bp block parameters
440
     * @param Closure $cb callback function to render child context
441
     * @param Closure|null $else callback function to render child context when {{else}}
442
     *
443
     * @return string The rendered string of the token
444
     *
445
     * @expect '' when input array(), false, null, false, function () {return 'A';}
446
     * @expect '' when input array(), null, null, null, function () {return 'A';}
447
     * @expect '{"a":"b"}' when input array(), array('a'=>'b'), null, array('a'=>'c'), function ($c, $i) {return json_encode($i);}
448
     * @expect '-b=' when input array(), 'b', null, array('a'=>'b'), function ($c, $i) {return "-$i=";}
449
     */
450 28
    public static function wi($cx, $v, $bp, $in, $cb, $else = null) {
451 28
        if (isset($bp[0])) {
452 4
            $v = static::m($cx, $v, array($bp[0] => $v));
453
        }
454 28
        if (($v === false) || ($v === null) || (is_array($v) && (count($v) === 0))) {
455 5
            return $else ? $else($cx, $in) : '';
456
        }
457 24
        if ($v === $in) {
458 5
            $ret = $cb($cx, $v);
459
        } else {
460 19
            $cx['scopes'][] = $in;
461 19
            $ret = $cb($cx, $v);
462 19
            array_pop($cx['scopes']);
463
        }
464 24
        return $ret;
465
    }
466
467
    /**
468
     * Get merged context.
469
     *
470
     * @param array<string,array|string|integer> $cx render time context for lightncandy
471
     * @param array<array|string|integer>|string|integer|null $a the context to be merged
472
     * @param array<array|string|integer>|string|integer|null $b the new context to overwrite
473
     *
474
     * @return array<array|string|integer>|string|integer the merged context object
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|integer|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
475
     *
476
     */
477 93
    public static function m($cx, $a, $b) {
478 93
        if (is_array($b)) {
479 93
            if ($a === null) {
480 8
                return $b;
481 86
            } else if (is_array($a)) {
482 77
                return array_merge($a, $b);
483 9
            } else if (($cx['flags']['method'] || $cx['flags']['prop']) && is_object($a)) {
484 4
                foreach ($b as $i => $v) {
485 1
                    $a->$i = $v;
486
                }
487
            }
488
        }
489 9
        return $a;
490
    }
491
492
    /**
493
     * For {{> partial}} .
494
     *
495
     * @param array<string,array|string|integer> $cx render time context for lightncandy
496
     * @param string $p partial name
497
     * @param array<array|string|integer>|string|integer|null $v value to be the new context
498
     *
499
     * @return string The rendered string of the partial
500
     *
501
     */
502 88
    public static function p($cx, $p, $v, $pid, $sp = '') {
503 88
        $pp = ($p === '@partial-block') ? "$p" . ($pid > 0 ? $pid : $cx['partialid']) : $p;
504
505 88
        if (!isset($cx['partials'][$pp])) {
506 2
            static::err($cx, "Can not find partial named as '$pp' !!");
507 1
            return '';
508
        }
509
510 86
        $cx['partialid'] = ($p === '@partial-block') ? (($pid > 0) ? $pid : (($cx['partialid'] > 0) ? $cx['partialid'] - 1 : 0)) : $pid;
511
512 86
        return call_user_func($cx['partials'][$pp], $cx, static::m($cx, $v[0][0], $v[1]), $sp);
513
    }
514
515
    /**
516
     * For {{#* inlinepartial}} .
517
     *
518
     * @param array<string,array|string|integer> $cx render time context for lightncandy
519
     * @param string $p partial name
520
     * @param Closure $code the compiled partial code
521
     *
522
     */
523 7
    public static function in(&$cx, $p, $code) {
524 7
        $cx['partials'][$p] = $code;
525 7
    }
526
527
    /* For single custom helpers.
528
     *
529
     * @param array<string,array|string|integer> $cx render time context for lightncandy
530
     * @param string $ch the name of custom helper to be executed
531
     * @param array<array|string|integer>|string|integer|null $vars variables for the helper
532
     * @param string $op the name of variable resolver. should be one of: 'raw', 'enc', or 'encq'.
533
     * @param array<string,array|string|integer> $_this current rendering context for the helper
534
     *
535
     * @return string The rendered string of the token
536
     */
537 119
    public static function hbch($cx, $ch, $vars, $op, &$_this) {
538 119
        if (isset($cx['blparam'][0][$ch])) {
539 1
            return $cx['blparam'][0][$ch];
540
        }
541
542
        $options = array(
543 119
            'name' => $ch,
544 119
            'hash' => $vars[1],
545 119
            'contexts' => count($cx['scopes']) ? $cx['scopes'] : array(null),
546 119
            'fn.blockParams' => 0,
547 119
            '_this' => &$_this
548
        );
549
550 119
        if ($cx['flags']['spvar']) {
551 114
            $options['data'] = $cx['sp_vars'];
552
        }
553
554 119
        return static::exch($cx, $ch, $vars, $options);
555
    }
556
557
    /**
558
     * For block custom helpers.
559
     *
560
     * @param array<string,array|string|integer> $cx render time context for lightncandy
561
     * @param string $ch the name of custom helper to be executed
562
     * @param array<array|string|integer>|string|integer|null $vars variables for the helper
563
     * @param array<string,array|string|integer> $_this current rendering context for the helper
564
     * @param boolean $inverted the logic will be inverted
565
     * @param Closure|null $cb callback function to render child context
566
     * @param Closure|null $else callback function to render child context when {{else}}
567
     *
568
     * @return string The rendered string of the token
569
     */
570 56
    public static function hbbch($cx, $ch, $vars, &$_this, $inverted, $cb, $else = null) {
571
        $options = array(
572 56
            'name' => $ch,
573 56
            'hash' => $vars[1],
574 56
            'contexts' => count($cx['scopes']) ? $cx['scopes'] : array(null),
575 56
            'fn.blockParams' => 0,
576 56
            '_this' => &$_this,
577
        );
578
579 56
        if ($cx['flags']['spvar']) {
580 52
            $options['data'] = $cx['sp_vars'];
581
        }
582
583 56
        if (isset($vars[2])) {
584 3
            $options['fn.blockParams'] = count($vars[2]);
585
        }
586
587
        // $invert the logic
588 56
        if ($inverted) {
589
            $tmp = $else;
590
            $else = $cb;
591
            $cb = $tmp;
592
        }
593
594
        $options['fn'] = function ($context = '_NO_INPUT_HERE_', $data = null) use ($cx, &$_this, $cb, $options, $vars) {
595 45
            if ($cx['flags']['echo']) {
596
                ob_start();
597
            }
598 45
            if (isset($data['data'])) {
599 6
                $old_spvar = $cx['sp_vars'];
600 6
                $cx['sp_vars'] = array_merge(array('root' => $old_spvar['root']), $data['data'], array('_parent' => $old_spvar));
601
            }
602 45
            $ex = false;
603 45
            if (isset($data['blockParams']) && isset($vars[2])) {
604 3
                $ex = array_combine($vars[2], array_slice($data['blockParams'], 0, count($vars[2])));
605 3
                array_unshift($cx['blparam'], $ex);
606 43
            } else if (isset($cx['blparam'][0])) {
607 1
                $ex = $cx['blparam'][0];
608
            }
609 45
            if (($context === '_NO_INPUT_HERE_') || ($context === $_this)) {
610 28
                $ret = $cb($cx, is_array($ex) ? static::m($cx, $_this, $ex) : $_this);
611
            } else {
612 20
                $cx['scopes'][] = $_this;
613 20
                $ret = $cb($cx, is_array($ex) ? static::m($cx, $context, $ex) : $context);
614 20
                array_pop($cx['scopes']);
615
            }
616 45
            if (isset($data['data'])) {
617 6
                $cx['sp_vars'] = $old_spvar;
618
            }
619 45
            return $cx['flags']['echo'] ? ob_get_clean() : $ret;
620
        };
621
622 56
        if ($else) {
623
            $options['inverse'] = function ($context = '_NO_INPUT_HERE_') use ($cx, $_this, $else) {
624 6
                if ($cx['flags']['echo']) {
625
                    ob_start();
626
                }
627 6
                if ($context === '_NO_INPUT_HERE_') {
628 1
                    $ret = $else($cx, $_this);
629
                } else {
630 5
                    $cx['scopes'][] = $_this;
631 5
                    $ret = $else($cx, $context);
632 5
                    array_pop($cx['scopes']);
633
                }
634 6
                return $cx['flags']['echo'] ? ob_get_clean() : $ret;
635 10
            };
636
        } else {
637
            $options['inverse'] = function () {
638
                return '';
639
            };
640
        }
641
642 56
        return static::exch($cx, $ch, $vars, $options);
643
    }
644
645
    /**
646
     * Execute custom helper with prepared options
647
     *
648
     * @param array<string,array|string|integer> $cx render time context for lightncandy
649
     * @param string $ch the name of custom helper to be executed
650
     * @param array<array|string|integer>|string|integer|null $vars variables for the helper
651
     * @param array<string,array|string|integer> $options the options object
652
     *
653
     * @return string The rendered string of the token
654
     */
655 165
    public static function exch($cx, $ch, $vars, &$options) {
656 165
        $args = $vars[0];
657 165
        $args[] = $options;
658 165
        $e = null;
659 165
        $r = true;
660
661
        try {
662 165
            $r = call_user_func_array($cx['helpers'][$ch], $args);
663 2
        } catch (\Exception $E) {
664 2
            $e = "Runtime: call custom helper '$ch' error: " . $E->getMessage();
665
        }
666
667 165
        if($e !== null) {
668 2
            static::err($cx, $e);
669
        }
670
671 164
        return $r;
672
    }
673
}
674