‪TYPO3CMS  9.5
TableController.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\ServerRequestInterface;
33 
39 {
41 
47  protected ‪$deprecatedPublicProperties = [
48  'content' => 'Using $content of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
49  'inputStyle' => 'Using $inputStyle of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
50  'xmlStorage' => 'Using $xmlStorage of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
51  'numNewRows' => 'Using $numNewRows of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
52  'colsFieldName' => 'Using $colsFieldName of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
53  'P' => 'Using $P of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
54  'TABLECFG' => 'Using $TABLECFG of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
55  'tableParsing_quote' => 'Using $tableParsing_quote of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
56  'tableParsing_delimiter' => 'Using $tableParsing_delimiter of class TableController from the outside is discouraged, as this variable is only used for internal storage.',
57  ];
58 
64  protected ‪$content;
65 
71  protected ‪$inputStyle = false;
72 
80  protected ‪$xmlStorage = 0;
81 
87  protected ‪$numNewRows = 1;
88 
95  protected ‪$colsFieldName = 'cols';
96 
102  protected ‪$P;
103 
109  protected ‪$TABLECFG;
110 
118 
124  protected ‪$tableParsing_delimiter;
125 
129  protected ‪$iconFactory;
130 
136  protected ‪$moduleTemplate;
137 
141  public function ‪__construct()
142  {
143  $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
144  $this->‪getLanguageService()->‪includeLLFile('EXT:core/Resources/Private/Language/locallang_wizards.xlf');
145 
146  // @deprecated since TYPO3 v9, will be moved out of __construct() in TYPO3 v10.0
147  $this->‪init(‪$GLOBALS['TYPO3_REQUEST']);
148  }
149 
157  public function ‪mainAction(ServerRequestInterface $request): ResponseInterface
158  {
159  $response = $this->‪renderContent($request);
160 
161  if (empty($response)) {
162  $response = new ‪HtmlResponse($this->moduleTemplate->renderContent());
163  }
164 
165  return $response;
166  }
167 
173  public function ‪main()
174  {
175  trigger_error('TableController->main() will be replaced by protected method renderContent() in TYPO3 v10.0. Do not call from other extensions.', E_USER_DEPRECATED);
176 
177  $response = $this->‪renderContent(‪$GLOBALS['TYPO3_REQUEST']);
178 
179  if ($response instanceof ‪RedirectResponse) {
180  ‪HttpUtility::redirect($response->getHeaders()['location'][0]);
181  }
182  }
183 
192  public function ‪tableWizard()
193  {
194  trigger_error('TableController->tableWizard() will be replaced by protected method renderTableWizard() in TYPO3 v10.0. Do not call from other extensions.', E_USER_DEPRECATED);
195 
196  $result = $this->‪renderTableWizard(‪$GLOBALS['TYPO3_REQUEST']);
197 
198  if ($result instanceof ‪RedirectResponse) {
199  ‪HttpUtility::redirect($result->getHeaders()['location'][0]);
200  }
201 
202  return $result;
203  }
204 
214  public function ‪getConfigCode($row)
215  {
216  trigger_error('TableController->getConfigCode() will be replaced by protected method getConfiguration() in TYPO3 v10.0. Do not call from other extensions.', E_USER_DEPRECATED);
217 
218  $result = $this->‪getConfiguration($row, ‪$GLOBALS['TYPO3_REQUEST']);
219 
220  if ($result instanceof ‪RedirectResponse) {
221  ‪HttpUtility::redirect($result->getHeaders()['location'][0]);
222  }
223 
224  return $result;
225  }
226 
236  public function ‪getTableHTML($configuration)
237  {
238  trigger_error('TableController->getTableHTML() will be replaced by protected method getTableWizard() in TYPO3 v10.0. Do not call from other extensions.', E_USER_DEPRECATED);
239  return $this->‪getTableWizard($configuration);
240  }
241 
250  public function ‪changeFunc()
251  {
252  trigger_error('TableController->changeFunc() will be replaced by protected method manipulateTable() in TYPO3 v10.0. Do not call from other extensions.', E_USER_DEPRECATED);
253  $this->‪manipulateTable();
254  }
255 
265  public function ‪cfgArray2CfgString($cfgArr)
266  {
267  trigger_error('TableController->cfgArray2CfgString() will be replaced by protected method configurationArrayToString() in TYPO3 v10.0. Do not call from other extensions.', E_USER_DEPRECATED);
268  return $this->‪configurationArrayToString($cfgArr);
269  }
270 
281  public function ‪cfgString2CfgArray($configurationCode, $columns)
282  {
283  trigger_error('TableController->cfgString2CfgArray() will be replaced by protected method configurationStringToArray() in TYPO3 v10.0. Do not call from other extensions.', E_USER_DEPRECATED);
284  return $this->‪configurationStringToArray($configurationCode, $columns);
285  }
286 
292  protected function ‪init(ServerRequestInterface $request): void
293  {
294  $parsedBody = $request->getParsedBody();
295  $queryParams = $request->getQueryParams();
296  // GPvars:
297  $this->P = $parsedBody['P'] ?? $queryParams['P'] ?? null;
298  $this->TABLECFG = $parsedBody['TABLE'] ?? $queryParams['TABLE'] ?? null;
299  // Setting options:
300  $this->xmlStorage = $this->P['params']['xmlOutput'];
301  $this->numNewRows = ‪MathUtility::forceIntegerInRange($this->P['params']['numNewRows'], 1, 50, 5);
302  // Textareas or input fields:
303  $this->inputStyle = isset($this->TABLECFG['textFields']) ? (bool)$this->TABLECFG['textFields'] : true;
304  $this->tableParsing_delimiter = '|';
305  $this->tableParsing_quote = '';
306  }
307 
314  protected function ‪renderContent(ServerRequestInterface $request): ?ResponseInterface
315  {
316  $normalizedParams = $request->getAttribute('normalizedParams');
317  $requestUri = $normalizedParams->getRequestUri();
318  list($rUri) = explode('#', $requestUri);
319  $this->content .= '<form action="' . htmlspecialchars($rUri) . '" method="post" id="TableController" name="wizardForm">';
320  if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
321  $tableWizard = $this->‪renderTableWizard($request);
322 
323  if ($tableWizard instanceof ‪RedirectResponse) {
324  return $tableWizard;
325  }
326 
327  $this->content .= '<h2>' . htmlspecialchars($this->‪getLanguageService()->getLL('table_title')) . '</h2>'
328  . '<div>' . $tableWizard . '</div>';
329  } else {
330  $this->content .= '<h2>' . htmlspecialchars($this->‪getLanguageService()->getLL('table_title')) . '</h2>'
331  . '<div><span class="text-danger">' . htmlspecialchars($this->‪getLanguageService()->getLL('table_noData')) . '</span></div>';
332  }
333  $this->content .= '</form>';
334  // Setting up the buttons and markers for docHeader
335  $this->‪getButtons();
336  // Build the <body> for the module
337  $this->moduleTemplate->setContent($this->content);
338 
339  return null;
340  }
341 
345  protected function ‪getButtons(): void
346  {
347  $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
348  if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
349  // CSH
350  $cshButton = $buttonBar->makeHelpButton()
351  ->setModuleName('xMOD_csh_corebe')
352  ->setFieldName('wizard_table_wiz');
353  $buttonBar->addButton($cshButton);
354  // Close
355  $closeButton = $buttonBar->makeLinkButton()
356  ->setHref($this->P['returnUrl'])
357  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-close', ‪Icon::SIZE_SMALL))
358  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
359  ->setShowLabelText(true);
360  $buttonBar->addButton($closeButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 1);
361  // Save
362  $saveButton = $buttonBar->makeInputButton()
363  ->setName('_savedok')
364  ->setValue('1')
365  ->setForm('TableController')
366  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', ‪Icon::SIZE_SMALL))
367  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'))
368  ->setShowLabelText(true);
369  $buttonBar->addButton($saveButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 2);
370  // Reload
371  $reloadButton = $buttonBar->makeInputButton()
372  ->setName('_refresh')
373  ->setValue('1')
374  ->setForm('TableController')
375  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-refresh', ‪Icon::SIZE_SMALL))
376  ->setTitle($this->‪getLanguageService()->getLL('forms_refresh'));
377  $buttonBar->addButton($reloadButton, ‪ButtonBar::BUTTON_POSITION_RIGHT);
378  }
379  }
380 
388  protected function ‪renderTableWizard(ServerRequestInterface $request)
389  {
390  if (!$this->‪checkEditAccess($this->P['table'], $this->P['uid'])) {
391  throw new \RuntimeException('Wizard Error: No access', 1349692692);
392  }
393  // First, check the references by selecting the record:
394  $row = ‪BackendUtility::getRecord($this->P['table'], $this->P['uid']);
395  if (!is_array($row)) {
396  throw new \RuntimeException('Wizard Error: No reference to record', 1294587125);
397  }
398  // This will get the content of the form configuration code field to us - possibly cleaned up,
399  // saved to database etc. if the form has been submitted in the meantime.
400  $tableCfgArray = $this->‪getConfiguration($row, $request);
401 
402  if ($tableCfgArray instanceof ResponseInterface) {
403  return $tableCfgArray;
404  }
405 
406  // Generation of the Table Wizards HTML code:
407  ‪$content = $this->‪getTableWizard($tableCfgArray);
408  // Return content:
409  return ‪$content;
410  }
411 
420  protected function ‪getConfiguration(array $row, ServerRequestInterface $request)
421  {
422  // Get delimiter settings
423  $this->tableParsing_quote = $row['table_enclosure'] ? chr((int)$row['table_enclosure']) : '';
424  $this->tableParsing_delimiter = $row['table_delimiter'] ? chr((int)$row['table_delimiter']) : '|';
425  // If some data has been submitted, then construct
426  if (isset($this->TABLECFG['c'])) {
427  // Process incoming:
428  $this->‪manipulateTable();
429  // Convert to string (either line based or XML):
430  if ($this->xmlStorage) {
431  // Convert the input array to XML:
432  $bodyText = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>' . LF . GeneralUtility::array2xml($this->TABLECFG['c'], '', 0, 'T3TableWizard');
433  // Setting cfgArr directly from the input:
434  $configuration = $this->TABLECFG['c'];
435  } else {
436  // Convert the input array to a string of configuration code:
437  $bodyText = $this->‪configurationArrayToString($this->TABLECFG['c']);
438  // Create cfgArr from the string based configuration - that way it is cleaned up
439  // and any incompatibilities will be removed!
440  $configuration = $this->‪configurationStringToArray($bodyText, (int)$row[$this->colsFieldName]);
441  }
442  // If a save button has been pressed, then save the new field content:
443  if ($_POST['_savedok'] || $_POST['_saveandclosedok']) {
444  // Get DataHandler object:
446  $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
447  // Put content into the data array:
448  $data = [];
449  if ($this->P['flexFormPath']) {
450  // Current value of flexForm path:
451  $currentFlexFormData = GeneralUtility::xml2array($row[$this->P['field']]);
453  $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
454  $flexFormTools->setArrayValueByPath($this->P['flexFormPath'], $currentFlexFormData, $bodyText);
455  $data[$this->P['table']][$this->P['uid']][$this->P['field']] = $currentFlexFormData;
456  } else {
457  $data[$this->P['table']][$this->P['uid']][$this->P['field']] = $bodyText;
458  }
459  // Perform the update:
460  $dataHandler->start($data, []);
461  $dataHandler->process_datamap();
462  // If the save/close button was pressed, then redirect the screen:
463  if ($_POST['_saveandclosedok']) {
464  return new RedirectResponse(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']));
465  }
466  }
467  } else {
468  // If nothing has been submitted, load the $bodyText variable from the selected database row:
469  if ($this->xmlStorage) {
470  $configuration = GeneralUtility::xml2array($row[$this->P['field']]);
471  } else {
472  if ($this->P['flexFormPath']) {
473  // Current value of flexForm path:
474  $currentFlexFormData = GeneralUtility::xml2array($row[$this->P['field']]);
476  $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
477  $configuration = $flexFormTools->getArrayValueByPath(
478  $this->P['flexFormPath'],
479  $currentFlexFormData
480  );
481  $configuration = $this->‪configurationStringToArray($configuration, 0);
482  } else {
483  // Regular line based table configuration:
484  $columns = $row[‪$this->colsFieldName] ?? 0;
485  $configuration = $this->‪configurationStringToArray($row[$this->P['field']] ?? '', (int)$columns);
486  }
487  }
488  $configuration = is_array($configuration) ? $configuration : [];
489  }
490  return $configuration;
491  }
492 
499  protected function ‪getTableWizard(array $configuration): string
500  {
501  // Traverse the rows:
502  $tRows = [];
503  $k = 0;
504  $countLines = count($configuration);
505  foreach ($configuration as $cellArr) {
506  if (is_array($cellArr)) {
507  // Initialize:
508  $cells = [];
509  $a = 0;
510  // Traverse the columns:
511  foreach ($cellArr as $cellContent) {
512  if ($this->inputStyle) {
513  $cells[] = '<input class="form-control" type="text" name="TABLE[c][' . ($k + 1) * 2 . '][' . ($a + 1) * 2 . ']" value="' . htmlspecialchars($cellContent) . '" />';
514  } else {
515  $cellContent = preg_replace('/<br[ ]?[\\/]?>/i', LF, $cellContent);
516  $cells[] = '<textarea class="form-control" rows="6" name="TABLE[c][' . ($k + 1) * 2 . '][' . ($a + 1) * 2 . ']">' . htmlspecialchars($cellContent) . '</textarea>';
517  }
518  // Increment counter:
519  $a++;
520  }
521  // CTRL panel for a table row (move up/down/around):
522  $onClick = 'document.wizardForm.action+=' . GeneralUtility::quoteJSvalue('#ANC_' . (($k + 1) * 2 - 2)) . ';';
523  $onClick = ' onclick="' . htmlspecialchars($onClick) . '"';
524  $ctrl = '';
525  if ($k !== 0) {
526  $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>';
527  } else {
528  $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>';
529  }
530  if ($k + 1 !== $countLines) {
531  $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>';
532  } else {
533  $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>';
534  }
535  $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>';
536  $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>';
537  $tRows[] = '
538  <tr>
539  <td>
540  <a name="ANC_' . ($k + 1) * 2 . '"></a>
541  <span class="btn-group' . ($this->inputStyle ? '' : '-vertical') . '">' . $ctrl . '</span>
542  </td>
543  <td>' . implode('</td>
544  <td>', $cells) . '</td>
545  </tr>';
546  // Increment counter:
547  $k++;
548  }
549  }
550  // CTRL panel for a table column (move left/right/around/delete)
551  $cells = [];
552  $cells[] = '';
553  // Finding first row:
554  $firstRow = reset($configuration);
555  if (is_array($firstRow)) {
556  $cols = count($firstRow);
557  for ($a = 1; $a <= $cols; $a++) {
558  $b = $a * 2;
559  $ctrl = '';
560  if ($a !== 1) {
561  $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>';
562  } else {
563  $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>';
564  }
565  if ($a != $cols) {
566  $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>';
567  } else {
568  $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>';
569  }
570  $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>';
571  $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>';
572  $cells[] = '<span class="btn-group">' . $ctrl . '</span>';
573  }
574  $tRows[] = '
575  <tfoot>
576  <tr>
577  <td>' . implode('</td>
578  <td>', $cells) . '</td>
579  </tr>
580  </tfoot>';
581  }
582  ‪$content = '';
583  $addSubmitOnClick = 'onclick="document.getElementById(\'TableController\').submit();"';
584  // Implode all table rows into a string, wrapped in table tags.
585  ‪$content .= '
586 
587  <!-- Table wizard -->
588  <div class="table-fit table-fit-inline-block">
589  <table id="typo3-tablewizard" class="table table-center">
590  ' . implode('', $tRows) . '
591  </table>
592  </div>';
593  // Input type checkbox:
594  ‪$content .= '
595 
596  <!-- Input mode check box: -->
597  <div class="checkbox">
598  <input type="hidden" name="TABLE[textFields]" value="0" />
599  <label for="textFields">
600  <input type="checkbox" ' . $addSubmitOnClick . ' name="TABLE[textFields]" id="textFields" value="1"' . ($this->inputStyle ? ' checked="checked"' : '') . ' />
601  ' . $this->‪getLanguageService()->‪getLL('table_smallFields') . '
602  </label>
603  </div>';
604  return ‪$content;
605  }
606 
611  protected function ‪manipulateTable(): void
612  {
613  if ($this->TABLECFG['col_remove']) {
614  $kk = key($this->TABLECFG['col_remove']);
615  $cmd = 'col_remove';
616  } elseif ($this->TABLECFG['col_add']) {
617  $kk = key($this->TABLECFG['col_add']);
618  $cmd = 'col_add';
619  } elseif ($this->TABLECFG['col_start']) {
620  $kk = key($this->TABLECFG['col_start']);
621  $cmd = 'col_start';
622  } elseif ($this->TABLECFG['col_end']) {
623  $kk = key($this->TABLECFG['col_end']);
624  $cmd = 'col_end';
625  } elseif ($this->TABLECFG['col_left']) {
626  $kk = key($this->TABLECFG['col_left']);
627  $cmd = 'col_left';
628  } elseif ($this->TABLECFG['col_right']) {
629  $kk = key($this->TABLECFG['col_right']);
630  $cmd = 'col_right';
631  } elseif ($this->TABLECFG['row_remove']) {
632  $kk = key($this->TABLECFG['row_remove']);
633  $cmd = 'row_remove';
634  } elseif ($this->TABLECFG['row_add']) {
635  $kk = key($this->TABLECFG['row_add']);
636  $cmd = 'row_add';
637  } elseif ($this->TABLECFG['row_top']) {
638  $kk = key($this->TABLECFG['row_top']);
639  $cmd = 'row_top';
640  } elseif ($this->TABLECFG['row_bottom']) {
641  $kk = key($this->TABLECFG['row_bottom']);
642  $cmd = 'row_bottom';
643  } elseif ($this->TABLECFG['row_up']) {
644  $kk = key($this->TABLECFG['row_up']);
645  $cmd = 'row_up';
646  } elseif ($this->TABLECFG['row_down']) {
647  $kk = key($this->TABLECFG['row_down']);
648  $cmd = 'row_down';
649  } else {
650  $kk = '';
651  $cmd = '';
652  }
654  if (strpos($cmd, 'row_') === 0) {
655  switch ($cmd) {
656  case 'row_remove':
657  unset($this->TABLECFG['c'][$kk]);
658  break;
659  case 'row_add':
660  for ($a = 1; $a <= ‪$this->numNewRows; $a++) {
661  // Checking if set: The point is that any new row between existing rows
662  // will be TRUE after one row is added while if rows are added in the bottom
663  // of the table there will be no existing rows to stop the addition of new rows
664  // which means it will add up to $this->numNewRows rows then.
665  if (!isset($this->TABLECFG['c'][$kk + $a])) {
666  $this->TABLECFG['c'][$kk + $a] = [];
667  } else {
668  break;
669  }
670  }
671  break;
672  case 'row_top':
673  $this->TABLECFG['c'][1] = $this->TABLECFG['c'][$kk];
674  unset($this->TABLECFG['c'][$kk]);
675  break;
676  case 'row_bottom':
677  $this->TABLECFG['c'][10000000] = $this->TABLECFG['c'][$kk];
678  unset($this->TABLECFG['c'][$kk]);
679  break;
680  case 'row_up':
681  $this->TABLECFG['c'][$kk - 3] = $this->TABLECFG['c'][$kk];
682  unset($this->TABLECFG['c'][$kk]);
683  break;
684  case 'row_down':
685  $this->TABLECFG['c'][$kk + 3] = $this->TABLECFG['c'][$kk];
686  unset($this->TABLECFG['c'][$kk]);
687  break;
688  }
689  ksort($this->TABLECFG['c']);
690  }
691  if (strpos($cmd, 'col_') === 0) {
692  foreach ($this->TABLECFG['c'] as $cAK => $value) {
693  switch ($cmd) {
694  case 'col_remove':
695  unset($this->TABLECFG['c'][$cAK][$kk]);
696  break;
697  case 'col_add':
698  $this->TABLECFG['c'][$cAK][$kk + 1] = '';
699  break;
700  case 'col_start':
701  $this->TABLECFG['c'][$cAK][1] = $this->TABLECFG['c'][$cAK][$kk];
702  unset($this->TABLECFG['c'][$cAK][$kk]);
703  break;
704  case 'col_end':
705  $this->TABLECFG['c'][$cAK][1000000] = $this->TABLECFG['c'][$cAK][$kk];
706  unset($this->TABLECFG['c'][$cAK][$kk]);
707  break;
708  case 'col_left':
709  $this->TABLECFG['c'][$cAK][$kk - 3] = $this->TABLECFG['c'][$cAK][$kk];
710  unset($this->TABLECFG['c'][$cAK][$kk]);
711  break;
712  case 'col_right':
713  $this->TABLECFG['c'][$cAK][$kk + 3] = $this->TABLECFG['c'][$cAK][$kk];
714  unset($this->TABLECFG['c'][$cAK][$kk]);
715  break;
716  }
717  ksort($this->TABLECFG['c'][$cAK]);
718  }
719  }
720  }
721  // Convert line breaks to <br /> tags:
722  foreach ($this->TABLECFG['c'] as $a => $value) {
723  foreach ($this->TABLECFG['c'][$a] as $b => $value2) {
724  $this->TABLECFG['c'][$a][$b] = str_replace(
725  [CR, LF],
726  ['', '<br />'],
727  $this->TABLECFG['c'][$a][$b]
728  );
729  }
730  }
731  }
732 
740  protected function ‪configurationArrayToString(array $cfgArr): string
741  {
742  $inLines = [];
743  // Traverse the elements of the table wizard and transform the settings into configuration code.
744  foreach ($cfgArr as $valueA) {
745  $thisLine = [];
746  foreach ($valueA as $valueB) {
747  $thisLine[] = $this->tableParsing_quote
748  . str_replace($this->tableParsing_delimiter, '', $valueB) . ‪$this->tableParsing_quote;
749  }
750  $inLines[] = implode($this->tableParsing_delimiter, $thisLine);
751  }
752  // Finally, implode the lines into a string:
753  return implode(LF, $inLines);
754  }
755 
764  protected function ‪configurationStringToArray(string $configurationCode, int $columns): array
765  {
766  // Explode lines in the configuration code - each line is a table row.
767  $tableLines = explode(LF, $configurationCode);
768  // Setting number of columns
769  // auto...
770  if (!$columns && trim($tableLines[0])) {
771  $columns = count(explode($this->tableParsing_delimiter, $tableLines[0]));
772  }
773  $columns = $columns ?: 4;
774  // Traverse the number of table elements:
775  $configurationArray = [];
776  foreach ($tableLines as $key => $value) {
777  // Initialize:
778  $valueParts = explode($this->tableParsing_delimiter, $value);
779  // Traverse columns:
780  for ($a = 0; $a < $columns; $a++) {
781  if ($this->tableParsing_quote
782  && $valueParts[$a][0] === $this->tableParsing_quote
783  && substr($valueParts[$a], -1, 1) === $this->tableParsing_quote
784  ) {
785  $valueParts[$a] = substr(trim($valueParts[$a]), 1, -1);
786  }
787  $configurationArray[$key][$a] = (string)$valueParts[$a];
788  }
789  }
790  return $configurationArray;
791  }
792 }
‪TYPO3\CMS\Core\DataHandling\DataHandler
Definition: DataHandler.php:81
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:29
‪TYPO3\CMS\Core\Localization\LanguageService\includeLLFile
‪mixed includeLLFile($fileRef, $setGlobal=true, $mergeLocalOntoDefault=false)
Definition: LanguageService.php:260
‪TYPO3\CMS\Backend\Controller\Wizard\AbstractWizardController\getLanguageService
‪LanguageService getLanguageService()
Definition: AbstractWizardController.php:77
‪TYPO3\CMS\Backend\Template\Components\ButtonBar\BUTTON_POSITION_LEFT
‪const BUTTON_POSITION_LEFT
Definition: ButtonBar.php:35
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:73
‪TYPO3\CMS\Backend\Template\Components\ButtonBar
Definition: ButtonBar.php:31
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\mainAction
‪ResponseInterface mainAction(ServerRequestInterface $request)
Definition: TableController.php:144
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\changeFunc
‪changeFunc()
Definition: TableController.php:237
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\getConfigCode
‪array getConfigCode($row)
Definition: TableController.php:201
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:25
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$tableParsing_delimiter
‪string $tableParsing_delimiter
Definition: TableController.php:113
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$deprecatedPublicProperties
‪array $deprecatedPublicProperties
Definition: TableController.php:45
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$tableParsing_quote
‪string $tableParsing_quote
Definition: TableController.php:107
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:31
‪TYPO3\CMS\Backend\Controller\Wizard\AbstractWizardController
Definition: AbstractWizardController.php:28
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\getTableHTML
‪string getTableHTML($configuration)
Definition: TableController.php:223
‪TYPO3\CMS\Backend\Template\ModuleTemplate
Definition: ModuleTemplate.php:40
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$P
‪array $P
Definition: TableController.php:94
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$moduleTemplate
‪ModuleTemplate $moduleTemplate
Definition: TableController.php:123
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\renderContent
‪ResponseInterface null renderContent(ServerRequestInterface $request)
Definition: TableController.php:301
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$colsFieldName
‪string $colsFieldName
Definition: TableController.php:88
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\cfgString2CfgArray
‪array cfgString2CfgArray($configurationCode, $columns)
Definition: TableController.php:268
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\renderTableWizard
‪string ResponseInterface renderTableWizard(ServerRequestInterface $request)
Definition: TableController.php:375
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$inputStyle
‪bool $inputStyle
Definition: TableController.php:67
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\cfgArray2CfgString
‪string cfgArray2CfgString($cfgArr)
Definition: TableController.php:252
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\configurationArrayToString
‪string configurationArrayToString(array $cfgArr)
Definition: TableController.php:727
‪TYPO3\CMS\Backend\Controller\Wizard
Definition: AbstractWizardController.php:2
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\manipulateTable
‪manipulateTable()
Definition: TableController.php:598
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$xmlStorage
‪int $xmlStorage
Definition: TableController.php:75
‪TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools
Definition: FlexFormTools.php:36
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\getConfiguration
‪array ResponseInterface getConfiguration(array $row, ServerRequestInterface $request)
Definition: TableController.php:407
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\getButtons
‪getButtons()
Definition: TableController.php:332
‪TYPO3\CMS\Backend\Controller\Wizard\TableController
Definition: TableController.php:39
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:130
‪TYPO3\CMS\Core\Http\RedirectResponse
Definition: RedirectResponse.php:27
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\tableWizard
‪string tableWizard()
Definition: TableController.php:179
‪TYPO3\CMS\Backend\Controller\Wizard\AbstractWizardController\checkEditAccess
‪bool checkEditAccess($table, $uid)
Definition: AbstractWizardController.php:36
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$numNewRows
‪int $numNewRows
Definition: TableController.php:81
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$TABLECFG
‪array $TABLECFG
Definition: TableController.php:100
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$content
‪string $content
Definition: TableController.php:61
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\__construct
‪__construct()
Definition: TableController.php:128
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\main
‪main()
Definition: TableController.php:160
‪TYPO3\CMS\Core\Utility\HttpUtility
Definition: HttpUtility.php:21
‪TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait
Definition: PublicPropertyDeprecationTrait.php:66
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\configurationStringToArray
‪array configurationStringToArray(string $configurationCode, int $columns)
Definition: TableController.php:751
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\$iconFactory
‪IconFactory $iconFactory
Definition: TableController.php:117
‪TYPO3\CMS\Core\Localization\LanguageService\getLL
‪string getLL($index)
Definition: LanguageService.php:118
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\init
‪init(ServerRequestInterface $request)
Definition: TableController.php:279
‪TYPO3\CMS\Backend\Template\Components\ButtonBar\BUTTON_POSITION_RIGHT
‪const BUTTON_POSITION_RIGHT
Definition: ButtonBar.php:40
‪TYPO3\CMS\Core\Utility\HttpUtility\redirect
‪static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:103
‪TYPO3\CMS\Backend\Controller\Wizard\TableController\getTableWizard
‪string getTableWizard(array $configuration)
Definition: TableController.php:486
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:25