‪TYPO3CMS  ‪main
TcaPreparation.php
Go to the documentation of this file.
1 <?php
2 
3 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 
19 
21 
28 {
41  public function ‪prepare(array ‪$tca): array
42  {
44  ‪$tca = $this->‪configureFileReferences($tca);
45  return ‪$tca;
46  }
47 
67  protected function ‪configureCategoryRelations(array ‪$tca): array
68  {
69  foreach (‪$tca as $table => &$tableDefinition) {
70  if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
71  continue;
72  }
73  foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
74  if (($fieldConfig['config']['type'] ?? '') !== 'category') {
75  continue;
76  }
77 
78  if (!isset($fieldConfig['label'])) {
79  $fieldConfig['label'] = 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.categories';
80  }
81 
82  // Force foreign_table for type category
83  $fieldConfig['config']['foreign_table'] = 'sys_category';
84 
85  // Initialize default column configuration and merge it with already defined
86  $fieldConfig['config']['size'] ??= 20;
87  $fieldConfig['config']['foreign_table_where'] ??= ' AND {#sys_category}.{#sys_language_uid} IN (-1, 0)';
88 
89  // In case no relationship is given, fall back to "manyToMany"
90  if (empty($fieldConfig['config']['relationship'])) {
91  $fieldConfig['config']['relationship'] = 'manyToMany';
92  }
93 
94  if (!in_array($fieldConfig['config']['relationship'], ['oneToOne', 'oneToMany', 'manyToMany'], true)) {
95  throw new \RuntimeException(
96  $fieldName . ' of table ' . $table . ' is defined as type category with relationship "'
97  . $fieldConfig['config']['relationship'] . '", but only "oneToOne", "oneToMany" and "manyToMany"'
98  . ' are allowed.',
99  1627898896
100  );
101  }
102 
103  // Set the maxitems value (necessary for DataHandling and FormEngine)
104  if ($fieldConfig['config']['relationship'] === 'oneToOne') {
105  // In case relationship is set to "oneToOne", the database column for this
106  // field will be an integer column. This means, only one uid can be stored.
107  // Therefore maxitems must be 1.
108  if ((int)($fieldConfig['config']['maxitems'] ?? 0) > 1) {
109  throw new \RuntimeException(
110  $fieldName . ' of table ' . $table . ' is defined as type category with an oneToOne relationship. ' .
111  'Therefore maxitems must be 1. Otherwise, use oneToMany or manyToMany as relationship instead.',
112  1627335016
113  );
114  }
115  $fieldConfig['config']['maxitems'] = 1;
116  } elseif (!($fieldConfig['config']['maxitems'] ?? false)) {
117  // In case maxitems is not set or set to 0, set the default value "99999"
118  $fieldConfig['config']['maxitems'] = 99999;
119  } elseif ((int)($fieldConfig['config']['maxitems'] ?? 0) === 1) {
120  throw new \RuntimeException(
121  $fieldName . ' of table ' . $table . ' is defined as type category with a ' . $fieldConfig['config']['relationship'] .
122  ' relationship. Therefore, maxitems can not be set to 1. Use oneToOne as relationship instead.',
123  1627335017
124  );
125  }
126 
127  // Add the default value if not set
128  if (!isset($fieldConfig['config']['default'])
129  && $fieldConfig['config']['relationship'] !== 'oneToMany'
130  ) {
131  // @todo: This is db wise not accurate: A oneToOne relation without a relation being assigned,
132  // @todo: should have NULL as value, not 0, since 0 looks like a uid, but it isn't.
133  // @todo: The field should be nullable and DH should handle that.
134  $fieldConfig['config']['default'] = 0;
135  }
136 
137  // Add MM related properties in case relationship is set to "manyToMany".
138  // This will not be done for the sys_category table itself.
139  if ($fieldConfig['config']['relationship'] === 'manyToMany' && $table !== 'sys_category') {
140  // Note these settings are hard coded here and can't be overridden.
141  $fieldConfig['config'] = array_replace_recursive($fieldConfig['config'], [
142  'MM' => 'sys_category_record_mm',
143  'MM_opposite_field' => 'items',
144  'MM_match_fields' => [
145  'tablenames' => $table,
146  'fieldname' => $fieldName,
147  ],
148  ]);
149 
150  // Register opposite references for the foreign side of a category relation
151  if (empty(‪$tca['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$table])) {
152  ‪$tca['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$table] = [];
153  }
154  if (!in_array($fieldName, ‪$tca['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$table], true)) {
155  ‪$tca['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$table][] = $fieldName;
156  }
157 
158  // Take specific value of exclude flag into account
159  if (!isset($fieldConfig['exclude'])) {
160  $fieldConfig['exclude'] = true;
161  }
162  }
163  }
164  }
165 
166  return ‪$tca;
167  }
168 
169  protected function ‪configureFileReferences(array ‪$tca): array
170  {
171  foreach (‪$tca as $table => &$tableDefinition) {
172  if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
173  continue;
174  }
175  foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
176  if (($fieldConfig['config']['type'] ?? '') !== 'file') {
177  continue;
178  }
179 
180  // Set static values for this type. Most of them are not needed due to the
181  // dedicated TCA type. However a lot of underlying code in DataHandler and
182  // friends relies on those keys, especially "foreign_table" and "foreign_selector".
183  // @todo Check which of those values can be removed since only used by FormEngine
184  $fieldConfig['config'] = array_replace_recursive(
185  $fieldConfig['config'],
186  [
187  'foreign_table' => 'sys_file_reference',
188  'foreign_field' => 'uid_foreign',
189  'foreign_sortby' => 'sorting_foreign',
190  'foreign_table_field' => 'tablenames',
191  'foreign_match_fields' => [
192  'fieldname' => $fieldName,
193  ],
194  'foreign_label' => 'uid_local',
195  'foreign_selector' => 'uid_local',
196  ]
197  );
198 
199  if (!empty(($allowed = ($fieldConfig['config']['allowed'] ?? null)))) {
200  $fieldConfig['config']['allowed'] = ‪self::prepareFileExtensions($allowed);
201  }
202  if (!empty(($disallowed = ($fieldConfig['config']['disallowed'] ?? null)))) {
203  $fieldConfig['config']['disallowed'] = ‪self::prepareFileExtensions($disallowed);
204  }
205  }
206  }
207 
208  return ‪$tca;
209  }
210 
216  public static function ‪prepareFileExtensions(mixed $fileExtensions): string
217  {
218  if (is_array($fileExtensions)) {
219  $fileExtensions = implode(',', $fileExtensions);
220  } else {
221  $fileExtensions = (string)$fileExtensions;
222  }
223 
224  // Replace placeholders with the corresponding $GLOBALS value for now
225  if (preg_match_all('/common-(image|text|media)-types/', $fileExtensions, $matches)) {
226  foreach ($matches[1] as $key => $type) {
227  $fileExtensions = str_replace(
228  $matches[0][$key],
229  ‪$GLOBALS['TYPO3_CONF_VARS'][$type === 'image' ? 'GFX' : 'SYS'][$type . 'file_ext'] ?? '',
230  $fileExtensions
231  );
232  }
233  }
234 
235  return ‪StringUtility::uniqueList($fileExtensions);
236  }
237 }
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation
Definition: TcaPreparation.php:28
‪TYPO3\CMS\Core\Utility\StringUtility\uniqueList
‪static string uniqueList(string $list)
Definition: StringUtility.php:122
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation\configureCategoryRelations
‪configureCategoryRelations(array $tca)
Definition: TcaPreparation.php:67
‪TYPO3\CMS\Core\Configuration\Tca
Definition: TcaFactory.php:18
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation\configureFileReferences
‪configureFileReferences(array $tca)
Definition: TcaPreparation.php:169
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation\prepare
‪prepare(array $tca)
Definition: TcaPreparation.php:41
‪$tca
‪$tca
Definition: sys_file_metadata.php:5
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation\prepareFileExtensions
‪static prepareFileExtensions(mixed $fileExtensions)
Definition: TcaPreparation.php:216