1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Form
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * Color Form Field class for the Joomla Platform.
14 * This implementation is designed to be compatible with HTML5's `<input type="color">`
15 *
16 * @link http://www.w3.org/TR/html-markup/input.color.html
17 * @since 11.3
18 */
19 class JFormFieldColor extends JFormField
20 {
21 /**
22 * The form field type.
23 *
24 * @var string
25 * @since 11.3
26 */
27 protected $type = 'Color';
28
29 /**
30 * The control.
31 *
32 * @var mixed
33 * @since 3.2
34 */
35 protected $control = 'hue';
36
37 /**
38 * The format.
39 *
40 * @var string
41 * @since 3.6.0
42 */
43 protected $format = 'hex';
44
45 /**
46 * The keywords (transparent,initial,inherit).
47 *
48 * @var string
49 * @since 3.6.0
50 */
51 protected $keywords = '';
52
53 /**
54 * The position.
55 *
56 * @var mixed
57 * @since 3.2
58 */
59 protected $position = 'default';
60
61 /**
62 * The colors.
63 *
64 * @var mixed
65 * @since 3.2
66 */
67 protected $colors;
68
69 /**
70 * The split.
71 *
72 * @var integer
73 * @since 3.2
74 */
75 protected $split = 3;
76
77 /**
78 * Name of the layout being used to render the field
79 *
80 * @var string
81 * @since 3.5
82 */
83 protected $layout = 'joomla.form.field.color';
84
85 /**
86 * Method to get certain otherwise inaccessible properties from the form field object.
87 *
88 * @param string $name The property name for which to the the value.
89 *
90 * @return mixed The property value or null.
91 *
92 * @since 3.2
93 */
94 public function __get($name)
95 {
96 switch ($name)
97 {
98 case 'control':
99 case 'format':
100 case 'keywords':
101 case 'exclude':
102 case 'colors':
103 case 'split':
104 return $this->$name;
105 }
106
107 return parent::__get($name);
108 }
109
110 /**
111 * Method to set certain otherwise inaccessible properties of the form field object.
112 *
113 * @param string $name The property name for which to the the value.
114 * @param mixed $value The value of the property.
115 *
116 * @return void
117 *
118 * @since 3.2
119 */
120 public function __set($name, $value)
121 {
122 switch ($name)
123 {
124 case 'split':
125 $value = (int) $value;
126 case 'control':
127 case 'format':
128 $this->$name = (string) $value;
129 break;
130 case 'keywords':
131 $this->$name = (string) $value;
132 break;
133 case 'exclude':
134 case 'colors':
135 $this->$name = (string) $value;
136 break;
137
138 default:
139 parent::__set($name, $value);
140 }
141 }
142
143 /**
144 * Method to attach a JForm object to the field.
145 *
146 * @param SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
147 * @param mixed $value The form field value to validate.
148 * @param string $group The field name group control value. This acts as an array container for the field.
149 * For example if the field has name="foo" and the group value is set to "bar" then the
150 * full field name would end up being "bar[foo]".
151 *
152 * @return boolean True on success.
153 *
154 * @see JFormField::setup()
155 * @since 3.2
156 */
157 public function setup(SimpleXMLElement $element, $value, $group = null)
158 {
159 $return = parent::setup($element, $value, $group);
160
161 if ($return)
162 {
163 $this->control = isset($this->element['control']) ? (string) $this->element['control'] : 'hue';
164 $this->format = isset($this->element['format']) ? (string) $this->element['format'] : 'hex';
165 $this->keywords = isset($this->element['keywords']) ? (string) $this->element['keywords'] : '';
166 $this->position = isset($this->element['position']) ? (string) $this->element['position'] : 'default';
167 $this->colors = (string) $this->element['colors'];
168 $this->split = isset($this->element['split']) ? (int) $this->element['split'] : 3;
169 }
170
171 return $return;
172 }
173
174 /**
175 * Method to get the field input markup.
176 *
177 * @return string The field input markup.
178 *
179 * @since 11.3
180 */
181 protected function getInput()
182 {
183 // Switch the layouts
184 $this->layout = $this->control === 'simple' ? $this->layout . '.simple' : $this->layout . '.advanced';
185
186 // Trim the trailing line in the layout file
187 return rtrim($this->getRenderer($this->layout)->render($this->getLayoutData()), PHP_EOL);
188 }
189
190 /**
191 * Method to get the data to be passed to the layout for rendering.
192 *
193 * @return array
194 *
195 * @since 3.5
196 */
197 protected function getLayoutData()
198 {
199 $lang = JFactory::getLanguage();
200 $data = parent::getLayoutData();
201 $color = strtolower($this->value);
202 $color = ! $color ? '' : $color;
203
204 // Position of the panel can be: right (default), left, top or bottom (default RTL is left)
205 $position = ' data-position="' . (($lang->isRTL() && $this->position == 'default') ? 'left' : $this->position) . '"';
206
207 if (!$color || in_array($color, array('none', 'transparent')))
208 {
209 $color = 'none';
210 }
211 elseif ($color['0'] != '#' && $this->format == 'hex')
212 {
213 $color = '#' . $color;
214 }
215
216 // Assign data for simple/advanced mode
217 $controlModeData = $this->control === 'simple' ? $this->getSimpleModeLayoutData() : $this->getAdvancedModeLayoutData($lang);
218
219 $extraData = array(
220 'color' => $color,
221 'format' => $this->format,
222 'keywords' => $this->keywords,
223 'position' => $position,
224 'validate' => $this->validate
225 );
226
227 return array_merge($data, $extraData, $controlModeData);
228 }
229
230 /**
231 * Method to get the data for the simple mode to be passed to the layout for rendering.
232 *
233 * @return array
234 *
235 * @since 3.5
236 */
237 protected function getSimpleModeLayoutData()
238 {
239 $colors = strtolower($this->colors);
240
241 if (empty($colors))
242 {
243 $colors = array(
244 'none',
245 '#049cdb',
246 '#46a546',
247 '#9d261d',
248 '#ffc40d',
249 '#f89406',
250 '#c3325f',
251 '#7a43b6',
252 '#ffffff',
253 '#999999',
254 '#555555',
255 '#000000',
256 );
257 }
258 else
259 {
260 $colors = explode(',', $colors);
261 }
262
263 if (!$this->split)
264 {
265 $count = count($colors);
266 if ($count % 5 == 0)
267 {
268 $split = 5;
269 }
270 else
271 {
272 if ($count % 4 == 0)
273 {
274 $split = 4;
275 }
276 }
277 }
278
279 $split = $this->split ? $this->split : 3;
280
281 return array(
282 'colors' => $colors,
283 'split' => $split,
284 );
285 }
286
287 /**
288 * Method to get the data for the advanced mode to be passed to the layout for rendering.
289 *
290 * @param object $lang The language object
291 *
292 * @return array
293 *
294 * @since 3.5
295 */
296 protected function getAdvancedModeLayoutData($lang)
297 {
298 return array(
299 'colors' => $this->colors,
300 'control' => $this->control,
301 'lang' => $lang,
302 );
303 }
304 }
305