[TASK] Migrate eID scripts to use PSR-7
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / Classes / SelectImage.php
1 <?php
2 namespace TYPO3\CMS\Rtehtmlarea;
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
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Core\Resource;
19
20 /**
21 * Script Class
22 */
23 class SelectImage extends \TYPO3\CMS\Recordlist\Browser\ElementBrowser {
24
25 /**
26 * These file extensions are allowed in the "plain" image selection mode.
27 *
28 * @const
29 */
30 const PLAIN_MODE_IMAGE_FILE_EXTENSIONS = 'jpg,jpeg,gif,png';
31
32 /**
33 * @var string
34 */
35 public $extKey = 'rtehtmlarea';
36
37 /**
38 * @var string
39 */
40 public $content;
41
42 public $allowedItems;
43
44 public $allowedFileTypes = array();
45
46 protected $defaultClass;
47
48 /**
49 * Relevant for RTE mode "plain": the maximum width an image must have to be selectable.
50 *
51 * @var int
52 */
53 protected $plainMaxWidth;
54
55 /**
56 * Relevant for RTE mode "plain": the maximum height an image must have to be selectable.
57 *
58 * @var int
59 */
60 protected $plainMaxHeight;
61
62 protected $imgPath;
63
64 public $editorNo;
65
66 public $sys_language_content;
67
68 public $thisConfig;
69
70 public $buttonConfig;
71
72 protected $imgObj;
73
74 /**
75 * Initialisation
76 *
77 * @return void
78 */
79 public function init() {
80 $this->initVariables();
81 $this->initConfiguration();
82 $this->initHookObjects('ext/rtehtmlarea/mod4/class.tx_rtehtmlarea_select_image.php');
83 $this->allowedItems = $this->getAllowedItems('magic,plain,image');
84 // Insert the image and exit
85 $this->insertImage();
86 // or render dialogue
87 $this->initDocumentTemplate();
88 }
89
90 /**
91 * Initialize class variables
92 *
93 * @return void
94 */
95 public function initVariables() {
96 parent::initVariables();
97 // Get "act"
98 $this->act = GeneralUtility::_GP('act');
99 if (!$this->act) {
100 $this->act = FALSE;
101 }
102 $this->addModifyTab = GeneralUtility::_GP('addModifyTab');
103 // Process bparams
104 $pArr = explode('|', $this->bparams);
105 $pRteArr = explode(':', $pArr[1]);
106 $this->editorNo = $pRteArr[0];
107 $this->sys_language_content = $pRteArr[1];
108 $this->RTEtsConfigParams = $pArr[2];
109 if (!$this->editorNo) {
110 $this->editorNo = GeneralUtility::_GP('editorNo');
111 $this->sys_language_content = GeneralUtility::_GP('sys_language_content');
112 $this->RTEtsConfigParams = GeneralUtility::_GP('RTEtsConfigParams');
113 }
114 $pArr[1] = implode(':', array($this->editorNo, $this->sys_language_content));
115 $pArr[2] = $this->RTEtsConfigParams;
116 if ($this->act == 'dragdrop' || $this->act == 'plain') {
117 $this->allowedFileTypes = explode(',', self::PLAIN_MODE_IMAGE_FILE_EXTENSIONS);
118 }
119 $pArr[3] = implode(',', $this->allowedFileTypes);
120 $this->bparams = implode('|', $pArr);
121 }
122
123 /**
124 * Initialize document template object
125 *
126 * @return void
127 */
128 protected function initDocumentTemplate() {
129 parent::initDocumentTemplate();
130
131 $this->doc->bodyTagId = 'typo3-browse-links-php';
132 $this->doc->bodyTagAdditions = $this->getBodyTagAdditions();
133 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/LegacyTree', 'function(Tree) {
134 Tree.ajaxID = "SC_alt_file_navframe::expandCollapse";
135 }');
136 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Rtehtmlarea/Modules/SelectImage', 'function(SelectImage) {
137 SelectImage.editorNo = ' . GeneralUtility::quoteJSvalue($this->editorNo) . ';
138 SelectImage.act = ' . GeneralUtility::quoteJSvalue(($this->act ?: reset($this->allowedItems))) . ';
139 SelectImage.sys_language_content = ' . GeneralUtility::quoteJSvalue($this->sys_language_content) . ';
140 SelectImage.RTEtsConfigParams = ' . GeneralUtility::quoteJSvalue(rawurlencode($this->RTEtsConfigParams)) . ';
141 SelectImage.bparams = ' . GeneralUtility::quoteJSvalue($this->bparams) . ';
142 }');
143 $this->getPageRenderer()->addCssFile($this->doc->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('t3skin') . 'rtehtmlarea/htmlarea.css');
144 $this->doc->getContextMenuCode();
145 }
146
147 /**
148 * Provide the additional parameters to be included in the template body tag
149 *
150 * @return string the body tag additions
151 */
152 public function getBodyTagAdditions() {
153 return 'onload="SelectImage.initEventListeners();"';
154 }
155
156 /**
157 * Insert the image in the editing area
158 *
159 * @return void
160 */
161 protected function insertImage() {
162 $uidList = (string)GeneralUtility::_GP('uidList');
163 if (GeneralUtility::_GP('insertImage') && $uidList) {
164 $uids = explode('|', $uidList);
165 $insertJsStatements = array();
166 foreach ($uids as $uid) {
167 /** @var $fileObject Resource\File */
168 $fileObject = Resource\ResourceFactory::getInstance()->getFileObject((int)$uid);
169 // Get default values for alt and title attributes from file properties
170 $altText = $fileObject->getProperty('alternative');
171 $titleText = $fileObject->getProperty('title');
172 switch ($this->act) {
173 case 'magic':
174 $insertJsStatements[] = $this->insertMagicImage($fileObject, $altText, $titleText, 'data-htmlarea-file-uid="' . $uid . '"');
175 break;
176 case 'plain':
177 $insertJsStatements[] = $this->insertPlainImage($fileObject, $altText, $titleText, 'data-htmlarea-file-uid="' . $uid . '"');
178 break;
179 default:
180 // Call hook
181 foreach ($this->hookObjects as $hookObject) {
182 if (method_exists($hookObject, 'insertElement')) {
183 $hookObject->insertElement($this->act);
184 }
185 }
186 }
187 }
188 $this->insertImages($insertJsStatements);
189 die;
190 }
191 }
192
193 /**
194 * Insert a magic image
195 *
196 * @param Resource\File $fileObject: the image file
197 * @param string $altText: text for the alt attribute of the image
198 * @param string $titleText: text for the title attribute of the image
199 * @param string $additionalParams: text representing more HTML attributes to be added on the img tag
200 * @return string the magic image JS insertion statement
201 */
202 public function insertMagicImage(Resource\File $fileObject, $altText = '', $titleText = '', $additionalParams = '') {
203 // Create the magic image service
204 /** @var $magicImageService Resource\Service\MagicImageService */
205 $magicImageService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Service\MagicImageService::class);
206 $magicImageService->setMagicImageMaximumDimensions($this->thisConfig);
207 // Create the magic image
208 $imageConfiguration = array(
209 'width' => GeneralUtility::_GP('cWidth'),
210 'height' => GeneralUtility::_GP('cHeight')
211 );
212 $magicImage = $magicImageService->createMagicImage($fileObject, $imageConfiguration);
213 $imageUrl = $magicImage->getPublicUrl();
214 // If file is local, make the url absolute
215 if (substr($imageUrl, 0, 4) !== 'http') {
216 $imageUrl = $this->siteURL . $imageUrl;
217 }
218 // Insert the magic image
219 return $this->imageInsertJsStatement($imageUrl, $magicImage->getProperty('width'), $magicImage->getProperty('height'), $altText, $titleText, $additionalParams);
220 }
221
222 /**
223 * Insert a plain image
224 *
225 * @param \TYPO3\CMS\Core\Resource\File $fileObject: the image file
226 * @param string $altText: text for the alt attribute of the image
227 * @param string $titleText: text for the title attribute of the image
228 * @param string $additionalParams: text representing more HTML attributes to be added on the img tag
229 * @return string the plain image JS insertion statement
230 */
231 public function insertPlainImage(Resource\File $fileObject, $altText = '', $titleText = '', $additionalParams = '') {
232 $width = $fileObject->getProperty('width');
233 $height = $fileObject->getProperty('height');
234 if (!$width || !$height) {
235 $filePath = $fileObject->getForLocalProcessing(FALSE);
236 $imageInfo = @getimagesize($filePath);
237 $width = $imageInfo[0];
238 $height = $imageInfo[1];
239 }
240 $imageUrl = $fileObject->getPublicUrl();
241 // If file is local, make the url absolute
242 if (substr($imageUrl, 0, 4) !== 'http') {
243 $imageUrl = $this->siteURL . $imageUrl;
244 }
245 return $this->imageInsertJsStatement($imageUrl, $width, $height, $altText, $titleText, $additionalParams);
246 }
247
248 /**
249 * Assemble the image insertion JS statement
250 *
251 * @param string $url: the url of the image
252 * @param int $width: the width of the image
253 * @param int $height: the height of the image
254 * @param string $altText: text for the alt attribute of the image
255 * @param string $titleText: text for the title attribute of the image
256 * @param string $additionalParams: text representing more html attributes to be added on the img tag
257 * @return string the image insertion JS statement
258 */
259 protected function imageInsertJsStatement($url, $width, $height, $altText = '', $titleText = '', $additionalParams = '') {
260 return 'insertImage(' . GeneralUtility::quoteJSvalue($url, 1) . ',' . $width . ',' . $height . ',' . GeneralUtility::quoteJSvalue($altText, 1) . ',' . GeneralUtility::quoteJSvalue($titleText, 1) . ',' . GeneralUtility::quoteJSvalue($additionalParams, 1) . ');';
261 }
262
263 /**
264 * Echo the HTML page and JS that will insert the images
265 *
266 * @param array $insertJsStatements: array of image insertion JS statements
267 * @return void
268 */
269 protected function insertImages($insertJsStatements) {
270 echo '
271 <!DOCTYPE html>
272 <html>
273 <head>
274 <title>Untitled</title>
275 <script type="text/javascript">
276 /*<![CDATA[*/
277 var plugin = window.parent.RTEarea[' . GeneralUtility::quoteJSvalue($this->editorNo) . '].editor.getPlugin("TYPO3Image");
278 var imageTags = [];
279 function insertImage(file,width,height,alt,title,additionalParams) {
280 imageTags.push(\'<img src="\'+file+\'" width="\'+parseInt(width)+\'" height="\'+parseInt(height)+\'"\'' . ($this->defaultClass ? '+\' class="' . $this->defaultClass . '"\'' : '') . '+(alt?\' alt="\'+alt+\'"\':\'\')+(title?\' title="\'+title+\'"\':\'\')+(additionalParams?\' \'+additionalParams:\'\')+\' />\');
281 }
282 /*]]>*/
283 </script>
284 </head>
285 <body>
286 <script type="text/javascript">
287 /*<![CDATA[*/' . implode (LF, $insertJsStatements) . 'plugin.insertImage(imageTags.join(\' \'));/*]]>*/
288 </script>
289 </body>
290 </html>';
291 }
292
293 /**
294 * Generate JS code to be used on the image insert/modify dialogue
295 *
296 * @param string $act: the action to be performed
297 * @param string $editorNo: the number of the RTE instance on the page
298 * @param string $sys_language_content: the language of the content element
299 * @return string the generated JS code
300 */
301 public function getJSCode($act, $editorNo, $sys_language_content) {
302 $JScode = '
303 function insertElement(table, uid, type, fileName, filePath, fileExt, fileIcon, action, close) {
304 return SelectImage.jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript()) . ' + "insertImage=1&uidList=" + uid);
305 }
306 function insertMultiple(table, uidList) {
307 var uids = uidList.join("|");
308 return SelectImage.jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript()) . ' + "insertImage=1&uidList=" + uids);
309 }
310 function jumpToUrl(URL,anchor) {
311 SelectImage.jumpToUrl(URL, anchor);
312 };';
313 return $JScode;
314 }
315
316 /**
317 * Session data for this class can be set from outside with this method.
318 * Call after init()
319 *
320 * @param array $data Session data array
321 * @return array Session data and boolean which indicates that data needs to be stored in session because it's changed
322 */
323 public function processSessionData($data) {
324 $store = FALSE;
325 if ($this->act != 'image') {
326 if (isset($this->act)) {
327 $data['act'] = $this->act;
328 $store = TRUE;
329 } else {
330 $this->act = $data['act'];
331 }
332 }
333 if (isset($this->expandFolder)) {
334 $data['expandFolder'] = $this->expandFolder;
335 $store = TRUE;
336 } else {
337 $this->expandFolder = $data['expandFolder'];
338 }
339 return array($data, $store);
340 }
341
342 /**
343 * Rich Text Editor (RTE) image selector
344 *
345 * @param bool $wiz Not used here, kept for method signature compatibility with parent class
346 * @return string Modified content variable.
347 * @return string
348 */
349 public function main_rte($wiz = FALSE) {
350 // Starting content:
351 $this->content = $this->doc->startPage($GLOBALS['LANG']->getLL('Insert Image', TRUE));
352
353 $this->content .= $this->doc->getTabMenuRaw($this->buildMenuArray($wiz, $this->allowedItems));
354 switch ($this->act) {
355 case 'image':
356 $classesImage = $this->buttonConfig['properties.']['class.']['allowedClasses'] || $this->thisConfig['classesImage'] ? 'true' : 'false';
357 $removedProperties = array();
358 if (is_array($this->buttonConfig['properties.'])) {
359 if ($this->buttonConfig['properties.']['removeItems']) {
360 $removedProperties = GeneralUtility::trimExplode(',', $this->buttonConfig['properties.']['removeItems'], TRUE);
361 }
362 }
363 $classesImageJSOptions = '';
364 if ($this->buttonConfig['properties.']['class.']['allowedClasses']) {
365 $classesImageArray = GeneralUtility::trimExplode(',', $this->buttonConfig['properties.']['class.']['allowedClasses'], TRUE);
366 $classesImageJSOptions = '<option value=""></option>';
367 foreach ($classesImageArray as $class) {
368 $classesImageJSOptions .= '<option value="' . $class . '">' . $class . '</option>';
369 }
370 }
371 $lockPlainWidth = 'false';
372 $lockPlainHeight = 'false';
373 if (is_array($this->thisConfig['proc.']) && $this->thisConfig['proc.']['plainImageMode']) {
374 $plainImageMode = $this->thisConfig['proc.']['plainImageMode'];
375 $lockPlainWidth = $plainImageMode == 'lockDimensions' ? 'true' : 'false';
376 $lockPlainHeight = $lockPlainWidth || $plainImageMode == 'lockRatio' || $plainImageMode == 'lockRatioWhenSmaller' ? 'true' : 'false';
377 }
378 $labels = array('notSet','nonFloating','right','left','class','width','height','border','float','padding_top','padding_left','padding_bottom','padding_right','title','alt','update');
379 foreach ($labels as $label) {
380 $localizedLabels[$label] = $GLOBALS['LANG']->getLL($label);
381 }
382 $localizedLabels['image_zoom'] = $GLOBALS['LANG']->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:image_zoom', TRUE);
383 $JScode = '
384 require(["TYPO3/CMS/Rtehtmlarea/Modules/SelectImage"], function(SelectImage) {
385 SelectImage.editorNo = "' . $this->editorNo . '";
386 SelectImage.act = "' . $this->act . '";
387 SelectImage.sys_language_content = "' . $this->sys_language_content . '";
388 SelectImage.RTEtsConfigParams = "' . rawurlencode($this->RTEtsConfigParams) . '";
389 SelectImage.bparams = "' . $this->bparams . '";
390 SelectImage.classesImage = ' . $classesImage . ';
391 SelectImage.labels = ' . json_encode($localizedLabels) . ';
392 SelectImage.Form.build(' . GeneralUtility::quoteJSvalue($classesImageJSOptions) . ', ' . json_encode($removedProperties) . ', ' . $lockPlainWidth . ', ' . $lockPlainHeight . ');
393 SelectImage.Form.insertImageProperties();
394 });';
395 $this->content .= '<br />' . $this->doc->wrapScriptTags($JScode);
396 break;
397 case 'plain':
398 case 'magic':
399 // Create folder tree:
400 $foldertree = GeneralUtility::makeInstance(\TYPO3\CMS\Rtehtmlarea\FolderTree::class);
401 $foldertree->thisScript = $this->thisScript;
402 $tree = $foldertree->getBrowsableTree();
403 // Get currently selected folder
404 if (!$this->curUrlInfo['value'] || $this->curUrlInfo['act'] != $this->act) {
405 $cmpPath = '';
406 } else {
407 $cmpPath = $this->curUrlInfo['value'];
408 if (!isset($this->expandFolder)) {
409 $this->expandFolder = $cmpPath;
410 }
411 }
412 // Get the selected folder
413 $selectedFolder = FALSE;
414 if ($this->expandFolder) {
415 $fileOrFolderObject = NULL;
416 try {
417 $fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->expandFolder);
418 } catch (\Exception $e) {
419 // No path is selected
420 }
421 if ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\Folder) {
422 // it's a folder
423 $selectedFolder = $fileOrFolderObject;
424 } elseif ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\FileInterface) {
425 // it's a file
426 try {
427 $selectedFolder = $fileOrFolderObject->getParentFolder();
428 } catch (\Exception $e) {
429 // Accessing the parent folder failed for some reason. e.g. permissions
430 }
431 }
432 }
433 // If no folder is selected, get the user's default upload folder
434 if (!$selectedFolder) {
435 try {
436 $selectedFolder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
437 } catch (\Exception $e) {
438 // The configured default user folder does not exist
439 }
440 }
441 // Build the file upload and folder creation form
442 $uploadForm = '';
443 $createFolder = '';
444 if ($selectedFolder) {
445 $uploadForm = $this->uploadForm($selectedFolder);
446 $createFolder = $this->createFolder($selectedFolder);
447 }
448 // Insert the upload form on top, if so configured
449 if ($GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
450 $this->content .= $uploadForm;
451 }
452 // Render the filelist if there is a folder selected
453 $files = '';
454 if ($selectedFolder) {
455 $files = $this->TBE_expandFolder($selectedFolder, $this->act === 'plain' ? self::PLAIN_MODE_IMAGE_FILE_EXTENSIONS : $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $GLOBALS['BE_USER']->getTSConfigVal('options.noThumbsInRTEimageSelect'));
456 }
457 // Setup filelist indexed elements:
458 $this->doc->JScode .= $this->doc->wrapScriptTags('
459 require(["TYPO3/CMS/Backend/BrowseLinks"], function(BrowseLinks) {
460 BrowseLinks.addElements(' . json_encode($this->elements) . ');
461 });');
462 // Wrap tree
463 $this->content .= '
464
465 <!--
466 Wrapper table for folder tree / file/folder list:
467 -->
468 <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkFiles">
469 <tr>
470 <td class="c-wCell" valign="top">' . $this->barheader(($GLOBALS['LANG']->getLL('folderTree') . ':')) . $tree . '</td>
471 <td class="c-wCell" valign="top">' . $files . '</td>
472 </tr>
473 </table>
474 ';
475 // Add help message
476 $helpMessage = $this->getHelpMessage($this->act);
477 if ($helpMessage) {
478 $this->content .= $this->getMsgBox($helpMessage);
479 }
480 // Adding create folder + upload form if applicable
481 if (!$GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
482 $this->content .= $uploadForm;
483 }
484 $this->content .= $createFolder;
485 $this->content .= '<br />';
486 break;
487 case 'dragdrop':
488 $foldertree = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\View\ElementBrowserFolderTreeView::class);
489 $foldertree->thisScript = $this->thisScript;
490 $foldertree->ext_noTempRecyclerDirs = TRUE;
491 $tree = $foldertree->getBrowsableTree();
492 // Get currently selected folder
493 if (!$this->curUrlInfo['value'] || $this->curUrlInfo['act'] != $this->act) {
494 $cmpPath = '';
495 } else {
496 $cmpPath = $this->curUrlInfo['value'];
497 if (!isset($this->expandFolder)) {
498 $this->expandFolder = $cmpPath;
499 }
500 }
501 $selectedFolder = FALSE;
502 if ($this->expandFolder) {
503 try {
504 $selectedFolder = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFolderObjectFromCombinedIdentifier($this->expandFolder);
505 } catch (\Exception $e) {
506 }
507 }
508 // Render the filelist if there is a folder selected
509 $files = '';
510 if ($selectedFolder) {
511 $files = $this->TBE_dragNDrop($selectedFolder, implode(',', $this->allowedFileTypes));
512 }
513 // Wrap tree
514 $this->content .= '<table border="0" cellpadding="0" cellspacing="0">
515 <tr>
516 <td style="vertical-align: top;">' . $this->barheader(($GLOBALS['LANG']->getLL('folderTree') . ':')) . $tree . '</td>
517 <td>&nbsp;</td>
518 <td style="vertical-align: top;">' . $files . '</td>
519 </tr>
520 </table>';
521 break;
522 default:
523 // Call hook
524 foreach ($this->hookObjects as $hookObject) {
525 $this->content .= $hookObject->getTab($this->act);
526 }
527 }
528 $this->content .= $this->doc->endPage();
529 $this->doc->JScodeArray['rtehtmlarea'] = $this->getJSCode($this->act, $this->editorNo, $this->sys_language_content);
530 $this->content = $this->doc->insertStylesAndJS($this->content);
531 return $this->content;
532 }
533
534 /**
535 * Returns an array definition of the top menu
536 *
537 * @param $wiz
538 * @param $allowedItems
539 * @return array
540 */
541 protected function buildMenuArray($wiz, $allowedItems) {
542 $menuDef = array();
543 if (in_array('image', $this->allowedItems) && ($this->act === 'image' || $this->addModifyTab)) {
544 $menuDef['image']['isActive'] = FALSE;
545 $menuDef['image']['label'] = $GLOBALS['LANG']->getLL('currentImage', TRUE);
546 $menuDef['image']['url'] = '#';
547 $menuDef['image']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript()) . ' + \'act=image\');return false;"';
548 }
549 if (in_array('magic', $this->allowedItems)) {
550 $menuDef['magic']['isActive'] = FALSE;
551 $menuDef['magic']['label'] = $GLOBALS['LANG']->getLL('magicImage', TRUE);
552 $menuDef['magic']['url'] = '#';
553 $menuDef['magic']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript()) . ' + \'act=magic\');return false;"';
554 }
555 if (in_array('plain', $this->allowedItems)) {
556 $menuDef['plain']['isActive'] = FALSE;
557 $menuDef['plain']['label'] = $GLOBALS['LANG']->getLL('plainImage', TRUE);
558 $menuDef['plain']['url'] = '#';
559 $menuDef['plain']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript()) . ' + \'act=plain\');return false;"';
560 }
561 if (in_array('dragdrop', $this->allowedItems)) {
562 $menuDef['dragdrop']['isActive'] = FALSE;
563 $menuDef['dragdrop']['label'] = $GLOBALS['LANG']->getLL('dragDropImage', TRUE);
564 $menuDef['dragdrop']['url'] = '#';
565 $menuDef['dragdrop']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript()) . ' + \'act=dragdrop\');return false;"';
566 }
567 // Call hook for extra options
568 foreach ($this->hookObjects as $hookObject) {
569 $menuDef = $hookObject->modifyMenuDefinition($menuDef);
570 }
571 // Order the menu items as specified in Page TSconfig
572 $menuDef = $this->orderMenuDefinition($menuDef);
573 // Set active menu item
574 reset($menuDef);
575 if ($this->act === FALSE || !in_array($this->act, $this->allowedItems)) {
576 $this->act = key($menuDef);
577 }
578 $menuDef[$this->act]['isActive'] = TRUE;
579 return $menuDef;
580 }
581
582 /**
583 * Initializes the configuration variables
584 *
585 * @return void
586 */
587 public function initConfiguration() {
588 $this->thisConfig = $this->getRTEConfig();
589 $this->buttonConfig = $this->getButtonConfig();
590 $this->imgPath = $this->getImgPath();
591 $this->defaultClass = $this->getDefaultClass();
592 $this->setMaximumPlainImageDimensions();
593 }
594
595 /**
596 * Get the path of the image to be inserted or modified
597 *
598 * @return string path to the image
599 */
600 protected function getImgPath() {
601 $RTEtsConfigParts = explode(':', $this->RTEtsConfigParams);
602 return $RTEtsConfigParts[6];
603 }
604
605 /**
606 * Get the configuration of the image button
607 *
608 * @return array the configuration array of the image button
609 */
610 protected function getButtonConfig() {
611 return is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['image.']) ? $this->thisConfig['buttons.']['image.'] : array();
612 }
613
614 /**
615 * Get the allowed items or tabs
616 *
617 * @param string $items: initial list of possible items
618 * @return array the allowed items
619 */
620 public function getAllowedItems($items) {
621 $allowedItems = explode(',', $items);
622 $clientInfo = GeneralUtility::clientInfo();
623 if ($clientInfo['BROWSER'] !== 'opera') {
624 $allowedItems[] = 'dragdrop';
625 }
626 // Call hook for extra options
627 foreach ($this->hookObjects as $hookObject) {
628 $allowedItems = $hookObject->addAllowedItems($allowedItems);
629 }
630 // Remove tab "image" if there is no current image
631 if ($this->act !== 'image' && !$this->addModifyTab) {
632 $allowedItems = array_diff($allowedItems, array('image'));
633 }
634 // Remove options according to RTE configuration
635 if (is_array($this->buttonConfig['options.']) && $this->buttonConfig['options.']['removeItems']) {
636 $allowedItems = array_diff($allowedItems, GeneralUtility::trimExplode(',', $this->buttonConfig['options.']['removeItems'], TRUE));
637 }
638 return $allowedItems;
639 }
640
641 /**
642 * Order the definition of menu items according to configured order
643 *
644 * @param array $menuDefinition: definition of menu items
645 * @return array ordered menu definition
646 */
647 public function orderMenuDefinition($menuDefinition) {
648 $orderedMenuDefinition = array();
649 if (is_array($this->buttonConfig['options.']) && $this->buttonConfig['options.']['orderItems']) {
650 $orderItems = GeneralUtility::trimExplode(',', $this->buttonConfig['options.']['orderItems'], TRUE);
651 $orderItems = array_intersect($orderItems, $this->allowedItems);
652 foreach ($orderItems as $item) {
653 $orderedMenuDefinition[$item] = $menuDefinition[$item];
654 }
655 } else {
656 $orderedMenuDefinition = $menuDefinition;
657 }
658 return $orderedMenuDefinition;
659 }
660
661 /**
662 * Get the default image class
663 *
664 * @return string the default class, if any
665 */
666 protected function getDefaultClass() {
667 $defaultClass = '';
668 if (is_array($this->buttonConfig['properties.'])) {
669 if (is_array($this->buttonConfig['properties.']['class.']) && trim($this->buttonConfig['properties.']['class.']['default'])) {
670 $defaultClass = trim($this->buttonConfig['properties.']['class.']['default']);
671 }
672 }
673 return $defaultClass;
674 }
675
676 /**
677 * Set variables for maximum plain image dimensions
678 *
679 * @return void
680 */
681 protected function setMaximumPlainImageDimensions() {
682 if (is_array($this->buttonConfig['options.']) && is_array($this->buttonConfig['options.']['plain.'])) {
683 if ($this->buttonConfig['options.']['plain.']['maxWidth']) {
684 $this->plainMaxWidth = $this->buttonConfig['options.']['plain.']['maxWidth'];
685 }
686 if ($this->buttonConfig['options.']['plain.']['maxHeight']) {
687 $this->plainMaxHeight = $this->buttonConfig['options.']['plain.']['maxHeight'];
688 }
689 }
690 if (!$this->plainMaxWidth) {
691 $this->plainMaxWidth = 640;
692 }
693 if (!$this->plainMaxHeight) {
694 $this->plainMaxHeight = 680;
695 }
696 }
697
698 /**
699 * Get the help message to be displayed on a given tab
700 *
701 * @param string $act: the identifier of the tab
702 * @return string the text of the message
703 */
704 public function getHelpMessage($act) {
705 switch ($act) {
706 case 'plain':
707 return sprintf($GLOBALS['LANG']->getLL('plainImage_msg'), $this->plainMaxWidth, $this->plainMaxHeight);
708 break;
709 case 'magic':
710 return sprintf($GLOBALS['LANG']->getLL('magicImage_msg'));
711 break;
712 default:
713 return '';
714 }
715 }
716
717 /**
718 * Checks if the given file is selectable in the file list.
719 *
720 * In "plain" RTE mode only image files with a maximum width and height are selectable.
721 *
722 * @param \TYPO3\CMS\Core\Resource\FileInterface $file
723 * @param array $imgInfo Image dimensions from \TYPO3\CMS\Core\Imaging\GraphicalFunctions::getImageDimensions()
724 * @return bool TRUE if file is selectable.
725 */
726 protected function fileIsSelectableInFileList(\TYPO3\CMS\Core\Resource\FileInterface $file, array $imgInfo) {
727 return (
728 $this->act !== 'plain'
729 || (
730 GeneralUtility::inList(self::PLAIN_MODE_IMAGE_FILE_EXTENSIONS, strtolower($file->getExtension()))
731 && $imgInfo[0] <= $this->plainMaxWidth
732 && $imgInfo[1] <= $this->plainMaxHeight
733 )
734 );
735 }
736
737 }