f6766cb91d3ad1638d8cdd96c3225b18ed66e22a
[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 $htmlAttributes = array_fill_keys($htmlAttributes, null);
96 $defaultHtmlAttributeValues = $this->getModelConfigurationByScope($elementType, 'defaultHtmlAttributeValues.');
97 if (is_array($defaultHtmlAttributeValues)) {
98 foreach ($defaultHtmlAttributeValues as $defaultHtmlAttributeKey => $defaultHtmlAttibuteValue) {
99 $htmlAttributes[$defaultHtmlAttributeKey] = $defaultHtmlAttibuteValue;
100 }
101 } elseif (!is_array($htmlAttributes)) {
102 $htmlAttributes = array();
103 }
104 return $htmlAttributes;
105 }
106
107 /**
108 * Get the default fluid template for a element.
109 *
110 * @param string $elementType
111 * @param string $partialType
112 * @return string
113 */
114 public function getDefaultFluidTemplate($elementType, $partialType = 'partialPath') {
115 $partialPath = $this->getModelConfigurationByScope($elementType, $partialType);
116 if ($partialPath) {
117 return $partialPath;
118 }
119 return '';
120 }
121
122 /**
123 * Get the model definition from TypoScript for a specific scope.
124 *
125 * @param string $elementType
126 * @param string $scope
127 * @return mixed
128 */
129 public function getModelConfigurationByScope($elementType, $scope) {
130 if (isset($this->modelDefinitionTypoScript['settings.']['registeredElements.'][$elementType . '.'][$scope])) {
131 return $this->modelDefinitionTypoScript['settings.']['registeredElements.'][$elementType . '.'][$scope];
132 }
133 return NULL;
134 }
135
136 /**
137 * Get a registered class name by a
138 * specific scope (validator or filter)
139 *
140 * @param string $name
141 * @param string $scope (registeredValidators, registeredFilters)
142 * @return mixed
143 */
144 public function getRegisteredClassName($name, $scope) {
145 $name = strtolower($name);
146 if (isset($this->modelDefinitionTypoScript['settings.'][$scope . '.'][$name . '.']['className'])) {
147 return $this->modelDefinitionTypoScript['settings.'][$scope . '.'][$name . '.']['className'];
148 }
149 return NULL;
150 }
151
152 /**
153 * Render a TypoScript and resolve all references (eg. " < plugin.tx_form...") recursively
154 *
155 * @param array $typoScript
156 * @return array
157 * @todo Extract to core then...
158 */
159 protected function resolveTypoScriptReferences(array $typoScript) {
160 $ignoreKeys = array();
161 foreach ($typoScript as $key => $value) {
162 if (isset($ignoreKeys[$key])) {
163 continue;
164 }
165 // i am a reference
166 if ($value[0] === '<') {
167 if (isset($typoScript[$key . '.'])) {
168 $oldTypoScript = $typoScript[$key . '.'];
169 } else {
170 $oldTypoScript = array();
171 }
172 // detect search level
173 $referencePath = trim(substr($value, 1));
174 $dotPosition = strpos($referencePath, '.');
175 if ($dotPosition === 0) {
176 // same position x =< .y
177 list($flatValue, $arrayValue) = $this->typoScriptParser->getVal(substr($referencePath, 1), $typoScript);
178 } else {
179 list($flatValue, $arrayValue) = $this->typoScriptParser->getVal($referencePath, $GLOBALS['TSFE']->tmpl->setup);
180 }
181 if (is_array($arrayValue)) {
182 $typoScript[$key . '.'] = array_replace_recursive($arrayValue, $oldTypoScript);
183 }
184 if ($flatValue[0] === '<') {
185 $temporaryTypoScript = array(
186 'temp' => $flatValue,
187 'temp.' => $typoScript[$key . '.'],
188 );
189 $temporaryTypoScript = $this->resolveTypoScriptReferences($temporaryTypoScript);
190 $arrayValue = array_replace_recursive($temporaryTypoScript['temp.'], $arrayValue, $oldTypoScript);
191 }
192 if (is_array($arrayValue)) {
193 $typoScript[$key . '.'] = array_replace_recursive($arrayValue, $oldTypoScript);
194 } elseif (isset($flatValue)) {
195 $typoScript[$key] = $flatValue;
196 } else {
197 $typoScript[$key . '.'] = $oldTypoScript;
198 }
199 }
200 // if array, then look deeper
201 if (isset($typoScript[$key . '.'])) {
202 $ignoreKeys[$key . '.'] = TRUE;
203 $typoScript[$key . '.'] = $this->resolveTypoScriptReferences($typoScript[$key . '.']);
204 } elseif (is_array($typoScript[$key])) {
205 // if array, then look deeper
206 $typoScript[$key] = $this->resolveTypoScriptReferences($typoScript[$key]);
207 }
208 }
209 return $typoScript;
210 }
211
212 }