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