QuotedNode::compare()   B
last analyzed

Complexity

Conditions 5
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 6
nc 3
nop 1
1
<?php
2
3
/*
4
 * This file is part of the ILess
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace ILess\Node;
11
12
use ILess\Context;
13
use ILess\FileInfo;
14
use ILess\Node;
15
use ILess\Output\OutputInterface;
16
use ILess\Util;
17
18
/**
19
 * Quoted node.
20
 */
21
class QuotedNode extends Node implements ComparableInterface
22
{
23
    /**
24
     * The content.
25
     *
26
     * @var string
27
     */
28
    public $content;
29
30
    /**
31
     * The quote.
32
     *
33
     * @var string
34
     */
35
    public $quote;
36
37
    /**
38
     * Current index.
39
     *
40
     * @var int
41
     */
42
    public $index = 0;
43
44
    /**
45
     * Node type.
46
     *
47
     * @var string
48
     */
49
    protected $type = 'Quoted';
50
51
    /**
52
     * Escaped?
53
     *
54
     * @var bool
55
     */
56
    public $escaped = false;
57
58
    /**
59
     * Constructor.
60
     *
61
     * @param string $string The quote
62
     * @param string $content The string
63
     * @param bool $escaped Is the string escaped?
64
     * @param int $index Current index
65
     * @param FileInfo $currentFileInfo The current file info
66
     */
67
    public function __construct($string, $content = '', $escaped = false, $index = 0, FileInfo $currentFileInfo = null)
68
    {
69
        parent::__construct($content);
70
71
        $this->escaped = $escaped;
72
73
        $this->quote = isset($string[0]) ? $string[0] : '';
74
        $this->index = $index;
75
        $this->currentFileInfo = $currentFileInfo;
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    public function generateCSS(Context $context, OutputInterface $output)
82
    {
83
        if (!$this->escaped) {
84
            $output->add($this->quote, $this->currentFileInfo, $this->index);
85
        }
86
87
        $output->add($this->value);
0 ignored issues
show
Bug introduced by
It seems like $this->value can also be of type object<ILess\Node>; however, ILess\Output\OutputInterface::add() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
88
89
        if (!$this->escaped) {
90
            $output->add($this->quote);
91
        }
92
    }
93
94
    /**
95
     * @return bool
96
     */
97
    public function containsVariables()
98
    {
99
        return (bool) preg_match('/(`([^`]+)`)|@\{([\w-]+)\}/', $this->value);
100
    }
101
102
    /**
103
     * Compiles the node.
104
     *
105
     * @param Context $context The context
106
     * @param array|null $arguments Array of arguments
107
     * @param bool|null $important Important flag
108
     *
109
     * @return QuotedNode
110
     */
111
    public function compile(Context $context, $arguments = null, $important = null)
112
    {
113
        $value = $this->value;
114
115
        $iterativeReplace = function ($value, $regexp, $replacementFunc) {
116
            $evaluatedValue = $value;
117
            do {
118
                $value = $evaluatedValue;
119
                $evaluatedValue = preg_replace_callback($regexp, $replacementFunc, $value);
120
            } while ($value !== $evaluatedValue);
121
122
            return $evaluatedValue;
123
        };
124
125
        // javascript replacement
126
        $value = $iterativeReplace($value, '/`([^`]+)`/', function ($matches) use ($context) {
127
            $js = new JavascriptNode($matches[1], $this->index, true);
0 ignored issues
show
Documentation introduced by
$this->index is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
128
129
            return $js->compile($context)->value;
130
        });
131
132
        // interpolation replacement
133
        $value = $iterativeReplace($value, '/@\{([\w-]+)\}/', function ($matches) use (&$context) {
134
            $v = new VariableNode('@' . $matches[1], $this->index, $this->currentFileInfo);
135
            $canShorted = $context->canShortenColors;
136
            $context->canShortenColors = false;
137
            $v = $v->compile($context);
138
            $v = ($v instanceof QuotedNode) ? $v->value : $v->toCSS($context);
139
            $context->canShortenColors = $canShorted;
140
141
            return $v;
142
        });
143
144
        return new self($this->quote . $value . $this->quote, $value, $this->escaped, $this->index,
145
            $this->currentFileInfo);
146
    }
147
148
    /**
149
     * Compares with another node.
150
     *
151
     * @param Node $other
152
     *
153
     * @return int|null
154
     */
155
    public function compare(Node $other)
156
    {
157
        if ($other instanceof self && !$this->escaped && !$other->escaped) {
158
            return Util::numericCompare($this->value, $other->value);
159
        } else {
160
            $context = new Context();
161
162
            return $other->toCSS($context) === $this->toCSS($context) ? 0 : null;
163
        }
164
    }
165
}
166