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