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