TYPO3  7.6
T3editor.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\T3editor;
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 
21 
26 {
27  const MODE_TYPOSCRIPT = 'typoscript';
28  const MODE_JAVASCRIPT = 'javascript';
29  const MODE_CSS = 'css';
30  const MODE_XML = 'xml';
31  const MODE_HTML = 'html';
32  const MODE_PHP = 'php';
33  const MODE_SPARQL = 'sparql';
34  const MODE_MIXED = 'mixed';
35 
39  protected $mode = '';
40 
44  protected $ajaxSaveType = '';
45 
51  protected $editorCounter = 0;
52 
58  protected $relExtPath = '';
59 
65  protected $codemirrorPath = 'sysext/t3editor/Resources/Public/JavaScript/Contrib/codemirror/js/';
66 
72  protected $codeCompletionComponents = array('TsRef', 'CompletionResult', 'TsParser', 'TsCodeCompletion');
73 
80  public function setMode($mode)
81  {
82  $this->mode = $mode;
83  return $this;
84  }
85 
92  public function setAjaxSaveType($ajaxSaveType)
93  {
94  $this->ajaxSaveType = $ajaxSaveType;
95  return $this;
96  }
97 
104  public function setModeByFile($file)
105  {
106  $fileInfo = GeneralUtility::split_fileref($file);
107  // @TODO: @FIXME: the method setModeByType returns void, so this method will never return a string
108  return $this->setModeByType($fileInfo['fileext']);
109  }
110 
117  public function setModeByType($type)
118  {
119  switch ($type) {
120  case 'html':
121  case 'htm':
122  case 'tmpl':
123  $mode = self::MODE_HTML;
124  break;
125  case 'js':
126  $mode = self::MODE_JAVASCRIPT;
127  break;
128  case 'xml':
129  case 'svg':
130  $mode = self::MODE_XML;
131  break;
132  case 'css':
133  $mode = self::MODE_CSS;
134  break;
135  case 'ts':
136  $mode = self::MODE_TYPOSCRIPT;
137  break;
138  case 'sparql':
139  $mode = self::MODE_SPARQL;
140  break;
141  case 'php':
142  case 'phpsh':
143  case 'inc':
144  $mode = self::MODE_PHP;
145  break;
146  default:
147  $mode = self::MODE_MIXED;
148  }
149  $this->setMode($mode);
150  }
151 
157  public function getMode()
158  {
159  return $this->mode;
160  }
161 
166  public function isEnabled()
167  {
169  return true;
170  }
171 
175  public function __construct()
176  {
177  $GLOBALS['LANG']->includeLLFile('EXT:t3editor/Resources/Private/Language/locallang.xlf');
178  // Disable pmktextarea to avoid conflicts (thanks Peter Klein for this suggestion)
179  $GLOBALS['BE_USER']->uc['disablePMKTextarea'] = 1;
180 
181  $this->relExtPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('t3editor');
182  }
183 
189  public function getJavascriptCode()
190  {
192  $pageRenderer = $this->getPageRenderer();
193  $pageRenderer->addCssFile($this->relExtPath . 'Resources/Public/Css/t3editor.css');
194  // Include editor-js-lib
195  $pageRenderer->addJsLibrary('codemirror', $this->codemirrorPath . 'codemirror.js');
196  if ($this->mode === self::MODE_TYPOSCRIPT) {
197  foreach ($this->codeCompletionComponents as $codeCompletionComponent) {
198  $pageRenderer->loadRequireJsModule('TYPO3/CMS/T3editor/Plugins/CodeCompletion/' . $codeCompletionComponent);
199  }
200  }
201  $pageRenderer->loadRequireJsModule('TYPO3/CMS/T3editor/T3editor');
202  return '';
203  }
204 
210  protected function getPreparedTemplate()
211  {
212  $T3editor_template = GeneralUtility::getUrl(
213  GeneralUtility::getFileAbsFileName('EXT:t3editor/Resources/Private/Templates/t3editor.html')
214  );
215  return str_replace(array(CR, LF), '', $T3editor_template);
216  }
217 
224  protected function getParserfileByMode($mode)
225  {
226  switch ($mode) {
227  case self::MODE_TYPOSCRIPT:
228  $relPath = '../../../parse_typoscript/';
229  $parserfile = array($relPath . 'tokenizetyposcript.js', $relPath . 'parsetyposcript.js');
230  break;
231  case self::MODE_JAVASCRIPT:
232  $parserfile = array('tokenizetyposcript.js', 'parsejavascript.js');
233  break;
234  case self::MODE_CSS:
235  $parserfile = array('parsecss.js');
236  break;
237  case self::MODE_XML:
238  $parserfile = array('parsexml.js');
239  break;
240  case self::MODE_SPARQL:
241  $parserfile = array('parsesparql.js');
242  break;
243  case self::MODE_HTML:
244  $parserfile = array('tokenizejavascript.js', 'parsejavascript.js', 'parsecss.js', 'parsexml.js', 'parsehtmlmixed.js');
245  break;
246  case self::MODE_PHP:
247  case self::MODE_MIXED:
248  $parserfile = array('tokenizejavascript.js', 'parsejavascript.js', 'parsecss.js', 'parsexml.js', '../contrib/php/js/tokenizephp.js', '../contrib/php/js/parsephp.js', '../contrib/php/js/parsephphtmlmixed.js');
249  break;
250  }
251  return json_encode($parserfile);
252  }
253 
260  protected function getStylesheetByMode($mode)
261  {
262  switch ($mode) {
263  case self::MODE_TYPOSCRIPT:
264  $stylesheet = array($this->relExtPath . 'Resources/Public/Css/typoscriptcolors.css');
265  break;
266  case self::MODE_JAVASCRIPT:
267  $stylesheet = array($this->codemirrorPath . '../css/jscolors.css');
268  break;
269  case self::MODE_CSS:
270  $stylesheet = array($this->codemirrorPath . '../css/csscolors.css');
271  break;
272  case self::MODE_XML:
273  $stylesheet = array($this->codemirrorPath . '../css/xmlcolors.css');
274  break;
275  case self::MODE_HTML:
276  $stylesheet = array($this->codemirrorPath . '../css/xmlcolors.css', $this->codemirrorPath . '../css/jscolors.css', $this->codemirrorPath . '../css/csscolors.css');
277  break;
278  case self::MODE_SPARQL:
279  $stylesheet = array($this->codemirrorPath . '../css/sparqlcolors.css');
280  break;
281  case self::MODE_PHP:
282  $stylesheet = array($this->codemirrorPath . '../contrib/php/css/phpcolors.css');
283  break;
284  case self::MODE_MIXED:
285  $stylesheet = array($this->codemirrorPath . '../css/xmlcolors.css', $this->codemirrorPath . '../css/jscolors.css', $this->codemirrorPath . '../css/csscolors.css', $this->codemirrorPath . '../contrib/php/css/phpcolors.css');
286  break;
287  default:
288  $stylesheet = array();
289  }
290  $stylesheet[] = $this->relExtPath . 'Resources/Public/Css/t3editor_inner.css';
291  return json_encode($stylesheet);
292  }
293 
305  public function getCodeEditor($name, $class = '', $content = '', $additionalParams = '', $alt = '', array $hiddenfields = array())
306  {
307  $code = '';
308  $class .= ' t3editor';
309  $alt = htmlspecialchars($alt);
310  if (!empty($alt)) {
311  $alt = ' alt="' . $alt . '"';
312  }
313  $code .=
314  '<div class="t3editor">'
315  . '<div class="t3e_wrap">'
316  . $this->getPreparedTemplate()
317  . '</div>'
318  . '<textarea '
319  . 'id="t3editor_' . $this->editorCounter . '" '
320  . 'name="' . $name . '" '
321  . 'class="' . $class . '" '
322  . $additionalParams . ' '
323  . $alt
324  . ' data-labels="' . htmlspecialchars(json_encode($GLOBALS['LANG']->getLabelsWithPrefix('js.', 'label_'))) . '"'
325  . ' data-instance-number="' . $this->editorCounter . '"'
326  . ' data-editor-path="' . htmlspecialchars($this->relExtPath) . '"'
327  . ' data-codemirror-path="' . htmlspecialchars($this->codemirrorPath) . '"'
328  . ' data-ajaxsavetype="' . htmlspecialchars($this->ajaxSaveType) . '"'
329  . ' data-parserfile="' . htmlspecialchars($this->getParserfileByMode($this->mode)) . '"'
330  . ' data-stylesheet="' . htmlspecialchars($this->getStylesheetByMode($this->mode)) . '"'
331  . '>' . htmlspecialchars($content)
332  . '</textarea>'
333  . '</div>';
334  if (!empty($hiddenfields)) {
335  foreach ($hiddenfields as $name => $value) {
336  $code .= '<input type="hidden" ' . 'name="' . $name . '" ' . 'value="' . $value . '" />';
337  }
338  }
339  $this->editorCounter++;
340  return $code;
341  }
342 
350  public function ajaxSaveCode(ServerRequestInterface $request, ResponseInterface $response)
351  {
352  // cancel if its not an Ajax request
353  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
354  $codeType = isset($request->getParsedBody()['t3editor_savetype']) ? $request->getParsedBody()['t3editor_savetype'] : $request->getQueryParams()['t3editor_savetype'];
355  $savingsuccess = false;
356  try {
357  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode'])) {
358  $_params = array(
359  'pObj' => &$this,
360  'type' => $codeType,
361  'request' => $request,
362  'response' => $response
363  );
364  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode'] as $key => $_funcRef) {
365  $savingsuccess = GeneralUtility::callUserFunction($_funcRef, $_params, $this) || $savingsuccess;
366  }
367  }
368  $responseContent = array('result' => $savingsuccess);
369  } catch (\Exception $e) {
370  $responseContent = array(
371  'result' => false,
372  'exceptionMessage' => htmlspecialchars($e->getMessage()),
373  'exceptionCode' => $e->getCode()
374  );
375  }
377  $response = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\Response::class);
378  $response->getBody()->write(json_encode($responseContent));
379  }
380 
381  return $response;
382  }
383 
392  public function getPlugins(ServerRequestInterface $request, ResponseInterface $response)
393  {
394  $result = array();
395  $plugins = &$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3editor']['plugins'];
396  if (is_array($plugins)) {
397  $result = array_values($plugins);
398  }
399  $request->getBody()->write(json_encode($result));
400  return $request;
401  }
402 
406  protected function getPageRenderer()
407  {
408  return GeneralUtility::makeInstance(PageRenderer::class);
409  }
410 }