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