TYPO3 CMS  TYPO3_8-7
ColorpickerController.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
24 
33 {
40 
46  public $colorValue;
47 
56 
61 
67  public $fieldName;
68 
74  public $formName;
75 
81  public $md5ID;
82 
88  public $showPicker;
89 
93  public $HTMLcolorList = 'aqua,black,blue,fuchsia,gray,green,lime,maroon,navy,olive,purple,red,silver,teal,yellow,white';
94 
98  public $pickerImage = '';
99 
105  public $imageError = '';
106 
112  public $doc;
113 
117  public $content;
118 
122  protected $exampleImg;
123 
129  public function __construct()
130  {
132  parent::__construct();
133  $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_wizards.xlf');
134  $GLOBALS['SOBE'] = $this;
135 
136  $this->init();
137  }
138 
142  protected function init()
143  {
144  // Setting GET vars (used in frameset script):
145  $this->wizardParameters = GeneralUtility::_GP('P');
146  // Setting GET vars (used in colorpicker script):
147  $this->colorValue = GeneralUtility::_GP('colorValue');
148  $this->fieldChangeFunc = GeneralUtility::_GP('fieldChangeFunc');
149  $this->fieldChangeFuncHash = GeneralUtility::_GP('fieldChangeFuncHash');
150  $this->fieldName = GeneralUtility::_GP('fieldName');
151  $this->formName = GeneralUtility::_GP('formName');
152  $this->md5ID = GeneralUtility::_GP('md5ID');
153  $this->exampleImg = GeneralUtility::_GP('exampleImg');
154  // Resolving image (checking existence etc.)
155  $this->imageError = '';
156  if ($this->exampleImg) {
157  $this->pickerImage = GeneralUtility::getFileAbsFileName($this->exampleImg);
158  if (!$this->pickerImage || !@is_file($this->pickerImage)) {
159  $this->imageError = 'ERROR: The image "' . $this->exampleImg . '" could not be found!';
160  }
161  }
162  $update = [];
163  if ($this->areFieldChangeFunctionsValid()) {
164  // Setting field-change functions:
165  $fieldChangeFuncArr = unserialize($this->fieldChangeFunc);
166  unset($fieldChangeFuncArr['alert']);
167  foreach ($fieldChangeFuncArr as $v) {
168  $update[] = 'parent.opener.' . $v;
169  }
170  }
171  // Initialize document object:
172  $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
173  $this->getPageRenderer()->loadRequireJsModule(
174  'TYPO3/CMS/Backend/Wizard/Colorpicker',
175  'function(Colorpicker) {
176  Colorpicker.setFieldChangeFunctions({
177  fieldChangeFunctions: function() {'
178  . implode('', $update) .
179  '}
180  });
181  }'
182  );
183  // Start page:
184  $this->content .= $this->doc->startPage($this->getLanguageService()->getLL('colorpicker_title'));
185  }
186 
195  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
196  {
197  $this->main();
198 
199  $this->content .= $this->doc->endPage();
200  $this->content = $this->doc->insertStylesAndJS($this->content);
201 
202  $response->getBody()->write($this->content);
203  return $response;
204  }
205 
209  public function main()
210  {
211  // Show frameset by default:
212  if (!GeneralUtility::_GP('showPicker')) {
213  $this->frameSet();
214  } else {
215  // Putting together the items into a form:
216  $content = '
217  <form name="colorform" method="post" action="' . htmlspecialchars(BackendUtility::getModuleUrl('wizard_colorpicker')) . '">
218  ' . $this->colorMatrix() . '
219  ' . $this->colorList() . '
220  ' . $this->colorImage() . '
221 
222  <!-- Value box: -->
223  <p class="c-head">' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_colorValue')) . '</p>
224  <table border="0" cellpadding="0" cellspacing="3">
225  <tr>
226  <td>
227  <input id="colorValue" type="text" ' . $this->doc->formWidth(7) . ' maxlength="10" name="colorValue" value="' . htmlspecialchars($this->colorValue) . '" />
228  </td>
229  <td style="background-color:' . htmlspecialchars($this->colorValue) . '; border: 1px solid black;">
230  <span style="color: black;">' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_black')) . '</span>&nbsp;<span style="color: white;">' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_white')) . '</span>
231  </td>
232  <td>
233  <input class="btn btn-default" type="submit" id="colorpicker-saveclose" value="' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_setClose')) . '" />
234  </td>
235  </tr>
236  </table>
237 
238  <!-- Hidden fields with values that has to be kept constant -->
239  <input type="hidden" name="showPicker" value="1" />
240  <input type="hidden" name="fieldChangeFunc" value="' . htmlspecialchars($this->fieldChangeFunc) . '" />
241  <input type="hidden" name="fieldChangeFuncHash" value="' . htmlspecialchars($this->fieldChangeFuncHash) . '" />
242  <input type="hidden" name="fieldName" value="' . htmlspecialchars($this->fieldName) . '" />
243  <input type="hidden" name="formName" value="' . htmlspecialchars($this->formName) . '" />
244  <input type="hidden" name="md5ID" value="' . htmlspecialchars($this->md5ID) . '" />
245  <input type="hidden" name="exampleImg" value="' . htmlspecialchars($this->exampleImg) . '" />
246  </form>';
247 
248  $this->content .= '<h2>' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_title')) . '</h2>';
249  $this->content .= $content;
250  }
251  }
252 
258  public function frameSet()
259  {
260  $this->getDocumentTemplate()->JScode = GeneralUtility::wrapJS('
261  if (!window.opener) {
262  alert("ERROR: Sorry, no link to main window... Closing");
263  close();
264  }
265  ');
266  $this->getDocumentTemplate()->startPage($this->getLanguageService()->getLL('colorpicker_title'));
267 
268  // URL for the inner main frame:
269  $url = BackendUtility::getModuleUrl(
270  'wizard_colorpicker',
271  [
272  'showPicker' => 1,
273  'colorValue' => $this->wizardParameters['currentValue'],
274  'fieldName' => $this->wizardParameters['itemName'],
275  'formName' => $this->wizardParameters['formName'],
276  'exampleImg' => $this->wizardParameters['exampleImg'],
277  'md5ID' => $this->wizardParameters['md5ID'],
278  'fieldChangeFunc' => serialize($this->wizardParameters['fieldChangeFunc']),
279  'fieldChangeFuncHash' => $this->wizardParameters['fieldChangeFuncHash'],
280  ]
281  );
282  $this->content = $this->getPageRenderer()->render(PageRenderer::PART_HEADER) . '
283  <frameset rows="*,1" framespacing="0" frameborder="0" border="0">
284  <frame name="content" src="' . htmlspecialchars($url) . '" marginwidth="0" marginheight="0" frameborder="0" scrolling="auto" noresize="noresize" />
285  <frame name="menu" src="' . htmlspecialchars(BackendUtility::getModuleUrl('dummy')) . '" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" noresize="noresize" />
286  </frameset>
287  </html>';
288  }
289 
290  /************************************
291  *
292  * Rendering of various color selectors
293  *
294  ************************************/
300  public function colorMatrix()
301  {
302  $steps = 51;
303  // Get colors:
304  $color = [];
305  for ($rr = 0; $rr < 256; $rr += $steps) {
306  for ($gg = 0; $gg < 256; $gg += $steps) {
307  for ($bb = 0; $bb < 256; $bb += $steps) {
308  $color[] = '#' . substr(('0' . dechex($rr)), -2) . substr(('0' . dechex($gg)), -2) . substr(('0' . dechex($bb)), -2);
309  }
310  }
311  }
312  // Traverse colors:
313  $columns = 24;
314  $rows = 0;
315  $tRows = [];
316  while (isset($color[$columns * $rows])) {
317  $tCells = [];
318  for ($i = 0; $i < $columns; $i++) {
319  $tCells[] = '<td bgcolor="' . $color[$columns * $rows + $i] . '" class="t3js-colorpicker-value" data-color-value="' . htmlspecialchars($color[($columns * $rows + $i)]) . '" title="' . htmlspecialchars($color[($columns * $rows + $i)]) . '">&nbsp;&nbsp;</td>';
320  }
321  $tRows[] = '<tr>' . implode('', $tCells) . '</tr>';
322  $rows++;
323  }
324  return '<p class="c-head">' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_fromMatrix')) . '</p>
325  <table style="width:100%; border: 1px solid black; cursor:crosshair;">' . implode('', $tRows) . '</table>';
326  }
327 
333  public function colorList()
334  {
335  // Initialize variables:
336  $colors = explode(',', $this->HTMLcolorList);
337  $currentValue = strtolower($this->colorValue);
338  $opt = [];
339  $opt[] = '<option value=""></option>';
340  // Traverse colors, making option tags for selector box.
341  foreach ($colors as $colorName) {
342  $opt[] = '<option style="background-color: ' . $colorName . ';" value="' . htmlspecialchars($colorName) . '"' . ($currentValue === $colorName ? ' selected="selected"' : '') . '>' . htmlspecialchars($colorName) . '</option>';
343  }
344  // Compile selector box and return result:
345  return '<p class="c-head">' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_fromList')) . '</p>
346  <select class="t3js-colorpicker-selector">' . implode(LF, $opt) . '</select><br />';
347  }
348 
354  public function colorImage()
355  {
356  // Handling color-picker image if any:
357  if (!$this->imageError) {
358  if ($this->pickerImage) {
359  if (GeneralUtility::_POST('coords_x')) {
361  $image = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\GraphicalFunctions::class);
362  $this->colorValue = '#' . $this->getIndex($image->imageCreateFromFile($this->pickerImage), GeneralUtility::_POST('coords_x'), GeneralUtility::_POST('coords_y'));
363  }
364  $pickerFormImage = '
365  <p class="c-head">' . htmlspecialchars($this->getLanguageService()->getLL('colorpicker_fromImage')) . '</p>
366  <input type="image" src="' . PathUtility::getAbsoluteWebPath($this->pickerImage) . '" name="coords" style="cursor:crosshair;" /><br />';
367  } else {
368  $pickerFormImage = '';
369  }
370  } else {
371  $pickerFormImage = '
372  <p class="c-head">' . htmlspecialchars($this->imageError) . '</p>';
373  }
374  return $pickerFormImage;
375  }
376 
387  public function getIndex($im, $x, $y)
388  {
389  $rgb = imagecolorat($im, $x, $y);
390  $colorRgb = imagecolorsforindex($im, $rgb);
391  $index['r'] = dechex($colorRgb['red']);
392  $index['g'] = dechex($colorRgb['green']);
393  $index['b'] = dechex($colorRgb['blue']);
394  $hexValue = [];
395  foreach ($index as $value) {
396  if (strlen($value) === 1) {
397  $hexValue[] = strtoupper('0' . $value);
398  } else {
399  $hexValue[] = strtoupper($value);
400  }
401  }
402  $hex = implode('', $hexValue);
403  return $hex;
404  }
405 
412  protected function areFieldChangeFunctionsValid()
413  {
414  return $this->fieldChangeFunc && $this->fieldChangeFuncHash && hash_equals(GeneralUtility::hmac($this->fieldChangeFunc), $this->fieldChangeFuncHash);
415  }
416 
420  protected function getPageRenderer()
421  {
422  return GeneralUtility::makeInstance(PageRenderer::class);
423  }
424 }
mainAction(ServerRequestInterface $request, ResponseInterface $response)
static getAbsoluteWebPath($targetPath)
Definition: PathUtility.php:40
static hmac($input, $additionalSecret='')
static getFileAbsFileName($filename, $_=null, $_2=null)
static makeInstance($className,... $constructorArguments)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']