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