TYPO3 CMS  TYPO3_8-7
T3editorElement.php
Go to the documentation of this file.
1 <?php
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 
25 
30 {
31  const MODE_CSS = 'css';
32  const MODE_HTML = 'html';
33  const MODE_JAVASCRIPT = 'javascript';
34  const MODE_MIXED = 'mixed';
35  const MODE_PHP = 'php';
36  const MODE_SPARQL = 'sparql';
37  const MODE_TYPOSCRIPT = 'typoscript';
38  const MODE_XML = 'xml';
39 
43  protected $allowedModes = [
44  self::MODE_CSS,
45  self::MODE_HTML,
46  self::MODE_JAVASCRIPT,
47  self::MODE_MIXED,
48  self::MODE_PHP,
49  self::MODE_SPARQL,
50  self::MODE_TYPOSCRIPT,
51  self::MODE_XML,
52  ];
53 
57  protected $resultArray;
58 
62  protected $mode = '';
63 
69  protected $editorCounter = 0;
70 
76  protected $extPath = '';
77 
81  protected $codemirrorPath = 'Resources/Public/JavaScript/Contrib/codemirror/js/';
82 
88  protected $codeCompletionComponents = ['TsRef', 'CompletionResult', 'TsParser', 'TsCodeCompletion'];
89 
95  protected $defaultFieldWizard = [
96  'localizationStateSelector' => [
97  'renderType' => 'localizationStateSelector',
98  ],
99  'otherLanguageContent' => [
100  'renderType' => 'otherLanguageContent',
101  'after' => [
102  'localizationStateSelector'
103  ],
104  ],
105  'defaultLanguageDifferences' => [
106  'renderType' => 'defaultLanguageDifferences',
107  'after' => [
108  'otherLanguageContent',
109  ],
110  ],
111  ];
112 
118  public function render()
119  {
120  $this->getLanguageService()->includeLLFile('EXT:t3editor/Resources/Private/Language/locallang.xlf');
122  $this->codemirrorPath = $this->extPath . $this->codemirrorPath;
123 
124  $this->resultArray = $this->initializeResultArray();
125 
126  $parameterArray = $this->data['parameterArray'];
127 
128  $rows = MathUtility::forceIntegerInRange($parameterArray['fieldConf']['config']['rows'] ?: 10, 1, 40);
129  $this->setMode(isset($parameterArray['fieldConf']['config']['format']) ? $parameterArray['fieldConf']['config']['format'] : T3editor::MODE_MIXED);
130 
131  $attributes = [];
132  $attributes['rows'] = $rows;
133  $attributes['wrap'] = 'off';
134  $attributes['style'] = 'width:100%;';
135  $attributes['onchange'] = GeneralUtility::quoteJSvalue($parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged']);
136 
137  $attributeString = '';
138  foreach ($attributes as $param => $value) {
139  $attributeString .= $param . '="' . htmlspecialchars($value) . '" ';
140  }
141 
142  $editorHtml = $this->getHTMLCodeForEditor(
143  $parameterArray['itemFormElName'],
144  'text-monospace enable-tab',
145  $parameterArray['itemFormElValue'],
146  $attributeString,
147  $this->data['tableName'] . ' > ' . $this->data['fieldName'],
148  ['target' => 0]
149  );
150 
151  $legacyWizards = $this->renderWizards();
152  $legacyFieldControlHtml = implode(LF, $legacyWizards['fieldControl']);
153  $legacyFieldWizardHtml = implode(LF, $legacyWizards['fieldWizard']);
154 
155  $fieldInformationResult = $this->renderFieldInformation();
156  $fieldInformationHtml = $fieldInformationResult['html'];
157  $this->resultArray = $this->mergeChildReturnIntoExistingResult($this->resultArray, $fieldInformationResult, false);
158 
159  $fieldControlResult = $this->renderFieldControl();
160  $fieldControlHtml = $legacyFieldControlHtml . $fieldControlResult['html'];
161  $this->resultArray = $this->mergeChildReturnIntoExistingResult($this->resultArray, $fieldControlResult, false);
162 
163  $fieldWizardResult = $this->renderFieldWizard();
164  $fieldWizardHtml = $legacyFieldWizardHtml . $fieldWizardResult['html'];
165  $this->resultArray = $this->mergeChildReturnIntoExistingResult($this->resultArray, $fieldWizardResult, false);
166 
167  $html = [];
168  $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
169  $html[] = $fieldInformationHtml;
170  $html[] = '<div class="form-control-wrap">';
171  $html[] = '<div class="form-wizards-wrap">';
172  $html[] = '<div class="form-wizards-element">';
173  $html[] = $editorHtml;
174  $html[] = '</div>';
175  $html[] = '<div class="form-wizards-items-aside">';
176  $html[] = '<div class="btn-group">';
177  $html[] = $fieldControlHtml;
178  $html[] = '</div>';
179  $html[] = '</div>';
180  $html[] = '<div class="form-wizards-items-bottom">';
181  $html[] = $fieldWizardHtml;
182  $html[] = '</div>';
183  $html[] = '</div>';
184  $html[] = '</div>';
185  $html[] = '</div>';
186 
187  $this->resultArray['html'] = implode(LF, $html);
188 
189  $this->resultArray['additionalJavaScriptPost'][] = 'require(["TYPO3/CMS/T3editor/T3editor"], function(T3editor) {T3editor.findAndInitializeEditors();});';
190 
191  $this->initJavascriptCode();
192  return $this->resultArray;
193  }
194 
201  public function setMode($mode)
202  {
203  if (!in_array($mode, $this->allowedModes, true)) {
204  throw new \InvalidArgumentException($mode . 'is not allowed', 1438352574);
205  }
206  $this->mode = $mode;
207  }
208 
214  public function getMode()
215  {
216  return $this->mode;
217  }
218 
222  protected function initJavascriptCode()
223  {
224  $this->resultArray['stylesheetFiles'][] = 'EXT:t3editor/Resources/Public/Css/t3editor.css';
225  if ($this->mode === self::MODE_TYPOSCRIPT) {
226  foreach ($this->codeCompletionComponents as $codeCompletionComponent) {
227  $this->resultArray['requireJsModules'][] = 'TYPO3/CMS/T3editor/Plugins/CodeCompletion/' . $codeCompletionComponent;
228  }
229  }
230  }
231 
243  protected function getHTMLCodeForEditor($name, $class = '', $content = '', $additionalParams = '', $alt = '', array $hiddenfields = [])
244  {
245  $code = [];
246  $attributes = [];
247  $attributes['class'] = $class . ' t3editor';
248  $attributes['alt'] = $alt;
249  $attributes['id'] = 't3editor_' . $this->editorCounter;
250  $attributes['name'] = $name;
251  $attributes['data-labels'] = json_encode($this->getLanguageService()->getLabelsWithPrefix('js.', 'label_'));
252  $attributes['data-instance-number'] = $this->editorCounter;
253  $attributes['data-editor-path'] = $this->extPath;
254  $attributes['data-codemirror-path'] = $this->codemirrorPath;
255  $attributes['data-ajaxsavetype'] = ''; // no ajax save in FormEngine at the moment
256  $attributes['data-parserfile'] = $this->getParserfileByMode($this->mode);
257  $attributes['data-stylesheet'] = $this->getStylesheetByMode($this->mode);
258 
259  $attributesString = '';
260  foreach ($attributes as $attribute => $value) {
261  $attributesString .= $attribute . '="' . htmlspecialchars($value) . '" ';
262  }
263  $attributesString .= $additionalParams;
264 
265  $code[] = '<div class="t3editor">';
266  $code[] = '<div class="t3e_wrap">';
267  $code[] = str_replace([CR, LF], '', file_get_contents(GeneralUtility::getFileAbsFileName('EXT:t3editor/Resources/Private/Templates/t3editor.html')));
268  $code[] = '</div>';
269  $code[] = '<textarea ' . $attributesString . '>' . htmlspecialchars($content) . '</textarea>';
270  $code[] = '</div>';
271 
272  if (!empty($hiddenfields)) {
273  foreach ($hiddenfields as $name => $value) {
274  $code[] = '<input type="hidden" name="' . htmlspecialchars($name) . '" value="' . htmlspecialchars($value) . '" />';
275  }
276  }
277  $this->editorCounter++;
278  return implode(LF, $code);
279  }
280 
287  protected function getParserfileByMode($mode)
288  {
289  $parserfile = [];
290  switch ($mode) {
291  case self::MODE_TYPOSCRIPT:
292  $relPath = '../../../parse_typoscript/';
293  $parserfile = [$relPath . 'tokenizetyposcript.js', $relPath . 'parsetyposcript.js'];
294  break;
295  case self::MODE_JAVASCRIPT:
296  $parserfile = ['tokenizejavascript.js', 'parsejavascript.js'];
297  break;
298  case self::MODE_CSS:
299  $parserfile = ['parsecss.js'];
300  break;
301  case self::MODE_XML:
302  $parserfile = ['parsexml.js'];
303  break;
304  case self::MODE_SPARQL:
305  $parserfile = ['parsesparql.js'];
306  break;
307  case self::MODE_HTML:
308  $parserfile = ['tokenizejavascript.js', 'parsejavascript.js', 'parsecss.js', 'parsexml.js', 'parsehtmlmixed.js'];
309  break;
310  case self::MODE_PHP:
311  case self::MODE_MIXED:
312  $parserfile = ['tokenizejavascript.js', 'parsejavascript.js', 'parsecss.js', 'parsexml.js', '../contrib/php/js/tokenizephp.js', '../contrib/php/js/parsephp.js', '../contrib/php/js/parsephphtmlmixed.js'];
313  break;
314  }
315  return json_encode($parserfile);
316  }
317 
324  protected function getStylesheetByMode($mode)
325  {
326  switch ($mode) {
327  case self::MODE_TYPOSCRIPT:
328  $stylesheet = [$this->extPath . 'Resources/Public/Css/t3editor_typoscript_colors.css'];
329  break;
330  case self::MODE_JAVASCRIPT:
331  $stylesheet = [$this->codemirrorPath . '../css/jscolors.css'];
332  break;
333  case self::MODE_CSS:
334  $stylesheet = [$this->codemirrorPath . '../css/csscolors.css'];
335  break;
336  case self::MODE_XML:
337  $stylesheet = [$this->codemirrorPath . '../css/xmlcolors.css'];
338  break;
339  case self::MODE_HTML:
340  $stylesheet = [$this->codemirrorPath . '../css/xmlcolors.css', $this->codemirrorPath . '../css/jscolors.css', $this->codemirrorPath . '../css/csscolors.css'];
341  break;
342  case self::MODE_SPARQL:
343  $stylesheet = [$this->codemirrorPath . '../css/sparqlcolors.css'];
344  break;
345  case self::MODE_PHP:
346  $stylesheet = [$this->codemirrorPath . '../contrib/php/css/phpcolors.css'];
347  break;
348  case self::MODE_MIXED:
349  $stylesheet = [$this->codemirrorPath . '../css/xmlcolors.css', $this->codemirrorPath . '../css/jscolors.css', $this->codemirrorPath . '../css/csscolors.css', $this->codemirrorPath . '../contrib/php/css/phpcolors.css'];
350  break;
351  default:
352  $stylesheet = [];
353  }
354  $stylesheet[] = $this->extPath . 'Resources/Public/Css/t3editor_inner.css';
355  return json_encode($stylesheet);
356  }
357 
361  protected function getLanguageService()
362  {
363  return $GLOBALS['LANG'];
364  }
365 
369  protected function getBackendUserAuthentication()
370  {
371  return $GLOBALS['BE_USER'];
372  }
373 }
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
static getAbsoluteWebPath($targetPath)
Definition: PathUtility.php:40
static getFileAbsFileName($filename, $_=null, $_2=null)
getHTMLCodeForEditor($name, $class='', $content='', $additionalParams='', $alt='', array $hiddenfields=[])
renderWizards( $itemKinds=null, $wizConf=null, $table=null, $row=null, $fieldName=null, $PA=null, $itemName=null, $specConf=null, $RTE=null)
mergeChildReturnIntoExistingResult(array $existing, array $childReturn, bool $mergeHtml=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']