Style::convertToCodes()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3
1
<?php
2
3
namespace League\CLImate\Decorator;
4
5
use League\CLImate\Decorator\Parser\ParserFactory;
6
use League\CLImate\Util\Helper;
7
use League\CLImate\Util\System\System;
8
9
/**
10
 * @method void addColor(string $color, integer $code)
11
 * @method void addFormat(string $format, integer $code)
12
 * @method void addCommand(string $command, mixed $style)
13
 */
14
class Style
15
{
16
    /**
17
     * An array of Decorator objects
18
     *
19
     * @var Component\DecoratorInterface[] $style
20
     */
21
    protected $style = [];
22
23
    /**
24
     * An array of the available Decorators
25
     * and their corresponding class names
26
     *
27
     * @var array $available
28
     */
29
    protected $available = [
30
        'format'     =>  'Format',
31
        'color'      =>  'Color',
32
        'background' =>  'BackgroundColor',
33
        'command'    =>  'Command',
34
    ];
35
36
    protected $parser;
37
38
    /**
39
     * An array of the current styles applied
40
     *
41
     * @var array $current
42
     */
43
    protected $current = [];
44
45 948
    public function __construct()
46
    {
47 948
        foreach ($this->available as $key => $class) {
48 948
            $class = 'League\CLImate\Decorator\Component\\' . $class;
49 948
            $this->style[$key] = new $class();
50 948
        }
51 948
    }
52
53
    /**
54
     * Get all of the styles available
55
     *
56
     * @return array
57
     */
58 576
    public function all()
59
    {
60 576
        $all = [];
61
62 576
        foreach ($this->style as $style) {
63 576
            $all = array_merge($all, $this->convertToCodes($style->all()));
64 576
        }
65
66 576
        return $all;
67
    }
68
69
    /**
70
     * Attempt to get the corresponding code for the style
71
     *
72
     * @param  mixed $key
73
     *
74
     * @return mixed
75
     */
76 576
    public function get($key)
77
    {
78 576
        foreach ($this->style as $style) {
79 576
            if ($code = $style->get($key)) {
80 576
                return $code;
81
            }
82 576
        }
83
84
        return false;
85
    }
86
87
    /**
88
     * Attempt to set some aspect of the styling,
89
     * return true if attempt was successful
90
     *
91
     * @param  string   $key
92
     *
93
     * @return boolean
94
     */
95 112
    public function set($key)
96
    {
97 112
        foreach ($this->style as $style) {
98 112
            if ($code = $style->set($key)) {
99 112
                return $this->validateCode($code);
100
            }
101 92
        }
102
103
        return false;
104
    }
105
106
    /**
107
     * Reset the current styles applied
108
     *
109
     */
110 568
    public function reset()
111
    {
112 568
        foreach ($this->style as $style) {
113 568
            $style->reset();
114 568
        }
115 568
    }
116
117
    /**
118
     * Get a new instance of the Parser class based on the current settings
119
     *
120
     * @param \League\CLImate\Util\System\System $system
121
     *
122
     * @return \League\CLImate\Decorator\Parser\Parser
123
     */
124 568
    public function parser(System $system)
125
    {
126 568
        return ParserFactory::getInstance($system, $this->current(), new Tags($this->all()));
127
    }
128
129
    /**
130
     * Compile an array of the current codes
131
     *
132
     * @return array
133
     */
134 576
    public function current()
135
    {
136 576
        $full_current = [];
137
138 576
        foreach ($this->style as $style) {
139 576
            $full_current = array_merge($full_current, Helper::toArray($style->current()));
140 576
        }
141
142 576
        $full_current = array_filter($full_current);
143
144 576
        return array_values($full_current);
145
    }
146
147
    /**
148
     * Make sure that the code is an integer, if not let's try and get it there
149
     *
150
     * @param mixed $code
151
     *
152
     * @return boolean
153
     */
154 112
    protected function validateCode($code)
155
    {
156 112
        if (is_integer($code)) {
157
            return true;
158
        }
159
160
        // Plug it back in and see what we get
161 112
        if (is_string($code)) {
162 12
            return $this->set($code);
163
        }
164
165 112
        if (is_array($code)) {
166 4
            return $this->validateCodeArray($code);
167
        }
168
169 112
        return false;
170
    }
171
172
    /**
173
     * Validate an array of codes
174
     *
175
     * @param array $codes
176
     *
177
     * @return boolean
178
     */
179 4
    protected function validateCodeArray(array $codes)
180
    {
181
        // Loop through it and add each of the properties
182 4
        $adds = [];
183
184 4
        foreach ($codes as $code) {
185 4
            $adds[] = $this->set($code);
186 4
        }
187
188
        // If any of them came back true, we're good to go
189 4
        return in_array(true, $adds);
190
    }
191
192
    /**
193
     * Convert the array of codes to integers
194
     *
195
     * @param array $codes
196
     * @return array
197
     */
198 576
    protected function convertToCodes(array $codes)
199
    {
200 576
        foreach ($codes as $key => $code) {
201 576
            if (is_int($code)) {
202 576
                continue;
203
            }
204
205 576
            $codes[$key] = $this->getCode($code);
206 576
        }
207
208 576
        return $codes;
209
    }
210
211
    /**
212
     * Retrieve the integers from the mixed code input
213
     *
214
     * @param string|array $code
215
     *
216
     * @return integer|array
217
     */
218 576
    protected function getCode($code)
219
    {
220 576
        if (is_array($code)) {
221 8
            return $this->getCodeArray($code);
222
        }
223
224 576
        return $this->get($code);
225
    }
226
227
    /**
228
     * Retrieve an array of integers from the array of codes
229
     *
230
     * @param array $codes
231
     *
232
     * @return array
233
     */
234 8
    protected function getCodeArray(array $codes)
235
    {
236 8
        foreach ($codes as $key => $code) {
237 8
            $codes[$key] = $this->get($code);
238 8
        }
239
240 8
        return $codes;
241
    }
242
243
    /**
244
     * Parse the add method for the style they are trying to add
245
     *
246
     * @param string $method
247
     *
248
     * @return string
249
     */
250 28
    protected function parseAddMethod($method)
251
    {
252 28
        return strtolower(substr($method, 3, strlen($method)));
253
    }
254
255
    /**
256
     * Add a custom style
257
     *
258
     * @param string $style
259
     * @param string $key
260
     * @param string $value
261
     */
262 28
    protected function add($style, $key, $value)
263
    {
264 28
        $this->style[$style]->add($key, $value);
265
266
        // If we are adding a color, make sure it gets added
267
        // as a background color too
268 28
        if ($style == 'color') {
269 12
            $this->style['background']->add($key, $value);
270 12
        }
271 28
    }
272
273
    /**
274
     * Magic Methods
275
     *
276
     * List of possible magic methods are at the top of this class
277
     *
278
     * @param string $requested_method
279
     * @param array  $arguments
280
     */
281 28
    public function __call($requested_method, $arguments)
282
    {
283
        // The only methods we are concerned about are 'add' methods
284 28
        if (substr($requested_method, 0, 3) != 'add') {
285
            return false;
286
        }
287
288 28
        $style = $this->parseAddMethod($requested_method);
289
290 28
        if (array_key_exists($style, $this->style)) {
291 28
            list($key, $value) = $arguments;
292 28
            $this->add($style, $key, $value);
293 28
        }
294 28
    }
295
}
296