‪TYPO3CMS  ‪main
TcaFactory.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 
20 use Psr\EventDispatcher\EventDispatcherInterface;
21 use Symfony\Component\Finder\Finder;
27 use TYPO3\CMS\Core\Package\PackageManager;
29 
33 final class ‪TcaFactory
34 {
35  public function ‪__construct(
36  private readonly PackageManager $packageManager,
37  private readonly EventDispatcherInterface $eventDispatcher,
38  private readonly ‪PhpFrontend $codeCache,
39  ) {}
40 
44  public function get(): array
45  {
46  $cacheData = $this->codeCache->require($this->‪getTcaCacheIdentifier());
47  if ($cacheData) {
48  ‪$tca = $cacheData['tca'];
49  } else {
50  ‪$tca = $this->‪create();
52  }
53 
54  // @todo: The placement in this method is a hack and should be moved elsewhere.
55  $allowedRecordTypesForDefault = [];
56  foreach (‪$tca as $table => $tableConfiguration) {
57  if ($tableConfiguration['ctrl']['security']['ignorePageTypeRestriction'] ?? false) {
58  $allowedRecordTypesForDefault[] = $table;
59  }
60  }
61  GeneralUtility::makeInstance(PageDoktypeRegistry::class)->addAllowedRecordTypes($allowedRecordTypesForDefault);
62 
63  return ‪$tca;
64  }
65 
70  public function ‪create(): array
71  {
75  ‪$tca = $this->‪migrateTca(‪$tca);
76  ‪$tca = $this->‪prepareTca(‪$tca);
78  }
79 
83  public function ‪createNotMigrated(): array
84  {
87  }
88 
92  public function ‪createBaseTcaCacheFile(array ‪$tca): void
93  {
94  $this->codeCache->set(
95  $this->‪getTcaCacheIdentifier(),
96  'return '
97  . var_export(['tca' => ‪$tca], true)
98  . ';'
99  );
100  }
101 
102  private function ‪getTcaCacheIdentifier(): string
103  {
104  return (new ‪PackageDependentCacheIdentifier($this->packageManager))->withPrefix('tca_base')->toString();
105  }
106 
107  private function ‪loadConfigurationTcaFiles(): array
108  {
109  // To require TCA in a safe scoped environment avoiding local variable clashes.
110  // Note: Return type 'mixed' is intended, otherwise broken TCA files with missing "return [];" statement would
111  // emit a "return value must be of type array, int returned" PHP TypeError. This is mitigated by an array
112  // check below.
113  $scopedReturnRequire = static function (string $filename): mixed {
114  return require $filename;
115  };
116  // First load "full table" files from Configuration/TCA
117  ‪$GLOBALS['TCA'] = [];
118  $activePackages = $this->packageManager->getActivePackages();
119  foreach ($activePackages as $package) {
120  try {
121  ‪$finder = Finder::create()->files()->sortByName()->depth(0)->name('*.php')->in($package->getPackagePath() . 'Configuration/TCA');
122  } catch (\InvalidArgumentException) {
123  // No such directory in this package
124  continue;
125  }
126  foreach (‪$finder as $fileInfo) {
127  $tcaOfTable = $scopedReturnRequire($fileInfo->getPathname());
128  if (is_array($tcaOfTable)) {
129  $tcaTableName = substr($fileInfo->getBasename(), 0, -4);
130  ‪$GLOBALS['TCA'][$tcaTableName] = $tcaOfTable;
131  }
132  }
133  }
134  ‪$tca = ‪$GLOBALS['TCA'];
135  unset(‪$GLOBALS['TCA']);
136  return ‪$tca;
137  }
138 
139  private function ‪loadConfigurationTcaOverridesFiles(array ‪$tca): array
140  {
141  // To require TCA Overrides in a safe scoped environment avoiding local variable clashes.
142  $scopedRequire = static function (string $filename): void {
143  require $filename;
144  };
145  // Execute override files from Configuration/TCA/Overrides
146  ‪$GLOBALS['TCA'] = ‪$tca;
147  $activePackages = $this->packageManager->getActivePackages();
148  foreach ($activePackages as $package) {
149  try {
150  ‪$finder = Finder::create()->files()->sortByName()->depth(0)->name('*.php')->in($package->getPackagePath() . 'Configuration/TCA/Overrides');
151  } catch (\InvalidArgumentException) {
152  // No such directory in this package
153  continue;
154  }
155  foreach (‪$finder as $fileInfo) {
156  $scopedRequire($fileInfo->getPathname());
157  }
158  }
159  ‪$tca = ‪$GLOBALS['TCA'];
160  unset(‪$GLOBALS['TCA']);
161  return ‪$tca;
162  }
163 
164  private function ‪migrateTca(array ‪$tca): array
165  {
166  // Call the TcaMigration and log any deprecations.
167  $tcaMigration = new ‪TcaMigration();
168  ‪$tca = $tcaMigration->migrate(‪$tca);
169  $messages = $tcaMigration->getMessages();
170  if (!empty($messages)) {
171  $context = 'Automatic TCA migration done during bootstrap. Please adapt TCA accordingly, these migrations'
172  . ' will be removed. The backend module "Configuration -> TCA" shows the modified values.'
173  . ' Please adapt these areas:';
174  array_unshift($messages, $context);
175  trigger_error(implode(LF, $messages), E_USER_DEPRECATED);
176  }
177  return ‪$tca;
178  }
179 
180  private function ‪prepareTca(array ‪$tca): array
181  {
182  return (new ‪TcaPreparation())->prepare(‪$tca);
183  }
184 
186  {
187  return $this->eventDispatcher->dispatch(new ‪BeforeTcaOverridesEvent(‪$tca))->getTca();
188  }
189 
191  {
192  ‪$GLOBALS['TCA'] = ‪$tca;
193  ‪$tca = $this->eventDispatcher->dispatch(new ‪AfterTcaCompilationEvent(‪$tca))->getTca();
194  unset(‪$GLOBALS['TCA']);
195  return ‪$tca;
196  }
197 }
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory
Definition: TcaFactory.php:34
‪TYPO3\CMS\Core\DataHandling\PageDoktypeRegistry
Definition: PageDoktypeRegistry.php:35
‪$finder
‪if(PHP_SAPI !=='cli') $finder
Definition: header-comment.php:22
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\__construct
‪__construct(private readonly PackageManager $packageManager, private readonly EventDispatcherInterface $eventDispatcher, private readonly PhpFrontend $codeCache,)
Definition: TcaFactory.php:35
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\prepareTca
‪prepareTca(array $tca)
Definition: TcaFactory.php:180
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation
Definition: TcaPreparation.php:28
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\dispatchBeforeTcaOverridesEvent
‪dispatchBeforeTcaOverridesEvent($tca)
Definition: TcaFactory.php:185
‪TYPO3\CMS\Core\Configuration\Event\AfterTcaCompilationEvent
Definition: AfterTcaCompilationEvent.php:25
‪TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
Definition: PhpFrontend.php:25
‪TYPO3\CMS\Core\Package\Cache\PackageDependentCacheIdentifier
Definition: PackageDependentCacheIdentifier.php:30
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\createNotMigrated
‪createNotMigrated()
Definition: TcaFactory.php:83
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\loadConfigurationTcaFiles
‪loadConfigurationTcaFiles()
Definition: TcaFactory.php:107
‪TYPO3\CMS\Core\Configuration\Event\BeforeTcaOverridesEvent
Definition: BeforeTcaOverridesEvent.php:25
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\migrateTca
‪migrateTca(array $tca)
Definition: TcaFactory.php:164
‪TYPO3\CMS\Core\Configuration\Tca
Definition: TcaFactory.php:18
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\create
‪create()
Definition: TcaFactory.php:70
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\getTcaCacheIdentifier
‪getTcaCacheIdentifier()
Definition: TcaFactory.php:102
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\dispatchAfterTcaCompilationEvent
‪dispatchAfterTcaCompilationEvent($tca)
Definition: TcaFactory.php:190
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\createBaseTcaCacheFile
‪createBaseTcaCacheFile(array $tca)
Definition: TcaFactory.php:92
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪$tca
‪$tca
Definition: sys_file_metadata.php:5
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Configuration\Tca\TcaFactory\loadConfigurationTcaOverridesFiles
‪loadConfigurationTcaOverridesFiles(array $tca)
Definition: TcaFactory.php:139
‪TYPO3\CMS\Core\Configuration\Tca\TcaMigration
Definition: TcaMigration.php:31