caf91140d6ecf936512b04454dc5f1f8ee25acaf
[Packages/TYPO3.CMS.git] / typo3 / sysext / t3editor / class.tx_t3editor.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007-2009 Tobias Liebig <mail_typo3@etobi.de>
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 * [CLASS/FUNCTION INDEX of SCRIPT]
29 *
30 *
31 *
32 * 47: class tx_t3editor
33 * 85: public function __construct()
34 * 117: public function getJavascriptCode()
35 * 162: public function getCodeEditor($name, $class='', $content='', $additionalParams='', $alt='')
36 *
37 * TOTAL FUNCTIONS: 3
38 * (This index is automatically created/updated by the extension "extdeveval")
39 *
40 */
41
42 /**
43 * Provides a javascript-driven code editor with syntax highlighting for TS, HTML, CSS and more
44 *
45 * @author Tobias Liebig <mail_typo3@etobi.de>
46 */
47
48 $GLOBALS['LANG']->includeLLFile('EXT:t3editor/locallang.xml');
49
50 class tx_t3editor {
51
52 /**
53 * path to the main javascript-file
54 *
55 * @var string
56 */
57 protected $filepathEditorlib;
58
59 /**
60 * path to the main stylesheet
61 *
62 * @TODO: make it configurable
63 *
64 * @var string
65 */
66 protected $filepathEditorcss;
67
68 /**
69 * counts the editors on the current page
70 *
71 * @var int
72 */
73 protected $editorCounter;
74
75 /**
76 * flag to enable the t3editor
77 *
78 * @var bool
79 */
80 public $isEnabled;
81
82 /**
83 * Creates a new instance of the class
84 *
85 * @return void
86 */
87 public function __construct() {
88
89 $this->filepathEditorlib = 'jslib/t3editor.js';
90 $this->filepathEditorcss = 'css/t3editor.css';
91 $this->editorCounter = 0;
92 $this->isEnabled = true; //TODO add a method to switch to false and turn off the editor completly
93
94 // check BE user settings
95 //TODO give $state a more descriptive name / state of/for what?
96 $state = t3lib_div::_GP('t3editor_disableEditor') == 'true' ? true : $GLOBALS['BE_USER']->uc['disableT3Editor'];
97 $this->setBEUCdisableT3Editor($state);
98
99 // disable pmktextarea to avoid conflicts (thanks Peter Klein for this suggestion)
100 $GLOBALS["BE_USER"]->uc['disablePMKTextarea'] = 1;
101 }
102
103 /**
104 * Sets editor enabled/disabled state
105 *
106 * @param boolean $state <code>true</code> if editor is disabled
107 * @return void
108 */
109 public function setBEUCdisableT3Editor($state) { //TODO better descriptive name for $state
110 if ($GLOBALS['BE_USER']->uc['disableT3Editor'] != $state) {
111 $GLOBALS['BE_USER']->uc['disableT3Editor'] = $state;
112
113 $GLOBALS['BE_USER']->writeUC();
114 }
115 }
116
117 /**
118 * Retrieves JavaScript code for editor
119 *
120 * @param template $doc
121 * @return string JavaScript code
122 */
123 public function getJavascriptCode($doc) {
124 $code = ''; // TODO find a more descriptive name (low prio)
125
126 if ($this->isEnabled) {
127
128 $path_t3e = t3lib_extmgm::extRelPath('t3editor');
129
130 // include needed javascript-frameworks
131 /** @var $pageRenderer t3lib_PageRenderer */
132 $pageRenderer = $doc->getPageRenderer();
133 $pageRenderer->loadPrototype();
134 $pageRenderer->loadScriptaculous();
135
136 // include editor-css
137 $code.= '<link href="' .
138 $GLOBALS['BACK_PATH'] .
139 t3lib_extmgm::extRelPath('t3editor') .
140 $this->filepathEditorcss .
141 '" type="text/css" rel="stylesheet" />';
142
143 // include editor-js-lib
144 $doc->loadJavascriptLib($path_t3e . 'jslib/codemirror/codemirror.js');
145 $doc->loadJavascriptLib($path_t3e . 'jslib/t3editor.js');
146
147 $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/tsref.js');
148 $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/completionresult.js');
149 $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/tsparser.js');
150 $doc->loadJavascriptLib($path_t3e . 'jslib/ts_codecompletion/tscodecompletion.js');
151
152 // set correct path to the editor
153
154 $code.= t3lib_div::wrapJS(
155 'var PATH_t3e = "' . $GLOBALS['BACK_PATH'] . t3lib_extmgm::extRelPath('t3editor') . '"; ' .
156 'var URL_typo3 = "' . htmlspecialchars(t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir) . '"; '
157 );
158 }
159
160 return $code;
161 }
162
163 /**
164 * Generates HTML with code editor
165 *
166 * @param string $name Name attribute of HTML tag
167 * @param string $class Class attribute of HTML tag
168 * @param string $content Content of the editor
169 * @param string $additionalParams Any additional editor parameters
170 * @param string $alt Alt attribute
171 * @return string Generated HTML code for editor
172 */
173 public function getCodeEditor($name, $class='', $content='', $additionalParams='', $alt='', array $hiddenfields = array()) {
174 $code = '';
175
176 if ($this->isEnabled) {
177 $this->editorCounter++;
178
179 $class .= ' t3editor';
180 if (!empty($alt)) {
181 $alt = ' alt="' . $alt . '"';
182 }
183
184 $code .= '<div>' .
185 '<textarea id="t3editor_' . $this->editorCounter . '" ' .
186 'name="' . $name . '" ' .
187 'class="' . $class . '" ' .
188 $additionalParams . ' ' .
189 $alt . '>' .
190 $content .
191 '</textarea></div>';
192
193 $checked = $GLOBALS['BE_USER']->uc['disableT3Editor'] ? 'checked="checked"' : '';
194
195 $code .= '<br /><br />' .
196 '<input type="checkbox" ' .
197 'class="checkbox" ' .
198 'onclick="t3editor_toggleEditor(this);" ' .
199 'name="t3editor_disableEditor" ' .
200 'value="true" ' .
201 'id="t3editor_disableEditor_' . $this->editorCounter.'_checkbox" ' .
202 $checked.' />&nbsp;' .
203 '<label for="t3editor_disableEditor_' . $this->editorCounter . '_checkbox">' .
204 $GLOBALS['LANG']->getLL('deactivate') .
205 '</label>' .
206 '<br /><br />';
207
208 if (count($hiddenfields)) {
209 foreach ($hiddenfields as $name => $value) {
210 $code.= '<input type="hidden" ' .
211 'name="' . $name . '" ' .
212 'value="' . $value .
213 '" />';
214 }
215 }
216
217 } else {
218 // fallback
219 if (!empty($class)) {
220 $class = 'class="' . $class . '" ';
221 }
222
223 $code .= '<textarea name="' . $name . '" ' .
224 $class . $additionalParams.'>' .
225 $content . '</textarea>';
226 }
227
228 return $code;
229 }
230
231
232 public function makeGlobalEditorInstance() {
233 if (!is_object($GLOBALS['T3_VAR']['t3editorObj'])) {
234 $GLOBALS['T3_VAR']['t3editorObj'] = t3lib_div::getUserObj('EXT:t3editor/class.tx_t3editor.php:&tx_t3editor');
235 }
236 }
237
238 /**
239 * Hook-function: inject t3editor JavaScript code before the page is compiled
240 * called in typo3/template.php:startPage
241 *
242 * @param array $parameters
243 * @param template $pObj
244 */
245 public function preStartPageHook($parameters, $pObj) {
246 // enable editor in Template-Modul
247 if (preg_match('/sysext\/tstemplate\/ts\/index\.php/', $_SERVER['SCRIPT_NAME'])) {
248
249 tx_t3editor::makeGlobalEditorInstance();
250
251 // insert javascript code in document header
252 $pObj->JScode .= $GLOBALS['T3_VAR']['t3editorObj']->getJavascriptCode($pObj);
253 }
254 }
255
256
257 /**
258 * Hook-function:
259 * called in typo3/sysext/tstemplate_info/class.tx_tstemplateinfo.php
260 *
261 * @param array $parameters
262 * @param tx_tstemplateinfo $pObj
263 */
264 public function postOutputProcessingHook($parameters, $pObj) {
265 tx_t3editor::makeGlobalEditorInstance();
266 if (!$GLOBALS['T3_VAR']['t3editorObj']->isEnabled) {
267 return;
268 }
269
270 // Template Constants
271 if ($parameters['e']['constants']) {
272 $attributes = 'rows="' . $parameters['numberOfRows'] . '" ' .
273 'wrap="off" ' .
274 $pObj->pObj->doc->formWidthText(48, 'width:98%;height:60%', 'off');
275
276 $title = $GLOBALS['LANG']->getLL('template') . ' ' .
277 htmlspecialchars($parameters['tplRow']['title']) .
278 $GLOBALS['LANG']->getLL('delimiter') . ' ' .
279 $GLOBALS['LANG']->getLL('constants');
280
281 $outCode = $GLOBALS['T3_VAR']['t3editorObj']->getCodeEditor(
282 'data[constants]',
283 'fixed-font enable-tab',
284 t3lib_div::formatForTextarea($parameters['tplRow']['constants']),
285 $attributes,
286 $title,
287 array(
288 'pageId' => intval($pObj->pObj->id),
289 't3editor_savetype' => 'tx_tstemplateinfo',
290 )
291 );
292 $parameters['theOutput'] = preg_replace(
293 '/\<textarea name="data\[constants\]".*\>([^\<]*)\<\/textarea\>/mi',
294 $outCode,
295 $parameters['theOutput']
296 );
297 }
298
299 // Template Setup
300 if ($parameters['e']['config']) {
301 $attributes = 'rows="' . $parameters['numberOfRows'] . '" ' .
302 'wrap="off" ' .
303 $pObj->pObj->doc->formWidthText(48, 'width:98%;height:60%', 'off');
304
305 $title = $GLOBALS['LANG']->getLL('template') . ' ' .
306 htmlspecialchars($parameters['tplRow']['title']) .
307 $GLOBALS['LANG']->getLL('delimiter') . ' ' .
308 $GLOBALS['LANG']->getLL('setup');
309
310 $outCode = $GLOBALS['T3_VAR']['t3editorObj']->getCodeEditor(
311 'data[config]',
312 'fixed-font enable-tab',
313 t3lib_div::formatForTextarea($parameters['tplRow']['config']),
314 $attributes,
315 $title,
316 array(
317 'pageId' => intval($pObj->pObj->id),
318 't3editor_savetype' => 'tx_tstemplateinfo',
319 )
320 );
321 $parameters['theOutput'] = preg_replace(
322 '/\<textarea name="data\[config\]".*\>([^\<]*)\<\/textarea\>/mi',
323 $outCode,
324 $parameters['theOutput']
325 );
326 }
327 }
328
329 /**
330 * Save the content from t3editor retrieved via Ajax
331 *
332 * new Ajax.Request('/dev/t3e/dummy/typo3/ajax.php', {
333 * parameters: {
334 * ajaxID: 'tx_t3editor::saveCode',
335 * t3editor_savetype: 'tx_tstemplateinfo'
336 * }
337 * });
338 *
339 * @param array params Parameters (not used yet)
340 * @param TYPO3AJAX ajaxObj AjaxObject to handle response
341 */
342 public function saveCode($params, $ajaxObj) {
343 // cancel if its not an Ajax request
344 if((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX)) {
345 $ajaxObj->setContentFormat('json');
346 $codeType = t3lib_div::_GP('t3editor_savetype');
347 $savingsuccess = false;
348
349 switch ($codeType) {
350 case 'tx_tstemplateinfo':
351 $savingsuccess = $this->saveCodeTsTemplateInfo();
352 break;
353
354 // TODO: fileadmin, extmng, TCEform, ...
355
356 default:
357 $ajaxObj->setError($GLOBALS['LANG']->getLL('unknownContentType') . ' ' . $codeType);
358 }
359 $ajaxObj->setContent(array('result' => $savingsuccess));
360 }
361 }
362
363 /**
364 * Process saving request like in class.tstemplateinfo.php (TCE processing)
365 *
366 * @return boolean true if successful
367 */
368 public function saveCodeTsTemplateInfo() {
369 $savingsuccess = false;
370
371 $pageId = t3lib_div::_GP('pageId');
372
373 if (!is_numeric($pageId) || $pageId < 1) {
374 return false;
375 }
376
377 // if given use the requested template_uid
378 // if not, use the first template-record on the page (in this case there should only be one record!)
379 $set = t3lib_div::_GP('SET');
380 $template_uid = $set['templatesOnPage'] ? $set['templatesOnPage'] : 0;
381
382 $tmpl = t3lib_div::makeInstance('t3lib_tsparser_ext'); // Defined global here!
383 $tmpl->tt_track = 0; // Do not log time-performance information
384 $tmpl->init();
385
386 // Get the row of the first VISIBLE template of the page. whereclause like the frontend.
387 $tplRow = $tmpl->ext_getFirstTemplate($pageId, $template_uid);
388 $existTemplate = (is_array($tplRow) ? true : false);
389
390 if ($existTemplate) {
391 $saveId = ($tplRow['_ORIG_uid'] ? $tplRow['_ORIG_uid'] : $tplRow['uid']);
392
393 // Update template ?
394 $POST = t3lib_div::_POST();
395
396 if ($POST['submit']) {
397 require_once(PATH_t3lib . 'class.t3lib_tcemain.php');
398
399 // Set the data to be saved
400 $recData = array();
401
402 if (is_array($POST['data'])) {
403 foreach ($POST['data'] as $field => $val) {
404 switch ($field) {
405 case 'constants':
406 case 'config':
407 case 'title':
408 case 'sitetitle':
409 case 'description':
410 $recData['sys_template'][$saveId][$field] = $val;
411 break;
412 }
413 }
414 }
415 if (count($recData)) {
416 // Create new tce-object
417 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
418 $tce->stripslashes_values = 0;
419
420 // Initialize
421 $tce->start($recData, array());
422
423 // Saved the stuff
424 $tce->process_datamap();
425
426 // Clear the cache (note: currently only admin-users can clear the
427 // cache in tce_main.php)
428 $tce->clear_cacheCmd('all');
429
430 $savingsuccess = true;
431 }
432 }
433 }
434 return $savingsuccess;
435 }
436
437 /**
438 * Gets plugins that are defined at $TYPO3_CONF_VARS['EXTCONF']['t3editor']['plugins']
439 * (called by typo3/ajax.php)
440 *
441 * @param array $params: additional parameters (not used here)
442 * @param TYPO3AJAX &$ajaxObj: the TYPO3AJAX object of this request
443 * @return void
444 * @author Oliver Hader <oliver@typo3.org>
445 */
446 public function getPlugins($params, TYPO3AJAX &$ajaxObj) {
447 $result = array();
448 $plugins =& $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3editor']['plugins'];
449
450 if (is_array($plugins)) {
451 $result = array_values($plugins);
452 }
453
454 $ajaxObj->setContent($result);
455 $ajaxObj->setContentFormat('jsonbody');
456 }
457 }
458
459
460
461 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/class.tx_t3editor.php']) {
462 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/t3editor/class.tx_t3editor.php']);
463 }
464
465 ?>