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