|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2007-2011 Tobias Liebig <mail_typo3@etobi.de> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 00028 00029 /** 00030 * Provides a javascript-driven code editor with syntax highlighting for TS, HTML, CSS and more 00031 * 00032 * @author Tobias Liebig <mail_typo3@etobi.de> 00033 */ 00034 00035 $GLOBALS['LANG']->includeLLFile('EXT:t3editor/locallang.xml'); 00036 00037 class tx_t3editor implements t3lib_Singleton { 00038 00039 const MODE_TYPOSCRIPT = 'typoscript'; 00040 const MODE_JAVASCRIPT = 'javascript'; 00041 const MODE_CSS = 'css'; 00042 const MODE_XML = 'xml'; 00043 const MODE_HTML = 'html'; 00044 const MODE_PHP = 'php'; 00045 const MODE_MIXED = 'mixed'; 00046 00047 protected $mode = ''; 00048 00049 protected $ajaxSaveType = ''; 00050 00051 /** 00052 * counts the editors on the current page 00053 * 00054 * @var int 00055 */ 00056 protected $editorCounter = 0; 00057 00058 /** 00059 * flag to enable the t3editor 00060 * 00061 * @var bool 00062 */ 00063 protected $_isEnabled = true; 00064 00065 /** 00066 * sets the type of code to edit (::MODE_TYPOSCRIPT, ::MODE_JAVASCRIPT) 00067 * 00068 * @param $mode string expects one of the predefined constants 00069 * @return tx_t3editor 00070 */ 00071 public function setMode($mode) { 00072 $this->mode = $mode; 00073 return $this; 00074 } 00075 00076 /** 00077 * 00078 * @param $ajaxSaveType 00079 * @return tx_t3editor 00080 */ 00081 public function setAjaxSaveType($ajaxSaveType) { 00082 $this->ajaxSaveType = $ajaxSaveType; 00083 return $this; 00084 } 00085 00086 public function setModeByFile($file) { 00087 $fileInfo = t3lib_div::split_fileref($file); 00088 switch ($fileInfo['fileext']) { 00089 case 'html': 00090 case 'htm': 00091 case 'tmpl': 00092 $mode = self::MODE_HTML; 00093 break; 00094 case 'js': 00095 $mode = self::MODE_JAVASCRIPT; 00096 break; 00097 case 'xml': 00098 case 'svg': 00099 $mode = self::MODE_XML; 00100 break; 00101 case 'css': 00102 $mode = self::MODE_CSS; 00103 break; 00104 case 'ts': 00105 $mode = self::MODE_TYPOSCRIPT; 00106 break; 00107 case 'php': 00108 case 'phpsh': 00109 case 'inc': 00110 $mode = self::MODE_PHP; 00111 break; 00112 default: 00113 $mode = self::MODE_MIXED; 00114 } 00115 $this->setMode($mode); 00116 } 00117 00118 public function getMode() { 00119 return $this->mode; 00120 } 00121 00122 /** 00123 * @return boolean true if the t3editor is enabled 00124 */ 00125 public function isEnabled() { 00126 return $this->_isEnabled; 00127 } 00128 00129 /** 00130 * Creates a new instance of the class 00131 * 00132 * @return void 00133 */ 00134 public function __construct() { 00135 // disable pmktextarea to avoid conflicts (thanks Peter Klein for this suggestion) 00136 $GLOBALS["BE_USER"]->uc['disablePMKTextarea'] = 1; 00137 } 00138 00139 /** 00140 * Retrieves JavaScript code (header part) for editor 00141 * 00142 * @param template $doc 00143 * @return string JavaScript code 00144 */ 00145 public function getJavascriptCode($doc) { 00146 $content = ''; 00147 00148 if ($this->isEnabled()) { 00149 00150 $path_t3e = t3lib_extmgm::extRelPath('t3editor'); 00151 $path_codemirror = 'contrib/codemirror/js/'; 00152 00153 // include needed javascript-frameworks 00154 $pageRenderer = $doc->getPageRenderer(); 00155 /** @var $pageRenderer t3lib_PageRenderer */ 00156 $pageRenderer->loadPrototype(); 00157 $pageRenderer->loadScriptaculous(); 00158 00159 // include editor-css 00160 $content .= '<link href="' . 00161 t3lib_div::createVersionNumberedFilename($GLOBALS['BACK_PATH'] . 00162 t3lib_extmgm::extRelPath('t3editor') . 00163 'res/css/t3editor.css') . 00164 '" type="text/css" rel="stylesheet" />'; 00165 00166 // include editor-js-lib 00167 $doc->loadJavascriptLib($path_codemirror . 'codemirror.js'); 00168 $doc->loadJavascriptLib($path_t3e . 'res/jslib/t3editor.js'); 00169 00170 $content .= t3lib_div::wrapJS( 00171 'T3editor = T3editor || {};' . 00172 'T3editor.lang = ' . json_encode($this->getJavaScriptLabels()) .';' . LF. 00173 'T3editor.PATH_t3e = "' . $GLOBALS['BACK_PATH'] . $path_t3e . '"; ' . LF. 00174 'T3editor.PATH_codemirror = "' . $GLOBALS['BACK_PATH'] . $path_codemirror . '"; ' . LF. 00175 'T3editor.URL_typo3 = "' . htmlspecialchars(t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir) . '"; ' .LF. 00176 'T3editor.template = '. $this->getPreparedTemplate() .';' .LF. 00177 ($this->ajaxSaveType ? 'T3editor.ajaxSavetype = "' . $this->ajaxSaveType . '";' . LF : '') . 00178 ($this->mode ? 'T3editor.parserfile = ' . $this->getParserfileByMode($this->mode) . ';' . LF : '') . 00179 ($this->mode ? 'T3editor.stylesheet = ' . $this->getStylesheetByMode($this->mode) . ';' : '') 00180 ); 00181 $content .= $this->getModeSpecificJavascriptCode(); 00182 } 00183 00184 return $content; 00185 } 00186 00187 public function getModeSpecificJavascriptCode() { 00188 if (empty($this->mode)) { 00189 return ''; 00190 } 00191 00192 $path_t3e = $GLOBALS['BACK_PATH'] . t3lib_extmgm::extRelPath('t3editor'); 00193 $content = ''; 00194 00195 if ($this->mode === self::MODE_TYPOSCRIPT) { 00196 $content .= '<script type="text/javascript" src="' . $path_t3e . 'res/jslib/ts_codecompletion/tsref.js' . '"></script>'; 00197 $content .= '<script type="text/javascript" src="' . $path_t3e . 'res/jslib/ts_codecompletion/completionresult.js' . '"></script>'; 00198 $content .= '<script type="text/javascript" src="' . $path_t3e . 'res/jslib/ts_codecompletion/tsparser.js' . '"></script>'; 00199 $content .= '<script type="text/javascript" src="' . $path_t3e . 'res/jslib/ts_codecompletion/tscodecompletion.js' . '"></script>'; 00200 } 00201 00202 $content .= t3lib_div::wrapJS( 00203 'T3editor.parserfile = ' . $this->getParserfileByMode($this->mode) . ';' . LF . 00204 'T3editor.stylesheet = ' . $this->getStylesheetByMode($this->mode) . ';' 00205 ); 00206 return $content; 00207 } 00208 00209 /** 00210 * get the template code, prepared for javascript (no line breaks, quoted in single quotes) 00211 * 00212 * @return string the template code, prepared to use in javascript 00213 */ 00214 protected function getPreparedTemplate() { 00215 $T3Editor_template = t3lib_div::getURL( 00216 t3lib_div::getFileAbsFileName( 00217 'EXT:t3editor/res/templates/t3editor.html' 00218 ) 00219 ); 00220 $T3Editor_template = addslashes($T3Editor_template); 00221 $T3Editor_template = str_replace(LF, "' + '", $T3Editor_template); 00222 00223 return '\'' . $T3Editor_template . '\''; 00224 } 00225 00226 /** 00227 * determine the correct parser js file for given mode 00228 * 00229 * @param string $mode 00230 * @return string parser file name 00231 */ 00232 protected function getParserfileByMode($mode) { 00233 switch ($mode) { 00234 case tx_t3editor::MODE_TYPOSCRIPT: 00235 $relPath = $GLOBALS['BACK_PATH'] . t3lib_extmgm::extRelPath('t3editor') . 'res/jslib/parse_typoscript/'; 00236 $parserfile = '["' . $relPath . 'tokenizetyposcript.js", "' . $relPath . 'parsetyposcript.js"]'; 00237 break; 00238 00239 case tx_t3editor::MODE_JAVASCRIPT: 00240 $parserfile = '["tokenizejavascript.js", "parsejavascript.js"]'; 00241 break; 00242 00243 case tx_t3editor::MODE_CSS: 00244 $parserfile = '"parsecss.js"'; 00245 break; 00246 00247 case tx_t3editor::MODE_XML: 00248 $parserfile = '"parsexml.js"'; 00249 break; 00250 00251 case tx_t3editor::MODE_HTML: 00252 $parserfile = '["tokenizejavascript.js", "parsejavascript.js", "parsecss.js", "parsexml.js", "parsehtmlmixed.js"]'; 00253 break; 00254 00255 case tx_t3editor::MODE_PHP: 00256 case tx_t3editor::MODE_MIXED: 00257 $parserfile = '[' . 00258 '"tokenizejavascript.js", ' . 00259 '"parsejavascript.js", ' . 00260 '"parsecss.js", ' . 00261 '"parsexml.js", ' . 00262 '"../contrib/php/js/tokenizephp.js", ' . 00263 '"../contrib/php/js/parsephp.js", ' . 00264 '"../contrib/php/js/parsephphtmlmixed.js"' . 00265 ']'; 00266 break; 00267 } 00268 return $parserfile; 00269 } 00270 00271 /** 00272 * determine the correct css file for given mode 00273 * 00274 * @param string $mode 00275 * @return string css file name 00276 */ 00277 protected function getStylesheetByMode($mode) { 00278 switch ($mode) { 00279 case tx_t3editor::MODE_TYPOSCRIPT: 00280 $stylesheet = '"res/css/typoscriptcolors.css"'; 00281 break; 00282 00283 case tx_t3editor::MODE_JAVASCRIPT: 00284 $stylesheet = '"res/css/jscolors.css"'; 00285 break; 00286 00287 case tx_t3editor::MODE_CSS: 00288 $stylesheet = '"res/css/csscolors.css"'; 00289 break; 00290 00291 case tx_t3editor::MODE_XML: 00292 $stylesheet = '"res/css/xmlcolors.css"'; 00293 break; 00294 00295 case tx_t3editor::MODE_HTML: 00296 $stylesheet = '"res/css/xmlcolors.css", ' . 00297 'T3editor.PATH_t3e + "res/css/jscolors.css", ' . 00298 'T3editor.PATH_t3e + "res/css/csscolors.css"'; 00299 break; 00300 00301 case tx_t3editor::MODE_PHP: 00302 $stylesheet = '"../../contrib/codemirror/contrib/php/css/phpcolors.css"'; 00303 break; 00304 00305 case tx_t3editor::MODE_MIXED: 00306 $stylesheet = '"res/css/xmlcolors.css", ' . 00307 'T3editor.PATH_t3e + "res/css/jscolors.css", ' . 00308 'T3editor.PATH_t3e + "res/css/csscolors.css", ' . 00309 'T3editor.PATH_codemirror + "../contrib/php/css/phpcolors.css"'; 00310 break; 00311 } 00312 return '[T3editor.PATH_t3e + ' . $stylesheet . ', T3editor.PATH_t3e + "res/css/t3editor_inner.css"]'; 00313 } 00314 00315 /** 00316 * Gets the labels to be used in JavaScript in the Ext JS interface. 00317 * TODO this method is copied from EXT:Recycler, maybe this should be refactored into a helper class 00318 * 00319 * @return array The labels to be used in JavaScript 00320 */ 00321 protected function getJavaScriptLabels() { 00322 $coreLabels = array(); 00323 $extensionLabels = $this->getJavaScriptLabelsFromLocallang('js.', 'label_'); 00324 return array_merge($coreLabels, $extensionLabels); 00325 } 00326 00327 /** 00328 * Gets labels to be used in JavaScript fetched from the current locallang file. 00329 * TODO this method is copied from EXT:Recycler, maybe this should be refactored into a helper class 00330 * 00331 * @param string $selectionPrefix: Prefix to select the correct labels (default: 'js.') 00332 * @param string $stripFromSelectionName: Sub-prefix to be removed from label names in the result (default: '') 00333 * @return array Lables to be used in JavaScript of the current locallang file 00334 * @todo Check, whether this method can be moved in a generic way to $GLOBALS['LANG'] 00335 */ 00336 protected function getJavaScriptLabelsFromLocallang($selectionPrefix = 'js.', $stripFromSelectionName = '') { 00337 $extraction = array(); 00338 $labels = array_merge( 00339 (array)$GLOBALS['LOCAL_LANG']['default'], 00340 (array)$GLOBALS['LOCAL_LANG'][$GLOBALS['LANG']->lang] 00341 ); 00342 // Regular expression to strip the selection prefix and possibly something from the label name: 00343 $labelPattern = '#^' . preg_quote($selectionPrefix, '#') . '(' . preg_quote($stripFromSelectionName, '#') . ')?#'; 00344 // Iterate throuh all locallang lables: 00345 foreach ($labels as $label => $value) { 00346 if (strpos($label, $selectionPrefix) === 0) { 00347 $key = preg_replace($labelPattern, '', $label); 00348 $extraction[$key] = $value; 00349 } 00350 } 00351 return $extraction; 00352 } 00353 00354 /** 00355 * Generates HTML with code editor 00356 * 00357 * @param string $name Name attribute of HTML tag 00358 * @param string $class Class attribute of HTML tag 00359 * @param string $content Content of the editor 00360 * @param string $additionalParams Any additional editor parameters 00361 * @param string $alt Alt attribute 00362 * @return string Generated HTML code for editor 00363 */ 00364 public function getCodeEditor($name, $class='', $content='', $additionalParams='', $alt='', array $hiddenfields = array()) { 00365 $code = ''; 00366 00367 if ($this->isEnabled()) { 00368 $this->editorCounter++; 00369 00370 $class .= ' t3editor'; 00371 $alt = htmlspecialchars($alt); 00372 if (!empty($alt)) { 00373 $alt = ' alt="' . $alt . '"'; 00374 } 00375 00376 $code .= '<div>' . 00377 '<textarea id="t3editor_' . $this->editorCounter . '" ' . 00378 'name="' . $name . '" ' . 00379 'class="' . $class . '" ' . 00380 $additionalParams . ' ' . 00381 $alt . '>' . 00382 $content . 00383 '</textarea></div>'; 00384 00385 $checked = $GLOBALS['BE_USER']->uc['disableT3Editor'] ? 'checked="checked"' : ''; 00386 00387 $code .= '<br /><br />' . 00388 '<input type="checkbox" ' . 00389 'class="checkbox t3editor_disableEditor" ' . 00390 'onclick="T3editor.toggleEditor(this);" ' . 00391 'name="t3editor_disableEditor" ' . 00392 'value="true" ' . 00393 'id="t3editor_disableEditor_' . $this->editorCounter . '_checkbox" ' . 00394 $checked.' /> ' . 00395 '<label for="t3editor_disableEditor_' . $this->editorCounter . '_checkbox">' . 00396 $GLOBALS['LANG']->getLL('deactivate') . 00397 '</label>' . 00398 '<br /><br />'; 00399 00400 if (count($hiddenfields)) { 00401 foreach ($hiddenfields as $name => $value) { 00402 $code.= '<input type="hidden" ' . 00403 'name="' . $name . '" ' . 00404 'value="' . $value . 00405 '" />'; 00406 } 00407 } 00408 00409 } else { 00410 // fallback 00411 if (!empty($class)) { 00412 $class = 'class="' . $class . '" '; 00413 } 00414 00415 $code .= '<textarea name="' . $name . '" ' . 00416 $class . $additionalParams.'>' . 00417 $content . '</textarea>'; 00418 } 00419 00420 return $code; 00421 } 00422 00423 00424 00425 /** 00426 * Save the content from t3editor retrieved via Ajax 00427 * 00428 * new Ajax.Request('/dev/t3e/dummy/typo3/ajax.php', { 00429 * parameters: { 00430 * ajaxID: 'tx_t3editor::saveCode', 00431 * t3editor_savetype: 'tx_tstemplateinfo' 00432 * } 00433 * }); 00434 * 00435 * @param array params Parameters (not used yet) 00436 * @param TYPO3AJAX ajaxObj AjaxObject to handle response 00437 */ 00438 public function ajaxSaveCode($params, $ajaxObj) { 00439 // cancel if its not an Ajax request 00440 if((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX)) { 00441 $ajaxObj->setContentFormat('json'); 00442 $codeType = t3lib_div::_GP('t3editor_savetype'); 00443 $savingsuccess = false; 00444 00445 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode'])) { 00446 $_params = array( 00447 'pObj' => &$this, 00448 'type' => $codeType, 00449 'ajaxObj' => &$ajaxObj, 00450 ); 00451 foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode'] as $key => $_funcRef) { 00452 $savingsuccess = t3lib_div::callUserFunction($_funcRef,$_params,$this) || $savingsuccess; 00453 } 00454 } 00455 00456 $ajaxObj->setContent(array('result' => $savingsuccess)); 00457 } 00458 } 00459 00460 /** 00461 * Gets plugins that are defined at $TYPO3_CONF_VARS['EXTCONF']['t3editor']['plugins'] 00462 * (called by typo3/ajax.php) 00463 * 00464 * @param array $params: additional parameters (not used here) 00465 * @param TYPO3AJAX &$ajaxObj: the TYPO3AJAX object of this request 00466 * @return void 00467 * @author Oliver Hader <oliver@typo3.org> 00468 */ 00469 public function getPlugins($params, TYPO3AJAX &$ajaxObj) { 00470 $result = array(); 00471 $plugins =& $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3editor']['plugins']; 00472 00473 if (is_array($plugins)) { 00474 $result = array_values($plugins); 00475 } 00476 00477 $ajaxObj->setContent($result); 00478 $ajaxObj->setContentFormat('jsonbody'); 00479 } 00480 00481 } 00482 00483 00484 00485 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor.php'])) { 00486 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/t3editor/classes/class.tx_t3editor.php']); 00487 } 00488 00489 ?>
1.8.0