[BUGFIX] Check if value is array to prevent a PHP warning
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Domain / Repository / TypoScriptRepository.php
1 <?php
2 namespace TYPO3\CMS\Form\Domain\Repository;
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 TYPO3\CMS\Core\SingletonInterface;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
20
21 /**
22 * Provide the TypoScript data-source
23 */
24 class TypoScriptRepository implements SingletonInterface {
25
26 /**
27 * @var array
28 */
29 protected $modelDefinitionTypoScript = array();
30
31 /**
32 * @var array
33 */
34 protected $registeredElementTypes = array();
35
36 /**
37 * @var \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
38 */
39 protected $typoScriptParser;
40
41 /**
42 * The constructor
43 */
44 public function __construct() {
45 $this->typoScriptParser = GeneralUtility::makeInstance(TypoScriptParser::class);
46 $this->modelDefinitionTypoScript = $this->resolveTypoScriptReferences(
47 $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_form.']
48 );
49 $this->setRegisteredElementTypes();
50 }
51
52 /**
53 * Get all registered form elements
54 *
55 * @return array
56 */
57 public function getRegisteredElementTypes() {
58 return $this->registeredElementTypes;
59 }
60
61 /**
62 * Set all registered form elements
63 *
64 * @param array $registeredElementTypes
65 * @return void
66 * @throws \InvalidArgumentException
67 */
68 public function setRegisteredElementTypes(array $registeredElementTypes = array()) {
69 if (!empty($registeredElementTypes)) {
70 $this->registeredElementTypes = $registeredElementTypes;
71 } else {
72 if (!isset($this->modelDefinitionTypoScript['settings.']['registeredElements.'])) {
73 throw new \InvalidArgumentException('There are no registeredElements available.', 1441791615);
74 }
75 $registeredElements = $this->modelDefinitionTypoScript['settings.']['registeredElements.'];
76 foreach ($registeredElements as $registeredElementKey => $value) {
77 $registeredElementKey = rtrim($registeredElementKey, '.');
78 $this->registeredElementTypes[] = $registeredElementKey;
79 }
80 }
81 }
82
83 /**
84 * Get the html attributes defined by the model
85 * with their default values
86 *
87 * @param string $elementType
88 * @return array
89 */
90 public function getModelDefinedHtmlAttributes($elementType = '') {
91 if ($elementType == '') {
92 return array();
93 }
94 $htmlAttributes = $this->getModelConfigurationByScope($elementType, 'htmlAttributes.');
95 if (is_array($htmlAttributes)) {
96 $htmlAttributes = array_fill_keys($htmlAttributes, NULL);
97 } else {
98 $htmlAttributes = array();
99 }
100 $defaultHtmlAttributeValues = $this->getModelConfigurationByScope($elementType, 'defaultHtmlAttributeValues.');
101 if (is_array($defaultHtmlAttributeValues)) {
102 foreach ($defaultHtmlAttributeValues as $defaultHtmlAttributeKey => $defaultHtmlAttributeValue) {
103 $htmlAttributes[$defaultHtmlAttributeKey] = $defaultHtmlAttributeValue;
104 }
105 } elseif (!is_array($htmlAttributes)) {
106 $htmlAttributes = array();
107 }
108 return $htmlAttributes;
109 }
110
111 /**
112 * Get the default fluid template for a element.
113 *
114 * @param string $elementType
115 * @param string $partialType
116 * @return string
117 */
118 public function getDefaultFluidTemplate($elementType, $partialType = 'partialPath') {
119 $partialPath = $this->getModelConfigurationByScope($elementType, $partialType);
120 if ($partialPath) {
121 return $partialPath;
122 }
123 return '';
124 }
125
126 /**
127 * Get the model definition from TypoScript for a specific scope.
128 *
129 * @param string $elementType
130 * @param string $scope
131 * @return mixed
132 */
133 public function getModelConfigurationByScope($elementType, $scope) {
134 if (isset($this->modelDefinitionTypoScript['settings.']['registeredElements.'][$elementType . '.'][$scope])) {
135 return $this->modelDefinitionTypoScript['settings.']['registeredElements.'][$elementType . '.'][$scope];
136 }
137 return NULL;
138 }
139
140 /**
141 * Get a registered class name by a
142 * specific scope (validator or filter)
143 *
144 * @param string $name
145 * @param string $scope (registeredValidators, registeredFilters)
146 * @return mixed
147 */
148 public function getRegisteredClassName($name, $scope) {
149 $name = strtolower($name);
150 if (isset($this->modelDefinitionTypoScript['settings.'][$scope . '.'][$name . '.']['className'])) {
151 return $this->modelDefinitionTypoScript['settings.'][$scope . '.'][$name . '.']['className'];
152 }
153 return NULL;
154 }
155
156 /**
157 * Render a TypoScript and resolve all references (eg. " < plugin.tx_form...") recursively
158 *
159 * @param array $typoScript
160 * @return array
161 * @todo Extract to core then...
162 */
163 protected function resolveTypoScriptReferences(array $typoScript) {
164 $ignoreKeys = array();
165 foreach ($typoScript as $key => $value) {
166 if (isset($ignoreKeys[$key])) {
167 continue;
168 }
169 // i am a reference
170 if ($value[0] === '<') {
171 if (isset($typoScript[$key . '.'])) {
172 $oldTypoScript = $typoScript[$key . '.'];
173 } else {
174 $oldTypoScript = array();
175 }
176 // detect search level
177 $referencePath = trim(substr($value, 1));
178 $dotPosition = strpos($referencePath, '.');
179 if ($dotPosition === 0) {
180 // same position x =< .y
181 list($flatValue, $arrayValue) = $this->typoScriptParser->getVal(substr($referencePath, 1), $typoScript);
182 } else {
183 list($flatValue, $arrayValue) = $this->typoScriptParser->getVal($referencePath, $GLOBALS['TSFE']->tmpl->setup);
184 }
185 if (is_array($arrayValue)) {
186 $typoScript[$key . '.'] = array_replace_recursive($arrayValue, $oldTypoScript);
187 }
188 if ($flatValue[0] === '<') {
189 $temporaryTypoScript = array(
190 'temp' => $flatValue,
191 'temp.' => $typoScript[$key . '.'],
192 );
193 $temporaryTypoScript = $this->resolveTypoScriptReferences($temporaryTypoScript);
194 $arrayValue = array_replace_recursive($temporaryTypoScript['temp.'], $arrayValue, $oldTypoScript);
195 }
196 if (is_array($arrayValue)) {
197 $typoScript[$key . '.'] = array_replace_recursive($arrayValue, $oldTypoScript);
198 } elseif (isset($flatValue)) {
199 $typoScript[$key] = $flatValue;
200 } else {
201 $typoScript[$key . '.'] = $oldTypoScript;
202 }
203 }
204 // if array, then look deeper
205 if (isset($typoScript[$key . '.'])) {
206 $ignoreKeys[$key . '.'] = TRUE;
207 $typoScript[$key . '.'] = $this->resolveTypoScriptReferences($typoScript[$key . '.']);
208 } elseif (is_array($typoScript[$key])) {
209 // if array, then look deeper
210 $typoScript[$key] = $this->resolveTypoScriptReferences($typoScript[$key]);
211 }
212 }
213 return $typoScript;
214 }
215
216 }