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