[TASK] EXT:form - make 'grid rows' independent from 'grid containers'
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / ViewHelpers / GridColumnClassAutoConfigurationViewHelper.php
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Form\ViewHelpers;
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 TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
19 use TYPO3\CMS\Form\Domain\Model\FormElements\GridContainerInterface;
20 use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
21 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
22 use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
23
24 /**
25 * Scope: frontend
26 * @api
27 */
28 class GridColumnClassAutoConfigurationViewHelper extends AbstractViewHelper
29 {
30 use CompileWithRenderStatic;
31
32 /**
33 * @var bool
34 */
35 protected $escapeOutput = false;
36
37 /**
38 * Initialize the arguments.
39 *
40 * @return void
41 * @internal
42 */
43 public function initializeArguments()
44 {
45 parent::initializeArguments();
46 $this->registerArgument('element', RootRenderableInterface::class, 'A RootRenderableInterface instance', true);
47 }
48
49 /**
50 * @param array $arguments
51 * @param \Closure $renderChildrenClosure
52 * @param RenderingContextInterface $renderingContext
53 * @return string
54 * @public
55 */
56 public static function renderStatic(
57 array $arguments,
58 \Closure $renderChildrenClosure,
59 RenderingContextInterface $renderingContext
60 ) {
61 $formElement = $arguments['element'];
62
63 $gridRowElement = $formElement->getParentRenderable();
64 $gridContainerElement = $gridRowElement->getParentRenderable();
65 $gridRowEChildElements = $gridRowElement->getElementsRecursively();
66
67 if ($gridContainerElement instanceof GridContainerInterface) {
68 $gridViewPortConfiguration = $gridContainerElement->getProperties()['gridColumnClassAutoConfiguration'];
69 } else {
70 $gridViewPortConfiguration = $gridRowElement->getProperties()['gridColumnClassAutoConfiguration'];
71 }
72
73 if (empty($gridViewPortConfiguration)) {
74 return '';
75 }
76 $gridSize = (int)$gridViewPortConfiguration['gridSize'];
77
78 $columnsToCalculate = [];
79 $usedColumns = [];
80 foreach ($gridRowEChildElements as $childElement) {
81 if (empty($childElement->getProperties()['gridColumnClassAutoConfiguration'])) {
82 foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) {
83 $columnsToCalculate[$viewPortName]['elements']++;
84 }
85 } else {
86 $gridColumnViewPortConfiguration = $childElement->getProperties()['gridColumnClassAutoConfiguration'];
87 foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) {
88 $configuration = $gridColumnViewPortConfiguration['viewPorts'][$viewPortName];
89 if (
90 isset($configuration['numbersOfColumnsToUse'])
91 && (int)$configuration['numbersOfColumnsToUse'] > 0
92 ) {
93 $usedColumns[$viewPortName]['sum'] += (int)$configuration['numbersOfColumnsToUse'];
94 if ($childElement->getIdentifier() === $formElement->getIdentifier()) {
95 $usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'] = (int)$configuration['numbersOfColumnsToUse'];
96 if ($usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'] > $gridSize) {
97 $usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'] = $gridSize;
98 }
99 }
100 } else {
101 $columnsToCalculate[$viewPortName]['elements']++;
102 }
103 }
104 }
105 }
106
107 $classes = [];
108 foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) {
109 if (isset($usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'])) {
110 $numbersOfColumnsToUse = $usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'];
111 } else {
112 $restColumnsToDivide = $gridSize - $usedColumns[$viewPortName]['sum'];
113 $restElements = (int)$columnsToCalculate[$viewPortName]['elements'];
114
115 if ($restColumnsToDivide < 1) {
116 $restColumnsToDivide = 1;
117 }
118 if ($restElements < 1) {
119 $restElements = 1;
120 }
121 $numbersOfColumnsToUse = floor($restColumnsToDivide / $restElements);
122 }
123
124 $classes[] = str_replace(
125 '{@numbersOfColumnsToUse}',
126 $numbersOfColumnsToUse,
127 $configuration['classPattern']
128 );
129 }
130
131 return implode(' ', $classes);
132 }
133 }