Follow up for bug #8232: Creating and editing of fields, forms, etc. in FCE's is...
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / pi2 / class.tx_rtehtmlarea_pi2.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2005-2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Front end RTE based on htmlArea
29 *
30 * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
31 *
32 * $Id$ *
33 */
34
35 require_once(t3lib_extMgm::extPath('rtehtmlarea').'class.tx_rtehtmlarea_base.php');
36 require_once(PATH_t3lib.'class.t3lib_parsehtml_proc.php');
37 require_once(PATH_t3lib.'class.t3lib_befunc.php');
38
39 class tx_rtehtmlarea_pi2 extends tx_rtehtmlarea_base {
40
41 // External:
42 var $RTEWrapStyle = ''; // Alternative style for RTE wrapper <div> tag.
43 var $RTEdivStyle = ''; // Alternative style for RTE <div> tag.
44 var $extHttpPath; // full Path to this extension for http (so no Server path). It ends with "/"
45 public $httpTypo3Path;
46
47 // For the editor
48 var $elementId;
49 var $elementParts;
50 var $tscPID;
51 var $typeVal;
52 var $thePid;
53 var $RTEsetup = array();
54 var $thisConfig = array();
55 var $confValues;
56 public $language;
57 public $OutputCharset;
58 var $specConf;
59 var $LOCAL_LANG;
60
61 /**
62 * Draws the RTE as an iframe
63 *
64 * @param object Reference to parent object, which is an instance of the TCEforms.
65 * @param string The table name
66 * @param string The field name
67 * @param array The current row from which field is being rendered
68 * @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.
69 * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
70 * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
71 * @param string Record "type" field value.
72 * @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!
73 * @param integer PID value of record (true parent page id)
74 * @return string HTML code for RTE!
75 */
76 function drawRTE($parentObject,$table,$field,$row,$PA,$specConf,$thisConfig,$RTEtypeVal,$RTErelPath,$thePidValue) {
77 global $TSFE, $TYPO3_CONF_VARS, $TYPO3_DB;
78
79 $this->TCEform =& $parentObject;
80 $this->client = $this->clientInfo();
81 $this->typoVersion = t3lib_div::int_from_ver(TYPO3_version);
82
83 /* =======================================
84 * INIT THE EDITOR-SETTINGS
85 * =======================================
86 */
87
88 // first get the http-path to typo3:
89 $this->httpTypo3Path = substr( substr( t3lib_div::getIndpEnv('TYPO3_SITE_URL'), strlen( t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') ) ), 0, -1 );
90 if (strlen($this->httpTypo3Path) == 1) {
91 $this->httpTypo3Path = '/';
92 } else {
93 $this->httpTypo3Path .= '/';
94 }
95 // Get the path to this extension:
96 $this->extHttpPath = $this->httpTypo3Path.t3lib_extMgm::siteRelPath($this->ID);
97 // Get the site URL
98 $this->siteURL = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
99 // Get the host URL
100 $this->hostURL = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
101
102 // Element ID + pid
103 $this->elementId = $PA['itemFormElName'];
104 $this->elementParts[0] = $table;
105 $this->elementParts[1] = $row['uid'];
106 $this->tscPID = $thePidValue;
107 $this->thePid = $thePidValue;
108
109 // Record "type" field value:
110 $this->typeVal = $RTEtypeVal; // TCA "type" value for record
111
112 // RTE configuration
113 $pageTSConfig = $TSFE->getPagesTSconfig();
114 if (is_array($pageTSConfig) && is_array($pageTSConfig['RTE.'])) {
115 $this->RTEsetup = $pageTSConfig['RTE.'];
116 }
117
118 if (is_array($thisConfig) && !empty($thisConfig)) {
119 $this->thisConfig = $thisConfig;
120 } else if (is_array($this->RTEsetup['default.']) && is_array($this->RTEsetup['default.']['FE.'])) {
121 $this->thisConfig = $this->RTEsetup['default.']['FE.'];
122 }
123
124 // Special configuration (line) and default extras:
125 $this->specConf = $specConf;
126
127 if ($this->thisConfig['forceHTTPS']) {
128 $this->httpTypo3Path = preg_replace('/^(http|https)/', 'https', $this->httpTypo3Path);
129 $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
130 $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
131 $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
132 }
133
134 /* =======================================
135 * LANGUAGES & CHARACTER SETS
136 * =======================================
137 */
138 // Language
139 $TSFE->initLLvars();
140 $this->language = $TSFE->lang;
141 $this->LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $this->ID . '/locallang.xml', $this->language);
142 if ($this->language == 'default' || !$this->language) {
143 $this->language = 'en';
144 }
145
146 $this->contentISOLanguage = $TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['defaultDictionary'];
147 $this->contentLanguageUid = ($row['sys_language_uid'] > 0) ? $row['sys_language_uid'] : 0;
148 if (t3lib_extMgm::isLoaded('static_info_tables')) {
149 if ($this->contentLanguageUid) {
150 $tableA = 'sys_language';
151 $tableB = 'static_languages';
152 $languagesUidsList = $this->contentLanguageUid;
153 $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
154 $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
155 $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
156 $whereClause .= t3lib_BEfunc::BEenableFields($tableA);
157 $whereClause .= t3lib_BEfunc::deleteClause($tableA);
158 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
159 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
160 $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']).(trim($languageRow['lg_country_iso_2'])?'_'.trim($languageRow['lg_country_iso_2']):''));
161 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
162 }
163 } else {
164 $this->contentISOLanguage = trim($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['defaultDictionary']) ? trim($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['defaultDictionary']) : 'en';
165 $selectFields = 'lg_iso_2, lg_typo3';
166 $tableAB = 'static_languages';
167 $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
168 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
169 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
170 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
171 }
172 }
173 }
174
175 $this->contentISOLanguage = $this->contentISOLanguage?$this->contentISOLanguage:$this->language;
176 $this->contentTypo3Language = $this->contentTypo3Language?$this->contentTypo3Language:$TSFE->lang;
177 if ($this->contentTypo3Language == 'default') {
178 $this->contentTypo3Language = 'en';
179 }
180
181 // Character set
182 $this->charset = $TSFE->renderCharset;
183 $this->OutputCharset = $TSFE->metaCharset ? $TSFE->metaCharset : $TSFE->renderCharset;
184
185 // Set the charset of the content
186 $this->contentCharset = $TSFE->csConvObj->charSetArray[$this->contentTypo3Language];
187 $this->contentCharset = $this->contentCharset ? $this->contentCharset : 'iso-8859-1';
188 $this->contentCharset = trim($TSFE->config['config']['metaCharset']) ? trim($TSFE->config['config']['metaCharset']) : $this->contentCharset;
189
190 /* =======================================
191 * TOOLBAR CONFIGURATION
192 * =======================================
193 */
194
195 // htmlArea plugins list
196 $this->pluginEnabledArray = t3lib_div::trimExplode(',', $this->pluginList, 1);
197 $this->enableRegisteredPlugins();
198 $hidePlugins = array();
199 if ($this->client['BROWSER'] == 'opera') {
200 $hidePlugins[] = 'ContextMenu';
201 $this->thisConfig['hideTableOperationsInToolbar'] = 0;
202 $this->thisConfig['disableEnterParagraphs'] = 1;
203 }
204 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
205
206 // Toolbar
207 $this->settoolbar();
208
209 // Check if some plugins need to be disabled
210 $this->setPlugins();
211
212 // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
213 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = $this->pluginEnabledArray;
214 if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])) {
215 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray,$this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])));
216 }
217
218 /* =======================================
219 * SET STYLES
220 * =======================================
221 */
222
223 $RTEWidth = 460+($this->TCEform->docLarge ? 150 : 0);
224 $RTEHeight = 380;
225 $RTEHeightOverride = intval($this->thisConfig['RTEHeightOverride']);
226 $RTEHeight = ($RTEHeightOverride > 0) ? $RTEHeightOverride : $RTEHeight;
227 $editorWrapWidth = $RTEWidth . 'px';
228 $editorWrapHeight = $RTEHeight . 'px';
229 $this->RTEWrapStyle = $this->RTEWrapStyle ? $this->RTEWrapStyle : ($this->RTEdivStyle ? $this->RTEdivStyle : ('height:' . ($RTEHeight+2) . 'px; width:'. ($RTEWidth+2) . 'px;'));
230 $this->RTEdivStyle = $this->RTEdivStyle ? $this->RTEdivStyle : 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:'.$RTEWidth.'px; border: 1px solid black;';
231 $this->toolbar_level_size = $RTEWidth;
232
233 /* =======================================
234 * LOAD JS, CSS and more
235 * =======================================
236 */
237 // Preloading the pageStyle
238 $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
239 $additionalCode_loadCSS = '
240 <link rel="alternate stylesheet" type="text/css" href="' . $this->getFullFileName($filename) . '" title="HTMLArea RTE Content CSS" />';
241
242 // Loading the editor skin
243 $skinFilename = trim($this->thisConfig['skin']) ? trim($this->thisConfig['skin']) : 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
244 if($this->client['BROWSER'] == 'gecko' && $this->client['VERSION'] == '1.3' && substr($skinFilename,0,4) == 'EXT:') {
245 $skinFilename = 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
246 }
247 if (substr($skinFilename,0,4) == 'EXT:') { // extension
248 list($extKey,$local) = explode('/',substr($skinFilename,4),2);
249 $skinFilename='';
250 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
251 $skinFilename = $this->httpTypo3Path . t3lib_extMgm::siteRelPath($extKey).$local;
252 $skinDir = $this->siteURL . t3lib_extMgm::siteRelPath($extKey) . dirname($local);
253 }
254 } elseif (substr($skinFilename,0,1) != '/') {
255 $skinDir = $this->siteURL.dirname($skinFilename);
256 $skinFilename = $this->siteURL.$skinFilename;
257 } else {
258 $skinDir = substr($this->siteURL,0,-1) . dirname($skinFilename);
259 }
260
261 $this->editorCSS = $skinFilename;
262 $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
263 $additionalCode_loadCSS .= '
264 <link rel="alternate stylesheet" type="text/css" href="' . $this->editedContentCSS . '" />';
265
266 // Main stylesheet
267 $additionalCode_loadCSS .= '
268 <link rel="stylesheet" type="text/css" href="' . $this->editorCSS . '" />';
269
270 // Additional icons from registered plugins
271 foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
272 if (is_object($this->registeredPlugins[$pluginId])) {
273 $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
274 if ($pathToSkin) {
275 $additionalCode_loadCSS .= '
276 <link rel="stylesheet" type="text/css" href="' . $this->httpTypo3Path . t3lib_extMgm::siteRelPath($this->registeredPlugins[$pluginId]->getExtensionKey()) . $pathToSkin . '" />';
277 }
278 }
279 }
280
281 // Loading CSS, JavaScript files and code
282 $TSFE->additionalHeaderData['htmlArea'] = $additionalCode_loadCSS;
283 $this->TCEform->additionalJS_initial = $this->loadJSfiles($this->TCEform->RTEcounter);
284 $this->TCEform->additionalJS_pre[] = $this->loadJScode($this->TCEform->RTEcounter);
285
286 /* =======================================
287 * DRAW THE EDITOR
288 * =======================================
289 */
290 // Transform value:
291 $value = $this->transformContent('rte',$PA['itemFormElValue'],$table,$field,$row,$specConf,$thisConfig,$RTErelPath,$thePidValue);
292
293 // Further content transformation by registered plugins
294 foreach ($this->registeredPlugins as $pluginId => $plugin) {
295 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "transformContent")) {
296 $value = $plugin->transformContent($value);
297 }
298 }
299
300 // Register RTE windows:
301 $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
302 $textAreaId = htmlspecialchars($PA['itemFormElName']);
303
304 // Register RTE in JS:
305 $this->TCEform->additionalJS_post[] = $this->registerRTEinJS($this->TCEform->RTEcounter, '', '', '',$textAreaId);
306
307 // Set the save option for the RTE:
308 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
309
310 // draw the textarea
311 $visibility = 'hidden';
312 $item = $this->triggerField($PA['itemFormElName']).'
313 <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: none;" >' . $TSFE->csConvObj->conv($TSFE->getLLL('Please wait',$this->LOCAL_LANG), $this->charset, $TSFE->renderCharset) . '</div>
314 <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="'. htmlspecialchars($this->RTEWrapStyle). '">
315 <textarea id="RTEarea' . $textAreaId . '" name="'.htmlspecialchars($PA['itemFormElName']).'" style="'.htmlspecialchars($this->RTEdivStyle).'">'.t3lib_div::formatForTextarea($value).'</textarea>
316 </div>' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? '<div id="HTMLAreaLog"></div>' : '') . '
317 ';
318 return $item;
319 }
320
321 /**
322 * Return the JS-Code for copy the HTML-Code from the editor in the hidden input field.
323 * This is for submit function from the form.
324 *
325 * @param integer $RTEcounter: The index number of the RTE editing area.
326 * @param string $form: the name of the form
327 * @param string $textarea: the name of the textarea
328 *
329 * @return string the JS-Code
330 */
331 function setSaveRTE($RTEcounter, $form, $textarea) {
332 return '
333 rteFound = false;
334 for (editornumber = 1; editornumber < RTEarea.length; editornumber++) {
335 if (RTEarea[editornumber].textAreaId == \'' . $textarea . '\') {
336 if (!RTEarea[editornumber].deleted) {
337 fields = document.getElementsByName(\'' . $textarea . '\');
338 field = fields.item(0);
339 if(field && field.tagName.toLowerCase() == \'textarea\') field.value = RTEarea[editornumber][\'editor\'].getHTML();
340 }
341 rteFound = true;
342 break;
343 }
344 }
345 if (!rteFound) {
346 OK = 0;
347 }
348 ';
349 }
350
351
352 }
353
354 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php']) {
355 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/pi2/class.tx_rtehtmlarea_pi2.php']);
356 }
357
358 ?>