eff6b33906091f2f8df1742198ffaf5adf7d6e0e
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / class.tx_rtehtmlarea_base.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2004-2011 Kasper Skårhøj (kasper@typo3.com)
6 * (c) 2004-2011 Philipp Borgmann <philipp.borgmann@gmx.de>
7 * (c) 2004-2011 Stanislas Rolland <typo3(arobas)sjbr.ca>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * A RTE using the htmlArea editor
31 *
32 * @author Philipp Borgmann <philipp.borgmann@gmx.de>
33 * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
34 *
35 * $Id$ *
36 */
37
38 class tx_rtehtmlarea_base extends t3lib_rteapi {
39 // Configuration of supported browsers
40 var $conf_supported_browser = array (
41 'msie' => array (
42 array (
43 'version' => 6.0,
44 'system' => array(
45 'allowed' => array(
46 'winNT',
47 'win98',
48 'win95',
49 ),
50 ),
51 ),
52 ),
53 'gecko' => array (
54 array (
55 'version' => 1.8,
56 ),
57 ),
58 'webkit' => array (
59 array (
60 'version' => 523,
61 'system' => array(
62 'disallowed' => array(
63 'iOS',
64 'android',
65 ),
66 ),
67 ),
68 ),
69 'opera' => array (
70 array (
71 'version' => 9.62,
72 'system' => array(
73 'disallowed' => array(
74 'iOS',
75 'android',
76 ),
77 ),
78 ),
79 )
80 );
81
82 // Always hide these toolbar buttons (TYPO3 button name)
83 var $conf_toolbar_hide = array (
84 'showhelp', // Has no content yet
85 );
86
87 // The order of the toolbar: the name is the TYPO3-button name
88 var $defaultToolbarOrder;
89
90 // Conversion array: TYPO3 button names to htmlArea button names
91 var $convertToolbarForHtmlAreaArray = array (
92 'showhelp' => 'ShowHelp',
93 'space' => 'space',
94 'bar' => 'separator',
95 'linebreak' => 'linebreak',
96 );
97
98 var $pluginButton = array();
99 var $pluginLabel = array();
100 // Alternative style for RTE <div> tag.
101 public $RTEdivStyle;
102 // Relative path to this extension. It ends with "/"
103 public $extHttpPath;
104 public $backPath = '';
105 // TYPO3 site url
106 public $siteURL;
107 // TYPO3 host url
108 public $hostURL;
109 // Typo3 version
110 public $typoVersion;
111 // Identifies the RTE as being the one from the "rtehtmlarea" extension if any external code needs to know
112 var $ID = 'rtehtmlarea';
113 // If set, the content goes into a regular TEXT area field - for developing testing of transformations.
114 var $debugMode = FALSE;
115 // For the editor
116 var $client;
117
118 /**
119 * Reference to parent object, which is an instance of the TCEforms
120 *
121 * @var t3lib_TCEforms
122 */
123 var $TCEform;
124 var $elementId;
125 var $elementParts;
126 var $tscPID;
127 var $typeVal;
128 var $thePid;
129 var $RTEsetup;
130 var $thisConfig;
131 var $confValues;
132 public $language;
133 public $contentTypo3Language;
134 public $contentISOLanguage;
135 public $contentCharset;
136 public $OutputCharset;
137 var $editorCSS;
138 var $specConf;
139 var $toolbar = array(); // Save the buttons for the toolbar
140 var $toolbarOrderArray = array();
141 protected $pluginEnabledArray = array(); // Array of plugin id's enabled in the current RTE editing area
142 protected $pluginEnabledCumulativeArray = array(); // Cumulative array of plugin id's enabled so far in any of the RTE editing areas of the form
143 protected $cumulativeScripts = array();
144 public $registeredPlugins = array(); // Array of registered plugins indexed by their plugin Id's
145 protected $fullScreen = false;
146
147 /**
148 * Returns true if the RTE is available. Here you check if the browser requirements are met.
149 * If there are reasons why the RTE cannot be displayed you simply enter them as text in ->errorLog
150 *
151 * @return boolean TRUE if this RTE object offers an RTE in the current browser environment
152 */
153 function isAvailable() {
154
155 $this->client = $this->clientInfo();
156 $this->errorLog = array();
157 if (!$this->debugMode) { // If debug-mode, let any browser through
158 $rteIsAvailable = FALSE;
159 $rteConfBrowser = $this->conf_supported_browser;
160 if (is_array($rteConfBrowser)) {
161 foreach ($rteConfBrowser as $browser => $browserConf) {
162 if ($browser == $this->client['browser']) {
163 // Config for Browser found, check it:
164 if (is_array($browserConf)) {
165 foreach ($browserConf as $browserConfSub) {
166 if ($browserConfSub['version'] <= $this->client['version'] || empty($browserConfSub['version'])) {
167 // Version is supported
168 if (is_array($browserConfSub['system'])) {
169 // Check against allowed systems
170 if (is_array($browserConfSub['system']['allowed'])) {
171 foreach ($browserConfSub['system']['allowed'] as $system) {
172 if (in_array($system, $this->client['all_systems'])) {
173 $rteIsAvailable = TRUE;
174 break;
175 }
176 }
177 } else {
178 // All allowed
179 $rteIsAvailable = TRUE;
180 }
181 // Check against disallowed systems
182 if (is_array($browserConfSub['system']['disallowed'])) {
183 foreach ($browserConfSub['system']['disallowed'] as $system) {
184 if (in_array($system, $this->client['all_systems'])) {
185 $rteIsAvailable = FALSE;
186 break;
187 }
188 }
189 }
190 } else {
191 // No system config: system is supported
192 $rteIsAvailable = TRUE;
193 break;
194 }// End of System
195 }// End of Version
196 }// End of foreach-BrowserSubpart
197 } else {
198 // no config for this browser found, so all versions or system with this browsers are allow
199 $rteIsAvailable = TRUE;
200 break;
201 }
202 } // End of Browser Check
203 } // foreach: Browser Check
204 } else {
205 // no Browser config for this RTE-Editor, so all Clients are allow
206 }
207 if (!$rteIsAvailable) {
208 $this->errorLog[] = 'RTE: Browser not supported.';
209 }
210 if (t3lib_div::int_from_ver(TYPO3_version) < 4000000) {
211 $rteIsAvailable = FALSE;
212 $this->errorLog[] = 'rte: This version of htmlArea RTE cannot run under this version of TYPO3.';
213 }
214 }
215 return $rteIsAvailable;
216 }
217
218 /**
219 * Draws the RTE as an iframe
220 *
221 * @param object Reference to parent object, which is an instance of the TCEforms.
222 * @param string The table name
223 * @param string The field name
224 * @param array The current row from which field is being rendered
225 * @param array Array of standard content for rendering form fields from TCEforms. See TCEforms for details on this. Includes for instance the value and the form field name, java script actions and more.
226 * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
227 * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
228 * @param string Record "type" field value.
229 * @param string Relative path for images/links in RTE; this is used when the RTE edits content from static files where the path of such media has to be transformed forth and back!
230 * @param integer PID value of record (true parent page id)
231 * @return string HTML code for RTE!
232 */
233
234 function drawRTE($parentObject, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
235 global $BE_USER, $LANG, $TYPO3_DB, $TYPO3_CONF_VARS;
236
237 $this->TCEform = $parentObject;
238 $inline = $this->TCEform->inline;
239 $LANG->includeLLFile('EXT:' . $this->ID . '/locallang.xml');
240 $this->client = $this->clientInfo();
241 $this->typoVersion = t3lib_div::int_from_ver(TYPO3_version);
242 $this->userUid = 'BE_' . $BE_USER->user['uid'];
243
244 // Draw form element:
245 if ($this->debugMode) { // Draws regular text area (debug mode)
246 $item = parent::drawRTE($this->TCEform, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue);
247 } else { // Draw real RTE
248
249 /* =======================================
250 * INIT THE EDITOR-SETTINGS
251 * =======================================
252 */
253 // Set backPath
254 $this->backPath = $this->TCEform->backPath;
255 // Get the path to this extension:
256 $this->extHttpPath = $this->backPath . t3lib_extMgm::extRelPath($this->ID);
257 // Get the site URL
258 $this->siteURL = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
259 // Get the host URL
260 $this->hostURL = $this->siteURL . TYPO3_mainDir;
261 // Element ID + pid
262 $this->elementId = $PA['itemFormElName']; // Form element name
263 $this->elementParts = explode('][',preg_replace('/\]$/','',preg_replace('/^(TSFE_EDIT\[data\]\[|data\[)/','',$this->elementId)));
264 // Find the page PIDs:
265 list($this->tscPID,$this->thePid) = t3lib_BEfunc::getTSCpid(trim($this->elementParts[0]),trim($this->elementParts[1]),$thePidValue);
266
267 // Record "types" field value:
268 $this->typeVal = $RTEtypeVal; // TCA "types" value for record
269
270 // Find "thisConfig" for record/editor:
271 unset($this->RTEsetup);
272 $this->RTEsetup = $BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($this->tscPID));
273 $this->thisConfig = $thisConfig;
274
275 // Special configuration and default extras:
276 $this->specConf = $specConf;
277
278 if ($this->thisConfig['forceHTTPS']) {
279 $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
280 $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
281 $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
282 }
283 // Register RTE windows
284 $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
285 $textAreaId = preg_replace('/[^a-zA-Z0-9_:.-]/', '_', $PA['itemFormElName']);
286 $textAreaId = htmlspecialchars(preg_replace('/^[^a-zA-Z]/', 'x', $textAreaId));
287
288 /* =======================================
289 * LANGUAGES & CHARACTER SETS
290 * =======================================
291 */
292
293 // Languages: interface and content
294 $this->language = $LANG->lang;
295 if ($this->language=='default' || !$this->language) {
296 $this->language='en';
297 }
298 $this->contentTypo3Language = ($this->language == 'en') ? 'default' : $this->language;
299 $this->contentISOLanguage = 'en';
300 $this->contentLanguageUid = ($row['sys_language_uid'] > 0) ? $row['sys_language_uid'] : 0;
301 if (t3lib_extMgm::isLoaded('static_info_tables')) {
302 if ($this->contentLanguageUid) {
303 $tableA = 'sys_language';
304 $tableB = 'static_languages';
305 $languagesUidsList = $this->contentLanguageUid;
306 $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
307 $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
308 $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
309 $whereClause .= t3lib_BEfunc::BEenableFields($tableA);
310 $whereClause .= t3lib_BEfunc::deleteClause($tableA);
311 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
312 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
313 $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']).(trim($languageRow['lg_country_iso_2'])?'_'.trim($languageRow['lg_country_iso_2']):''));
314 $this->contentTypo3Language = trim($languageRow['lg_typo3']) ? strtolower(trim($languageRow['lg_typo3'])) : 'default';
315 }
316 } else {
317 $this->contentISOLanguage = trim($this->thisConfig['defaultContentLanguage']) ? trim($this->thisConfig['defaultContentLanguage']) : 'en';
318 $selectFields = 'lg_iso_2, lg_typo3';
319 $tableAB = 'static_languages';
320 $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
321 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
322 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
323 $this->contentTypo3Language = trim($languageRow['lg_typo3']) ? strtolower(trim($languageRow['lg_typo3'])) : 'default';
324 }
325 }
326 }
327
328 // Character sets: interface and content
329 $this->charset = $LANG->charSet;
330 $this->OutputCharset = $this->charset;
331
332 $this->contentCharset = $LANG->csConvObj->charSetArray[$this->contentTypo3Language];
333 $this->contentCharset = $this->contentCharset ? $this->contentCharset : 'iso-8859-1';
334 $this->origContentCharSet = $this->contentCharset;
335 $this->contentCharset = (trim($TYPO3_CONF_VARS['BE']['forceCharset']) ? trim($TYPO3_CONF_VARS['BE']['forceCharset']) : $this->contentCharset);
336
337 /* =======================================
338 * TOOLBAR CONFIGURATION
339 * =======================================
340 */
341 $this->initializeToolbarConfiguration();
342
343 /* =======================================
344 * SET STYLES
345 * =======================================
346 */
347
348 $RTEWidth = isset($BE_USER->userTS['options.']['RTESmallWidth']) ? $BE_USER->userTS['options.']['RTESmallWidth'] : '530';
349 $RTEHeight = isset($BE_USER->userTS['options.']['RTESmallHeight']) ? $BE_USER->userTS['options.']['RTESmallHeight'] : '380';
350 $RTEWidth = $RTEWidth + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeWidthIncrement']) ? $BE_USER->userTS['options.']['RTELargeWidthIncrement'] : '150') : 0);
351 $RTEWidth -= ($inline->getStructureDepth() > 0 ? ($inline->getStructureDepth()+1)*$inline->getLevelMargin() : 0);
352 $RTEWidthOverride = (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteWidth']) && trim($GLOBALS['BE_USER']->uc['rteWidth'])) ? trim($GLOBALS['BE_USER']->uc['rteWidth']) : trim($this->thisConfig['RTEWidthOverride']);
353 if ($RTEWidthOverride) {
354 if (strstr($RTEWidthOverride, '%')) {
355 if ($this->client['browser'] != 'msie') {
356 $RTEWidth = (intval($RTEWidthOverride) > 0) ? $RTEWidthOverride : '100%';
357 }
358 } else {
359 $RTEWidth = (intval($RTEWidthOverride) > 0) ? intval($RTEWidthOverride) : $RTEWidth;
360 }
361 }
362 $RTEWidth = strstr($RTEWidth, '%') ? $RTEWidth : $RTEWidth . 'px';
363 $RTEHeight = $RTEHeight + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeHeightIncrement']) ? $BE_USER->userTS['options.']['RTELargeHeightIncrement'] : 0) : 0);
364 $RTEHeightOverride = (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteHeight']) && intval($GLOBALS['BE_USER']->uc['rteHeight'])) ? intval($GLOBALS['BE_USER']->uc['rteHeight']) : intval($this->thisConfig['RTEHeightOverride']);
365 $RTEHeight = ($RTEHeightOverride > 0) ? $RTEHeightOverride : $RTEHeight;
366 $editorWrapWidth = '99%';
367 $editorWrapHeight = '100%';
368 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:'.$RTEWidth.'; border: 1px solid black; padding: 2px 2px 2px 2px;';
369 // Check if wizard_rte called this for fullscreen edtition; if so, change the size of the RTE to fullscreen using JS
370 if (basename(PATH_thisScript) == 'wizard_rte.php') {
371 $this->fullScreen = TRUE;
372 $editorWrapWidth = '100%';
373 $editorWrapHeight = '100%';
374 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:100%; width:100%; border: 1px solid black; padding: 2px 0px 2px 2px;';
375 }
376 /* =======================================
377 * LOAD CSS AND JAVASCRIPT
378 * =======================================
379 */
380 // Preloading the pageStyle and including RTE skin stylesheets
381 $this->addPageStyle();
382 $this->addSkin();
383 // Re-initialize the scripts array so that only the cumulative set of plugins of the last RTE on the page is used
384 $this->cumulativeScripts[$this->TCEform->RTEcounter] = array();
385 $this->includeScriptFiles($this->TCEform->RTEcounter);
386 $this->buildJSMainLangFile($this->TCEform->RTEcounter);
387 // Register RTE in JS:
388 $this->TCEform->additionalJS_post[] = $this->registerRTEinJS($this->TCEform->RTEcounter, $table, $row['uid'], $field, $textAreaId);
389 // Set the save option for the RTE:
390 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId, $PA['itemFormElName']);
391 $this->TCEform->additionalJS_delete[] = $this->setDeleteRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
392 // Loading JavaScript files and code
393 if ($this->TCEform->RTEcounter == 1) {
394 $this->TCEform->additionalJS_pre['rtehtmlarea-loadJScode'] = $this->loadJScode($this->TCEform->RTEcounter);
395 }
396 $this->TCEform->additionalCode_pre['rtehtmlarea-loadJSfiles'] = $this->loadJSfiles($this->TCEform->RTEcounter);
397 $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
398 $pageRenderer->enableExtJSQuickTips();
399 if (!$GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts']) {
400 $pageRenderer->enableExtJsDebug();
401 }
402 $pageRenderer->addJsFile('../t3lib/js/extjs/notifications.js');
403 /* =======================================
404 * DRAW THE EDITOR
405 * =======================================
406 */
407
408 // Transform value:
409 $value = $this->transformContent('rte',$PA['itemFormElValue'],$table,$field,$row,$specConf,$thisConfig,$RTErelPath,$thePidValue);
410
411 // Further content transformation by registered plugins
412 foreach ($this->registeredPlugins as $pluginId => $plugin) {
413 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "transformContent")) {
414 $value = $plugin->transformContent($value);
415 }
416 }
417 // Draw the textarea
418 $visibility = 'hidden';
419 $item = $this->triggerField($PA['itemFormElName']).'
420 <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $LANG->getLL('Please wait') . '</div>
421 <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth . '; height:' . $editorWrapHeight . ';">
422 <textarea id="RTEarea' . $textAreaId . '" name="'.htmlspecialchars($PA['itemFormElName']).'" rows="0" cols="0" style="'.t3lib_div::deHSCentities(htmlspecialchars($this->RTEdivStyle)).'">'.t3lib_div::formatForTextarea($value).'</textarea>
423 </div>' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? '<div id="HTMLAreaLog"></div>' : '') . '
424 ';
425 }
426
427 // Return form item:
428 return $item;
429 }
430
431 /**
432 * Add link to content style sheet to document header
433 *
434 * @return void
435 */
436 protected function addPageStyle() {
437 $this->addStyleSheet(
438 'rtehtmlarea-page-style',
439 $this->getContentCssFileName(),
440 'htmlArea RTE Content CSS',
441 'alternate stylesheet'
442 );
443 }
444
445 /**
446 * Get the name of the contentCSS file to use
447 *
448 * @return the full file name of the content css file to use
449 */
450 protected function getContentCssFileName() {
451 // Get stylesheet file name from Page TSConfig if any
452 $fileName = trim($this->thisConfig['contentCSS']);
453 if ($fileName) {
454 $fileName = $this->getFullFileName($fileName);
455 }
456 $absolutePath = $fileName
457 ? t3lib_div::resolveBackPath(PATH_site . (($this->is_FE() || $this->isFrontendEditActive()) ? '' : TYPO3_mainDir) . $fileName)
458 : '';
459 // Fallback to default content css file if configured file does not exists or is of zero size
460 if (!$fileName || !file_exists($absolutePath) || !filesize($absolutePath)) {
461 $fileName = $this->getFullFileName('EXT:' . $this->ID . '/res/contentcss/default.css');
462 }
463 return $fileName;
464 }
465
466 /**
467 * Add links to skin style sheet(s) to document header
468 *
469 * @return void
470 */
471 protected function addSkin() {
472 // Get skin file name from Page TSConfig if any
473 $skinFilename = trim($this->thisConfig['skin']) ? trim($this->thisConfig['skin']) : 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
474 $this->editorCSS = $this->getFullFileName($skinFilename);
475 $skinDir = dirname($this->editorCSS);
476 // Editing area style sheet
477 $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
478 $this->addStyleSheet(
479 'rtehtmlarea-editing-area-skin',
480 $this->editedContentCSS
481 );
482 // Main skin
483 $this->addStyleSheet(
484 'rtehtmlarea-skin',
485 $this->editorCSS
486 );
487 // Additional icons from registered plugins
488 foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
489 if (is_object($this->registeredPlugins[$pluginId])) {
490 $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
491 if ($pathToSkin) {
492 $key = $this->registeredPlugins[$pluginId]->getExtensionKey();
493 $this->addStyleSheet(
494 'rtehtmlarea-plugin-' . $pluginId . '-skin',
495 ($this->is_FE() ? t3lib_extMgm::siteRelPath($key) : $this->backPath . t3lib_extMgm::extRelPath($key)) . $pathToSkin
496 );
497 }
498 }
499 }
500 }
501
502 /**
503 * Add style sheet file to document header
504 *
505 * @param string $key: some key identifying the style sheet
506 * @param string $href: uri to the style sheet file
507 * @param string $title: value for the title attribute of the link element
508 * @return string $relation: value for the rel attribute of the link element
509 * @return void
510 */
511 protected function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
512 // If it was not known that an RTE-enabled would be created when the page was first created, the css would not be added to head
513 if (is_object($this->TCEform->inline) && $this->TCEform->inline->isAjaxCall) {
514 $this->TCEform->additionalCode_pre[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '" title="' . $title. '" />';
515 } else {
516 $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
517 $pageRenderer->addCssFile($href, $relation, 'screen', $title);
518 }
519 }
520
521 /**
522 * Initialize toolbar configuration and enable registered plugins
523 *
524 * @return void
525 */
526 protected function initializeToolbarConfiguration() {
527
528 // Enable registred plugins
529 $this->enableRegisteredPlugins();
530
531 // Configure toolbar
532 $this->setToolbar();
533
534 // Check if some plugins need to be disabled
535 $this->setPlugins();
536
537 // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
538 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = $this->pluginEnabledArray;
539 if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])) {
540 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray,$this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])));
541 }
542 }
543
544 /**
545 * Add registered plugins to the array of enabled plugins
546 *
547 */
548 function enableRegisteredPlugins() {
549 global $TYPO3_CONF_VARS;
550 // Traverse registered plugins
551 if (is_array($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'])) {
552 foreach($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
553 $plugin = false;
554 if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
555 $plugin = t3lib_div::getUserObj($pluginObjectConfiguration['objectReference']);
556 }
557 if (is_object($plugin)) {
558 if ($plugin->main($this)) {
559 $this->registeredPlugins[$pluginId] = $plugin;
560 // Override buttons from previously registered plugins
561 $pluginButtons = t3lib_div::trimExplode(',', $plugin->getPluginButtons(), 1);
562 foreach ($this->pluginButton as $previousPluginId => $buttonList) {
563 $this->pluginButton[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginButton[$previousPluginId], 1), $pluginButtons));
564 }
565 $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
566 $pluginLabels = t3lib_div::trimExplode(',', $plugin->getPluginLabels(), 1);
567 foreach ($this->pluginLabel as $previousPluginId => $labelList) {
568 $this->pluginLabel[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginLabel[$previousPluginId], 1), $pluginLabels));
569 }
570 $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
571 $this->pluginEnabledArray[] = $pluginId;
572 }
573 }
574 }
575 }
576 // Process overrides
577 $hidePlugins = array();
578 foreach ($this->registeredPlugins as $pluginId => $plugin) {
579 if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
580 $hidePlugins[] = $pluginId;
581 }
582 }
583 $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
584 }
585
586 /**
587 * Set the toolbar config (only in this PHP-Object, not in JS):
588 *
589 */
590
591 function setToolbar() {
592 global $BE_USER;
593
594 if ($this->client['browser'] == 'msie' || $this->client['browser'] == 'opera') {
595 $this->thisConfig['keepButtonGroupTogether'] = 0;
596 }
597
598 $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
599 bar, formattext, bold, strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
600 bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line,
601 bar, left, center, right, justifyfull,
602 bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft, language, showlanguagemarks,
603 bar, textcolor, bgcolor, textindicator,
604 bar, editelement, emoticon, insertcharacter, link, unlink, image, table,' . (($this->thisConfig['hideTableOperationsInToolbar'] && is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['toggleborders.']) && $this->thisConfig['buttons.']['toggleborders.']['keepInToolbar']) ? ' toggleborders,': '') . ' user, acronym, bar, findreplace, spellcheck,
605 bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pastetoggle, pastebehaviour, bar, undo, redo, bar, showhelp, about, linebreak,
606 ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '': 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
607 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
608 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
609
610 // Additional buttons from registered plugins
611 foreach($this->registeredPlugins as $pluginId => $plugin) {
612 if ($this->isPluginEnabled($pluginId)) {
613 $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
614 }
615 }
616 $toolbarOrder = $this->thisConfig['toolbarOrder'] ? $this->thisConfig['toolbarOrder'] : $this->defaultToolbarOrder;
617
618 // Getting rid of undefined buttons
619 $this->toolbarOrderArray = array_intersect(t3lib_div::trimExplode(',', $toolbarOrder, 1), t3lib_div::trimExplode(',', $this->defaultToolbarOrder, 1));
620 $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
621
622 // Fetching specConf for field from backend
623 $pList = is_array($this->specConf['richtext']['parameters']) ? implode(',',$this->specConf['richtext']['parameters']) : '';
624 if ($pList != '*') { // If not all
625 $show = is_array($this->specConf['richtext']['parameters']) ? $this->specConf['richtext']['parameters'] : array();
626 if ($this->thisConfig['showButtons']) {
627 if (!t3lib_div::inList($this->thisConfig['showButtons'],'*')) {
628 $show = array_unique(array_merge($show,t3lib_div::trimExplode(',',$this->thisConfig['showButtons'],1)));
629 } else {
630 $show = array_unique(array_merge($show, $toolbarOrder));
631 }
632 }
633 if (is_array($this->thisConfig['showButtons.'])) {
634 foreach ($this->thisConfig['showButtons.'] as $buttonId => $value) {
635 if ($value) $show[] = $buttonId;
636 }
637 $show = array_unique($show);
638 }
639 } else {
640 $show = $toolbarOrder;
641 }
642
643 // Resticting to RTEkeyList for backend user
644 if(is_object($BE_USER)) {
645 $RTEkeyList = isset($BE_USER->userTS['options.']['RTEkeyList']) ? $BE_USER->userTS['options.']['RTEkeyList'] : '*';
646 if ($RTEkeyList != '*') { // If not all
647 $show = array_intersect($show, t3lib_div::trimExplode(',',$RTEkeyList,1));
648 }
649 }
650
651 // Hiding buttons of disabled plugins
652 $hideButtons = array('space', 'bar', 'linebreak');
653 foreach ($this->pluginButton as $pluginId => $buttonList) {
654 if (!$this->isPluginEnabled($pluginId)) {
655 $buttonArray = t3lib_div::trimExplode(',',$buttonList,1);
656 foreach ($buttonArray as $button) {
657 $hideButtons[] = $button;
658 }
659 }
660 }
661
662 // Hiding labels of disabled plugins
663 foreach ($this->pluginLabel as $pluginId => $label) {
664 if (!$this->isPluginEnabled($pluginId)) {
665 $hideButtons[] = $label;
666 }
667 }
668
669 // Hiding buttons
670 $show = array_diff($show, $this->conf_toolbar_hide, t3lib_div::trimExplode(',',$this->thisConfig['hideButtons'],1));
671
672 // Apply toolbar constraints from registered plugins
673 foreach ($this->registeredPlugins as $pluginId => $plugin) {
674 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "applyToolbarConstraints")) {
675 $show = $plugin->applyToolbarConstraints($show);
676 }
677 }
678 // Getting rid of the buttons for which we have no position
679 $show = array_intersect($show, $toolbarOrder);
680 $this->toolbar = $show;
681 }
682
683 /**
684 * Disable some plugins
685 *
686 */
687 function setPlugins() {
688
689 // Disabling a plugin that adds buttons if none of its buttons is in the toolbar
690 $hidePlugins = array();
691 foreach ($this->pluginButton as $pluginId => $buttonList) {
692 if ($this->registeredPlugins[$pluginId]->addsButtons()) {
693 $showPlugin = false;
694 $buttonArray = t3lib_div::trimExplode(',', $buttonList, 1);
695 foreach ($buttonArray as $button) {
696 if (in_array($button, $this->toolbar)) {
697 $showPlugin = true;
698 }
699 }
700 if (!$showPlugin) {
701 $hidePlugins[] = $pluginId;
702 }
703 }
704 }
705 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
706
707 // Hiding labels of disabled plugins
708 $hideLabels = array();
709 foreach ($this->pluginLabel as $pluginId => $label) {
710 if (!$this->isPluginEnabled($pluginId)) {
711 $hideLabels[] = $label;
712 }
713 }
714 $this->toolbar = array_diff($this->toolbar, $hideLabels);
715
716 // Adding plugins declared as prerequisites by enabled plugins
717 $requiredPlugins = array();
718 foreach ($this->registeredPlugins as $pluginId => $plugin) {
719 if ($this->isPluginEnabled($pluginId)) {
720 $requiredPlugins = array_merge($requiredPlugins, t3lib_div::trimExplode(',', $plugin->getRequiredPlugins(), 1));
721 }
722 }
723 $requiredPlugins = array_unique($requiredPlugins);
724 foreach ($requiredPlugins as $pluginId) {
725 if (is_object($this->registeredPlugins[$pluginId]) && !$this->isPluginEnabled($pluginId)) {
726 $this->pluginEnabledArray[] = $pluginId;
727 }
728 }
729 $this->pluginEnabledArray = array_unique($this->pluginEnabledArray);
730
731 // Completing the toolbar conversion array for htmlArea
732 foreach ($this->registeredPlugins as $pluginId => $plugin) {
733 if ($this->isPluginEnabled($pluginId)) {
734 $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
735 }
736 }
737 }
738
739 /**
740 * Convert the TYPO3 names of buttons into the names for htmlArea RTE
741 *
742 * @param string buttonname (typo3-name)
743 * @return string buttonname (htmlarea-name)
744 */
745
746 function convertToolbarForHTMLArea($button) {
747 return $this->convertToolbarForHtmlAreaArray[$button];
748 }
749 /**
750 * Return the HTML code for loading the Javascript files
751 *
752 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
753 *
754 * @return void
755 */
756 protected function includeScriptFiles($RTEcounter) {
757 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea.js', 'htmlarea', 'js', '', TRUE);
758 if ($this->client['browser'] == 'msie') {
759 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-ie.js', 'htmlarea-ie', 'js', '', TRUE);
760 } else {
761 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-gecko.js', 'htmlarea-gecko', 'js', '', TRUE);
762 }
763 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
764 $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() : $this->ID;
765 $this->writeTemporaryFile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $pluginId . '/' . strtolower(preg_replace('/([a-z])([A-Z])([a-z])/', "$1".'-'."$2"."$3", $pluginId)) . '.js', $pluginId, 'js', '', TRUE);
766 }
767 }
768 /**
769 * Return the HTML code for loading the Javascript files
770 *
771 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
772 *
773 * @return string the html code for loading the Javascript Files
774 */
775 protected function loadJSfiles($RTEcounter) {
776 $loadJavascriptCode = '<script type="text/javascript" src="' . $this->doConcatenate($RTEcounter) . '"></script>' . LF;
777 $loadJavascriptCode .= t3lib_div::wrapJS('
778 if (typeof(RTEarea) == "undefined") {
779 RTEarea = new Object();
780 RTEarea[0] = new Object();
781 RTEarea[0].version = "' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['version'] . '";
782 RTEarea[0].editorUrl = "' . $this->extHttpPath . 'htmlarea/";
783 RTEarea[0].editorCSS = "' . t3lib_div::createVersionNumberedFilename($this->editorCSS) . '";
784 RTEarea[0].editorSkin = "' . dirname($this->editorCSS) . '/";
785 RTEarea[0].editedContentCSS = "' . t3lib_div::createVersionNumberedFilename($this->editedContentCSS) . '";
786 RTEarea[0].hostUrl = "' . $this->hostURL . '";
787 RTEarea[0].enableDebugMode = ' . ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableDebugMode'] ? 'true' : 'false') . ';
788 RTEarea.init = function() {
789 if (typeof(HTMLArea) == "undefined" || !Ext.isReady) {
790 window.setTimeout("RTEarea.init();", 40);
791 } else {
792 Ext.QuickTips.init();
793 HTMLArea.init();
794 }
795 };
796 RTEarea.initEditor = function(editorNumber) {
797 if (typeof(HTMLArea) == "undefined") {
798 RTEarea.initEditor.defer(40, null, [editorNumber]);
799 } else {
800 HTMLArea.initEditor(editorNumber);
801 }
802 };
803 }'
804 );
805 return $loadJavascriptCode;
806 }
807
808 /**
809 * Return the Javascript code for initializing the RTE
810 *
811 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
812 *
813 * @return string the Javascript code for initializing the RTE
814 */
815 function loadJScode($RTEcounter) {
816 return TAB . 'RTEarea.init();';
817 }
818
819 /**
820 * Return the Javascript code for configuring the RTE
821 *
822 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
823 * @param string $table: The table that includes this RTE (optional, necessary for IRRE).
824 * @param string $uid: The uid of that table that includes this RTE (optional, necessary for IRRE).
825 * @param string $field: The field of that record that includes this RTE (optional).
826 *
827 * @return string the Javascript code for configuring the RTE
828 */
829 function registerRTEinJS($RTEcounter, $table='', $uid='', $field='', $textAreaId = '') {
830 $configureRTEInJavascriptString = '
831 if (typeof(configureEditorInstance) == "undefined") {
832 configureEditorInstance = new Object();
833 }
834 configureEditorInstance["' . $textAreaId . '"] = function() {
835 if (typeof(RTEarea) == "undefined" || typeof(HTMLArea) == "undefined") {
836 window.setTimeout("configureEditorInstance[\'' . $textAreaId . '\']();", 40);
837 } else {
838 editornumber = "' . $textAreaId . '";
839 RTEarea[editornumber] = new Object();
840 RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";
841 RTEarea[editornumber].number = editornumber;
842 RTEarea[editornumber].deleted = false;
843 RTEarea[editornumber].textAreaId = "' . $textAreaId . '";
844 RTEarea[editornumber].id = "RTEarea" + editornumber;
845 RTEarea[editornumber].RTEWidthOverride = "' . ((is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteWidth']) && trim($GLOBALS['BE_USER']->uc['rteWidth'])) ? trim($GLOBALS['BE_USER']->uc['rteWidth']) : trim($this->thisConfig['RTEWidthOverride'])) . '";
846 RTEarea[editornumber].RTEHeightOverride = "' . ((is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteHeight']) && intval($GLOBALS['BE_USER']->uc['rteHeight'])) ? intval($GLOBALS['BE_USER']->uc['rteHeight']) : intval($this->thisConfig['RTEHeightOverride'])) . '";
847 RTEarea[editornumber].resizable = ' . ((is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteResize']) && $GLOBALS['BE_USER']->uc['rteResize']) ? 'true' : (trim($this->thisConfig['rteResize']) ? 'true' : 'false')) . ';
848 RTEarea[editornumber].maxHeight = "' . ((is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteMaxHeight']) && intval($GLOBALS['BE_USER']->uc['rteMaxHeight'])) ? trim($GLOBALS['BE_USER']->uc['rteMaxHeight']) : (intval($this->thisConfig['rteMaxHeight']) ? intval($this->thisConfig['rteMaxHeight']) : '2000')) . '";
849 RTEarea[editornumber].fullScreen = ' . ($this->fullScreen ? 'true' : 'false') . ';
850 RTEarea[editornumber].showStatusBar = ' . (trim($this->thisConfig['showStatusBar'])?'true':'false') . ';
851 RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean'])?'true':'false') . ';
852 RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->thisConfig['removeComments'])?'true':'false') . ';
853 RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs'])?'true':'false') . ';
854 RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing'])?'true':'false') . ';
855 RTEarea[editornumber].removeTrailingBR = ' . (trim($this->thisConfig['removeTrailingBR'])?'true':'false') . ';
856 RTEarea[editornumber].useCSS = ' . (trim($this->thisConfig['useCSS'])?'true':'false') . ';
857 RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->thisConfig['keepButtonGroupTogether'])?'true':'false') . ';
858 RTEarea[editornumber].disablePCexamples = ' . (trim($this->thisConfig['disablePCexamples'])?'true':'false') . ';
859 RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->thisConfig['showTagFreeClasses'])?'true':'false') . ';
860 RTEarea[editornumber].useHTTPS = ' . ((trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'])?'true':'false') . ';
861 RTEarea[editornumber].tceformsNested = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true) : '[]') . ';
862 RTEarea[editornumber].dialogueWindows = new Object();';
863 if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])) {
864 $configureRTEInJavascriptString .= '
865 RTEarea[editornumber].dialogueWindows.positionFromTop = ' . intval($this->thisConfig['dialogueWindows.']['defaultPositionFromTop']) . ';';
866 }
867 if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])) {
868 $configureRTEInJavascriptString .= '
869 RTEarea[editornumber].dialogueWindows.positionFromLeft = ' . intval($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft']) . ';';
870 }
871 // The following properties apply only to the backend
872 if (!$this->is_FE()) {
873 $configureRTEInJavascriptString .= '
874 RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '";
875 RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '";
876 RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '";
877 RTEarea[editornumber].userUid = "' . $this->userUid . '";';
878 }
879
880 // Setting the plugin flags
881 $configureRTEInJavascriptString .= '
882 RTEarea[editornumber].plugin = new Object();
883 RTEarea[editornumber].pathToPluginDirectory = new Object();';
884 foreach ($this->pluginEnabledArray as $pluginId) {
885 $configureRTEInJavascriptString .= '
886 RTEarea[editornumber].plugin.'.$pluginId.' = true;';
887 if (is_object($this->registeredPlugins[$pluginId])) {
888 $pathToPluginDirectory = $this->registeredPlugins[$pluginId]->getPathToPluginDirectory();
889 if ($pathToPluginDirectory) {
890 $configureRTEInJavascriptString .= '
891 RTEarea[editornumber].pathToPluginDirectory.'.$pluginId.' = "' . $pathToPluginDirectory . '";';
892 }
893 }
894 }
895
896 // Setting the buttons configuration
897 $configureRTEInJavascriptString .= '
898 RTEarea[editornumber].buttons = new Object();';
899 if (is_array($this->thisConfig['buttons.'])) {
900 foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) {
901 $button = substr($buttonIndex, 0, -1);
902 if (is_array($conf)) {
903 $configureRTEInJavascriptString .= '
904 RTEarea[editornumber].buttons.'.$button.' = ' . $this->buildNestedJSArray($conf) . ';';
905 }
906 }
907 }
908
909 // Setting the list of tags to be removed if specified in the RTE config
910 if (trim($this->thisConfig['removeTags'])) {
911 $configureRTEInJavascriptString .= '
912 RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTags'], 1)) . ')$/i;';
913 }
914
915 // Setting the list of tags to be removed with their contents if specified in the RTE config
916 if (trim($this->thisConfig['removeTagsAndContents'])) {
917 $configureRTEInJavascriptString .= '
918 RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTagsAndContents'], 1)) . ')$/i;';
919 }
920 // Process default style configuration
921 $configureRTEInJavascriptString .= '
922 RTEarea[editornumber].defaultPageStyle = "' . $this->writeTemporaryFile('', 'defaultPageStyle', 'css', $this->buildStyleSheet()) . '";';
923 // Setting the pageStyle
924 $configureRTEInJavascriptString .= '
925 RTEarea[editornumber].pageStyle = "' . t3lib_div::createVersionNumberedFilename($this->getContentCssFileName()) .'";';
926 // Process classes configuration
927 $classesConfigurationRequired = false;
928 foreach ($this->registeredPlugins as $pluginId => $plugin) {
929 if ($this->isPluginEnabled($pluginId)) {
930 $classesConfigurationRequired = $classesConfigurationRequired || $plugin->requiresClassesConfiguration();
931 }
932 }
933 if ($classesConfigurationRequired) {
934 $configureRTEInJavascriptString .= $this->buildJSClassesConfig($RTEcounter);
935 }
936 // Add Javascript configuration for registered plugins
937 foreach ($this->registeredPlugins as $pluginId => $plugin) {
938 if ($this->isPluginEnabled($pluginId)) {
939 $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber');
940 }
941 }
942 // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call
943 $configureRTEInJavascriptString .= '
944 RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . ';
945 RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . ';
946 RTEarea.initEditor(editornumber);
947 }
948 };
949 configureEditorInstance["' . $textAreaId . '"]();';
950 return $configureRTEInJavascriptString;
951 }
952
953 /**
954 * Return true, if the plugin can be loaded
955 *
956 * @param string $pluginId: The identification string of the plugin
957 *
958 * @return boolean true if the plugin can be loaded
959 */
960
961 function isPluginEnabled($pluginId) {
962 return in_array($pluginId, $this->pluginEnabledArray);
963 }
964
965 /**
966 * Build the default content style sheet
967 *
968 * @return string Style sheet
969 */
970 function buildStyleSheet() {
971
972 if (!trim($this->thisConfig['ignoreMainStyleOverride'])) {
973 $mainStyle_font = $this->thisConfig['mainStyle_font'] ? $this->thisConfig['mainStyle_font']: 'Verdana,sans-serif';
974
975 $mainElements = array();
976 $mainElements['P'] = $this->thisConfig['mainStyleOverride_add.']['P'];
977 $elList = explode(',','H1,H2,H3,H4,H5,H6,PRE');
978 foreach ($elList as $elListName) {
979 if ($this->thisConfig['mainStyleOverride_add.'][$elListName]) {
980 $mainElements[$elListName] = $this->thisConfig['mainStyleOverride_add.'][$elListName];
981 }
982 }
983
984 $addElementCode = '';
985 foreach ($mainElements as $elListName => $elValue) {
986 $addElementCode .= strToLower($elListName) . ' {' . $elValue . '}' . LF;
987 }
988
989 $stylesheet = $this->thisConfig['mainStyleOverride'] ? $this->thisConfig['mainStyleOverride'] : LF .
990 'body.htmlarea-content-body { font-family: ' . $mainStyle_font .
991 '; font-size: '.($this->thisConfig['mainStyle_size'] ? $this->thisConfig['mainStyle_size'] : '12px') .
992 '; color: '.($this->thisConfig['mainStyle_color']?$this->thisConfig['mainStyle_color'] : 'black') .
993 '; background-color: '.($this->thisConfig['mainStyle_bgcolor'] ? $this->thisConfig['mainStyle_bgcolor'] : 'white') .
994 ';'.$this->thisConfig['mainStyleOverride_add.']['BODY'].'}' . LF .
995 'td { ' . $this->thisConfig['mainStyleOverride_add.']['TD'].'}' . LF .
996 'div { ' . $this->thisConfig['mainStyleOverride_add.']['DIV'].'}' . LF .
997 'pre { ' . $this->thisConfig['mainStyleOverride_add.']['PRE'].'}' . LF .
998 'ol { ' . $this->thisConfig['mainStyleOverride_add.']['OL'].'}' . LF .
999 'ul { ' . $this->thisConfig['mainStyleOverride_add.']['UL'].'}' . LF .
1000 'blockquote { ' . $this->thisConfig['mainStyleOverride_add.']['BLOCKQUOTE'].'}' . LF .
1001 $addElementCode;
1002
1003 if (is_array($this->thisConfig['inlineStyle.'])) {
1004 $stylesheet .= LF . implode(LF, $this->thisConfig['inlineStyle.']) . LF;
1005 }
1006 } else {
1007 $stylesheet = '/* mainStyleOverride and inlineStyle properties ignored. */';
1008 }
1009 return $stylesheet;
1010 }
1011
1012 /**
1013 * Return Javascript configuration of classes
1014 *
1015 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1016 *
1017 * @return string Javascript configuration of classes
1018 */
1019 function buildJSClassesConfig($RTEcounter) {
1020 // Build JS array of lists of classes
1021 $classesTagList = 'classesCharacter, classesParagraph, classesImage, classesTable, classesLinks, classesTD';
1022 $classesTagConvert = array( 'classesCharacter' => 'span', 'classesParagraph' => 'div', 'classesImage' => 'img', 'classesTable' => 'table', 'classesLinks' => 'a', 'classesTD' => 'td');
1023 $classesTagArray = t3lib_div::trimExplode(',' , $classesTagList);
1024 $configureRTEInJavascriptString = '
1025 RTEarea[editornumber].classesTag = new Object();';
1026 foreach ($classesTagArray as $classesTagName) {
1027 $HTMLAreaJSClasses = ($this->thisConfig[$classesTagName])?('"' . $this->cleanList($this->thisConfig[$classesTagName]) . '";'):'null;';
1028 $configureRTEInJavascriptString .= '
1029 RTEarea[editornumber].classesTag.'. $classesTagConvert[$classesTagName] .' = '. $HTMLAreaJSClasses;
1030 }
1031 // Include JS arrays of configured classes
1032 $configureRTEInJavascriptString .= '
1033 RTEarea[editornumber].classesUrl = "' . $this->writeTemporaryFile('', 'classes_' . $this->language, 'js', $this->buildJSClassesArray(), TRUE) . '";';
1034 return $configureRTEInJavascriptString;
1035 }
1036
1037 /**
1038 * Return JS arrays of classes configuration
1039 *
1040 * @return string JS classes arrays
1041 */
1042 function buildJSClassesArray() {
1043 if ($this->is_FE()) {
1044 $RTEProperties = $this->RTEsetup;
1045 } else {
1046 $RTEProperties = $this->RTEsetup['properties'];
1047 }
1048 $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'XOR' => array());
1049 $JSClassesArray = '';
1050 // Scanning the list of classes if specified in the RTE config
1051 if (is_array($RTEProperties['classes.'])) {
1052 foreach ($RTEProperties['classes.'] as $className => $conf) {
1053 $className = rtrim($className, '.');
1054 $classesArray['labels'][$className] = $this->getPageConfigLabel($conf['name'], FALSE);
1055 $classesArray['values'][$className] = str_replace('\\\'', '\'', $conf['value']);
1056 if (isset($conf['noShow'])) {
1057 $classesArray['noShow'][$className] = $conf['noShow'];
1058 }
1059 if (is_array($conf['alternating.'])) {
1060 $classesArray['alternating'][$className] = $conf['alternating.'];
1061 }
1062 if (is_array($conf['counting.'])) {
1063 $classesArray['counting'][$className] = $conf['counting.'];
1064 }
1065 }
1066 }
1067 // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
1068 if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) {
1069 foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) {
1070 $classSet = t3lib_div::trimExplode(',', $conf, 1);
1071 $classList = implode(',', $classSet);
1072 foreach ($classSet as $className) {
1073 $classesArray['XOR'][$className] = '/^(' . implode('|', t3lib_div::trimExplode(',', t3lib_div::rmFromList($className, $classList), 1)) . ')$/';
1074 }
1075 }
1076 }
1077 foreach ($classesArray as $key => $subArray) {
1078 $JSClassesArray .= 'HTMLArea.classes' . ucfirst($key) . ' = ' . $this->buildNestedJSArray($subArray) . ';' . LF;
1079 }
1080 return $JSClassesArray;
1081 }
1082
1083 /**
1084 * Translate Page TS Config array in JS nested array definition
1085 * Replace 0 values with false
1086 * Unquote regular expression values
1087 * Replace empty arrays with empty objects
1088 *
1089 * @param array $conf: Page TSConfig configuration array
1090 *
1091 * @return string nested JS array definition
1092 */
1093 function buildNestedJSArray($conf) {
1094 $convertedConf = t3lib_div::removeDotsFromTS($conf);
1095 if ($this->is_FE()) {
1096 $GLOBALS['TSFE']->csConvObj->convArray($convertedConf, ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'iso-8859-1'), 'utf-8');
1097 } else {
1098 $GLOBALS['LANG']->csConvObj->convArray($convertedConf, $GLOBALS['LANG']->charSet, 'utf-8');
1099 }
1100 return str_replace(array(':"0"', ':"\/^(', ')$\/i"', ':"\/^(', ')$\/"', '[]'), array(':false', ':/^(', ')$/i', ':/^(', ')$/', '{}'), json_encode($convertedConf));
1101 }
1102
1103 /**
1104 * Return a Javascript localization array for htmlArea RTE
1105 *
1106 * @return string Javascript localization array
1107 */
1108 function buildJSMainLangArray() {
1109 $JSLanguageArray = 'HTMLArea.I18N = new Object();' . LF;
1110 $labelsArray = array('tooltips' => array(), 'msg' => array(), 'dialogs' => array());
1111 foreach ($labelsArray as $labels => $subArray) {
1112 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $this->ID . '/htmlarea/locallang_' . $labels . '.xml', $this->language, 'utf-8');
1113 if (!empty($LOCAL_LANG[$this->language])) {
1114 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language], FALSE, FALSE);
1115 } else {
1116 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1117 }
1118 $labelsArray[$labels] = $LOCAL_LANG[$this->language];
1119 }
1120 $JSLanguageArray .= 'HTMLArea.I18N = ' . json_encode($labelsArray) . ';' . LF;
1121 return $JSLanguageArray;
1122 }
1123
1124 /**
1125 * Writes contents in a file in typo3temp/rtehtmlarea directory and returns the file name
1126 *
1127 * @param string $sourceFileName: The name of the file from which the contents should be extracted
1128 * @param string $label: A label to insert at the beginning of the name of the file
1129 * @param string $fileExtension: The file extension of the file, defaulting to 'js'
1130 * @param string $contents: The contents to write into the file if no $sourceFileName is provided
1131 *
1132 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1133 */
1134 public function writeTemporaryFile($sourceFileName='', $label, $fileExtension='js', $contents='', $concatenate = FALSE) {
1135 global $TYPO3_CONF_VARS;
1136
1137 if ($sourceFileName) {
1138 $output = '';
1139 $source = t3lib_div::getFileAbsFileName($sourceFileName);
1140 $output = file_get_contents($source);
1141 } else {
1142 $output = $contents;
1143 }
1144 $compress = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] && ($fileExtension == 'js') && ($output != '');
1145 $relativeFilename = 'typo3temp/' . $this->ID . '/' . str_replace('-','_',$label) . '_' . t3lib_div::shortMD5((TYPO3_version . $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . ($sourceFileName ? $sourceFileName : $output)), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1146 $destination = PATH_site . $relativeFilename;
1147 if(!file_exists($destination)) {
1148 $compressedJavaScript = '';
1149 if ($compress && $fileExtension == 'js') {
1150 $compressedJavaScript = t3lib_div::minifyJavaScript($output);
1151 }
1152 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $compressedJavaScript ? $compressedJavaScript : $output);
1153 if ($failure) {
1154 die($failure);
1155 }
1156 }
1157 if ($concatenate && $fileExtension == 'js') {
1158 $this->cumulativeScripts[$this->TCEform->RTEcounter][] = $destination;
1159 }
1160 if ($this->is_FE()) {
1161 $filename = ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1162 } else {
1163 $filename = t3lib_div::createVersionNumberedFilename(($this->isFrontendEditActive() ? '' : ($this->backPath . '../')) . $relativeFilename);
1164 }
1165 return t3lib_div::resolveBackPath($filename);
1166 }
1167 /**
1168 * Concatenates all accumulated scripts in a file in typo3temp/rtehtmlarea directory and returns the file name
1169 *
1170 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1171 *
1172 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1173 */
1174 protected function doConcatenate($RTEcounter) {
1175 $fileExtension = 'js';
1176 $compress = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'];
1177 $token = implode('|', $this->cumulativeScripts[$RTEcounter]);
1178 $relativeFilename = 'typo3temp/' . $this->ID . '/' . 'htmlarea_cumulative' . '_' . t3lib_div::shortMD5((TYPO3_version . $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . $token ), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1179 $destination = PATH_site . $relativeFilename;
1180 if (!file_exists($destination)) {
1181 foreach ($this->cumulativeScripts[$RTEcounter] as $fileName) {
1182 $contents = file_get_contents($fileName);
1183 if (!file_exists($destination)) {
1184 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $contents);
1185 if ($failure) {
1186 die($failure);
1187 }
1188 } else {
1189 $success = file_put_contents($destination, $contents, FILE_APPEND);
1190 if (!$success) {
1191 die('Could not append script' + $fileName);
1192 }
1193 }
1194 }
1195 }
1196 if ($this->is_FE()) {
1197 $filename = ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1198 } else {
1199 if ($compress) {
1200 $compressor = t3lib_div::makeInstance('t3lib_Compressor');
1201 $filename = $compressor->compressJsFile(($this->isFrontendEditActive() ? '' : $this->backPath) . '../' . $relativeFilename);
1202 if ($this->isFrontendEditActive()) {
1203 $filename = preg_replace('/^..\//', '', $filename);
1204 }
1205 } else {
1206 $filename = t3lib_div::createVersionNumberedFilename(($this->isFrontendEditActive() ? '' : ($this->backPath . '../')) . $relativeFilename);
1207 }
1208 }
1209 return t3lib_div::resolveBackPath($filename);
1210 }
1211
1212 /**
1213 * Return a file name containing the main JS language array for HTMLArea
1214 *
1215 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1216 *
1217 * @return string filename
1218 */
1219 function buildJSMainLangFile($RTEcounter) {
1220 $contents = $this->buildJSMainLangArray() . LF;
1221 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
1222 $contents .= $this->buildJSLangArray($pluginId) . LF;
1223 }
1224 return $this->writeTemporaryFile('', $this->language.'_'.$this->OutputCharset, 'js', $contents, TRUE);
1225 }
1226
1227 /**
1228 * Return a Javascript localization array for the plugin
1229 *
1230 * @param string $plugin: identification string of the plugin
1231 *
1232 * @return string Javascript localization array
1233 */
1234
1235 function buildJSLangArray($plugin) {
1236 $LOCAL_LANG = FALSE;
1237 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID;
1238 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $plugin . '/locallang.xml', $this->language, 'utf-8', 1);
1239 $linebreak = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : LF;
1240 $JSLanguageArray = 'HTMLArea.I18N["' . $plugin . '"] = new Object();' . $linebreak;
1241 if (is_array($LOCAL_LANG)) {
1242 if (!empty($LOCAL_LANG[$this->language])) {
1243 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language], FALSE, FALSE);
1244 } else {
1245 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1246 }
1247 $JSLanguageArray .= 'HTMLArea.I18N["' . $plugin . '"] = ' . json_encode($LOCAL_LANG[$this->language]) . ';'. LF;
1248 }
1249 return $JSLanguageArray;
1250 }
1251
1252 /**
1253 * Return the JS code of the toolbar configuration for the HTMLArea editor
1254 *
1255 * @return string the JS code as nested JS arrays
1256 */
1257 protected function getJSToolbarArray() {
1258 // The toolbar array
1259 $toolbar = array();
1260 // The current row; a "linebreak" ends the current row
1261 $row = array();
1262 // The current group; each group is between "bar"s; a "linebreak" ends the current group
1263 $group = array();
1264 // Process each toolbar item in the toolbar order list
1265 foreach ($this->toolbarOrderArray as $item) {
1266 switch ($item) {
1267 case 'linebreak':
1268 // Add row to toolbar if not empty
1269 if (!empty($group)) {
1270 $row[] = $group;
1271 $group = array();
1272 }
1273 if (!empty($row)) {
1274 $toolbar[] = $row;
1275 $row = array();
1276 }
1277 break;
1278 case 'bar':
1279 // Add group to row if not empty
1280 if (!empty($group)) {
1281 $row[] = $group;
1282 $group = array();
1283 }
1284 break;
1285 case 'space':
1286 if (end($group) != $this->convertToolbarForHTMLArea($item)) {
1287 $group[] = $this->convertToolbarForHTMLArea($item);
1288 }
1289 break;
1290 default:
1291 if (in_array($item, $this->toolbar)) {
1292 // Add the item to the group
1293 $convertedItem = $this->convertToolbarForHTMLArea($item);
1294 if ($convertedItem) {
1295 $group[] = $convertedItem;
1296 }
1297 }
1298 break;
1299 }
1300 }
1301 // Add the last group and last line, if not empty
1302 if (!empty($group)) {
1303 $row[] = $group;
1304 }
1305 if (!empty($row)) {
1306 $toolbar[] = $row;
1307 }
1308 return json_encode($toolbar);
1309 }
1310
1311 public function getLLContent($string) {
1312 global $LANG;
1313
1314 $BE_lang = $LANG->lang;
1315 $BE_charSet = $LANG->charSet;
1316 $LANG->lang = $this->contentTypo3Language;
1317 $LANG->charSet = $this->contentCharset;
1318 $LLString = $LANG->JScharCode($LANG->sL($string));
1319 $LANG->lang = $BE_lang;
1320 $LANG->charSet = $BE_charSet;
1321 return $LLString;
1322 }
1323
1324 public function getPageConfigLabel($string,$JScharCode=1) {
1325 global $LANG, $TSFE, $TYPO3_CONF_VARS;
1326
1327 if ($this->is_FE()) {
1328 if (strcmp(substr($string,0,4),'LLL:') && $TYPO3_CONF_VARS['BE']['forceCharset']) {
1329 // A pure string coming from Page TSConfig must be in forceCharset, otherwise we just don't know..
1330 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $TYPO3_CONF_VARS['BE']['forceCharset'], $this->OutputCharset);
1331 } else {
1332 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $this->charset, $this->OutputCharset);
1333 }
1334 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1335 $label = $JScharCode ? $this->feJScharCode($label) : $label;
1336 } else {
1337 if (strcmp(substr($string,0,4),'LLL:')) {
1338 $label = $string;
1339 } else {
1340 $label = $LANG->sL(trim($string));
1341 }
1342 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1343 $label = $JScharCode ? $LANG->JScharCode($label): $label;
1344 }
1345 return $label;
1346 }
1347
1348 function feJScharCode($str) {
1349 global $TSFE;
1350 // Convert string to UTF-8:
1351 if ($this->OutputCharset != 'utf-8') $str = $TSFE->csConvObj->utf8_encode($str,$this->OutputCharset);
1352 // Convert the UTF-8 string into a array of char numbers:
1353 $nArr = $TSFE->csConvObj->utf8_to_numberarray($str);
1354 return 'String.fromCharCode('.implode(',',$nArr).')';
1355 }
1356
1357 public function getFullFileName($filename) {
1358 if (substr($filename,0,4)=='EXT:') { // extension
1359 list($extKey,$local) = explode('/',substr($filename,4),2);
1360 $newFilename = '';
1361 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
1362 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? t3lib_extMgm::siteRelPath($extKey) : $this->backPath . t3lib_extMgm::extRelPath($extKey)) . $local;
1363 }
1364 } elseif (substr($filename,0,1) != '/') {
1365 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? '' : ($this->backPath . '../')) . $filename;
1366 } else {
1367 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? '' : ($this->backPath . '../')) . substr($filename, 1);
1368 }
1369 return t3lib_div::resolveBackPath($newFilename);
1370 }
1371
1372 /**
1373 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1374 * This is for submit function of the form.
1375 *
1376 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1377 * @param string $formName: the name of the form
1378 * @param string $textareaId: the id of the textarea
1379 * @param string $textareaName: the name of the textarea
1380 *
1381 * @return string Javascript code
1382 */
1383 function setSaveRTE($RTEcounter, $formName, $textareaId, $textareaName) {
1384 return 'if (RTEarea["' . $textareaId . '"]) { document.' . $formName . '["' . $textareaName . '"].value = RTEarea["' . $textareaId . '"].editor.getHTML(); } else { OK = 0; };';
1385 }
1386
1387 /**
1388 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1389 * This is for submit function of the form.
1390 *
1391 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1392 * @param string $formName: the name of the form
1393 * @param string $textareaId: the id of the textarea
1394 *
1395 * @return string Javascript code
1396 */
1397 function setDeleteRTE($RTEcounter, $formName, $textareaId) {
1398 return 'if (RTEarea["' . $textareaId . '"]) { RTEarea["' . $textareaId . '"].deleted = true;}';
1399 }
1400
1401 /**
1402 * Return true if we are in the FE, but not in the FE editing feature of BE.
1403 *
1404 * @return boolean
1405 */
1406
1407 function is_FE() {
1408 return is_object($GLOBALS['TSFE']) && !$this->isFrontendEditActive() && TYPO3_MODE=='FE';
1409 }
1410
1411 /**
1412 * Checks whether frontend editing is active.
1413 *
1414 * @return boolean
1415 */
1416 public function isFrontendEditActive() {
1417 return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && ($GLOBALS['BE_USER']->frontendEdit instanceof t3lib_frontendedit);
1418 }
1419 /**
1420 * Client Browser Information
1421 *
1422 * @param string $userAgent: The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
1423 * @return array Contains keys "useragent", "browser", "version", "system"
1424 * where "browser" is limited to the engines
1425 * and where "version" is a floating number
1426 */
1427 function clientInfo ($userAgent='') {
1428 if (!$userAgent) {
1429 $userAgent = t3lib_div::getIndpEnv('HTTP_USER_AGENT');
1430 }
1431 $browserInfo = t3lib_utility_Client::getBrowserInfo($userAgent);
1432 // Known engines: order is not irrelevant!
1433 $knownEngines = array('opera', 'msie', 'gecko', 'webkit');
1434 if (is_array($browserInfo['all'])) {
1435 foreach ($knownEngines as $engine) {
1436 if ($browserInfo['all'][$engine]) {
1437 $browserInfo['browser'] = $engine;
1438 $browserInfo['version'] = t3lib_utility_Client::getVersion($browserInfo['all'][$engine]);
1439 break;
1440 }
1441 }
1442 }
1443 return $browserInfo;
1444 }
1445 /***************************
1446 *
1447 * OTHER FUNCTIONS: (from Classic RTE)
1448 *
1449 ***************************/
1450 /**
1451 * @return [type] ...
1452 * @desc
1453 */
1454
1455 function RTEtsConfigParams() {
1456 if($this->is_FE()) {
1457 return '';
1458 } else {
1459 $p = t3lib_BEfunc::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']);
1460 return $this->elementParts[0].':'.$this->elementParts[1].':'.$this->elementParts[2].':'.$this->thePid.':'.$this->typeVal.':'.$this->tscPID.':'.$p['imgpath'];
1461 }
1462 }
1463
1464 public function cleanList($str) {
1465 if (strstr($str,'*')) {
1466 $str = '*';
1467 } else {
1468 $str = implode(',',array_unique(t3lib_div::trimExplode(',',$str,1)));
1469 }
1470 return $str;
1471 }
1472
1473 function filterStyleEl($elValue,$matchList) {
1474 $matchParts = t3lib_div::trimExplode(',',$matchList,1);
1475 $styleParts = explode(';',$elValue);
1476 $nStyle=array();
1477 foreach ($styleParts as $k => $p) {
1478 $pp = t3lib_div::trimExplode(':',$p);
1479 if ($pp[0]&&$pp[1]) {
1480 foreach ($matchParts as $el) {
1481 $star=substr($el,-1)=='*';
1482 if (!strcmp($pp[0],$el) || ($star && t3lib_div::isFirstPartOfStr($pp[0],substr($el,0,-1)) )) {
1483 $nStyle[]=$pp[0].':'.$pp[1];
1484 } else unset($styleParts[$k]);
1485 }
1486 } else {
1487 unset($styleParts[$k]);
1488 }
1489 }
1490 return implode('; ',$nStyle);
1491 }
1492
1493 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode
1494 function loremIpsumInsert($params) {
1495 return "
1496 if (typeof(lorem_ipsum) == 'function' && " . $params['element'] . ".tagName.toLowerCase() == 'textarea' ) lorem_ipsum(" . $params['element'] . ", lipsum_temp_strings[lipsum_temp_pointer]);
1497 ";
1498 }
1499 }
1500 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php'])) {
1501 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']);
1502 }
1503 ?>