[TASK] Add spaces around '=' of 'strict_types=1'
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / NodeExpansion / FieldControl.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Backend\Form\NodeExpansion;
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\Backend\Form\AbstractNode;
19 use TYPO3\CMS\Core\Imaging\Icon;
20 use TYPO3\CMS\Core\Imaging\IconFactory;
21 use TYPO3\CMS\Core\Localization\LanguageService;
22 use TYPO3\CMS\Core\Service\DependencyOrderingService;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25 /**
26 * Field controls are additional HTML on a single element level that are typically
27 * shown right aside the main element HTML.
28 *
29 * They are restricted to only allow an icon as output.
30 *
31 * The "link popup" button next to the input field of a renderType "inputLink"
32 * is an example of such an additional control.
33 *
34 * The element itself must position any field controls at an appropriate place.
35 * For instance the "group" element shows them in a row vertically, while others
36 * display single controls next to each other.
37 */
38 class FieldControl extends AbstractNode
39 {
40 /**
41 * Order the list of field wizards to be rendered with the ordering service,
42 * then call each wizard element through the node factory and merge their
43 * results.
44 *
45 * @return array Result array
46 */
47 public function render(): array
48 {
49 $result = $this->initializeResultArray();
50 if (!isset($this->data['renderData']['fieldControl'])) {
51 return $result;
52 }
53
54 $languageService = $this->getLanguageService();
55
56 $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
57 $fieldControl = $this->data['renderData']['fieldControl'];
58 $orderingService = GeneralUtility::makeInstance(DependencyOrderingService::class);
59 $orderedFieldControl = $orderingService->orderByDependencies($fieldControl, 'before', 'after');
60
61 foreach ($orderedFieldControl as $anOrderedFieldControl => $orderedFieldControlConfiguration) {
62 if (isset($orderedFieldControlConfiguration['disabled']) && $orderedFieldControlConfiguration['disabled']
63 || !isset($fieldControl[$anOrderedFieldControl]['renderType'])
64 ) {
65 // Don't consider this control if disabled.
66 // Also ignore if renderType is not given.
67 // Missing renderType may happen if an element registers a default field control
68 // as disabled, and TCA enabled that. If then additionally for instance the
69 // element renderType is changed to an element that doesn't register the control
70 // by default anymore, this would then fatal if we don't continue here.
71 // @todo: the above scenario indicates a small configuration flaw, maybe log an error somewhere?
72 continue;
73 }
74
75 $options = $this->data;
76 $options['renderType'] = $fieldControl[$anOrderedFieldControl]['renderType'];
77 $options['renderData']['fieldControlOptions'] = $orderedFieldControlConfiguration['options'] ?? [];
78 $controlResult = $this->nodeFactory->create($options)->render();
79
80 if (!is_array($controlResult)) {
81 throw new \RuntimeException(
82 'Field controls must return an array',
83 1484838560
84 );
85 }
86
87 // If the controlResult is empty (this control rendered nothing), continue to next one
88 if (empty($controlResult)) {
89 continue;
90 }
91
92 if (empty($controlResult['iconIdentifier'])) {
93 throw new \RuntimeException(
94 'Field controls must return an iconIdentifier',
95 1483890332
96 );
97 }
98 if (empty($controlResult['title'])) {
99 throw new \RuntimeException(
100 'Field controls must return a title',
101 1483890482
102 );
103 }
104 if (empty($controlResult['linkAttributes'])) {
105 throw new \RuntimeException(
106 'Field controls must return link attributes',
107 1483891272
108 );
109 }
110
111 $icon = $controlResult['iconIdentifier'];
112 $title = $languageService->sL($controlResult['title']);
113 $linkAttributes = $controlResult['linkAttributes'];
114 if (!isset($linkAttributes['class'])) {
115 $linkAttributes['class'] = 'btn btn-default';
116 } else {
117 $linkAttributes['class'] .= 'btn btn-default';
118 }
119 if (!isset($linkAttributes['href'])) {
120 $linkAttributes['href'] = '#';
121 }
122
123 unset($controlResult['iconIdentifier']);
124 unset($controlResult['title']);
125 unset($controlResult['linkAttributes']);
126
127 $html = [];
128 $html[] = '<a ' . GeneralUtility::implodeAttributes($linkAttributes, true) . '>';
129 $html[] = '<span alt="' . htmlspecialchars($title) . '" title="' . htmlspecialchars($title) . '">';
130 $html[] = $iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render();
131 $html[] = '</span>';
132 $html[] = '</a>';
133
134 $finalControlResult = $this->initializeResultArray();
135 $finalControlResult = array_merge($finalControlResult, $controlResult);
136 $finalControlResult['html'] = implode(LF, $html);
137
138 $result = $this->mergeChildReturnIntoExistingResult($result, $finalControlResult);
139 }
140 return $result;
141 }
142
143 /**
144 * @return LanguageService
145 */
146 protected function getLanguageService()
147 {
148 return $GLOBALS['LANG'];
149 }
150 }