TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
TableController.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Backend\Controller\Wizard;
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 use Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
28 
33 {
39  public $content;
40 
46  public $inputStyle = false;
47 
55  public $xmlStorage = 0;
56 
62  public $numNewRows = 1;
63 
70  public $colsFieldName = 'cols';
71 
77  public $P;
78 
84  public $TABLECFG;
85 
93 
100 
104  protected $iconFactory;
105 
109  public function __construct()
110  {
111  parent::__construct();
112  $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_wizards.xlf');
113  $GLOBALS['SOBE'] = $this;
114 
115  $this->init();
116  }
117 
123  protected function init()
124  {
125  // GPvars:
126  $this->P = GeneralUtility::_GP('P');
127  $this->TABLECFG = GeneralUtility::_GP('TABLE');
128  // Setting options:
129  $this->xmlStorage = $this->P['params']['xmlOutput'];
130  $this->numNewRows = MathUtility::forceIntegerInRange($this->P['params']['numNewRows'], 1, 50, 5);
131  // Textareas or input fields:
132  $this->inputStyle = isset($this->TABLECFG['textFields']) ? (bool)$this->TABLECFG['textFields'] : true;
133  $this->tableParsing_delimiter = '|';
134  $this->tableParsing_quote = '';
135  }
136 
145  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
146  {
147  $this->main();
148  $response->getBody()->write($this->moduleTemplate->renderContent());
149  return $response;
150  }
151 
157  public function main()
158  {
159  list($rUri) = explode('#', GeneralUtility::getIndpEnv('REQUEST_URI'));
160  $this->content .= '<form action="' . htmlspecialchars($rUri) . '" method="post" id="TableController" name="wizardForm">';
161  if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
162  $this->content .= '<h2>' . htmlspecialchars($this->getLanguageService()->getLL('table_title')) . '</h2>'
163  . '<div>' . $this->tableWizard() . '</div>';
164  } else {
165  $this->content .= '<h2>' . htmlspecialchars($this->getLanguageService()->getLL('table_title')) . '</h2>'
166  . '<div><span class="text-danger">' . htmlspecialchars($this->getLanguageService()->getLL('table_noData')) . '</span></div>';
167  }
168  $this->content .= '</form>';
169  // Setting up the buttons and markers for docHeader
170  $this->getButtons();
171  // Build the <body> for the module
172  $this->moduleTemplate->setContent($this->content);
173  }
174 
178  protected function getButtons()
179  {
180  $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
181  if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
182  // CSH
183  $cshButton = $buttonBar->makeHelpButton()
184  ->setModuleName('xMOD_csh_corebe')
185  ->setFieldName('wizard_table_wiz');
186  $buttonBar->addButton($cshButton);
187  // Close
188  $closeButton = $buttonBar->makeLinkButton()
189  ->setHref($this->P['returnUrl'])
190  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
191  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL));
192  $buttonBar->addButton($closeButton);
193  // Save
194  $saveButton = $buttonBar->makeInputButton()
195  ->setName('_savedok')
196  ->setValue('1')
197  ->setForm('TableController')
198  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL))
199  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'));
200  // Save & Close
201  $saveAndCloseButton = $buttonBar->makeInputButton()
202  ->setName('_saveandclosedok')
203  ->setValue('1')
204  ->setForm('TableController')
205  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveCloseDoc'))
206  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
207  'actions-document-save-close',
209  ));
210  $splitButtonElement = $buttonBar->makeSplitButton()
211  ->addItem($saveButton)
212  ->addItem($saveAndCloseButton);
213 
214  $buttonBar->addButton($splitButtonElement, ButtonBar::BUTTON_POSITION_LEFT, 3);
215  // Reload
216  $reloadButton = $buttonBar->makeInputButton()
217  ->setName('_refresh')
218  ->setValue('1')
219  ->setForm('TableController')
220  ->setTitle($this->getLanguageService()->getLL('forms_refresh'))
221  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-refresh', Icon::SIZE_SMALL));
222  $buttonBar->addButton($reloadButton);
223  }
224  }
225 
232  public function tableWizard()
233  {
234  if (!$this->checkEditAccess($this->P['table'], $this->P['uid'])) {
235  throw new \RuntimeException('Wizard Error: No access', 1349692692);
236  }
237  // First, check the references by selecting the record:
238  $row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
239  if (!is_array($row)) {
240  throw new \RuntimeException('Wizard Error: No reference to record', 1294587125);
241  }
242  // This will get the content of the form configuration code field to us - possibly cleaned up,
243  // saved to database etc. if the form has been submitted in the meantime.
244  $tableCfgArray = $this->getConfigCode($row);
245  // Generation of the Table Wizards HTML code:
246  $content = $this->getTableHTML($tableCfgArray);
247  // Return content:
248  return $content;
249  }
250 
251  /*
252  *
253  * Helper functions
254  *
255  */
256 
265  public function getConfigCode($row)
266  {
267  // Get delimiter settings
268  $flexForm = GeneralUtility::xml2array($row['pi_flexform']);
269  if (is_array($flexForm)) {
270  $this->tableParsing_quote = $flexForm['data']['s_parsing']['lDEF']['tableparsing_quote']['vDEF'] ? chr((int)$flexForm['data']['s_parsing']['lDEF']['tableparsing_quote']['vDEF']) : '';
271  $this->tableParsing_delimiter = $flexForm['data']['s_parsing']['lDEF']['tableparsing_delimiter']['vDEF'] ? chr((int)$flexForm['data']['s_parsing']['lDEF']['tableparsing_delimiter']['vDEF']) : '|';
272  }
273  // If some data has been submitted, then construct
274  if (isset($this->TABLECFG['c'])) {
275  // Process incoming:
276  $this->changeFunc();
277  // Convert to string (either line based or XML):
278  if ($this->xmlStorage) {
279  // Convert the input array to XML:
280  $bodyText = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>' . LF . GeneralUtility::array2xml($this->TABLECFG['c'], '', 0, 'T3TableWizard');
281  // Setting cfgArr directly from the input:
282  $configuration = $this->TABLECFG['c'];
283  } else {
284  // Convert the input array to a string of configuration code:
285  $bodyText = $this->cfgArray2CfgString($this->TABLECFG['c']);
286  // Create cfgArr from the string based configuration - that way it is cleaned up
287  // and any incompatibilities will be removed!
288  $configuration = $this->cfgString2CfgArray($bodyText, $row[$this->colsFieldName]);
289  }
290  // If a save button has been pressed, then save the new field content:
291  if ($_POST['_savedok'] || $_POST['_saveandclosedok']) {
292  // Get DataHandler object:
294  $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
295  // Put content into the data array:
296  $data = [];
297  if ($this->P['flexFormPath']) {
298  // Current value of flexForm path:
299  $currentFlexFormData = GeneralUtility::xml2array($row[$this->P['field']]);
301  $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
302  $flexFormTools->setArrayValueByPath($this->P['flexFormPath'], $currentFlexFormData, $bodyText);
303  $data[$this->P['table']][$this->P['uid']][$this->P['field']] = $currentFlexFormData;
304  } else {
305  $data[$this->P['table']][$this->P['uid']][$this->P['field']] = $bodyText;
306  }
307  // Perform the update:
308  $dataHandler->start($data, []);
309  $dataHandler->process_datamap();
310  // If the save/close button was pressed, then redirect the screen:
311  if ($_POST['_saveandclosedok']) {
313  }
314  }
315  } else {
316  // If nothing has been submitted, load the $bodyText variable from the selected database row:
317  if ($this->xmlStorage) {
318  $configuration = GeneralUtility::xml2array($row[$this->P['field']]);
319  } else {
320  if ($this->P['flexFormPath']) {
321  // Current value of flexForm path:
322  $currentFlexFormData = GeneralUtility::xml2array($row[$this->P['field']]);
324  $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
325  $configuration = $flexFormTools->getArrayValueByPath(
326  $this->P['flexFormPath'],
327  $currentFlexFormData
328  );
329  $configuration = $this->cfgString2CfgArray($configuration, 0);
330  } else {
331  // Regular line based table configuration:
332  $configuration = $this->cfgString2CfgArray($row[$this->P['field']], $row[$this->colsFieldName]);
333  }
334  }
335  $configuration = is_array($configuration) ? $configuration : [];
336  }
337  return $configuration;
338  }
339 
347  public function getTableHTML($configuration)
348  {
349  // Traverse the rows:
350  $tRows = [];
351  $k = 0;
352  $countLines = count($configuration);
353  foreach ($configuration as $cellArr) {
354  if (is_array($cellArr)) {
355  // Initialize:
356  $cells = [];
357  $a = 0;
358  // Traverse the columns:
359  foreach ($cellArr as $cellContent) {
360  if ($this->inputStyle) {
361  $cells[] = '<input class="form-control" type="text" name="TABLE[c][' . ($k + 1) * 2 . '][' . ($a + 1) * 2 . ']" value="' . htmlspecialchars($cellContent) . '" />';
362  } else {
363  $cellContent = preg_replace('/<br[ ]?[\\/]?>/i', LF, $cellContent);
364  $cells[] = '<textarea class="form-control" rows="6" name="TABLE[c][' . ($k + 1) * 2 . '][' . ($a + 1) * 2 . ']">' . htmlspecialchars($cellContent) . '</textarea>';
365  }
366  // Increment counter:
367  $a++;
368  }
369  // CTRL panel for a table row (move up/down/around):
370  $onClick = 'document.wizardForm.action+=' . GeneralUtility::quoteJSvalue('#ANC_' . (($k + 1) * 2 - 2)) . ';';
371  $onClick = ' onclick="' . htmlspecialchars($onClick) . '"';
372  $ctrl = '';
373  if ($k !== 0) {
374  $ctrl .= '<button class="btn btn-default" name="TABLE[row_up][' . ($k + 1) * 2 . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_up')) . '"' . $onClick . '><span class="t3-icon fa fa-fw fa-angle-up"></span></button>';
375  } else {
376  $ctrl .= '<button class="btn btn-default" name="TABLE[row_bottom][' . ($k + 1) * 2 . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_bottom')) . '"' . $onClick . '><span class="t3-icon fa fa-fw fa-angle-double-down"></span></button>';
377  }
378  if ($k + 1 !== $countLines) {
379  $ctrl .= '<button class="btn btn-default" name="TABLE[row_down][' . ($k + 1) * 2 . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_down')) . '"' . $onClick . '><span class="t3-icon fa fa-fw fa-angle-down"></span></button>';
380  } else {
381  $ctrl .= '<button class="btn btn-default" name="TABLE[row_top][' . ($k + 1) * 2 . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_top')) . '"' . $onClick . '><span class="t3-icon fa fa-fw fa-angle-double-up"></span></button>';
382  }
383  $ctrl .= '<button class="btn btn-default" name="TABLE[row_remove][' . ($k + 1) * 2 . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_removeRow')) . '"' . $onClick . '><span class="t3-icon fa fa-fw fa-trash"></span></button>';
384  $ctrl .= '<button class="btn btn-default" name="TABLE[row_add][' . ($k + 1) * 2 . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_addRow')) . '"' . $onClick . '><span class="t3-icon fa fa-fw fa-plus"></span></button>';
385  $tRows[] = '
386  <tr>
387  <td>
388  <a name="ANC_' . ($k + 1) * 2 . '"></a>
389  <span class="btn-group' . ($this->inputStyle ? '' : '-vertical') . '">' . $ctrl . '</span>
390  </td>
391  <td>' . implode('</td>
392  <td>', $cells) . '</td>
393  </tr>';
394  // Increment counter:
395  $k++;
396  }
397  }
398  // CTRL panel for a table column (move left/right/around/delete)
399  $cells = [];
400  $cells[] = '';
401  // Finding first row:
402  $firstRow = reset($configuration);
403  if (is_array($firstRow)) {
404  $cols = count($firstRow);
405  for ($a = 1; $a <= $cols; $a++) {
406  $b = $a * 2;
407  $ctrl = '';
408  if ($a !== 1) {
409  $ctrl .= '<button class="btn btn-default" name="TABLE[col_left][' . $b . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_left')) . '"><span class="t3-icon fa fa-fw fa-angle-left"></span></button>';
410  } else {
411  $ctrl .= '<button class="btn btn-default" name="TABLE[col_end][' . $b . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_end')) . '"><span class="t3-icon fa fa-fw fa-angle-double-right"></span></button>';
412  }
413  if ($a != $cols) {
414  $ctrl .= '<button class="btn btn-default" name="TABLE[col_right][' . $b . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_right')) . '"><span class="t3-icon fa fa-fw fa-angle-right"></span></button>';
415  } else {
416  $ctrl .= '<button class="btn btn-default" name="TABLE[col_start][' . $b . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_start')) . '"><span class="t3-icon fa fa-fw fa-angle-double-left"></span></button>';
417  }
418  $ctrl .= '<button class="btn btn-default" name="TABLE[col_remove][' . $b . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_removeColumn')) . '"><span class="t3-icon fa fa-fw fa-trash"></span></button>';
419  $ctrl .= '<button class="btn btn-default" name="TABLE[col_add][' . $b . ']" title="' . htmlspecialchars($this->getLanguageService()->getLL('table_addColumn')) . '"><span class="t3-icon fa fa-fw fa-plus"></span></button>';
420  $cells[] = '<span class="btn-group">' . $ctrl . '</span>';
421  }
422  $tRows[] = '
423  <tfoot>
424  <tr>
425  <td>' . implode('</td>
426  <td>', $cells) . '</td>
427  </tr>
428  </tfoot>';
429  }
430  $content = '';
431  $addSubmitOnClick = 'onclick="document.getElementById(\'TableController\').submit();"';
432  // Implode all table rows into a string, wrapped in table tags.
433  $content .= '
434 
435  <!-- Table wizard -->
436  <div class="table-fit table-fit-inline-block">
437  <table id="typo3-tablewizard" class="table table-center">
438  ' . implode('', $tRows) . '
439  </table>
440  </div>';
441  // Input type checkbox:
442  $content .= '
443 
444  <!-- Input mode check box: -->
445  <div class="checkbox">
446  <input type="hidden" name="TABLE[textFields]" value="0" />
447  <label for="textFields">
448  <input type="checkbox" ' . $addSubmitOnClick . ' name="TABLE[textFields]" id="textFields" value="1"' . ($this->inputStyle ? ' checked="checked"' : '') . ' />
449  ' . $this->getLanguageService()->getLL('table_smallFields') . '
450  </label>
451  </div>';
452  return $content;
453  }
454 
462  public function changeFunc()
463  {
464  if ($this->TABLECFG['col_remove']) {
465  $kk = key($this->TABLECFG['col_remove']);
466  $cmd = 'col_remove';
467  } elseif ($this->TABLECFG['col_add']) {
468  $kk = key($this->TABLECFG['col_add']);
469  $cmd = 'col_add';
470  } elseif ($this->TABLECFG['col_start']) {
471  $kk = key($this->TABLECFG['col_start']);
472  $cmd = 'col_start';
473  } elseif ($this->TABLECFG['col_end']) {
474  $kk = key($this->TABLECFG['col_end']);
475  $cmd = 'col_end';
476  } elseif ($this->TABLECFG['col_left']) {
477  $kk = key($this->TABLECFG['col_left']);
478  $cmd = 'col_left';
479  } elseif ($this->TABLECFG['col_right']) {
480  $kk = key($this->TABLECFG['col_right']);
481  $cmd = 'col_right';
482  } elseif ($this->TABLECFG['row_remove']) {
483  $kk = key($this->TABLECFG['row_remove']);
484  $cmd = 'row_remove';
485  } elseif ($this->TABLECFG['row_add']) {
486  $kk = key($this->TABLECFG['row_add']);
487  $cmd = 'row_add';
488  } elseif ($this->TABLECFG['row_top']) {
489  $kk = key($this->TABLECFG['row_top']);
490  $cmd = 'row_top';
491  } elseif ($this->TABLECFG['row_bottom']) {
492  $kk = key($this->TABLECFG['row_bottom']);
493  $cmd = 'row_bottom';
494  } elseif ($this->TABLECFG['row_up']) {
495  $kk = key($this->TABLECFG['row_up']);
496  $cmd = 'row_up';
497  } elseif ($this->TABLECFG['row_down']) {
498  $kk = key($this->TABLECFG['row_down']);
499  $cmd = 'row_down';
500  } else {
501  $kk = '';
502  $cmd = '';
503  }
504  if ($cmd && MathUtility::canBeInterpretedAsInteger($kk)) {
505  if (strpos($cmd, 'row_') === 0) {
506  switch ($cmd) {
507  case 'row_remove':
508  unset($this->TABLECFG['c'][$kk]);
509  break;
510  case 'row_add':
511  for ($a = 1; $a <= $this->numNewRows; $a++) {
512  // Checking if set: The point is that any new row between existing rows
513  // will be TRUE after one row is added while if rows are added in the bottom
514  // of the table there will be no existing rows to stop the addition of new rows
515  // which means it will add up to $this->numNewRows rows then.
516  if (!isset($this->TABLECFG['c'][$kk + $a])) {
517  $this->TABLECFG['c'][$kk + $a] = [];
518  } else {
519  break;
520  }
521  }
522  break;
523  case 'row_top':
524  $this->TABLECFG['c'][1] = $this->TABLECFG['c'][$kk];
525  unset($this->TABLECFG['c'][$kk]);
526  break;
527  case 'row_bottom':
528  $this->TABLECFG['c'][10000000] = $this->TABLECFG['c'][$kk];
529  unset($this->TABLECFG['c'][$kk]);
530  break;
531  case 'row_up':
532  $this->TABLECFG['c'][$kk - 3] = $this->TABLECFG['c'][$kk];
533  unset($this->TABLECFG['c'][$kk]);
534  break;
535  case 'row_down':
536  $this->TABLECFG['c'][$kk + 3] = $this->TABLECFG['c'][$kk];
537  unset($this->TABLECFG['c'][$kk]);
538  break;
539  }
540  ksort($this->TABLECFG['c']);
541  }
542  if (strpos($cmd, 'col_') === 0) {
543  foreach ($this->TABLECFG['c'] as $cAK => $value) {
544  switch ($cmd) {
545  case 'col_remove':
546  unset($this->TABLECFG['c'][$cAK][$kk]);
547  break;
548  case 'col_add':
549  $this->TABLECFG['c'][$cAK][$kk + 1] = '';
550  break;
551  case 'col_start':
552  $this->TABLECFG['c'][$cAK][1] = $this->TABLECFG['c'][$cAK][$kk];
553  unset($this->TABLECFG['c'][$cAK][$kk]);
554  break;
555  case 'col_end':
556  $this->TABLECFG['c'][$cAK][1000000] = $this->TABLECFG['c'][$cAK][$kk];
557  unset($this->TABLECFG['c'][$cAK][$kk]);
558  break;
559  case 'col_left':
560  $this->TABLECFG['c'][$cAK][$kk - 3] = $this->TABLECFG['c'][$cAK][$kk];
561  unset($this->TABLECFG['c'][$cAK][$kk]);
562  break;
563  case 'col_right':
564  $this->TABLECFG['c'][$cAK][$kk + 3] = $this->TABLECFG['c'][$cAK][$kk];
565  unset($this->TABLECFG['c'][$cAK][$kk]);
566  break;
567  }
568  ksort($this->TABLECFG['c'][$cAK]);
569  }
570  }
571  }
572  // Convert line breaks to <br /> tags:
573  foreach ($this->TABLECFG['c'] as $a => $value) {
574  foreach ($this->TABLECFG['c'][$a] as $b => $value2) {
575  $this->TABLECFG['c'][$a][$b] = str_replace(
576  LF,
577  '<br />',
578  str_replace(CR, '', $this->TABLECFG['c'][$a][$b])
579  );
580  }
581  }
582  }
583 
591  public function cfgArray2CfgString($cfgArr)
592  {
593  $inLines = [];
594  // Traverse the elements of the table wizard and transform the settings into configuration code.
595  foreach ($cfgArr as $valueA) {
596  $thisLine = [];
597  foreach ($valueA as $valueB) {
598  $thisLine[] = $this->tableParsing_quote
599  . str_replace($this->tableParsing_delimiter, '', $valueB) . $this->tableParsing_quote;
600  }
601  $inLines[] = implode($this->tableParsing_delimiter, $thisLine);
602  }
603  // Finally, implode the lines into a string:
604  return implode(LF, $inLines);
605  }
606 
615  public function cfgString2CfgArray($configurationCode, $columns)
616  {
617  // Explode lines in the configuration code - each line is a table row.
618  $tableLines = explode(LF, $configurationCode);
619  // Setting number of columns
620  // auto...
621  if (!$columns && trim($tableLines[0])) {
622  $columns = count(explode($this->tableParsing_delimiter, $tableLines[0]));
623  }
624  $columns = $columns ?: 4;
625  // Traverse the number of table elements:
626  $configurationArray = [];
627  foreach ($tableLines as $key => $value) {
628  // Initialize:
629  $valueParts = explode($this->tableParsing_delimiter, $value);
630  // Traverse columns:
631  for ($a = 0; $a < $columns; $a++) {
632  if ($this->tableParsing_quote
633  && $valueParts[$a][0] === $this->tableParsing_quote
634  && substr($valueParts[$a], -1, 1) === $this->tableParsing_quote
635  ) {
636  $valueParts[$a] = substr(trim($valueParts[$a]), 1, -1);
637  }
638  $configurationArray[$key][$a] = $valueParts[$a];
639  }
640  }
641  return $configurationArray;
642  }
643 }
static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:76
static xml2array($string, $NSprefix= '', $reportDocTag=false)
static array2xml(array $array, $NSprefix= '', $level=0, $docTag= 'phparray', $spaceInd=0, array $options=[], array $stackData=[])
static getRecord($table, $uid, $fields= '*', $where= '', $useDeleteClause=true)
mainAction(ServerRequestInterface $request, ResponseInterface $response)
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static makeInstance($className,...$constructorArguments)
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31