1 <?php
2 /**
3 * Part of the Joomla Framework Application Package
4 *
5 * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
6 * @license GNU General Public License version 2 or later; see LICENSE
7 */
8
9 namespace Joomla\Application\Cli;
10
11 /**
12 * Class ColorStyle
13 *
14 * @since 1.0
15 */
16 final class ColorStyle
17 {
18 /**
19 * Known colors
20 *
21 * @var array
22 * @since 1.0
23 */
24 private static $knownColors = array(
25 'black' => 0,
26 'red' => 1,
27 'green' => 2,
28 'yellow' => 3,
29 'blue' => 4,
30 'magenta' => 5,
31 'cyan' => 6,
32 'white' => 7
33 );
34
35 /**
36 * Known styles
37 *
38 * @var array
39 * @since 1.0
40 */
41 private static $knownOptions = array(
42 'bold' => 1,
43 'underscore' => 4,
44 'blink' => 5,
45 'reverse' => 7,
46 );
47
48 /**
49 * Foreground base value
50 *
51 * @var integer
52 * @since 1.0
53 */
54 private static $fgBase = 30;
55
56 /**
57 * Background base value
58 *
59 * @var integer
60 * @since 1.0
61 */
62 private static $bgBase = 40;
63
64 /**
65 * Foreground color
66 *
67 * @var integer
68 * @since 1.0
69 */
70 private $fgColor = 0;
71
72 /**
73 * Background color
74 *
75 * @var integer
76 * @since 1.0
77 */
78 private $bgColor = 0;
79
80 /**
81 * Array of style options
82 *
83 * @var array
84 * @since 1.0
85 */
86 private $options = array();
87
88 /**
89 * Constructor
90 *
91 * @param string $fg Foreground color.
92 * @param string $bg Background color.
93 * @param array $options Style options.
94 *
95 * @since 1.0
96 * @throws \InvalidArgumentException
97 */
98 public function __construct($fg = '', $bg = '', $options = array())
99 {
100 if ($fg)
101 {
102 if (false == array_key_exists($fg, static::$knownColors))
103 {
104 throw new \InvalidArgumentException(
105 sprintf('Invalid foreground color "%1$s" [%2$s]',
106 $fg,
107 implode(', ', $this->getKnownColors())
108 )
109 );
110 }
111
112 $this->fgColor = static::$fgBase + static::$knownColors[$fg];
113 }
114
115 if ($bg)
116 {
117 if (false == array_key_exists($bg, static::$knownColors))
118 {
119 throw new \InvalidArgumentException(
120 sprintf('Invalid background color "%1$s" [%2$s]',
121 $bg,
122 implode(', ', $this->getKnownColors())
123 )
124 );
125 }
126
127 $this->bgColor = static::$bgBase + static::$knownColors[$bg];
128 }
129
130 foreach ($options as $option)
131 {
132 if (false == array_key_exists($option, static::$knownOptions))
133 {
134 throw new \InvalidArgumentException(
135 sprintf('Invalid option "%1$s" [%2$s]',
136 $option,
137 implode(', ', $this->getKnownOptions())
138 )
139 );
140 }
141
142 $this->options[] = $option;
143 }
144 }
145
146 /**
147 * Convert to a string.
148 *
149 * @return string
150 *
151 * @since 1.0
152 */
153 public function __toString()
154 {
155 return $this->getStyle();
156 }
157
158 /**
159 * Create a color style from a parameter string.
160 *
161 * Example: fg=red;bg=blue;options=bold,blink
162 *
163 * @param string $string The parameter string.
164 *
165 * @return ColorStyle Instance of $this to allow chaining.
166 *
167 * @since 1.0
168 * @throws \RuntimeException
169 */
170 public static function fromString($string)
171 {
172 $fg = '';
173 $bg = '';
174 $options = array();
175
176 $parts = explode(';', $string);
177
178 foreach ($parts as $part)
179 {
180 $subParts = explode('=', $part);
181
182 if (count($subParts) < 2)
183 {
184 continue;
185 }
186
187 switch ($subParts[0])
188 {
189 case 'fg':
190 $fg = $subParts[1];
191 break;
192
193 case 'bg':
194 $bg = $subParts[1];
195 break;
196
197 case 'options':
198 $options = explode(',', $subParts[1]);
199 break;
200
201 default:
202 throw new \RuntimeException('Invalid option');
203 break;
204 }
205 }
206
207 return new self($fg, $bg, $options);
208 }
209
210 /**
211 * Get the translated color code.
212 *
213 * @return string
214 *
215 * @since 1.0
216 */
217 public function getStyle()
218 {
219 $values = array();
220
221 if ($this->fgColor)
222 {
223 $values[] = $this->fgColor;
224 }
225
226 if ($this->bgColor)
227 {
228 $values[] = $this->bgColor;
229 }
230
231 foreach ($this->options as $option)
232 {
233 $values[] = static::$knownOptions[$option];
234 }
235
236 return implode(';', $values);
237 }
238
239 /**
240 * Get the known colors.
241 *
242 * @return string
243 *
244 * @since 1.0
245 */
246 public function getKnownColors()
247 {
248 return array_keys(static::$knownColors);
249 }
250
251 /**
252 * Get the known options.
253 *
254 * @return array
255 *
256 * @since 1.0
257 */
258 public function getKnownOptions()
259 {
260 return array_keys(static::$knownOptions);
261 }
262 }
263