[CLEANUP] main_rte function of the ElementBrowser
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / Classes / BrowseLinks.php
1 <?php
2 namespace TYPO3\CMS\Rtehtmlarea;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the text file GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
19 *
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28
29 use TYPO3\CMS\Backend\Utility\BackendUtility;
30 use TYPO3\CMS\Core\Utility\GeneralUtility;
31
32 /**
33 * Script class for the Element Browser window.
34 *
35 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
36 */
37 class BrowseLinks extends \TYPO3\CMS\Recordlist\Browser\ElementBrowser {
38
39 public $editorNo;
40 /**
41 * TYPO3 language code of the content language
42 */
43 public $contentTypo3Language;
44
45 public $contentTypo3Charset = 'utf-8';
46 /**
47 * Language service object for localization to the content language
48 */
49 protected $contentLanguageService;
50
51 public $additionalAttributes = array();
52
53 public $buttonConfig = array();
54
55 public $RTEProperties = array();
56
57 public $anchorTypes = array('page', 'url', 'file', 'mail', 'spec');
58
59 public $classesAnchorDefault = array();
60
61 public $classesAnchorDefaultTitle = array();
62
63 public $classesAnchorClassTitle = array();
64
65 public $classesAnchorDefaultTarget = array();
66
67 public $classesAnchorJSOptions = array();
68
69 protected $defaultLinkTarget;
70
71 public $allowedItems;
72
73 /**
74 * Constructor:
75 * Initializes a lot of variables, setting JavaScript functions in header etc.
76 *
77 * @return void
78 */
79 public function init() {
80 $this->initVariables();
81 // Create content language service
82 $this->contentLanguageService = GeneralUtility::makeInstance('TYPO3\\CMS\\Lang\\LanguageService');
83 $this->contentLanguageService->init($this->contentTypo3Language);
84 $this->initConfiguration();
85
86 $this->initDocumentTemplate();
87
88 // Initializing hooking browsers
89 $this->initHookObjects('ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php');
90 $this->allowedItems = $this->getAllowedItems('page,file,folder,url,mail,spec');
91 $this->initCurrentUrl();
92 // Determine nature of current url:
93 $this->act = GeneralUtility::_GP('act');
94 if (!$this->act) {
95 $this->act = $this->curUrlInfo['act'];
96 }
97 // Setting initial values for link attributes
98 $this->initLinkAttributes();
99
100 // Adding RTE JS code
101 // also unset the default jumpToUrl() function before
102 unset($this->doc->JScodeArray['jumpToUrl']);
103 $this->doc->JScodeArray['rtehtmlarea'] = $this->getJSCode();
104 }
105
106 /**
107 * Initialize class variables
108 *
109 * @return void
110 */
111 public function initVariables() {
112 parent::initVariables();
113
114 // Process bparams
115 $pArr = explode('|', $this->bparams);
116 $pRteArr = explode(':', $pArr[1]);
117 $this->editorNo = $pRteArr[0];
118 $this->contentTypo3Language = $pRteArr[1];
119 $this->RTEtsConfigParams = $pArr[2];
120 if (!$this->editorNo) {
121 $this->editorNo = GeneralUtility::_GP('editorNo');
122 $this->contentTypo3Language = GeneralUtility::_GP('contentTypo3Language');
123 $this->RTEtsConfigParams = GeneralUtility::_GP('RTEtsConfigParams');
124 }
125 $pArr[1] = implode(':', array($this->editorNo, $this->contentTypo3Language, $this->contentTypo3Charset));
126 $pArr[2] = $this->RTEtsConfigParams;
127 $this->bparams = implode('|', $pArr);
128 }
129
130 /**
131 * Initializes the configuration variables
132 *
133 * @return void
134 */
135 public function initConfiguration() {
136 $this->thisConfig = $this->getRTEConfig();
137 $this->buttonConfig = $this->getButtonConfig('link');
138 }
139
140 /**
141 * Initialize document template object
142 *
143 * @return void
144 */
145 protected function initDocumentTemplate() {
146 parent::initDocumentTemplate();
147 $this->doc->getContextMenuCode();
148 // Apply the same styles as those of the base script
149 $this->doc->bodyTagId = 'typo3-browse-links-php';
150 $this->doc->getPageRenderer()->addCssFile($this->doc->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('t3skin') . 'rtehtmlarea/htmlarea.css');
151 // Add attributes to body tag. Note: getBodyTagAdditions will invoke the hooks
152 $this->doc->bodyTagAdditions = $this->getBodyTagAdditions();
153 }
154
155 /**
156 * Initialize $this->curUrlArray and $this->curUrlInfo based on script parameters
157 *
158 * @return void
159 */
160 protected function initCurrentUrl() {
161 // CurrentUrl - the current link url must be passed around if it exists
162 $this->curUrlArray = GeneralUtility::_GP('curUrl');
163 if ($this->curUrlArray['all']) {
164 $this->curUrlArray = GeneralUtility::get_tag_attributes($this->curUrlArray['all']);
165 $this->curUrlArray['href'] = htmlspecialchars_decode($this->curUrlArray['href']);
166 }
167 // Note: parseCurUrl will invoke the hooks
168 $this->curUrlInfo = $this->parseCurUrl($this->curUrlArray['href'], $this->siteURL);
169 if (isset($this->curUrlArray['data-htmlarea-external']) && $this->curUrlInfo['act'] != 'mail') {
170 $this->curUrlInfo['act'] = 'url';
171 $this->curUrlInfo['info'] = $this->curUrlArray['href'];
172 }
173 }
174
175 /**
176 * Get the RTE configuration from Page TSConfig
177 *
178 * @return array RTE configuration array
179 */
180 protected function getRTEConfig() {
181 $RTEtsConfigParts = explode(':', $this->RTEtsConfigParams);
182 $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE', BackendUtility::getPagesTSconfig($RTEtsConfigParts[5]));
183 $this->RTEProperties = $RTEsetup['properties'];
184 return BackendUtility::RTEsetup($this->RTEProperties, $RTEtsConfigParts[0], $RTEtsConfigParts[2], $RTEtsConfigParts[4]);
185 }
186
187 /**
188 * Get the configuration of the button
189 *
190 * @param string $buttonName: the name of the button
191 * @return array the configuration array of the image button
192 */
193 protected function getButtonConfig($buttonName) {
194 return is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.'][$buttonName . '.'])
195 ? $this->thisConfig['buttons.'][$buttonName . '.']
196 : array();
197 }
198
199 /**
200 * Initialize the current or default values of the link attributes
201 *
202 * @return void
203 */
204 protected function initLinkAttributes() {
205 // Initializing the title value
206 $this->setTitle = $this->curUrlArray['title'];
207 // Processing the classes configuration
208 $classSelected = array();
209 if ($this->buttonConfig['properties.']['class.']['allowedClasses']) {
210 $this->setClass = $this->curUrlArray['class'];
211 $classesAnchorArray = GeneralUtility::trimExplode(',', $this->buttonConfig['properties.']['class.']['allowedClasses'], TRUE);
212 // Collecting allowed classes and configured default values
213 $classesAnchor = array();
214 $classesAnchor['all'] = array();
215 $titleReadOnly = $this->buttonConfig['properties.']['title.']['readOnly']
216 || $this->buttonConfig[$this->act . '.']['properties.']['title.']['readOnly'];
217 if (is_array($this->RTEProperties['classesAnchor.'])) {
218 foreach ($this->RTEProperties['classesAnchor.'] as $label => $conf) {
219 if (in_array($conf['class'], $classesAnchorArray)) {
220 $classesAnchor['all'][] = $conf['class'];
221 if (in_array($conf['type'], $this->anchorTypes)) {
222 $classesAnchor[$conf['type']][] = $conf['class'];
223 if ($this->buttonConfig[$conf['type'] . '.']['properties.']['class.']['default'] == $conf['class']) {
224 $this->classesAnchorDefault[$conf['type']] = $conf['class'];
225 if ($conf['titleText']) {
226 $this->classesAnchorDefaultTitle[$conf['type']] = $this->getLLContent(trim($conf['titleText']));
227 }
228 if ($conf['target']) {
229 $this->classesAnchorDefaultTarget[$conf['type']] = trim($conf['target']);
230 }
231 }
232 }
233 if ($titleReadOnly && $conf['titleText']) {
234 $this->classesAnchorClassTitle[$conf['class']] = ($this->classesAnchorDefaultTitle[$conf['type']] = $this->getLLContent(trim($conf['titleText'])));
235 }
236 }
237 }
238 }
239 // Constructing the class selector options
240 foreach ($this->anchorTypes as $anchorType) {
241 foreach ($classesAnchorArray as $class) {
242 if (!in_array($class, $classesAnchor['all']) || in_array($class, $classesAnchor['all']) && is_array($classesAnchor[$anchorType]) && in_array($class, $classesAnchor[$anchorType])) {
243 $selected = '';
244 if ($this->setClass == $class || !$this->setClass && $this->classesAnchorDefault[$anchorType] == $class) {
245 $selected = 'selected="selected"';
246 $classSelected[$anchorType] = TRUE;
247 }
248 $classLabel = is_array($this->RTEProperties['classes.']) && is_array($this->RTEProperties['classes.'][$class . '.']) && $this->RTEProperties['classes.'][$class . '.']['name'] ? $this->getPageConfigLabel($this->RTEProperties['classes.'][$class . '.']['name'], 0) : $class;
249 $classStyle = is_array($this->RTEProperties['classes.']) && is_array($this->RTEProperties['classes.'][$class . '.']) && $this->RTEProperties['classes.'][$class . '.']['value'] ? $this->RTEProperties['classes.'][$class . '.']['value'] : '';
250 $this->classesAnchorJSOptions[$anchorType] .= '<option ' . $selected . ' value="' . $class . '"' . ($classStyle ? ' style="' . $classStyle . '"' : '') . '>' . $classLabel . '</option>';
251 }
252 }
253 if ($this->classesAnchorJSOptions[$anchorType] && !($this->buttonConfig['properties.']['class.']['required'] || $this->buttonConfig[$this->act . '.']['properties.']['class.']['required'])) {
254 $selected = '';
255 if (!$this->setClass && !$this->classesAnchorDefault[$anchorType]) {
256 $selected = 'selected="selected"';
257 }
258 $this->classesAnchorJSOptions[$anchorType] = '<option ' . $selected . ' value=""></option>' . $this->classesAnchorJSOptions[$anchorType];
259 }
260 }
261 }
262 // Initializing the target value
263 // Unset the target if it is set to a value different than default and if no class is selected and the target field is not displayed
264 // In other words, do not forward the target if we changed tab and the target field is not displayed
265 $this->defaultLinkTarget = isset($this->buttonConfig['properties.']['target.']['default']) ? $this->buttonConfig['properties.']['target.']['default'] : '';
266 $this->setTarget = '';
267 if (isset($this->curUrlArray['target']) && !($this->curUrlArray['target'] != $this->defaultLinkTarget && !$classSelected[$this->act] && is_array($this->buttonConfig['targetSelector.']) && $this->buttonConfig['targetSelector.']['disabled'] && is_array($this->buttonConfig['popupSelector.']) && $this->buttonConfig['popupSelector.']['disabled'])) {
268 $this->setTarget = $this->curUrlArray['target'];
269 }
270 if ($this->defaultLinkTarget && !isset($this->curUrlArray['target'])) {
271 $this->setTarget = $this->defaultLinkTarget;
272 }
273 // Initializing additional attributes
274 if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['TYPO3Link']['additionalAttributes']) {
275 $addAttributes = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['TYPO3Link']['additionalAttributes'], TRUE);
276 foreach ($addAttributes as $attribute) {
277 $this->additionalAttributes[$attribute] = isset($this->curUrlArray[$attribute]) ? $this->curUrlArray[$attribute] : '';
278 }
279 }
280 }
281
282 /**
283 * Provide the additional parameters to be included in the template body tag
284 *
285 * @return string the body tag additions
286 */
287 public function getBodyTagAdditions() {
288 $bodyTagAdditions = array();
289 // call hook for extra additions
290 foreach ($this->hookObjects as $hookObject) {
291 if (method_exists($hookObject, 'addBodyTagAdditions')) {
292 $bodyTagAdditions = $hookObject->addBodyTagAdditions($bodyTagAdditions);
293 }
294 }
295 return GeneralUtility::implodeAttributes($bodyTagAdditions, TRUE);
296 }
297
298 /**
299 * Generate JS code to be used on the link insert/modify dialogue
300 *
301 * @return string the generated JS code
302 * @todo Define visibility
303 */
304 public function getJSCode() {
305 // BEGIN accumulation of header JavaScript:
306 $JScode = '';
307 $JScode .= '
308 var plugin = window.parent.RTEarea["' . $this->editorNo . '"].editor.getPlugin("TYPO3Link");
309 var HTMLArea = window.parent.HTMLArea;
310 var add_href=' . GeneralUtility::quoteJSvalue($this->curUrlArray['href'] ? '&curUrl[href]=' . rawurlencode($this->curUrlArray['href']) : '') . ';
311 var add_target=' . GeneralUtility::quoteJSvalue($this->setTarget ? '&curUrl[target]=' . rawurlencode($this->setTarget) : '') . ';
312 var add_class=' . GeneralUtility::quoteJSvalue($this->setClass ? '&curUrl[class]=' . rawurlencode($this->setClass) : '') . ';
313 var add_title=' . GeneralUtility::quoteJSvalue($this->setTitle ? '&curUrl[title]=' . rawurlencode($this->setTitle) : '') . ';
314 var add_params=' . GeneralUtility::quoteJSvalue($this->bparams ? '&bparams=' . rawurlencode($this->bparams) : '') . ';
315 var additionalValues = ' . (count($this->additionalAttributes) ? json_encode($this->additionalAttributes, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) : '{}') . ';';
316 // Attributes setting functions
317 $JScode .= '
318 var cur_href=' . GeneralUtility::quoteJSvalue($this->curUrlArray['href'] ? ($this->curUrlInfo['query'] ? substr($this->curUrlArray['href'], 0, -strlen($this->curUrlInfo['query'])) : $this->curUrlArray['href']) : '') . ';
319 var cur_target=' . GeneralUtility::quoteJSvalue($this->setTarget ?: '') . ';
320 var cur_class=' . GeneralUtility::quoteJSvalue($this->setClass ?: '') . ';
321 var cur_title=' . GeneralUtility::quoteJSvalue($this->setTitle ?: '') . ';
322
323 function browse_links_setTarget(value) {
324 cur_target=value;
325 add_target="&curUrl[target]="+encodeURIComponent(value);
326 }
327 function browse_links_setClass(value) {
328 cur_class=value;
329 add_class="&curUrl[class]="+encodeURIComponent(value);
330 }
331 function browse_links_setTitle(value) {
332 cur_title=value;
333 add_title="&curUrl[title]="+encodeURIComponent(value);
334 }
335 function browse_links_setHref(value) {
336 cur_href=value;
337 add_href="&curUrl[href]="+value;
338 }
339 function browse_links_setAdditionalValue(name, value) {
340 additionalValues[name] = value;
341 }
342 ';
343 // Link setting functions
344 $JScode .= '
345 function link_typo3Page(id,anchor) {
346 var parameters = (document.ltargetform.query_parameters && document.ltargetform.query_parameters.value) ? (document.ltargetform.query_parameters.value.charAt(0) == "&" ? "" : "&") + document.ltargetform.query_parameters.value : "";
347 var theLink = \'' . $this->siteURL . '?id=\' + id + parameters + (anchor ? anchor : "");
348 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
349 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
350 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
351 if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
352 browse_links_setAdditionalValue("data-htmlarea-external", "");
353 plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
354 return false;
355 }
356 function link_folder(folder) {
357 if (folder && folder.substr(0, 5) == "file:") {
358 var theLink = \'' . $this->siteURL . '?file:\' + encodeURIComponent(folder.substr(5));
359 } else {
360 var theLink = \'' . $this->siteURL . '?\' + folder;
361 }
362 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
363 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
364 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
365 if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
366 browse_links_setAdditionalValue("data-htmlarea-external", "");
367 plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
368 return false;
369 }
370 function link_spec(theLink) {
371 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
372 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
373 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
374 browse_links_setAdditionalValue("data-htmlarea-external", "");
375 plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
376 return false;
377 }
378 function link_current() {
379 var parameters = (document.ltargetform.query_parameters && document.ltargetform.query_parameters.value) ? (document.ltargetform.query_parameters.value.charAt(0) == "&" ? "" : "&") + document.ltargetform.query_parameters.value : "";
380 if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
381 if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
382 if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
383 if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
384 if (cur_href!="http://" && cur_href!="mailto:") {
385 plugin.createLink(cur_href + parameters,cur_target,cur_class,cur_title,additionalValues);
386 }
387 return false;
388 }
389 ';
390 // General "jumpToUrl" and launchView functions:
391 $JScode .= '
392 function jumpToUrl(URL,anchor) {
393 if (URL.charAt(0) === \'?\') {
394 URL = ' . GeneralUtility::quoteJSvalue($this->getThisScript()) . ' + URL.substring(1);
395 }
396 var add_editorNo = URL.indexOf("editorNo=")==-1 ? "&editorNo=' . $this->editorNo . '" : "";
397 var add_contentTypo3Language = URL.indexOf("contentTypo3Language=")==-1 ? "&contentTypo3Language=' . $this->contentTypo3Language . '" : "";
398 var add_act = URL.indexOf("act=")==-1 ? "&act=' . $this->act . '" : "";
399 var add_mode = URL.indexOf("mode=")==-1 ? "&mode=' . $this->mode . '" : "";
400 var add_additionalValues = "";
401 if (plugin.pageTSConfiguration && plugin.pageTSConfiguration.additionalAttributes) {
402 var additionalAttributes = plugin.pageTSConfiguration.additionalAttributes.split(",");
403 for (var i = additionalAttributes.length; --i >= 0;) {
404 if (additionalValues[additionalAttributes[i]] != "") {
405 add_additionalValues += "&curUrl[" + additionalAttributes[i] + "]=" + encodeURIComponent(additionalValues[additionalAttributes[i]]);
406 }
407 }
408 }
409 var theLocation = URL+add_act+add_editorNo+add_contentTypo3Language+add_mode+add_href+add_target+add_class+add_title+add_additionalValues+add_params+(anchor?anchor:"");
410 window.location.href = theLocation;
411 return false;
412 }
413 function launchView(url) {
414 var thePreviewWindow="";
415 thePreviewWindow = window.open("' . $GLOBALS['BACK_PATH'] . 'show_item.php?table="+url,"ShowItem","height=300,width=410,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
416 if (thePreviewWindow && thePreviewWindow.focus) {
417 thePreviewWindow.focus();
418 }
419 }
420 ';
421 // Hook to overwrite or extend javascript functions
422 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode'])) {
423 $conf = array();
424 $_params = array(
425 'conf' => &$conf
426 );
427 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode'] as $objRef) {
428 $processor =& GeneralUtility::getUserObj($objRef);
429 $JScode .= $processor->extendJScode($_params, $this);
430 }
431 }
432 return $JScode;
433 }
434
435 /******************************************************************
436 *
437 * Main functions
438 *
439 ******************************************************************/
440 /**
441 * Rich Text Editor (RTE) link selector (MAIN function)
442 * Generates the link selector for the Rich Text Editor.
443 * Can also be used to select links for the TCEforms (see $wiz)
444 *
445 * @param boolean $wiz If set, the "remove link" is not shown in the menu: Used for the "Select link" wizard which is used by the TCEforms
446 * @return string Modified content variable.
447 */
448 public function main_rte($wiz = FALSE) {
449 // Starting content:
450 $content = $this->doc->startPage($GLOBALS['LANG']->getLL('Insert/Modify Link', TRUE));
451 // Making menu in top:
452 $content .= $this->doc->getTabMenuRaw($this->buildMenuArray($wiz, $this->allowedItems));
453 // Adding the menu and header to the top of page:
454 $content .= $this->printCurrentUrl($this->curUrlInfo['info']) . '<br />';
455 // Depending on the current action we will create the actual module content for selecting a link:
456 switch ($this->act) {
457 case 'mail':
458 $extUrl = $this->getEmailSelectorHtml();
459 $content .= $this->addAttributesForm($extUrl);
460 break;
461 case 'url':
462 $extUrl = $this->getExternalUrlSelectorHtml();
463 $content .= $this->addAttributesForm($extUrl);
464 break;
465 case 'file':
466 case 'folder':
467 $content .= $this->addAttributesForm();
468 $content .= $this->getFileSelectorHtml('TYPO3\\CMS\\Rtehtmlarea\\FolderTree');
469 break;
470 case 'spec':
471 $content .= $this->getUserLinkSelectorHtml();
472 break;
473 case 'page':
474 $content .= $this->addAttributesForm();
475 $content .= $this->getPageSelectorHtml('TYPO3\\CMS\\Rtehtmlarea\\PageTree');
476 break;
477 default:
478 // call hook
479 foreach ($this->hookObjects as $hookObject) {
480 $content .= $hookObject->getTab($this->act);
481 }
482 }
483 // End page, return content:
484 $content .= $this->doc->endPage();
485 $content = $this->doc->insertStylesAndJS($content);
486 return $content;
487 }
488
489 /**
490 * Returns an array definition of the top menu
491 *
492 * @param $wiz
493 * @param $allowedItems
494 * @return array
495 */
496 protected function buildMenuArray($wiz, $allowedItems) {
497 $menuDef = array();
498 if (!$wiz && $this->curUrlArray['href']) {
499 $menuDef['removeLink']['isActive'] = $this->act == 'removeLink';
500 $menuDef['removeLink']['label'] = $GLOBALS['LANG']->getLL('removeLink', TRUE);
501 $menuDef['removeLink']['url'] = '#';
502 $menuDef['removeLink']['addParams'] = 'onclick="plugin.unLink();return false;"';
503 }
504 if (in_array('page', $this->allowedItems)) {
505 $menuDef['page']['isActive'] = $this->act == 'page';
506 $menuDef['page']['label'] = $GLOBALS['LANG']->getLL('page', TRUE);
507 $menuDef['page']['url'] = '#';
508 $menuDef['page']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue('?act=page&mode=' . $this->mode . '&bparams=' . $this->bparams) . ');return false;"';
509 }
510 if (in_array('file', $this->allowedItems)) {
511 $menuDef['file']['isActive'] = $this->act == 'file';
512 $menuDef['file']['label'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:file', TRUE);
513 $menuDef['file']['url'] = '#';
514 $menuDef['file']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue('?act=file&mode=' . $this->mode . '&bparams=' . $this->bparams) . ');return false;"';
515 }
516 if (in_array('folder', $this->allowedItems)) {
517 $menuDef['folder']['isActive'] = $this->act == 'folder';
518 $menuDef['folder']['label'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:folder', TRUE);
519 $menuDef['folder']['url'] = '#';
520 $menuDef['folder']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue('?act=folder&mode=' . $this->mode . '&bparams=' . $this->bparams) . ');return false;"';
521 }
522 if (in_array('url', $this->allowedItems)) {
523 $menuDef['url']['isActive'] = $this->act == 'url';
524 $menuDef['url']['label'] = $GLOBALS['LANG']->getLL('extUrl', TRUE);
525 $menuDef['url']['url'] = '#';
526 $menuDef['url']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue('?act=url&mode=' . $this->mode . '&bparams=' . $this->bparams) . ');return false;"';
527 }
528 if (in_array('mail', $this->allowedItems)) {
529 $menuDef['mail']['isActive'] = $this->act == 'mail';
530 $menuDef['mail']['label'] = $GLOBALS['LANG']->getLL('email', TRUE);
531 $menuDef['mail']['url'] = '#';
532 $menuDef['mail']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue('?act=mail&mode=' . $this->mode . '&bparams=' . $this->bparams) . ');return false;"';
533 }
534 if (is_array($this->thisConfig['userLinks.']) && in_array('spec', $this->allowedItems)) {
535 $menuDef['spec']['isActive'] = $this->act == 'spec';
536 $menuDef['spec']['label'] = $GLOBALS['LANG']->getLL('special', TRUE);
537 $menuDef['spec']['url'] = '#';
538 $menuDef['spec']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue('?act=spec&mode=' . $this->mode . '&bparams=' . $this->bparams) . ');return false;"';
539 }
540 // call hook for extra options
541 foreach ($this->hookObjects as $hookObject) {
542 $menuDef = $hookObject->modifyMenuDefinition($menuDef);
543 }
544 return $menuDef;
545 }
546
547 /**
548 * Returns HTML of the email link from
549 *
550 * @return string
551 */
552 protected function getEmailSelectorHtml() {
553 $extUrl = '
554 <!--
555 Enter mail address:
556 -->
557 <tr>
558 <td><label>' . $GLOBALS['LANG']->getLL('emailAddress', TRUE) . ':</label></td>
559 <td><input type="text" name="lemail"' . $this->doc->formWidth(20)
560 . ' value="' . htmlspecialchars(($this->curUrlInfo['act'] == 'mail' ? $this->curUrlInfo['info'] : '')) . '" /> '
561 . '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', TRUE)
562 . '" onclick="browse_links_setTarget(\'\');browse_links_setHref(\'mailto:\'+document.ltargetform.lemail.value);'
563 . 'browse_links_setAdditionalValue(\'data-htmlarea-external\', \'\');return link_current();" /></td>
564 </tr>';
565 return $extUrl;
566 }
567
568 /**
569 * Returns HTML of the external url link from
570 *
571 * @return string
572 */
573 protected function getExternalUrlSelectorHtml() {
574 $extUrl = '
575 <!--
576 Enter External URL:
577 -->
578 <tr>
579 <td><label>URL:</label></td>
580 <td colspan="3"><input type="text" name="lurl"' . $this->doc->formWidth(20)
581 . ' value="' . htmlspecialchars(($this->curUrlInfo['act'] == 'url' ? $this->curUrlInfo['info'] : 'http://'))
582 . '" /> ' . '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', TRUE)
583 . '" onclick="if (/^[A-Za-z0-9_+]{1,8}:/.test(document.ltargetform.lurl.value)) { '
584 .' browse_links_setHref(document.ltargetform.lurl.value); } else { browse_links_setHref(\'http://\''
585 . '+document.ltargetform.lurl.value); }; browse_links_setAdditionalValue(\'data-htmlarea-external\', \'1\');'
586 . 'return link_current();" /></td>
587 </tr>';
588 return $extUrl;
589 }
590
591 /**
592 * Returns HTML of the user defined link selector
593 *
594 * @return string
595 */
596 protected function getUserLinkSelectorHtml() {
597 if (!is_array($this->thisConfig['userLinks.'])) {
598 return '';
599 }
600 $subcats = array();
601 $v = $this->thisConfig['userLinks.'];
602 foreach ($v as $k2 => $dummyValue) {
603 $k2i = (int)$k2;
604 if (substr($k2, -1) == '.' && is_array($v[$k2i . '.'])) {
605 // Title:
606 $title = trim($v[$k2i]);
607 if (!$title) {
608 $title = $v[$k2i . '.']['url'];
609 } else {
610 $title = $GLOBALS['LANG']->sL($title);
611 }
612 // Description:
613 $description = $v[$k2i . '.']['description'] ? $GLOBALS['LANG']->sL($v[($k2i . '.')]['description'], TRUE) . '<br />' : '';
614 // URL + onclick event:
615 $onClickEvent = '';
616 if (isset($v[$k2i . '.']['target'])) {
617 $onClickEvent .= 'browse_links_setTarget(\'' . $v[($k2i . '.')]['target'] . '\');';
618 }
619 $v[$k2i . '.']['url'] = str_replace('###_URL###', $this->siteURL, $v[$k2i . '.']['url']);
620 if (substr($v[$k2i . '.']['url'], 0, 7) == 'http://' || substr($v[$k2i . '.']['url'], 0, 7) == 'mailto:') {
621 $onClickEvent .= 'cur_href=' . GeneralUtility::quoteJSvalue($v[($k2i . '.')]['url']) . ';link_current();';
622 } else {
623 $onClickEvent .= 'link_spec(' . GeneralUtility::quoteJSvalue($this->siteURL . $v[($k2i . '.')]['url']) . ');';
624 }
625 // Link:
626 $A = array('<a href="#" onclick="' . htmlspecialchars($onClickEvent) . 'return false;">', '</a>');
627 // Adding link to menu of user defined links:
628 $icon = $this->curUrlInfo['info'] == $v[$k2i . '.']['url']
629 ? '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_right.gif', 'width="5" height="9"') . ' class="c-blinkArrowR" alt="" />'
630 : '';
631 $subcats[$k2i] = '
632 <tr>
633 <td class="bgColor4">' . $A[0]
634 . '<strong>' . htmlspecialchars($title) . $icon . '</strong><br />' . $description . $A[1] . '</td>
635 </tr>';
636 }
637 }
638 // Sort by keys:
639 ksort($subcats);
640 // Add menu to content:
641 $content = '
642 <!--
643 Special userdefined menu:
644 -->
645 <table border="0" cellpadding="1" cellspacing="1" id="typo3-linkSpecial">
646 <tr>
647 <td class="bgColor5" class="c-wCell" valign="top"><strong>' . $GLOBALS['LANG']->getLL('special', TRUE) . '</strong></td>
648 </tr>
649 ' . implode('', $subcats) . '
650 </table>
651 ';
652 return $content;
653 }
654
655 /**
656 * Get the allowed items or tabs
657 *
658 * @param string $items: initial list of possible items
659 * @return array the allowed items
660 */
661 public function getAllowedItems($items) {
662 $allowedItems = explode(',', $items);
663 // Calling hook for extra options
664 foreach ($this->hookObjects as $hookObject) {
665 $allowedItems = $hookObject->addAllowedItems($allowedItems);
666 }
667 // Removing items as per configuration
668 if (is_array($this->buttonConfig['options.']) && $this->buttonConfig['options.']['removeItems']) {
669 $allowedItems = array_diff($allowedItems, GeneralUtility::trimExplode(',', $this->buttonConfig['options.']['removeItems'], TRUE));
670 }
671 reset($allowedItems);
672 if (!in_array($this->act, $allowedItems)) {
673 $this->act = current($allowedItems);
674 }
675 return $allowedItems;
676 }
677
678 /**
679 * Creates a form for link attributes
680 *
681 * @param string $rows: html code for some initial rows of the table to be wrapped in form
682 * @return string The HTML code of the form
683 */
684 public function addAttributesForm($rows = '') {
685 $ltargetForm = '';
686 $additionalAttributeFields = '';
687 // Add page id, target, class selector box, title and parameters fields:
688 $lpageId = $this->addPageIdSelector();
689 $queryParameters = $this->addQueryParametersSelector();
690 $ltarget = $this->addTargetSelector();
691 $lclass = $this->addClassSelector();
692 $ltitle = $this->addTitleSelector();
693 $rel = $this->addRelField();
694 // additional fields for links
695 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields'])
696 && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields'])
697 ) {
698 $conf = array();
699 $_params = array(
700 'conf' => &$conf
701 );
702 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields'] as $objRef) {
703 $processor =& GeneralUtility::getUserObj($objRef);
704 $additionalAttributeFields .= $processor->getAttributefields($_params, $this);
705 }
706 }
707 if ($rows || $lpageId || $queryParameters || $lclass || $ltitle || $ltarget || $rel) {
708 $ltargetForm = $this->wrapInForm($rows . $lpageId . $queryParameters . $lclass . $ltitle . $ltarget . $rel . $additionalAttributeFields);
709 }
710 return $ltargetForm;
711 }
712
713 /**
714 * @todo Define visibility
715 */
716 public function wrapInForm($string) {
717 $form = '
718 <!--
719 Selecting target for link:
720 -->
721 <form action="" name="ltargetform" id="ltargetform">
722 <table id="typo3-linkTarget" class="htmlarea-window-table">' . $string;
723 if ($this->act == $this->curUrlInfo['act'] && $this->act != 'mail' && $this->curUrlArray['href']) {
724 $form .= '
725 <tr>
726 <td>
727 </td>
728 <td colspan="3">
729 <input type="submit" value="' . $GLOBALS['LANG']->getLL('update', TRUE) . '" onclick="'
730 . ($this->act == 'url' ? 'browse_links_setAdditionalValue(\'data-htmlarea-external\', \'1\'); ' : '')
731 . 'return link_current();" />
732 </td>
733 </tr>';
734 }
735 $form .= '
736 </table>
737 </form>';
738 return $form;
739 }
740
741 /**
742 * @todo Define visibility
743 */
744 public function addPageIdSelector() {
745 if ($this->act == 'page' && isset($this->buttonConfig['pageIdSelector.']['enabled'])
746 && $this->buttonConfig['pageIdSelector.']['enabled']
747 ) {
748 return '
749 <tr>
750 <td><label>' . $GLOBALS['LANG']->getLL('page_id', TRUE) . ':</label></td>
751 <td colspan="3">
752 <input type="text" size="6" name="luid" />&nbsp;<input type="submit" value="'
753 . $GLOBALS['LANG']->getLL('setLink', TRUE) . '" onclick="return link_typo3Page(document.ltargetform.luid.value);" />
754 </td>
755 </tr>';
756 }
757 return '';
758 }
759
760 /**
761 * @todo Define visibility
762 */
763 public function addRelField() {
764 if (($this->act == 'page' || $this->act == 'url' || $this->act == 'file')
765 && isset($this->buttonConfig['relAttribute.']['enabled']) && $this->buttonConfig['relAttribute.']['enabled']
766 ) {
767 return '
768 <tr>
769 <td><label>' . $GLOBALS['LANG']->getLL('linkRelationship', TRUE) . ':</label></td>
770 <td colspan="3">
771 <input type="text" name="lrel" value="' . $this->additionalAttributes['rel'] . '" '
772 . $this->doc->formWidth(30) . ' />
773 </td>
774 </tr>';
775 }
776 return '';
777 }
778
779 /**
780 * @todo Define visibility
781 */
782 public function addQueryParametersSelector() {
783 if ($this->act == 'page' && isset($this->buttonConfig['queryParametersSelector.']['enabled'])
784 && $this->buttonConfig['queryParametersSelector.']['enabled']
785 ) {
786 return '
787 <tr>
788 <td><label>' . $GLOBALS['LANG']->getLL('query_parameters', TRUE) . ':</label></td>
789 <td colspan="3">
790 <input type="text" name="query_parameters" value="' . ($this->curUrlInfo['query'] ?: '')
791 . '" ' . $this->doc->formWidth(30) . ' />
792 </td>
793 </tr>';
794 }
795 return '';
796 }
797
798 /**
799 * @todo Define visibility
800 */
801 public function addTargetSelector() {
802 if ($this->act === 'mail') {
803 return '';
804 }
805 $targetSelectorConfig = array();
806 $popupSelectorConfig = array();
807 if (is_array($this->buttonConfig['targetSelector.'])) {
808 $targetSelectorConfig = $this->buttonConfig['targetSelector.'];
809 }
810 if (is_array($this->buttonConfig['popupSelector.'])) {
811 $popupSelectorConfig = $this->buttonConfig['popupSelector.'];
812 }
813 $target = $this->setTarget
814 ? $this->setTarget
815 : ($this->setClass || !$this->classesAnchorDefault[$this->act]
816 ? ''
817 : $this->classesAnchorDefaultTarget[$this->act]);
818 $ltarget = '
819 <tr id="ltargetrow"' . ($targetSelectorConfig['disabled'] && $popupSelectorConfig['disabled'] ? ' style="display: none;"' : '') . '>
820 <td><label>' . $GLOBALS['LANG']->getLL('target', TRUE) . ':</label></td>
821 <td><input type="text" name="ltarget" onchange="browse_links_setTarget(this.value);" value="'
822 . htmlspecialchars($target) . '"' . $this->doc->formWidth(10) . ' /></td>';
823 $ltarget .= '
824 <td colspan="2">';
825 if (!$targetSelectorConfig['disabled']) {
826 $ltarget .= '
827 <select name="ltarget_type" onchange="browse_links_setTarget(this.options[this.selectedIndex].value);document.ltargetform.ltarget.value=this.options[this.selectedIndex].value;this.selectedIndex=0;">
828 <option></option>
829 <option value="_top">' . $GLOBALS['LANG']->getLL('top', TRUE) . '</option>
830 <option value="_blank">' . $GLOBALS['LANG']->getLL('newWindow', TRUE) . '</option>
831 </select>';
832 }
833 $ltarget .= '
834 </td>
835 </tr>';
836 if (!$popupSelectorConfig['disabled']) {
837 $selectJS = 'if (document.ltargetform.popup_width.options[document.ltargetform.popup_width.selectedIndex].value>0 && document.ltargetform.popup_height.options[document.ltargetform.popup_height.selectedIndex].value>0) {
838 document.ltargetform.ltarget.value = document.ltargetform.popup_width.options[document.ltargetform.popup_width.selectedIndex].value+\'x\'+document.ltargetform.popup_height.options[document.ltargetform.popup_height.selectedIndex].value;
839 browse_links_setTarget(document.ltargetform.ltarget.value);
840 document.ltargetform.popup_width.selectedIndex=0;
841 document.ltargetform.popup_height.selectedIndex=0;
842 }';
843 $ltarget .= '
844 <tr>
845 <td><label>' . $GLOBALS['LANG']->getLL('target_popUpWindow', TRUE) . ':</label></td>
846 <td colspan="3">
847 <select name="popup_width" onchange="' . $selectJS . '">
848 <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_width', TRUE) . '</option>
849 <option value="300">300</option>
850 <option value="400">400</option>
851 <option value="500">500</option>
852 <option value="600">600</option>
853 <option value="700">700</option>
854 <option value="800">800</option>
855 </select>
856 x
857 <select name="popup_height" onchange="' . $selectJS . '">
858 <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_height', TRUE) . '</option>
859 <option value="200">200</option>
860 <option value="300">300</option>
861 <option value="400">400</option>
862 <option value="500">500</option>
863 <option value="600">600</option>
864 </select>
865 </td>
866 </tr>';
867 }
868 return $ltarget;
869 }
870
871 /**
872 * Return html code for the class selector
873 *
874 * @return string the html code to be added to the form
875 */
876 public function addClassSelector() {
877 $selectClass = '';
878 if ($this->classesAnchorJSOptions[$this->act]) {
879 $selectClass = '
880 <tr>
881 <td><label>' . $GLOBALS['LANG']->getLL('anchor_class', TRUE) . ':</label></td>
882 <td colspan="3">
883 <select name="anchor_class" onchange="' . $this->getClassOnChangeJS() . '">
884 ' . $this->classesAnchorJSOptions[$this->act] . '
885 </select>
886 </td>
887 </tr>';
888 }
889 return $selectClass;
890 }
891
892 /**
893 * Return JS code for the class selector onChange event
894 *
895 * @return string class selector onChange JS code
896 */
897 public function getClassOnChangeJS() {
898 return '
899 if (document.ltargetform.anchor_class) {
900 document.ltargetform.anchor_class.value = document.ltargetform.anchor_class.options[document.ltargetform.anchor_class.selectedIndex].value;
901 if (document.ltargetform.anchor_class.value && HTMLArea.classesAnchorSetup) {
902 for (var i = HTMLArea.classesAnchorSetup.length; --i >= 0;) {
903 var anchorClass = HTMLArea.classesAnchorSetup[i];
904 if (anchorClass[\'name\'] == document.ltargetform.anchor_class.value) {
905 if (anchorClass[\'titleText\'] && document.ltargetform.anchor_title) {
906 document.ltargetform.anchor_title.value = anchorClass[\'titleText\'];
907 document.getElementById(\'rtehtmlarea-browse-links-title-readonly\').innerHTML = anchorClass[\'titleText\'];
908 browse_links_setTitle(anchorClass[\'titleText\']);
909 }
910 if (anchorClass[\'target\']) {
911 if (document.ltargetform.ltarget) {
912 document.ltargetform.ltarget.value = anchorClass[\'target\'];
913 }
914 browse_links_setTarget(anchorClass[\'target\']);
915 } else if (document.ltargetform.ltarget && document.getElementById(\'ltargetrow\').style.display == \'none\') {
916 // Reset target to default if field is not displayed and class has no configured target
917 document.ltargetform.ltarget.value = \'' . ($this->defaultLinkTarget ?: '') . '\';
918 browse_links_setTarget(document.ltargetform.ltarget.value);
919 }
920 break;
921 }
922 }
923 }
924 browse_links_setClass(document.ltargetform.anchor_class.value);
925 }
926 ';
927 }
928
929 /**
930 * @todo Define visibility
931 */
932 public function addTitleSelector() {
933 $title = $this->setTitle ?: ($this->setClass || !$this->classesAnchorDefault[$this->act] ? '' : $this->classesAnchorDefaultTitle[$this->act]);
934 $readOnly = $this->buttonConfig['properties.']['title.']['readOnly'] || $this->buttonConfig[$this->act . '.']['properties.']['title.']['readOnly'];
935 if ($readOnly) {
936 $title = $this->setClass
937 ? $this->classesAnchorClassTitle[$this->setClass]
938 : $this->classesAnchorDefaultTitle[$this->act];
939 }
940 return '
941 <tr>
942 <td><label for="rtehtmlarea-browse-links-anchor_title" id="rtehtmlarea-browse-links-title-label">' . $GLOBALS['LANG']->getLL('anchor_title', TRUE) . ':</label></td>
943 <td colspan="3">
944 <span id="rtehtmlarea-browse-links-title-input" style="display: ' . ($readOnly ? 'none' : 'inline') . ';">
945 <input type="text" id="rtehtmlarea-browse-links-anchor_title" name="anchor_title" value="' . $title . '" ' . $this->doc->formWidth(30) . ' />
946 </span>
947 <span id="rtehtmlarea-browse-links-title-readonly" style="display: ' . ($readOnly ? 'inline' : 'none') . ';">' . $title . '</span>
948 </td>
949 </tr>';
950 }
951
952 /**
953 * Localize a string using the language of the content element rather than the language of the BE interface
954 *
955 * @param string string: the label to be localized
956 * @return string Localized string.
957 */
958 public function getLLContent($string) {
959 return $this->contentLanguageService->sL($string);
960 }
961
962 /**
963 * Localize a label obtained from Page TSConfig
964 *
965 * @param string $string The label to be localized
966 * @param bool $JScharCode If needs to be converted to a array of char numbers
967 * @return string Localized string
968 */
969 public function getPageConfigLabel($string, $JScharCode = TRUE) {
970 if (substr($string, 0, 4) !== 'LLL:') {
971 $label = $string;
972 } else {
973 $label = $GLOBALS['LANG']->sL(trim($string));
974 }
975 $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label));
976 return $JScharCode ? GeneralUtility::quoteJSvalue($label) : $label;
977 }
978
979 }