Completed
Push — master ( c7f349...cbd67a )
by Remo
03:34
created

Css2Less::getVariables()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 11
ccs 9
cts 9
cp 1
rs 9.4286
cc 3
eloc 7
nc 3
nop 0
crap 3
1
<?php
2
3
namespace Ortic\Css2Less;
4
5
use Ortic\Css2Less\tokens\LessRuleList;
6
use Ortic\Css2Less\tokens\LessRule;
7
8
class Css2Less
9
{
10
    /**
11
     * @var string $cssContent
12
     */
13
    protected $cssContent;
14
15
    /**
16
     * @var \CssParser $parser
17
     */
18
    protected $parser;
19
20
    /**
21
     * Tokens.
22
     *
23
     * @var array
24
     */
25
    protected $tokens = [];
26
27
    /**
28
     * Nested CSS tree
29
     *
30
     * @var array
31
     */
32
    protected $lessTree = [];
33
34
    /**
35
     * List of CSS rules
36
     *
37
     * @var LessRuleList
38
     */
39
    protected $ruleSetList;
40
41
    /**
42
     * Variables.
43
     *
44
     * @var array
45
     */
46
    protected $variables = [];
47
48
    /**
49
     * Create a new parser object, use parameter to specify CSS you
50
     * wish to convert into a LESS file
51
     *
52
     * @param string $cssContent
53
     */
54 10
    public function __construct($cssContent)
55
    {
56 10
        $this->cssContent = $cssContent;
57 10
        $this->parser = new \CssParser($this->cssContent);
58 10
    }
59
60
    /**
61
     * Iterates through all tokens and extracts the values into variables
62
     */
63 1
    protected function extractVariables()
64
    {
65 1
        $properties = ['color', 'font-family'];
66 1
        foreach ($properties as $property) {
67 1
            $this->variables[$property] = [];
68 1
        }
69
70 1
        foreach ($this->tokens as $token) {
71 1
            if ($token instanceof \CssRulesetDeclarationToken) {
72 1
                if (in_array($token->Property, $properties)) {
73 1
                    if (!array_key_exists($token->Value, $this->variables[$token->Property])) {
74 1
                        $this->variables[$token->Property][$token->Value] = $token->Property . '_' . (count($this->variables[$token->Property]) + 1);
75
76 1
                    }
77 1
                    $token->Value = '$' . $this->variables[$token->Property][$token->Value];
78 1
                }
79 1
            }
80 1
        }
81 1
    }
82
83
    /**
84
     * Returns a string containing all variables to be printed in the output
85
     *
86
     * @return string
87
     */
88 1
    protected function getVariables()
89
    {
90 1
        $return = '';
91 1
        foreach ($this->variables as $properties) {
92 1
            foreach ($properties as $variable => $property) {
93 1
                $return .= "\${$property}: {$variable};\n";
94 1
            }
95 1
        }
96 1
        $return .= "\n";
97 1
        return $return;
98
    }
99
100
    /**
101
     * Returns a string containing the LESS content matching the CSS input
102
     * @return string
103
     */
104 10
    public function getLess($extractVariables = false)
105
    {
106
107 10
        $this->tokens = $this->parser->getTokens();
108
109
        // extract variables
110 10
        if ($extractVariables) {
111 1
            $this->extractVariables();
112 1
        }
113
114 10
        $this->buildNestedTree();
115
116 10
        $return = '';
117
118
        // print variables
119 10
        if ($extractVariables) {
120 1
            $return .= $this->getVariables();
121 1
        }
122
123 10
        foreach ($this->lessTree as $node) {
124
            // @TODO this format method shouldn't be in this class..
125 1
            $return .= $this->ruleSetList->formatTokenAsLess($node) . "\n";
126 10
        }
127
128 10
        $return .= $this->ruleSetList->lessify();
129
130 10
        return $return;
131
    }
132
133
    /**
134
     * Build a nested tree based on the flat CSS tokens
135
     */
136 10
    protected function buildNestedTree()
137
    {
138
        // this variable is true, if we're within a ruleset, e.g. p { .. here .. }
139
        // we have to normalize them
140 10
        $withinRulset = false;
141 10
        $ruleSet = null;
142 10
        $this->ruleSetList = new LessRuleList();
143
144 10
        foreach ($this->tokens as $token) {
145
            // we have to skip some tokens, their information is redundant
146 10
            if ($token instanceof \CssAtMediaStartToken ||
147
                $token instanceof \CssAtMediaEndToken
148 10
            ) {
149 1
                continue;
150
            }
151
152
            // we have to build a hierarchy with CssRulesetStartToken, CssRulesetEndToken
153 10
            if ($token instanceof \CssRulesetStartToken) {
154 10
                $withinRulset = true;
155 10
                $ruleSet = new LessRule($token->Selectors);
156 10
            } elseif ($token instanceof \CssRulesetEndToken) {
157 10
                $withinRulset = false;
158 10
                if ($ruleSet) {
159 10
                    $this->ruleSetList->addRule($ruleSet);
160 10
                }
161 10
                $ruleSet = null;
162 10
            } else {
163
                // as long as we're in a ruleset, we're adding all token to a custom array
164
                // this will be lessified once we've found CssRulesetEndToken and then added
165
                // to the actual $lessTree variable
166 10
                if ($withinRulset) {
167 10
                    $ruleSet->addToken($token);
168 10
                } else {
169 1
                    $this->lessTree[] = $token;
170
                }
171
            }
172 10
        }
173 10
    }
174
}
175