Fixed bug #15456: Changes made by ColorPicker Wizard are not saved (Thanks to Tobias...
[Packages/TYPO3.CMS.git] / typo3 / wizard_colorpicker.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Colorpicker wizard
29 *
30 * $Id $
31 * Revised for TYPO3 3.7 May/2004 by Kasper Skårhøj
32 *
33 * @author Mathias Schreiber <schreiber@wmdb.de>
34 * @author Peter Kühn <peter@kuehn.com>
35 * @author Kasper Skårhøj <typo3@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 75: class SC_wizard_colorpicker
43 * 103: function init()
44 * 182: function main()
45 * 233: function printContent()
46 * 246: function frameSet()
47 *
48 * SECTION: Rendering of various color selectors
49 * 305: function colorMatrix()
50 * 354: function colorList()
51 * 384: function colorImage()
52 * 417: function getIndex($im,$x,$y)
53 *
54 * TOTAL FUNCTIONS: 8
55 * (This index is automatically created/updated by the extension "extdeveval")
56 *
57 */
58
59
60 $BACK_PATH = '';
61 require('init.php');
62 require('template.php');
63 $LANG->includeLLFile('EXT:lang/locallang_wizards.xml');
64
65 /**
66 * Script Class for colorpicker wizard
67 *
68 * @author Mathias Schreiber <schreiber@wmdb.de>
69 * @author Peter Kühn <peter@kuehn.com>
70 * @author Kasper Skårhøj <typo3@typo3.com>
71 * @package TYPO3
72 * @subpackage core
73 */
74 class SC_wizard_colorpicker {
75
76 // GET vars:
77 var $P; // Wizard parameters, coming from TCEforms linking to the wizard.
78 var $colorValue; // Value of the current color picked.
79 var $fieldChangeFunc; // Serialized functions for changing the field... Necessary to call when the value is transferred to the TCEform since the form might need to do internal processing. Otherwise the value is simply not be saved.
80 protected $fieldChangeFuncHash;
81 var $fieldName; // Form name (from opener script)
82 var $formName; // Field name (from opener script)
83 var $md5ID; // ID of element in opener script for which to set color.
84 var $showPicker; // Internal: If false, a frameset is rendered, if true the content of the picker script.
85
86 // Static:
87 var $HTMLcolorList = "aqua,black,blue,fuchsia,gray,green,lime,maroon,navy,olive,purple,red,silver,teal,yellow,white";
88
89 // Internal:
90 var $pickerImage = '';
91 var $imageError = ''; // Error message if image not found.
92
93 /**
94 * document template object
95 *
96 * @var smallDoc
97 */
98 var $doc;
99 var $content; // Accumulated content.
100
101
102
103
104 /**
105 * Initialises the Class
106 *
107 * @return void
108 */
109 function init() {
110 global $BACK_PATH, $LANG;
111
112 // Setting GET vars (used in frameset script):
113 $this->P = t3lib_div::_GP('P',1);
114
115 // Setting GET vars (used in colorpicker script):
116 $this->colorValue = t3lib_div::_GP('colorValue');
117 $this->fieldChangeFunc = t3lib_div::_GP('fieldChangeFunc');
118 $this->fieldChangeFuncHash = t3lib_div::_GP('fieldChangeFuncHash');
119 $this->fieldName = t3lib_div::_GP('fieldName');
120 $this->formName = t3lib_div::_GP('formName');
121 $this->md5ID = t3lib_div::_GP('md5ID');
122 $this->exampleImg = t3lib_div::_GP('exampleImg');
123
124
125 // Resolving image (checking existence etc.)
126 $this->imageError = '';
127 if ($this->exampleImg) {
128 $this->pickerImage = t3lib_div::getFileAbsFileName($this->exampleImg,1,1);
129 if (!$this->pickerImage || !@is_file($this->pickerImage)) {
130 $this->imageError = 'ERROR: The image, "'.$this->exampleImg.'", could not be found!';
131 }
132 }
133
134 // Setting field-change functions:
135 $fieldChangeFuncArr = unserialize($this->fieldChangeFunc);
136 $update = '';
137 if ($this->areFieldChangeFunctionsValid()) {
138 unset($fieldChangeFuncArr['alert']);
139 foreach($fieldChangeFuncArr as $v) {
140 $update.= '
141 parent.opener.'.$v;
142 }
143 }
144
145 // Initialize document object:
146 $this->doc = t3lib_div::makeInstance('smallDoc');
147 $this->doc->backPath = $BACK_PATH;
148 $this->doc->JScode = $this->doc->wrapScriptTags('
149 function checkReference() { //
150 if (parent.opener && parent.opener.document && parent.opener.document.'.$this->formName.' && parent.opener.document.'.$this->formName.'["'.$this->fieldName.'"]) {
151 return parent.opener.document.'.$this->formName.'["'.$this->fieldName.'"];
152 } else {
153 close();
154 }
155 }
156 function changeBGcolor(color) { // Changes the color in the table sample back in the TCEform.
157 if (parent.opener.document.layers) {
158 parent.opener.document.layers["'.$this->md5ID.'"].bgColor = color;
159 } else if (parent.opener.document.all) {
160 parent.opener.document.all["'.$this->md5ID.'"].style.background = color;
161 } else if (parent.opener.document.getElementById && parent.opener.document.getElementById("'.$this->md5ID.'")) {
162 parent.opener.document.getElementById("'.$this->md5ID.'").bgColor = color;
163 }
164 }
165 function setValue(input) { //
166 var field = checkReference();
167 if (field) {
168 field.value = input;
169 '.$update.'
170 changeBGcolor(input);
171 }
172 }
173 function getValue() { //
174 var field = checkReference();
175 return field.value;
176 }
177 ');
178
179 // Start page:
180 $this->content.=$this->doc->startPage($LANG->getLL('colorpicker_title'));
181 }
182
183 /**
184 * Main Method, rendering either colorpicker or frameset depending on ->showPicker
185 *
186 * @return void
187 */
188 function main() {
189 global $LANG;
190
191 if(!t3lib_div::_GP('showPicker')) { // Show frameset by default:
192 $this->frameSet();
193 } else {
194
195 // Putting together the items into a form:
196 $content = '
197 <form name="colorform" method="post" action="wizard_colorpicker.php">
198 '.$this->colorMatrix().'
199 '.$this->colorList().'
200 '.$this->colorImage().'
201
202 <!-- Value box: -->
203 <p class="c-head">'.$LANG->getLL('colorpicker_colorValue',1).'</p>
204 <table border="0" cellpadding="0" cellspacing="3">
205 <tr>
206 <td><input type="text" '.$this->doc->formWidth(7).' maxlength="10" name="colorValue" value="'.htmlspecialchars($this->colorValue).'" /></td>
207 <td style="background-color:'.htmlspecialchars($this->colorValue).'; border: 1px solid black;">&nbsp;<span style="color: black;">'.$LANG->getLL('colorpicker_black',1).'</span>&nbsp;<span style="color: white;">'.$LANG->getLL('colorpicker_white',1).'</span>&nbsp;</td>
208 <td><input type="submit" name="save_close" value="'.$LANG->getLL('colorpicker_setClose',1).'" /></td>
209 </tr>
210 </table>
211
212 <!-- Hidden fields with values that has to be kept constant -->
213 <input type="hidden" name="showPicker" value="1" />
214 <input type="hidden" name="fieldChangeFunc" value="'.htmlspecialchars($this->fieldChangeFunc).'" />
215 <input type="hidden" name="fieldChangeFuncHash" value="'.htmlspecialchars($this->fieldChangeFuncHash).'" />
216 <input type="hidden" name="fieldName" value="'.htmlspecialchars($this->fieldName).'" />
217 <input type="hidden" name="formName" value="'.htmlspecialchars($this->formName).'" />
218 <input type="hidden" name="md5ID" value="'.htmlspecialchars($this->md5ID).'" />
219 <input type="hidden" name="exampleImg" value="'.htmlspecialchars($this->exampleImg).'" />
220 </form>';
221
222 // If the save/close button is clicked, then close:
223 if(t3lib_div::_GP('save_close')) {
224 $content.=$this->doc->wrapScriptTags('
225 setValue(\''.$this->colorValue.'\');
226 parent.close();
227 ');
228 }
229
230 // Output:
231 $this->content.=$this->doc->section($LANG->getLL('colorpicker_title'), $content, 0,1);
232 }
233 }
234
235 /**
236 * Returnes the sourcecode to the browser
237 *
238 * @return void
239 */
240 function printContent() {
241 $this->content.= $this->doc->endPage();
242 $this->content = $this->doc->insertStylesAndJS($this->content);
243 echo $this->content;
244 }
245
246 /**
247 * Returnes a frameset so our JavaScript Reference isn't lost
248 * Took some brains to figure this one out ;-)
249 * If Peter wouldn't have been I would've gone insane...
250 *
251 * @return void
252 */
253 function frameSet() {
254 global $LANG;
255
256 // Set doktype:
257 $GLOBALS['TBE_TEMPLATE']->docType = 'xhtml_frames';
258 $GLOBALS['TBE_TEMPLATE']->JScode = $GLOBALS['TBE_TEMPLATE']->wrapScriptTags('
259 if (!window.opener) {
260 alert("ERROR: Sorry, no link to main window... Closing");
261 close();
262 }
263 ');
264
265 $this->content = $GLOBALS['TBE_TEMPLATE']->startPage($LANG->getLL('colorpicker_title'));
266
267 // URL for the inner main frame:
268 $url = 'wizard_colorpicker.php?showPicker=1'.
269 '&colorValue='.rawurlencode($this->P['currentValue']).
270 '&fieldName='.rawurlencode($this->P['itemName']).
271 '&formName='.rawurlencode($this->P['formName']).
272 '&exampleImg='.rawurlencode($this->P['exampleImg']).
273 '&md5ID='.rawurlencode($this->P['md5ID']).
274 '&fieldChangeFunc='.rawurlencode(serialize($this->P['fieldChangeFunc'])) .
275 '&fieldChangeFuncHash=' . $this->P['fieldChangeFuncHash'];
276
277 $this->content.='
278 <frameset rows="*,1" framespacing="0" frameborder="0" border="0">
279 <frame name="content" src="'.htmlspecialchars($url).'" marginwidth="0" marginheight="0" frameborder="0" scrolling="auto" noresize="noresize" />
280 <frame name="menu" src="dummy.php" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" noresize="noresize" />
281 </frameset>
282 ';
283
284 $this->content.='
285 </html>';
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302 /************************************
303 *
304 * Rendering of various color selectors
305 *
306 ************************************/
307
308 /**
309 * Creates a color matrix table
310 *
311 * @return void
312 */
313 function colorMatrix() {
314 global $LANG;
315
316 $steps = 51;
317
318 // Get colors:
319 $color = array();
320
321 for($rr=0;$rr<256;$rr+=$steps) {
322 for($gg=0;$gg<256;$gg+=$steps) {
323 for($bb=0;$bb<256;$bb+=$steps) {
324 $color[] = '#'.
325 substr('0'.dechex($rr),-2).
326 substr('0'.dechex($gg),-2).
327 substr('0'.dechex($bb),-2);
328 }
329 }
330 }
331
332 // Traverse colors:
333 $columns = 24;
334
335 $rows = 0;
336 $tRows = array();
337 while(isset($color[$columns*$rows])) {
338 $tCells = array();
339 for($i=0;$i<$columns;$i++) {
340 $tCells[] = '
341 <td bgcolor="'.$color[$columns*$rows+$i].'" onclick="document.colorform.colorValue.value = \''.$color[$columns*$rows+$i].'\'; document.colorform.submit();" title="'.$color[$columns*$rows+$i].'">&nbsp;&nbsp;</td>';
342 }
343 $tRows[] = '
344 <tr>'.implode('',$tCells).'
345 </tr>';
346 $rows++;
347 }
348
349 $table = '
350 <p class="c-head">'.$LANG->getLL('colorpicker_fromMatrix',1).'</p>
351 <table border="0" cellpadding="1" cellspacing="1" style="width:100%; border: 1px solid black; cursor:crosshair;">'.implode('',$tRows).'
352 </table>';
353
354 return $table;
355 }
356
357 /**
358 * Creates a selector box with all HTML color names.
359 *
360 * @return void
361 */
362 function colorList() {
363 global $LANG;
364
365 // Initialize variables:
366 $colors = explode(',',$this->HTMLcolorList);
367 $currentValue = strtolower($this->colorValue);
368 $opt = array();
369 $opt[] = '<option value=""></option>';
370
371 // Traverse colors, making option tags for selector box.
372 foreach($colors as $colorName) {
373 $opt[] = '<option style="background-color: '.$colorName.';" value="'.htmlspecialchars($colorName).'"'.($currentValue==$colorName ? ' selected="selected"' : '').'>'.htmlspecialchars($colorName).'</option>';
374 }
375
376 // Compile selector box and return result:
377 $output = '
378 <p class="c-head">'.$LANG->getLL('colorpicker_fromList',1).'</p>
379 <select onchange="document.colorform.colorValue.value = this.options[this.selectedIndex].value; document.colorform.submit(); return false;">
380 '.implode('
381 ',$opt).'
382 </select><br />';
383
384 return $output;
385 }
386
387 /**
388 * Creates a color image selector
389 *
390 * @return void
391 */
392 function colorImage() {
393 global $LANG;
394
395 // Handling color-picker image if any:
396 if (!$this->imageError) {
397 if ($this->pickerImage) {
398 if(t3lib_div::_POST('coords_x')) {
399 $this->colorValue = '#'.$this->getIndex(t3lib_stdgraphic::imageCreateFromFile($this->pickerImage),t3lib_div::_POST('coords_x'),t3lib_div::_POST('coords_y'));
400 }
401 $pickerFormImage = '
402 <p class="c-head">'.$LANG->getLL('colorpicker_fromImage',1).'</p>
403 <input type="image" src="../'.substr($this->pickerImage,strlen(PATH_site)).'" name="coords" style="cursor:crosshair;" /><br />';
404 } else {
405 $pickerFormImage = '';
406 }
407 } else {
408 $pickerFormImage = '
409 <p class="c-head">'.htmlspecialchars($this->imageError).'</p>';
410 }
411
412 return $pickerFormImage;
413 }
414
415 /**
416 * Gets the HTML (Hex) Color Code for the selected pixel of an image
417 * This method handles the correct imageResource no matter what format
418 *
419 * @param pointer Valid ImageResource returned by t3lib_stdgraphic::imageCreateFromFile
420 * @param integer X-Coordinate of the pixel that should be checked
421 * @param integer Y-Coordinate of the pixel that should be checked
422 * @return string HEX RGB value for color
423 * @see colorImage()
424 */
425 function getIndex($im,$x,$y) {
426 $rgb = ImageColorAt($im, $x, $y);
427 $colorrgb = imagecolorsforindex($im,$rgb);
428 $index['r'] = dechex($colorrgb['red']);
429 $index['g'] = dechex($colorrgb['green']);
430 $index['b'] = dechex($colorrgb['blue']);
431 foreach ($index as $value) {
432 if(strlen($value) == 1) {
433 $hexvalue[] = strtoupper('0'.$value);
434 } else {
435 $hexvalue[] = strtoupper($value);
436 }
437 }
438 $hex = implode('',$hexvalue);
439 return $hex;
440 }
441
442 /**
443 * Determines whether submitted field change functions are valid
444 * and are coming from the system and not from an external abuse.
445 *
446 * @return boolean Whether the submitted field change functions are valid
447 */
448 protected function areFieldChangeFunctionsValid() {
449 return (
450 $this->fieldChangeFunc && $this->fieldChangeFuncHash
451 && $this->fieldChangeFuncHash == t3lib_div::hmac($this->fieldChangeFunc)
452 );
453 }
454 }
455
456
457 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/wizard_colorpicker.php']) {
458 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/wizard_colorpicker.php']);
459 }
460
461
462
463 // Make instance:
464 $SOBE = t3lib_div::makeInstance('SC_wizard_colorpicker');
465 $SOBE->init();
466 $SOBE->main();
467 $SOBE->printContent();
468
469 ?>