Completed
Push — master ( 14f6f1...9a86cf )
by Marcus
02:46
created

src/LesserPhp/Library/Functions.php (13 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace LesserPhp\Library;
4
5
use LesserPhp\Color\Converter;
6
use LesserPhp\Compiler;
7
use LesserPhp\Exception\GeneralException;
8
9
/**
10
 * lesserphp
11
 * https://www.maswaba.de/lesserphp
12
 *
13
 * LESS CSS compiler, adapted from http://lesscss.org
14
 *
15
 * Copyright 2013, Leaf Corcoran <[email protected]>
16
 * Copyright 2016, Marcus Schwarz <[email protected]>
17
 * Licensed under MIT or GPLv3, see LICENSE
18
 * @package LesserPhp
19
 */
20
class Functions
0 ignored issues
show
The property $lengths_to_base is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
21
{
22
23
    /**
24
     * @var \LesserPhp\Library\Assertions
25
     */
26
    private $assertions;
27
    /**
28
     * @var \LesserPhp\Library\Coerce
29
     */
30
    private $coerce;
31
32
    /**
33
     * @var \LesserPhp\Compiler
34
     */
35
    private $compiler;
36
37
    /**
38
     * @var \LesserPhp\Color\Converter
39
     */
40
    private $converter;
41
42
    static public $TRUE = ["keyword", "true"];
43
    static public $FALSE = ["keyword", "false"];
44
    static public $lengths = ["px", "m", "cm", "mm", "in", "pt", "pc"];
45
    static public $times = ["s", "ms"];
46
    static public $angles = ["rad", "deg", "grad", "turn"];
47
    static public $lengths_to_base = [1, 3779.52755906, 37.79527559, 3.77952756, 96, 1.33333333, 16];
48
49
50 49
    public function __construct(Assertions $assertions, Coerce $coerce, Compiler $compiler, Converter $converter)
51
    {
52 49
        $this->assertions = $assertions;
53 49
        $this->coerce = $coerce;
54 49
        $this->compiler = $compiler; // temporary solution to get it working
55 49
        $this->converter = $converter;
56 49
    }
57
58 1
    public function pow($args)
59
    {
60 1
        list($base, $exp) = $this->assertions->assertArgs($args, 2, "pow");
61
62
        return [
63 1
            "number",
64 1
            pow($this->assertions->assertNumber($base), $this->assertions->assertNumber($exp)),
65 1
            $args[2][0][2],
66
        ];
67
    }
68
69 1
    public function pi()
70
    {
71 1
        return M_PI;
72
    }
73
74 1
    public function mod($args)
75
    {
76 1
        list($a, $b) = $this->assertions->assertArgs($args, 2, "mod");
77
78 1
        return ["number", $this->assertions->assertNumber($a) % $this->assertions->assertNumber($b), $args[2][0][2]];
79
    }
80
81 1 View Code Duplication
    public function red($color)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
    {
83 1
        $color = $this->coerce->coerceColor($color);
84 1
        if ($color === null) {
85
            throw new GeneralException('color expected for red()');
86
        }
87
88 1
        return $color[1];
89
    }
90
91 1 View Code Duplication
    public function green($color)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
    {
93 1
        $color = $this->coerce->coerceColor($color);
94 1
        if ($color === null) {
95
            throw new GeneralException('color expected for green()');
96
        }
97
98 1
        return $color[2];
99
    }
100
101 1 View Code Duplication
    public function blue($color)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
    {
103 1
        $color = $this->coerce->coerceColor($color);
104 1
        if ($color === null) {
105
            throw new GeneralException('color expected for blue()');
106
        }
107
108 1
        return $color[3];
109
    }
110
111 2
    public function convert($args)
112
    {
113 2
        list($value, $to) = $this->assertions->assertArgs($args, 2, "convert");
114
115
        // If it's a keyword, grab the string version instead
116 2
        if (is_array($to) && $to[0] === "keyword") {
117 2
            $to = $to[1];
118
        }
119
120 2
        return $this->convertMe($value, $to);
121
    }
122
123 1
    public function abs($num)
124
    {
125 1
        return ["number", abs($this->assertions->assertNumber($num)), $num[2]];
126
    }
127
128 2 View Code Duplication
    public function min($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129
    {
130 2
        $values = $this->assertions->assertMinArgs($args, 1, "min");
131
132 1
        $first_format = $values[0][2];
133
134 1
        $min_index = 0;
135 1
        $min_value = $values[0][1];
136
137 1
        for ($a = 0, $max = count($values); $a < $max; $a++) {
138 1
            $converted = $this->convertMe($values[$a], $first_format);
139
140 1
            if ($converted[1] < $min_value) {
141 1
                $min_index = $a;
142 1
                $min_value = $values[$a][1];
143
            }
144
        }
145
146 1
        return $values[$min_index];
147
    }
148
149 3 View Code Duplication
    public function max($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150
    {
151 3
        $values = $this->assertions->assertMinArgs($args, 1, "max");
152
153 2
        $first_format = $values[0][2];
154
155 2
        $max_index = 0;
156 2
        $max_value = $values[0][1];
157
158 2
        for ($a = 0, $max = count($values); $a < $max; $a++) {
159 2
            $converted = $this->convertMe($values[$a], $first_format);
160
161 2
            if ($converted[1] > $max_value) {
162 1
                $max_index = $a;
163 1
                $max_value = $values[$a][1];
164
            }
165
        }
166
167 1
        return $values[$max_index];
168
    }
169
170 1
    public function tan($num)
171
    {
172 1
        return tan($this->assertions->assertNumber($num));
173
    }
174
175 1
    public function sin($num)
176
    {
177 1
        return sin($this->assertions->assertNumber($num));
178
    }
179
180 1
    public function cos($num)
181
    {
182 1
        return cos($this->assertions->assertNumber($num));
183
    }
184
185 1
    public function atan($num)
186
    {
187 1
        $num = atan($this->assertions->assertNumber($num));
188
189 1
        return ["number", $num, "rad"];
190
    }
191
192 1
    public function asin($num)
193
    {
194 1
        $num = asin($this->assertions->assertNumber($num));
195
196 1
        return ["number", $num, "rad"];
197
    }
198
199 1
    public function acos($num)
200
    {
201 1
        $num = acos($this->assertions->assertNumber($num));
202
203 1
        return ["number", $num, "rad"];
204
    }
205
206 1
    public function sqrt($num)
207
    {
208 1
        return sqrt($this->assertions->assertNumber($num));
209
    }
210
211 1
    public function extract($value)
212
    {
213 1
        list($list, $idx) = $this->assertions->assertArgs($value, 2, "extract");
214 1
        $idx = $this->assertions->assertNumber($idx);
215
        // 1 indexed
216 1
        if ($list[0] === "list" && isset($list[2][$idx - 1])) {
217 1
            return $list[2][$idx - 1];
218
        }
219
220 1
        return null;
221
    }
222
223 2
    public function isnumber($value)
224
    {
225 2
        return $this->toBool($value[0] === "number");
226
    }
227
228 1
    public function isstring($value)
229
    {
230 1
        return $this->toBool($value[0] === "string");
231
    }
232
233 3
    public function iscolor($value)
234
    {
235 3
        return $this->toBool($this->coerce->coerceColor($value));
236
    }
237
238 1
    public function iskeyword($value)
239
    {
240 1
        return $this->toBool($value[0] === "keyword");
241
    }
242
243 2
    public function ispixel($value)
244
    {
245 2
        return $this->toBool($value[0] === "number" && $value[2] === "px");
246
    }
247
248 1
    public function ispercentage($value)
249
    {
250 1
        return $this->toBool($value[0] === "number" && $value[2] === "%");
251
    }
252
253 1
    public function isem($value)
254
    {
255 1
        return $this->toBool($value[0] === "number" && $value[2] === "em");
256
    }
257
258
    public function isrem($value)
259
    {
260
        return $this->toBool($value[0] === "number" && $value[2] === "rem");
261
    }
262
263 1
    public function rgbahex($color)
264
    {
265 1
        $color = $this->coerce->coerceColor($color);
266 1
        if ($color === null) {
267
            throw new GeneralException("color expected for rgbahex");
268
        }
269
270 1
        return sprintf(
271 1
            "#%02x%02x%02x%02x",
272 1
            isset($color[4]) ? $color[4] * 255 : 255,
273 1
            $color[1],
274 1
            $color[2],
275 1
            $color[3]
276
        );
277
    }
278
279 1
    public function argb($color)
280
    {
281 1
        return $this->rgbahex($color);
282
    }
283
284
    /**
285
     * Given an url, decide whether to output a regular link or the base64-encoded contents of the file
286
     *
287
     * @param  array $value either an argument list (two strings) or a single string
288
     *
289
     * @return string        formatted url(), either as a link or base64-encoded
290
     */
291 1
    public function data_uri($value)
292
    {
293 1
        $mime = ($value[0] === 'list') ? $value[2][0][2] : null;
294 1
        $url = ($value[0] === 'list') ? $value[2][1][2][0] : $value[2][0];
295
296 1
        $fullpath = $this->findImport($url);
297
298 1
        if ($fullpath && ($fsize = filesize($fullpath)) !== false) {
299
            // IE8 can't handle data uris larger than 32KB
300 1
            if ($fsize / 1024 < 32) {
301 1
                if ($mime === null) {
302 1
                    $finfo = new \finfo(FILEINFO_MIME);
303 1
                    $mime = explode('; ', $finfo->file($fullpath));
304 1
                    $mime = $mime[0];
305
                }
306
307
                //todo find out why this suddenly breakes data-uri-test
308 1
                if ($mime !== null && $mime !== 'text/x-php') {
309
                    // fallback if the mime type is still unknown
310 1
                    $url = sprintf('data:%s;base64,%s', $mime, base64_encode(file_get_contents($fullpath)));
311
                }
312
            }
313
        }
314
315 1
        return 'url("' . $url . '")';
316
    }
317
318
    // utility func to unquote a string
319 13
    public function e($arg)
320
    {
321 13
        switch ($arg[0]) {
322 13
            case "list":
323 2
                $items = $arg[2];
324 2
                if (isset($items[0])) {
325 1
                    return $this->e($items[0]);
326
                }
327 1
                throw new GeneralException("unrecognised input");
328 12
            case "string":
329 12
                $arg[1] = "";
330
331 12
                return $arg;
332 6
            case "keyword":
333 3
                return $arg;
334
            default:
335 4
                return ["keyword", $this->compiler->compileValue($arg)];
336
        }
337
    }
338
339 1
    public function _sprintf($args)
340
    {
341 1
        if ($args[0] !== "list") {
342
            return $args;
343
        }
344 1
        $values = $args[2];
345 1
        $string = array_shift($values);
346 1
        $template = $this->compiler->compileValue($this->e($string));
347
348 1
        $i = 0;
349 1
        if (preg_match_all('/%[dsa]/', $template, $m)) {
350 1
            foreach ($m[0] as $match) {
351 1
                $val = isset($values[$i]) ?
352 1
                    $this->compiler->reduce($values[$i]) : ['keyword', ''];
353
354
                // lessjs compat, renders fully expanded color, not raw color
355 1
                $color = $this->coerce->coerceColor($val);
356 1
                if ($color !== null) {
357
                    $val = $color;
358
                }
359
360 1
                $i++;
361 1
                $rep = $this->compiler->compileValue($this->e($val));
362 1
                $template = preg_replace(
363 1
                    '/' . Compiler::pregQuote($match) . '/',
364
                    $rep,
365
                    $template,
366 1
                    1
367
                );
368
            }
369
        }
370
371 1
        $d = $string[0] === "string" ? $string[1] : '"';
372
373 1
        return ["string", $d, [$template]];
374
    }
375
376 1
    public function floor($arg)
377
    {
378 1
        $value = $this->assertions->assertNumber($arg);
379
380 1
        return ["number", floor($value), $arg[2]];
381
    }
382
383 1
    public function ceil($arg)
384
    {
385 1
        $value = $this->assertions->assertNumber($arg);
386
387 1
        return ["number", ceil($value), $arg[2]];
388
    }
389
390 1
    public function round($arg)
391
    {
392 1
        if ($arg[0] !== "list") {
393 1
            $value = $this->assertions->assertNumber($arg);
394
395 1
            return ["number", round($value), $arg[2]];
396
        } else {
397
            $value = $this->assertions->assertNumber($arg[2][0]);
398
            $precision = $this->assertions->assertNumber($arg[2][1]);
399
400
            return ["number", round($value, $precision), $arg[2][0][2]];
401
        }
402
    }
403
404 1
    public function unit($arg)
405
    {
406 1
        if ($arg[0] === "list") {
407 1
            list($number, $newUnit) = $arg[2];
408
409
            return [
410 1
                "number",
411 1
                $this->assertions->assertNumber($number),
412 1
                $this->compiler->compileValue($this->e($newUnit)),
413
            ];
414
        } else {
415 1
            return ["number", $this->assertions->assertNumber($arg), ""];
416
        }
417
    }
418
419
420 1 View Code Duplication
    public function darken($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
421
    {
422 1
        list($color, $delta) = $this->compiler->colorArgs($args);
423
424 1
        $hsl = $this->converter->toHSL($color);
425 1
        $hsl[3] = $this->converter->clamp($hsl[3] - $delta, 100);
426
427 1
        return $this->converter->toRGB($hsl);
428
    }
429
430 2 View Code Duplication
    public function lighten($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
431
    {
432 2
        list($color, $delta) = $this->compiler->colorArgs($args);
433
434 2
        $hsl = $this->converter->toHSL($color);
435 2
        $hsl[3] = $this->converter->clamp($hsl[3] + $delta, 100);
436
437 2
        return $this->converter->toRGB($hsl);
438
    }
439
440 1 View Code Duplication
    public function saturate($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
441
    {
442 1
        list($color, $delta) = $this->compiler->colorArgs($args);
443
444 1
        $hsl = $this->converter->toHSL($color);
445 1
        $hsl[2] = $this->converter->clamp($hsl[2] + $delta, 100);
446
447 1
        return $this->converter->toRGB($hsl);
448
    }
449
450 1 View Code Duplication
    public function desaturate($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
451
    {
452 1
        list($color, $delta) = $this->compiler->colorArgs($args);
453
454 1
        $hsl = $this->converter->toHSL($color);
455 1
        $hsl[2] = $this->converter->clamp($hsl[2] - $delta, 100);
456
457 1
        return $this->converter->toRGB($hsl);
458
    }
459
460 1
    public function spin($args)
461
    {
462 1
        list($color, $delta) = $this->compiler->colorArgs($args);
463
464 1
        $hsl = $this->converter->toHSL($color);
465
466 1
        $hsl[1] = $hsl[1] + $delta % 360;
467 1
        if ($hsl[1] < 0) {
468 1
            $hsl[1] += 360;
469
        }
470
471 1
        return $this->converter->toRGB($hsl);
472
    }
473
474 1 View Code Duplication
    public function fadeout($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
475
    {
476 1
        list($color, $delta) = $this->compiler->colorArgs($args);
477 1
        $color[4] = $this->converter->clamp((isset($color[4]) ? $color[4] : 1) - $delta / 100);
478
479 1
        return $color;
480
    }
481
482 1 View Code Duplication
    public function fadein($args)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
483
    {
484 1
        list($color, $delta) = $this->compiler->colorArgs($args);
485 1
        $color[4] = $this->converter->clamp((isset($color[4]) ? $color[4] : 1) + $delta / 100);
486
487 1
        return $color;
488
    }
489
490 1
    public function hue($color)
491
    {
492 1
        $hsl = $this->converter->toHSL($this->assertions->assertColor($color));
493
494 1
        return round($hsl[1]);
495
    }
496
497 1
    public function saturation($color)
498
    {
499 1
        $hsl = $this->converter->toHSL($this->assertions->assertColor($color));
500
501 1
        return round($hsl[2]);
502
    }
503
504
    /**
505
     * @param $color
506
     *
507
     * @return float
508
     */
509 1
    public function lightness($color)
510
    {
511 1
        $hsl = $this->converter->toHSL($this->assertions->assertColor($color));
512
513 1
        return round($hsl[3]);
514
    }
515
516
    /**
517
     * get the alpha of a color
518
     * defaults to 1 for non-colors or colors without an alpha
519
     *
520
     * @param array $value
521
     *
522
     * @return int|null
523
     */
524 2
    public function alpha($value)
525
    {
526 2
        $color = $this->coerce->coerceColor($value);
527 2
        if ($color !== null) {
528 1
            return isset($color[4]) ? $color[4] : 1;
529
        }
530
531 1
        return null;
532
    }
533
534
    // set the alpha of the color
535 1
    public function fade($args)
536
    {
537 1
        list($color, $alpha) = $this->compiler->colorArgs($args);
538 1
        $color[4] = $this->converter->clamp($alpha / 100.0);
539
540 1
        return $color;
541
    }
542
543 1
    public function percentage($arg)
544
    {
545 1
        $num = $this->assertions->assertNumber($arg);
546
547 1
        return ["number", $num * 100, "%"];
548
    }
549
550
    // mixes two colors by weight
551
    // mix(@color1, @color2, [@weight: 50%]);
552
    // http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method
553 1
    public function mix($args)
554
    {
555 1
        if ($args[0] !== "list" || count($args[2]) < 2) {
556
            throw new GeneralException("mix expects (color1, color2, weight)");
557
        }
558
559 1
        list($first, $second) = $args[2];
560 1
        $first = $this->assertions->assertColor($first);
561 1
        $second = $this->assertions->assertColor($second);
562
563 1
        $first_a = $this->alpha($first);
564 1
        $second_a = $this->alpha($second);
565
566 1
        if (isset($args[2][2])) {
567 1
            $weight = $args[2][2][1] / 100.0;
568
        } else {
569 1
            $weight = 0.5;
570
        }
571
572 1
        $w = $weight * 2 - 1;
573 1
        $a = $first_a - $second_a;
574
575 1
        $w1 = (($w * $a == -1 ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2.0;
576 1
        $w2 = 1.0 - $w1;
577
578
        $new = [
579 1
            'color',
580 1
            $w1 * $first[1] + $w2 * $second[1],
581 1
            $w1 * $first[2] + $w2 * $second[2],
582 1
            $w1 * $first[3] + $w2 * $second[3],
583
        ];
584
585 1
        if ($first_a != 1.0 || $second_a != 1.0) {
586 1
            $new[] = $first_a * $weight + $second_a * ($weight - 1);
587
        }
588
589 1
        return $this->compiler->fixColor($new);
590
    }
591
592 1
    public function contrast($args)
593
    {
594 1
        $darkColor = ['color', 0, 0, 0];
595 1
        $lightColor = ['color', 255, 255, 255];
596 1
        $threshold = 0.43;
597
598 1
        if ($args[0] === 'list') {
599 1
            $inputColor = (isset($args[2][0])) ? $this->assertions->assertColor($args[2][0]) : $lightColor;
600 1
            $darkColor = (isset($args[2][1])) ? $this->assertions->assertColor($args[2][1]) : $darkColor;
601 1
            $lightColor = (isset($args[2][2])) ? $this->assertions->assertColor($args[2][2]) : $lightColor;
602 1
            if (isset($args[2][3])) {
603 1
                if (isset($args[2][3][2]) && $args[2][3][2] === '%') {
604 1
                    $args[2][3][1] /= 100;
605 1
                    unset($args[2][3][2]);
606
                }
607 1
                $threshold = $this->assertions->assertNumber($args[2][3]);
608
            }
609
        } else {
610
            $inputColor = $this->assertions->assertColor($args);
611
        }
612
613 1
        $inputColor = $this->coerce->coerceColor($inputColor);
614 1
        $darkColor = $this->coerce->coerceColor($darkColor);
615 1
        $lightColor = $this->coerce->coerceColor($lightColor);
616
617
        //Figure out which is actually light and dark!
618 1
        if ($this->luma($darkColor) > $this->luma($lightColor)) {
619 1
            $t = $lightColor;
620 1
            $lightColor = $darkColor;
621 1
            $darkColor = $t;
622
        }
623
624 1
        $inputColor_alpha = $this->alpha($inputColor);
625 1
        if (($this->luma($inputColor) * $inputColor_alpha) < $threshold) {
626 1
            return $lightColor;
627
        }
628
629 1
        return $darkColor;
630
    }
631
632 1
    public function luma($color)
633
    {
634 1
        $color = $this->coerce->coerceColor($color);
635
636
        // todo why this changed semantics?
637 1
        return (0.2126 * $color[1] / 255) + (0.7152 * $color[2] / 255) + (0.0722 * $color[3] / 255);
638
        //return (0.2126 * $color[0] / 255) + (0.7152 * $color[1] / 255) + (0.0722 * $color[2] / 255);
639
    }
640
641
642 3
    public function convertMe($number, $to)
643
    {
644 3
        $value = $this->assertions->assertNumber($number);
645 3
        $from = $number[2];
646
647
        // easy out
648 3
        if ($from == $to) {
649 2
            return $number;
650
        }
651
652
        // check if the from value is a length
653 3
        if (($from_index = array_search($from, static::$lengths)) !== false) {
654
            // make sure to value is too
655 2
            if (in_array($to, static::$lengths)) {
656
                // do the actual conversion
657 1
                $to_index = array_search($to, static::$lengths);
658 1
                $px = $value * static::$lengths_to_base[$from_index];
659 1
                $result = $px * (1 / static::$lengths_to_base[$to_index]);
660
661 1
                $result = round($result, 8);
662
663 1
                return ["number", $result, $to];
664
            }
665
        }
666
667
        // do the same check for times
668 3
        if (in_array($from, static::$times) && in_array($to, static::$times)) {
669
            // currently only ms and s are valid
670 1
            if ($to === "ms") {
671 1
                $result = $value * 1000;
672
            } else {
673 1
                $result = $value / 1000;
674
            }
675
676 1
            $result = round($result, 8);
677
678 1
            return ["number", $result, $to];
679
        }
680
681
        // lastly check for an angle
682 3
        if (in_array($from, static::$angles)) {
683
            // convert whatever angle it is into degrees
684 1
            if ($from === "rad") {
685 1
                $deg = rad2deg($value);
686
            } else {
687 1
                if ($from === "turn") {
688 1
                    $deg = $value * 360;
689
                } else {
690 1
                    if ($from === "grad") {
691 1
                        $deg = $value / (400 / 360);
692
                    } else {
693 1
                        $deg = $value;
694
                    }
695
                }
696
            }
697
698
            // Then convert it from degrees into desired unit
699 1
            if ($to === "deg") {
700 1
                $result = $deg;
701
            }
702
703 1
            if ($to === "rad") {
704 1
                $result = deg2rad($deg);
705
            }
706
707 1
            if ($to === "turn") {
708 1
                $result = $value / 360;
709
            }
710
711 1
            if ($to === "grad") {
712 1
                $result = $value * (400 / 360);
713
            }
714
715 1
            $result = round($result, 8);
716
717 1
            return ["number", $result, $to];
718
        }
719
720
        // we don't know how to convert these
721 2
        throw new GeneralException("Cannot convert {$from} to {$to}");
722
    }
723
724
725 3
    public function toBool($a)
726
    {
727 3
        if ($a) {
728 2
            return static::$TRUE;
729
        } else {
730 3
            return static::$FALSE;
731
        }
732
    }
733
734
    /**
735
     * attempts to find the path of an import url, returns null for css files
736
     *
737
     * @param string $url
738
     *
739
     * @return null|string
740
     */
741 1 View Code Duplication
    public function findImport($url)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
742
    {
743 1
        foreach ($this->compiler->getImportDirs() as $dir) {
744 1
            $full = $dir . (substr($dir, -1) !== '/' ? '/' : '') . $url;
745 1
            if ($this->fileExists($file = $full . '.less') || $this->fileExists($file = $full)) {
746 1
                return $file;
747
            }
748
        }
749
750
        return null;
751
    }
752
753
    /**
754
     * @param string $name
755
     *
756
     * @return bool
757
     */
758 1
    public function fileExists($name)
759
    {
760 1
        return is_file($name);
761
    }
762
}
763