[TASK] Add action selector in toolbar in workspaces menu
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / Classes / Controller / FrontendRteController.php
1 <?php
2 namespace TYPO3\CMS\Rtehtmlarea\Controller;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16 /**
17 * Front end RTE based on htmlArea
18 *
19 * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
20 */
21 class FrontendRteController extends \TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase {
22
23 // External:
24 public $RTEWrapStyle = '';
25
26 // Alternative style for RTE wrapper <div> tag.
27 public $RTEdivStyle = '';
28
29 // Alternative style for RTE <div> tag.
30 // For the editor
31 /**
32 * @todo Define visibility
33 */
34 public $elementId;
35
36 /**
37 * @todo Define visibility
38 */
39 public $elementParts;
40
41 /**
42 * @todo Define visibility
43 */
44 public $tscPID;
45
46 /**
47 * @todo Define visibility
48 */
49 public $typeVal;
50
51 /**
52 * @todo Define visibility
53 */
54 public $thePid;
55
56 /**
57 * @todo Define visibility
58 */
59 public $RTEsetup = array();
60
61 /**
62 * @todo Define visibility
63 */
64 public $thisConfig = array();
65
66 /**
67 * @todo Define visibility
68 */
69 public $confValues;
70
71 public $language;
72
73 public $OutputCharset;
74
75 /**
76 * @todo Define visibility
77 */
78 public $specConf;
79
80 /**
81 * @todo Define visibility
82 */
83 public $LOCAL_LANG;
84
85 /**
86 * @var \TYPO3\CMS\Core\Page\PageRenderer
87 */
88 protected $pageRenderer;
89
90 /**
91 * Draws the RTE as an iframe
92 *
93 * @param object Reference to parent object, which is an instance of the TCEforms.
94 * @param string The table name
95 * @param string The field name
96 * @param array The current row from which field is being rendered
97 * @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.
98 * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
99 * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
100 * @param string Record "type" field value.
101 * @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!
102 * @param integer PID value of record (true parent page id)
103 * @return string HTML code for RTE!
104 * @todo Define visibility
105 */
106 public function drawRTE(&$parentObject, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
107 global $TSFE, $TYPO3_CONF_VARS, $TYPO3_DB;
108 $this->TCEform = $parentObject;
109 $this->client = $this->clientInfo();
110 $this->typoVersion = \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version);
111 /* =======================================
112 * INIT THE EDITOR-SETTINGS
113 * =======================================
114 */
115 // Get the path to this extension:
116 $this->extHttpPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->ID);
117 // Get the site URL
118 $this->siteURL = $GLOBALS['TSFE']->absRefPrefix ?: '';
119 // Get the host URL
120 $this->hostURL = '';
121 // Element ID + pid
122 $this->elementId = $PA['itemFormElName'];
123 $this->elementParts[0] = $table;
124 $this->elementParts[1] = $row['uid'];
125 $this->tscPID = $thePidValue;
126 $this->thePid = $thePidValue;
127 // Record "type" field value:
128 $this->typeVal = $RTEtypeVal;
129 // TCA "type" value for record
130 // RTE configuration
131 $pageTSConfig = $TSFE->getPagesTSconfig();
132 if (is_array($pageTSConfig) && is_array($pageTSConfig['RTE.'])) {
133 $this->RTEsetup = $pageTSConfig['RTE.'];
134 }
135 if (is_array($thisConfig) && !empty($thisConfig)) {
136 $this->thisConfig = $thisConfig;
137 } elseif (is_array($this->RTEsetup['default.']) && is_array($this->RTEsetup['default.']['FE.'])) {
138 $this->thisConfig = $this->RTEsetup['default.']['FE.'];
139 }
140 // Special configuration (line) and default extras:
141 $this->specConf = $specConf;
142 if ($this->thisConfig['forceHTTPS']) {
143 $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
144 $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
145 $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
146 }
147 // Register RTE windows:
148 $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
149 $textAreaId = preg_replace('/[^a-zA-Z0-9_:.-]/', '_', $PA['itemFormElName']);
150 $textAreaId = htmlspecialchars(preg_replace('/^[^a-zA-Z]/', 'x', $textAreaId)) . '_' . strval($this->TCEform->RTEcounter);
151 /* =======================================
152 * LANGUAGES & CHARACTER SETS
153 * =======================================
154 */
155 // Language
156 $TSFE->initLLvars();
157 $this->language = $TSFE->lang;
158 $this->LOCAL_LANG = \TYPO3\CMS\Core\Utility\GeneralUtility::readLLfile('EXT:' . $this->ID . '/locallang.xml', $this->language);
159 if ($this->language == 'default' || !$this->language) {
160 $this->language = 'en';
161 }
162 $this->contentLanguageUid = max($row['sys_language_uid'], 0);
163 if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('static_info_tables')) {
164 if ($this->contentLanguageUid) {
165 $tableA = 'sys_language';
166 $tableB = 'static_languages';
167 $languagesUidsList = $this->contentLanguageUid;
168 $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
169 $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
170 $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
171 $whereClause .= \TYPO3\CMS\Backend\Utility\BackendUtility::BEenableFields($tableA);
172 $whereClause .= \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause($tableA);
173 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
174 while ($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
175 $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']) . (trim($languageRow['lg_country_iso_2']) ? '_' . trim($languageRow['lg_country_iso_2']) : ''));
176 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
177 }
178 } else {
179 $this->contentISOLanguage = $GLOBALS['TSFE']->sys_language_isocode ?: 'en';
180 $selectFields = 'lg_iso_2, lg_typo3';
181 $tableAB = 'static_languages';
182 $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
183 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
184 while ($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
185 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
186 }
187 }
188 }
189 $this->contentISOLanguage = $this->contentISOLanguage ?: ($GLOBALS['TSFE']->sys_language_isocode ?: 'en');
190 $this->contentTypo3Language = $this->contentTypo3Language ?: $GLOBALS['TSFE']->lang;
191 if ($this->contentTypo3Language == 'default') {
192 $this->contentTypo3Language = 'en';
193 }
194 // Character set
195 $this->charset = $TSFE->renderCharset;
196 $this->OutputCharset = $TSFE->metaCharset ?: $TSFE->renderCharset;
197 // Set the charset of the content
198 $this->contentCharset = $TSFE->csConvObj->charSetArray[$this->contentTypo3Language];
199 $this->contentCharset = $this->contentCharset ?: 'utf-8';
200 $this->contentCharset = trim($TSFE->config['config']['metaCharset']) ?: $this->contentCharset;
201 /* =======================================
202 * TOOLBAR CONFIGURATION
203 * =======================================
204 */
205 $this->initializeToolbarConfiguration();
206 /* =======================================
207 * SET STYLES
208 * =======================================
209 */
210 $width = 460 + ($this->TCEform->docLarge ? 150 : 0);
211 if (isset($this->thisConfig['RTEWidthOverride'])) {
212 if (strstr($this->thisConfig['RTEWidthOverride'], '%')) {
213 if ($this->client['browser'] != 'msie') {
214 $width = (int)$this->thisConfig['RTEWidthOverride'] > 0 ? $this->thisConfig['RTEWidthOverride'] : '100%';
215 }
216 } else {
217 $width = (int)$this->thisConfig['RTEWidthOverride'] > 0 ? (int)$this->thisConfig['RTEWidthOverride'] : $width;
218 }
219 }
220 $RTEWidth = strstr($width, '%') ? $width : $width . 'px';
221 $editorWrapWidth = strstr($width, '%') ? $width : ($width + 2) . 'px';
222 $height = 380;
223 $RTEHeightOverride = (int)$this->thisConfig['RTEHeightOverride'];
224 $height = $RTEHeightOverride > 0 ? $RTEHeightOverride : $height;
225 $RTEHeight = $height . 'px';
226 $editorWrapHeight = ($height + 2) . 'px';
227 $this->RTEWrapStyle = $this->RTEWrapStyle ?: ($this->RTEdivStyle ?: 'height:' . $editorWrapHeight . '; width:' . $editorWrapWidth . ';');
228 $this->RTEdivStyle = $this->RTEdivStyle ?: 'position:relative; left:0px; top:0px; height:' . $RTEHeight . '; width:' . $RTEWidth . '; border: 1px solid black;';
229 /* =======================================
230 * LOAD JS, CSS and more
231 * =======================================
232 */
233 $this->getPageRenderer();
234 // Register RTE in JS
235 $this->TCEform->additionalJS_post[] = $this->wrapCDATA($this->registerRTEinJS($this->TCEform->RTEcounter, '', '', '', $textAreaId));
236 // Set the save option for the RTE:
237 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
238 // Loading ExtJs JavaScript files and inline code, if not configured in TS setup
239 if (!is_array($GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs.'])) {
240 $this->pageRenderer->loadExtJs();
241 $this->pageRenderer->enableExtJSQuickTips();
242 }
243 $this->pageRenderer->addJsFile($this->getFullFileName('typo3/js/extjs/ux/ext.resizable.js'));
244 $this->pageRenderer->addJsFile('sysext/backend/Resources/Public/JavaScript/notifications.js');
245 // Preloading the pageStyle and including RTE skin stylesheets
246 $this->addPageStyle();
247 $this->pageRenderer->addCssFile($this->siteURL . 'typo3/contrib/extjs/resources/css/ext-all-notheme.css');
248 $this->pageRenderer->addCssFile($this->siteURL . 'typo3/sysext/t3skin/extjs/xtheme-t3skin.css');
249 $this->addSkin();
250 $this->pageRenderer->addCssFile($this->siteURL . 'typo3/js/extjs/ux/resize.css');
251 // Add RTE JavaScript
252 $this->addRteJsFiles($this->TCEform->RTEcounter);
253 $this->pageRenderer->addJsFile($this->buildJSMainLangFile($this->TCEform->RTEcounter));
254 $this->pageRenderer->addJsInlineCode('HTMLArea-init', $this->getRteInitJsCode(), TRUE);
255 /* =======================================
256 * DRAW THE EDITOR
257 * =======================================
258 */
259 // Transform value:
260 $value = $this->transformContent('rte', $PA['itemFormElValue'], $table, $field, $row, $specConf, $thisConfig, $RTErelPath, $thePidValue);
261 // Further content transformation by registered plugins
262 foreach ($this->registeredPlugins as $pluginId => $plugin) {
263 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, 'transformContent')) {
264 $value = $plugin->transformContent($value);
265 }
266 }
267 // draw the textarea
268 $item = $this->triggerField($PA['itemFormElName']) . '
269 <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $TSFE->csConvObj->conv($TSFE->getLLL('Please wait', $this->LOCAL_LANG), $this->charset, $TSFE->renderCharset) . '</div>
270 <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; ' . htmlspecialchars($this->RTEWrapStyle) . '">
271 <textarea id="RTEarea' . $textAreaId . '" name="' . htmlspecialchars($PA['itemFormElName']) . '" rows="0" cols="0" style="' . htmlspecialchars($this->RTEdivStyle) . '">' . \TYPO3\CMS\Core\Utility\GeneralUtility::formatForTextarea($value) . '</textarea>
272 </div>' . LF;
273 return $item;
274 }
275
276 /**
277 * Add style sheet file to document header
278 *
279 * @param string $key: some key identifying the style sheet
280 * @param string $href: uri to the style sheet file
281 * @param string $title: value for the title attribute of the link element
282 * @param string $relation: value for the rel attribute of the link element
283 * @return void
284 */
285 protected function addStyleSheet($key, $href, $title = '', $relation = 'stylesheet') {
286 $this->pageRenderer->addCssFile($href, $relation, 'screen', $title);
287 }
288
289 /**
290 * Return the JS-Code for copy the HTML-Code from the editor in the hidden input field.
291 * This is for submit function from the form.
292 *
293 * @param integer $RTEcounter: The index number of the RTE editing area.
294 * @param string $form: the name of the form
295 * @param string $textareaId: the id of the textarea
296 * @return string the JS-Code
297 * @todo Define visibility
298 */
299 public function setSaveRTE($RTEcounter, $form, $textareaId) {
300 return '
301 if (RTEarea[\'' . $textareaId . '\'] && !RTEarea[\'' . $textareaId . '\'].deleted) {
302 var field = document.getElementById(\'RTEarea' . $textareaId . '\');
303 if (field && field.nodeName.toLowerCase() == \'textarea\') {
304 field.value = RTEarea[\'' . $textareaId . '\'][\'editor\'].getHTML();
305 }
306 } else {
307 OK = 0;
308 }';
309 }
310
311 /**
312 * Gets instance of PageRenderer
313 *
314 * @return PageRenderer
315 */
316 public function getPageRenderer() {
317 if (!isset($this->pageRenderer)) {
318 $this->pageRenderer = $GLOBALS['TSFE']->getPageRenderer();
319 $this->pageRenderer->setBackPath(TYPO3_mainDir);
320 }
321 return $this->pageRenderer;
322 }
323
324 /**
325 * Wrap input string in CDATA enclosure
326 *
327 * @param string $string: input to be wrapped
328 * @return string wrapped string
329 */
330 public function wrapCDATA($string) {
331 return implode(LF, array(
332 '',
333 '/*<![CDATA[*/',
334 $string,
335 '/*]]>*/'
336 ));
337 }
338 }