‪TYPO3CMS  ‪main
ExtensionManagementUtility.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;
30 use TYPO3\CMS\Core\Package\PackageManager;
32 
40 {
50  protected static bool ‪$extTablesWasReadFromCacheOnce = false;
51  protected static PackageManager ‪$packageManager;
52  protected static EventDispatcherInterface ‪$eventDispatcher;
53  protected static ?‪CacheManager ‪$cacheManager;
54 
61  public static function ‪setPackageManager(PackageManager ‪$packageManager): void
62  {
63  static::$packageManager = ‪$packageManager;
64  }
65 
71  public static function ‪setEventDispatcher(EventDispatcherInterface ‪$eventDispatcher): void
72  {
73  static::$eventDispatcher = ‪$eventDispatcher;
74  }
75 
79  protected static function ‪getCacheManager(): ‪CacheManager
80  {
81  return static::$cacheManager ??= GeneralUtility::makeInstance(CacheManager::class);
82  }
83 
84  /**************************************
85  *
86  * PATHS and other evaluation
87  *
88  ***************************************/
89 
93  public static function ‪isLoaded(string $key): bool
94  {
95  return static::$packageManager->isPackageActive($key);
96  }
97 
108  public static function ‪resolvePackagePath(string $path): string
109  {
110  return static::$packageManager->resolvePackagePath($path);
111  }
112 
120  public static function ‪extPath(string $key, string $script = ''): string
121  {
122  if (!static::$packageManager->isPackageActive($key)) {
123  throw new \BadFunctionCallException('TYPO3 Fatal Error: Extension key "' . $key . '" is NOT loaded!', 1365429656);
124  }
125  return static::$packageManager->getPackage($key)->getPackagePath() . $script;
126  }
127 
134  public static function ‪getCN(string $key): string
135  {
136  return str_starts_with($key, 'user_')
137  ? 'user_' . str_replace('_', '', substr($key, 5))
138  : 'tx_' . str_replace('_', '', $key);
139  }
140 
151  public static function ‪getExtensionVersion(string $key): string
152  {
153  if (empty($key)) {
154  throw new \InvalidArgumentException('Extension key must be a non-empty string.', 1294586096);
155  }
156  if (!static::isLoaded($key)) {
157  return '';
158  }
159  $version = static::$packageManager->getPackage($key)->getPackageMetaData()->getVersion();
160  if (empty($version)) {
161  throw new ‪PackageException('Version number in composer manifest of package "' . $key . '" is missing or invalid', 1395614959);
162  }
163  return $version;
164  }
165 
166  /**************************************
167  *
168  * Adding BACKEND features
169  * (related to core features)
170  *
171  ***************************************/
172 
183  public static function ‪addTCAcolumns(string $table, array $columnArray): void
184  {
185  if (is_array(‪$GLOBALS['TCA'][$table]['columns'] ?? false)) {
186  // Candidate for array_merge() if integer-keys will some day make trouble...
187  ‪$GLOBALS['TCA'][$table]['columns'] = array_merge(‪$GLOBALS['TCA'][$table]['columns'], $columnArray);
188  }
189  }
190 
204  public static function ‪addToAllTCAtypes(string $table, string $newFieldsString, string $typeList = '', string $position = ''): void
205  {
206  $newFieldsString = trim($newFieldsString);
207  if ($newFieldsString === '' || !is_array(‪$GLOBALS['TCA'][$table]['types'] ?? false)) {
208  return;
209  }
210  if ($position !== '') {
211  [$positionIdentifier, $entityName] = GeneralUtility::trimExplode(':', $position, false, 2);
212  } else {
213  $positionIdentifier = '';
214  $entityName = '';
215  }
216  $palettesChanged = [];
217 
218  foreach (‪$GLOBALS['TCA'][$table]['types'] as $type => &$typeDetails) {
219  // skip if we don't want to add the field for this type
220  if ($typeList !== '' && !‪GeneralUtility::inList($typeList, $type)) {
221  continue;
222  }
223  // skip if fields were already added
224  if (!isset($typeDetails['showitem'])) {
225  continue;
226  }
227 
228  $fieldArray = GeneralUtility::trimExplode(',', $typeDetails['showitem'], true);
229  if (in_array($newFieldsString, $fieldArray, true)) {
230  continue;
231  }
232 
233  $fieldExists = false;
234  $newPosition = '';
235  if (is_array(‪$GLOBALS['TCA'][$table]['palettes'] ?? false)) {
236  // Get the palette names used in current showitem
237  $paletteCount = preg_match_all('/(?:^|,) # Line start or a comma
238  (?:
239  \\s*\\-\\-palette\\-\\-;[^;]*;([^,$]*)| # --palette--;label;paletteName
240  \\s*\\b[^;,]+\\b(?:;[^;]*;([^;,]+))?[^,]* # field;label;paletteName
241  )/x', $typeDetails['showitem'], $paletteMatches);
242  if ($paletteCount > 0) {
243  $paletteNames = array_filter(array_merge($paletteMatches[1], $paletteMatches[2]));
244  if (!empty($paletteNames)) {
245  foreach ($paletteNames as $paletteName) {
246  if (!isset(‪$GLOBALS['TCA'][$table]['palettes'][$paletteName])) {
247  continue;
248  }
249  $palette = ‪$GLOBALS['TCA'][$table]['palettes'][$paletteName];
250  switch ($positionIdentifier) {
251  case 'after':
252  case 'before':
253  if (preg_match('/\\b' . preg_quote($entityName, '/') . '\\b/', $palette['showitem']) > 0 || $entityName === 'palette:' . $paletteName) {
254  $newPosition = $positionIdentifier . ':--palette--;;' . $paletteName;
255  }
256  break;
257  case 'replace':
258  // check if fields have been added to palette before
259  if (isset($palettesChanged[$paletteName])) {
260  $fieldExists = true;
261  continue 2;
262  }
263  if (preg_match('/\\b' . preg_quote($entityName, '/') . '\\b/', $palette['showitem']) > 0) {
264  ‪self::addFieldsToPalette($table, $paletteName, $newFieldsString, $position);
265  // Memorize that we already changed this palette, in case other types also use it
266  $palettesChanged[$paletteName] = true;
267  $fieldExists = true;
268  continue 2;
269  }
270  break;
271  default:
272  // Intentionally left blank
273  }
274  }
275  }
276  }
277  }
278  if ($fieldExists === false) {
279  $typeDetails['showitem'] = ‪self::executePositionedStringInsertion(
280  $typeDetails['showitem'],
281  $newFieldsString,
282  $newPosition !== '' ? $newPosition : $position
283  );
284  }
285  }
286  unset($typeDetails);
287  }
288 
332  public static function ‪addFieldsToAllPalettesOfField(string $table, string $field, string $addFields, string $insertionPosition = ''): void
333  {
334  if (!isset(‪$GLOBALS['TCA'][$table]['columns'][$field])) {
335  return;
336  }
337  if (!is_array(‪$GLOBALS['TCA'][$table]['types'])) {
338  return;
339  }
340 
341  // Iterate through all types and search for the field that defines the palette to be extended
342  foreach (‪$GLOBALS['TCA'][$table]['types'] as $typeName => $typeArray) {
343  // Continue if types has no showitem at all or if requested field is not in it
344  if (!isset($typeArray['showitem']) || !str_contains($typeArray['showitem'], $field)) {
345  continue;
346  }
347  $fieldArrayWithOptions = GeneralUtility::trimExplode(',', $typeArray['showitem']);
348  // Find the field we're handling
349  $newFieldStringArray = [];
350  foreach ($fieldArrayWithOptions as $fieldNumber => $fieldString) {
351  $newFieldStringArray[] = $fieldString;
352  $fieldArray = GeneralUtility::trimExplode(';', $fieldString);
353  if ($fieldArray[0] !== $field) {
354  continue;
355  }
356  if (
357  isset($fieldArrayWithOptions[$fieldNumber + 1])
358  && str_starts_with($fieldArrayWithOptions[$fieldNumber + 1], '--palette--')
359  ) {
360  // Match for $field and next field is a palette - add fields to this one
361  $paletteName = GeneralUtility::trimExplode(';', $fieldArrayWithOptions[$fieldNumber + 1]);
362  $paletteName = $paletteName[2];
363  ‪self::addFieldsToPalette($table, $paletteName, $addFields, $insertionPosition);
364  } else {
365  // Match for $field but next field is no palette - create a new one
366  $newPaletteName = 'generatedFor-' . $field;
367  ‪self::addFieldsToPalette($table, 'generatedFor-' . $field, $addFields, $insertionPosition);
368  $newFieldStringArray[] = '--palette--;;' . $newPaletteName;
369  }
370  }
371  ‪$GLOBALS['TCA'][$table]['types'][$typeName]['showitem'] = implode(', ', $newFieldStringArray);
372  }
373  }
374 
385  public static function ‪addFieldsToPalette(string $table, string $palette, string $addFields, string $insertionPosition = ''): void
386  {
387  if (isset(‪$GLOBALS['TCA'][$table])) {
388  $paletteData = &‪$GLOBALS['TCA'][$table]['palettes'][$palette];
389  // If palette already exists, merge the data:
390  if (is_array($paletteData)) {
391  $paletteData['showitem'] = ‪self::executePositionedStringInsertion($paletteData['showitem'], $addFields, $insertionPosition);
392  } else {
393  $paletteData['showitem'] = ‪self::removeDuplicatesForInsertion($addFields);
394  }
395  }
396  }
397 
429  public static function ‪addTcaSelectItem(string $table, string $field, array $item, string $relativeToField = '', string $relativePosition = ''): void
430  {
431  if ($relativePosition !== '' && $relativePosition !== 'before' && $relativePosition !== 'after' && $relativePosition !== 'replace') {
432  throw new \InvalidArgumentException('Relative position must be either empty or one of "before", "after", "replace".', 1303236967);
433  }
434  if (!isset(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'])
435  || !is_array(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'])
436  ) {
437  throw new \RuntimeException('Given select field item list was not found.', 1303237468);
438  }
439  // Make sure item keys are integers
440  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'] = array_values(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items']);
441  if ($relativePosition !== '') {
442  // Insert at specified position
443  $matchedPosition = ‪ArrayUtility::filterByValueRecursive($relativeToField, ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items']);
444  if (!empty($matchedPosition)) {
445  $relativeItemKey = key($matchedPosition);
446  if ($relativePosition === 'replace') {
447  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'][$relativeItemKey] = $item;
448  } else {
449  if ($relativePosition === 'before') {
450  $offset = $relativeItemKey;
451  } else {
452  $offset = $relativeItemKey + 1;
453  }
454  array_splice(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'], $offset, 0, [0 => $item]);
455  }
456  } else {
457  // Insert at new item at the end of the array if relative position was not found
458  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'][] = $item;
459  }
460  } else {
461  // Insert at new item at the end of the array
462  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'][] = $item;
463  }
464  }
465 
476  public static function ‪addTcaSelectItemGroup(string $table, string $field, string $groupId, string $groupLabel, ?string $position = 'bottom'): void
477  {
478  if (!is_array(‪$GLOBALS['TCA'][$table]['columns'][$field]['config'] ?? null)) {
479  throw new \RuntimeException('Given select field item list was not found.', 1586728563);
480  }
481  $itemGroups = ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['itemGroups'] ?? [];
482  // Group has been defined already, nothing to do
483  if (isset($itemGroups[$groupId])) {
484  return;
485  }
486  $position = (string)$position;
487  $positionGroupId = '';
488  if (str_contains($position, ':')) {
489  [$position, $positionGroupId] = explode(':', $position, 2);
490  }
491  // Referenced group was not not found, just append to the bottom
492  if (!isset($itemGroups[$positionGroupId])) {
493  $position = 'bottom';
494  }
495  switch ($position) {
496  case 'after':
497  $newItemGroups = [];
498  foreach ($itemGroups as $existingGroupId => $existingGroupLabel) {
499  $newItemGroups[$existingGroupId] = $existingGroupLabel;
500  if ($positionGroupId === $existingGroupId) {
501  $newItemGroups[$groupId] = $groupLabel;
502  }
503  }
504  $itemGroups = $newItemGroups;
505  break;
506  case 'before':
507  $newItemGroups = [];
508  foreach ($itemGroups as $existingGroupId => $existingGroupLabel) {
509  if ($positionGroupId === $existingGroupId) {
510  $newItemGroups[$groupId] = $groupLabel;
511  }
512  $newItemGroups[$existingGroupId] = $existingGroupLabel;
513  }
514  $itemGroups = $newItemGroups;
515  break;
516  case 'top':
517  $itemGroups = array_merge([$groupId => $groupLabel], $itemGroups);
518  break;
519  case 'bottom':
520  default:
521  $itemGroups[$groupId] = $groupLabel;
522  }
523  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['itemGroups'] = $itemGroups;
524  }
525 
534  public static function ‪addFieldsToUserSettings(string $addFields, string $insertionPosition = ''): void
535  {
536  ‪$GLOBALS['TYPO3_USER_SETTINGS']['showitem'] = ‪self::executePositionedStringInsertion(‪$GLOBALS['TYPO3_USER_SETTINGS']['showitem'] ?? '', $addFields, $insertionPosition);
537  }
538 
556  protected static function ‪executePositionedStringInsertion(string $list, string $insertionList, string $insertionPosition = ''): string
557  {
558  $list = trim($list, ", \t\n\r\0\x0B");
559 
560  if ($insertionPosition !== '') {
561  [$location, $positionName] = GeneralUtility::trimExplode(':', $insertionPosition, false, 2);
562  } else {
563  $location = '';
564  $positionName = '';
565  }
566 
567  if ($location !== 'replace') {
568  $insertionList = ‪self::removeDuplicatesForInsertion($insertionList, $list);
569  }
570 
571  if ($insertionList === '') {
572  return $list;
573  }
574  if ($list === '') {
575  return $insertionList;
576  }
577  if ($insertionPosition === '') {
578  return $list . ', ' . $insertionList;
579  }
580 
581  // The $insertPosition may be a palette: after:--palette--;;title
582  // In the $list the palette may contain a LLL string in between the ;;
583  // Adjust the regex to match that
584  $positionName = preg_quote($positionName, '/');
585  if (str_contains($positionName, ';;')) {
586  $positionName = str_replace(';;', ';[^;]*;', $positionName);
587  }
588 
589  $pattern = ('/(^|,\\s*)(' . $positionName . ')(;[^,$]+)?(,|$)/');
590  $newList = match ($location) {
591  'after' => preg_replace($pattern, '$1$2$3, ' . $insertionList . '$4', $list),
592  'before' => preg_replace($pattern, '$1' . $insertionList . ', $2$3$4', $list),
593  'replace' => preg_replace($pattern, '$1' . $insertionList . '$4', $list),
594  default => $list,
595  };
596 
597  // When preg_replace did not replace anything; append the $insertionList.
598  if ($newList === $list) {
599  return $list . ', ' . $insertionList;
600  }
601  return $newList;
602  }
603 
619  protected static function ‪removeDuplicatesForInsertion(string $insertionList, string $list = ''): string
620  {
621  $insertionListParts = preg_split('/\\s*,\\s*/', $insertionList);
622  $listMatches = [];
623  if ($list !== '') {
624  preg_match_all('/(?:^|,)\\s*\\b([^;,]+)\\b[^,]*/', $list, $listMatches);
625  $listMatches = $listMatches[1];
626  }
627 
628  $cleanInsertionListParts = [];
629  foreach ($insertionListParts as $fieldName) {
630  $fieldNameParts = explode(';', $fieldName, 2);
631  $cleanFieldName = $fieldNameParts[0];
632  if (
633  $cleanFieldName === '--linebreak--'
634  || (
635  !in_array($cleanFieldName, $cleanInsertionListParts, true)
636  && !in_array($cleanFieldName, $listMatches, true)
637  )
638  ) {
639  $cleanInsertionListParts[] = $fieldName;
640  }
641  }
642  return implode(', ', $cleanInsertionListParts);
643  }
644 
650  public static function ‪addPageTSConfig(string $content): void
651  {
652  trigger_error(
653  'ExtensionManagementUtility::addPageTSConfig() has been deprecated in TYPO3 v13.0 and will be removed in v14.0. Use Configuration/page.tsconfig files in extensions instead.',
654  E_USER_DEPRECATED
655  );
656  ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] .= chr(10) . $content;
657  }
658 
664  public static function ‪addUserTSConfig(string $content): void
665  {
666  trigger_error(
667  'ExtensionManagementUtility::addUserTSConfig() has been deprecated in TYPO3 v13.0 and will be removed in v14.0. Use Configuration/user.tsconfig files in extensions instead.',
668  E_USER_DEPRECATED
669  );
670  ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= chr(10) . $content;
671  }
672 
673  /**************************************
674  *
675  * Adding SERVICES features
676  *
677  ***************************************/
686  public static function ‪addService(string $extKey, string $serviceType, string $serviceKey, array $info): void
687  {
688  if (!$serviceType) {
689  throw new \InvalidArgumentException('No serviceType given.', 1507321535);
690  }
691  $info['priority'] = max(0, min(100, $info['priority']));
692  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey] = $info;
693  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['extKey'] = $extKey;
694  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceKey'] = $serviceKey;
695  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceType'] = $serviceType;
696  // Change the priority (and other values) from $GLOBALS['TYPO3_CONF_VARS']
697  // $GLOBALS['TYPO3_CONF_VARS']['T3_SERVICES'][$serviceType][$serviceKey]['priority']
698  // even the activation is possible (a unix service might be possible on windows for some reasons)
699  if (is_array(‪$GLOBALS['TYPO3_CONF_VARS']['T3_SERVICES'][$serviceType][$serviceKey] ?? false)) {
700  // No check is done here - there might be configuration values only the service type knows about, so
701  // we pass everything
702  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey] = array_merge(‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey], ‪$GLOBALS['TYPO3_CONF_VARS']['T3_SERVICES'][$serviceType][$serviceKey]);
703  }
704  // OS check
705  // Empty $os means 'not limited to one OS', therefore a check is not needed
706  if (!empty(‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['available']) && (‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['os'] ?? '') != '') {
707  $os_type = ‪Environment::isWindows() ? 'WIN' : 'UNIX';
708  $os = GeneralUtility::trimExplode(',', strtoupper(‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['os']));
709  if (!in_array($os_type, $os, true)) {
710  ‪self::deactivateService($serviceType, $serviceKey);
711  }
712  }
713  // Convert subtype list to array for quicker access
714  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceSubTypes'] = [];
715  $serviceSubTypes = GeneralUtility::trimExplode(',', $info['subtype']);
716  foreach ($serviceSubTypes as $subtype) {
717  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceSubTypes'][$subtype] = $subtype;
718  }
719  }
720 
729  public static function ‪findService(string $serviceType, string $serviceSubType = '', array $excludeServiceKeys = []): array|false
730  {
731  $serviceKey = false;
732  $serviceInfo = false;
733  $priority = 0;
734  $quality = 0;
735  if (is_array(‪$GLOBALS['T3_SERVICES'][$serviceType])) {
736  foreach (‪$GLOBALS['T3_SERVICES'][$serviceType] as $key => $info) {
737  if (in_array($key, $excludeServiceKeys)) {
738  continue;
739  }
740  // Select a subtype randomly
741  // Useful to start a service by service key without knowing his subtypes - for testing purposes
742  if ($serviceSubType === '*') {
743  $serviceSubType = key($info['serviceSubTypes']);
744  }
745  // This matches empty subtype too
746  if (($info['available'] ?? false)
747  && (($info['subtype'] ?? null) == $serviceSubType || ($info['serviceSubTypes'][$serviceSubType] ?? false))
748  && ($info['priority'] ?? 0) >= $priority
749  ) {
750  // Has a lower quality than the already found, therefore we skip this service
751  if ($info['priority'] == $priority && $info['quality'] < $quality) {
752  continue;
753  }
754  // Check if the service is available
755  $info['available'] = ‪self::isServiceAvailable($serviceType, $key, $info);
756  // Still available after exec check?
757  if ($info['available']) {
758  $serviceKey = $key;
759  $priority = $info['priority'];
760  $quality = $info['quality'];
761  }
762  }
763  }
764  }
765  if ($serviceKey) {
766  $serviceInfo = ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey];
767  }
768  return $serviceInfo;
769  }
770 
779  public static function ‪findServiceByKey(string $serviceKey): array
780  {
781  if (is_array(‪$GLOBALS['T3_SERVICES'])) {
782  // Loop on all service types
783  // NOTE: we don't care about the actual type, we are looking for a specific key
784  foreach (‪$GLOBALS['T3_SERVICES'] as $serviceType => $servicesPerType) {
785  if (isset($servicesPerType[$serviceKey])) {
786  $serviceDetails = $servicesPerType[$serviceKey];
787  // Test if service is available
788  if (self::isServiceAvailable($serviceType, $serviceKey, $serviceDetails)) {
789  // We have found the right service, return its information
790  return $serviceDetails;
791  }
792  }
793  }
794  }
795  throw new \TYPO3\CMS\Core\Exception('Service not found for key: ' . $serviceKey, 1319217244);
796  }
797 
806  public static function ‪isServiceAvailable(string $serviceType, string $serviceKey, array $serviceDetails): bool
807  {
808  // If the service depends on external programs - check if they exists
809  if (trim($serviceDetails['exec'] ?? '')) {
810  $executables = GeneralUtility::trimExplode(',', $serviceDetails['exec'], true);
811  foreach ($executables as $executable) {
812  // If at least one executable file is not available, exit early returning FALSE
813  if (!‪CommandUtility::checkCommand($executable)) {
814  ‪self::deactivateService($serviceType, $serviceKey);
815  return false;
816  }
817  }
818  }
819  // The service is available
820  return true;
821  }
822 
829  public static function ‪deactivateService(string $serviceType, string $serviceKey): void
830  {
831  // ... maybe it's better to move non-available services to a different array??
832  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['available'] = false;
833  }
834 
835  /**************************************
836  *
837  * Adding FRONTEND features
838  *
839  ***************************************/
853  public static function ‪addPlugin(array $itemArray, string $type = 'list_type', ?string $extensionKey = null): void
854  {
855  // $extensionKey is required, but presumably for BC reasons it still lives after $type in the
856  // parameter list, and $type is nominally optional.
857  if (!isset($extensionKey)) {
858  throw new \InvalidArgumentException(
859  'No extension key could be determined when calling addPlugin()!'
860  . LF
861  . 'This method is meant to be called from Configuration/TCA/Overrides files. '
862  . 'The extension key needs to be specified as third parameter. '
863  . 'Calling it from any other place e.g. ext_localconf.php does not work and is not supported.',
864  1404068038
865  );
866  }
867  if (!isset($itemArray[2]) || !$itemArray[2]) {
868  // @todo do we really set $itemArray[2], even if we cannot find an icon? (as that means it's set to 'EXT:foobar/')
869  $itemArray[2] = 'EXT:' . $extensionKey . '/' . static::getExtensionIcon(static::$packageManager->getPackage($extensionKey)->getPackagePath());
870  } elseif ($type === 'CType' && !isset(‪$GLOBALS['TCA']['tt_content']['ctrl']['typeicon_classes'][$itemArray[1]])) {
871  // Set the type icon as well
872  ‪$GLOBALS['TCA']['tt_content']['ctrl']['typeicon_classes'][$itemArray[1]] = $itemArray[2];
873  }
874  if (!isset($itemArray[3])) {
875  $itemArray[3] = 'default';
876  }
877  if (is_array(‪$GLOBALS['TCA']['tt_content']['columns']) && is_array(‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'])) {
878  foreach (‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'] as $k => $v) {
879  if ((string)($v['value'] ?? '') === (string)$itemArray[1]) {
880  ‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'][$k] = [
881  'label' => $itemArray[0] ?? '',
882  'value' => $itemArray[1] ?? '',
883  'icon' => $itemArray[2],
884  'group' => $itemArray[3],
885  ];
886  return;
887  }
888  }
889  ‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'][] = [
890  'label' => $itemArray[0] ?? '',
891  'value' => $itemArray[1] ?? '',
892  'icon' => $itemArray[2],
893  'group' => $itemArray[3],
894  ];
895  }
896  // Ensure to have at least some basic information available when editing the new type in FormEngine
897  if ($type === 'CType' && !isset(‪$GLOBALS['TCA']['tt_content']['types'][$itemArray[1]]) && isset(‪$GLOBALS['TCA']['tt_content']['types']['header'])) {
898  ‪$GLOBALS['TCA']['tt_content']['types'][$itemArray[1]] = ‪$GLOBALS['TCA']['tt_content']['types']['header'];
899  }
900  }
901 
912  public static function ‪addPiFlexFormValue(string $piKeyToMatch, string $value, string $CTypeToMatch = 'list'): void
913  {
914  if (is_array(‪$GLOBALS['TCA']['tt_content']['columns']) && is_array(‪$GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds'])) {
915  ‪$GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds'][$piKeyToMatch . ',' . $CTypeToMatch] = $value;
916  }
917  }
918 
928  public static function ‪addToInsertRecords(string $table, string $content_table = 'tt_content', string $content_field = 'records'): void
929  {
930  if (is_array(‪$GLOBALS['TCA'][$content_table]['columns']) && isset(‪$GLOBALS['TCA'][$content_table]['columns'][$content_field]['config']['allowed'])) {
931  ‪$GLOBALS['TCA'][$content_table]['columns'][$content_field]['config']['allowed'] .= ',' . $table;
932  }
933  }
934 
959  public static function ‪addPItoST43(string $key, string $_ = '', string $suffix = '', string $type = 'list_type', bool $cacheable = false): void
960  {
961  $cN = ‪self::getCN($key);
962  // General plugin
963  $pluginContent = trim('
964 plugin.' . $cN . $suffix . ' = USER' . ($cacheable ? '' : '_INT') . '
965 plugin.' . $cN . $suffix . '.userFunc = ' . $cN . $suffix . '->main
966 ');
967  ‪self::addTypoScript($key, 'setup', '
968 # Setting ' . $key . ' plugin TypoScript
969 ' . $pluginContent);
970  // Add after defaultContentRendering
971  switch ($type) {
972  case 'list_type':
973  $addLine = 'tt_content.list.20.' . $key . $suffix . ' = < plugin.' . $cN . $suffix;
974  break;
975  case 'CType':
976  $addLine = trim('
977 tt_content.' . $key . $suffix . ' =< lib.contentElement
978 tt_content.' . $key . $suffix . ' {
979  templateName = Generic
980  20 =< plugin.' . $cN . $suffix . '
981 }
982 ');
983  break;
984  case 'includeLib':
985  $addLine = 'page.1000 = < plugin.' . $cN . $suffix;
986  break;
987  default:
988  $addLine = '';
989  }
990  if ($addLine) {
991  ‪self::addTypoScript($key, 'setup', '
992 # Setting ' . $key . ' plugin TypoScript
993 ' . $addLine . '
994 ', 'defaultContentRendering');
995  }
996  }
997 
1013  public static function ‪addStaticFile(string $extKey, string $path, string $title): void
1014  {
1015  if (!$extKey) {
1016  throw new \InvalidArgumentException('No extension key given.', 1507321291);
1017  }
1018  if (!$path) {
1019  throw new \InvalidArgumentException('No file path given.', 1507321297);
1020  }
1021  if (is_array(‪$GLOBALS['TCA']['sys_template']['columns'])) {
1022  $value = str_replace(',', '', 'EXT:' . $extKey . '/' . $path);
1023  $itemArray = ['label' => trim($title . ' (' . $extKey . ')'), 'value' => $value];
1024  ‪$GLOBALS['TCA']['sys_template']['columns']['include_static_file']['config']['items'][] = $itemArray;
1025  }
1026  }
1027 
1037  public static function ‪registerPageTSConfigFile(string $extKey, string $filePath, string $title): void
1038  {
1039  if (!$extKey) {
1040  throw new \InvalidArgumentException('No extension key given.', 1447789490);
1041  }
1042  if (!$filePath) {
1043  throw new \InvalidArgumentException('No file path given.', 1447789491);
1044  }
1045  if (!is_array(‪$GLOBALS['TCA']['pages']['columns'] ?? null)) {
1046  throw new \InvalidArgumentException('No TCA definition for table "pages".', 1447789492);
1047  }
1048 
1049  $value = str_replace(',', '', 'EXT:' . $extKey . '/' . $filePath);
1050  $itemArray = ['label' => trim($title . ' (' . $extKey . ')'), 'value' => $value];
1051  ‪$GLOBALS['TCA']['pages']['columns']['tsconfig_includes']['config']['items'][] = $itemArray;
1052  }
1053 
1061  public static function ‪addTypoScriptSetup(string $content): void
1062  {
1063  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup'] ??= '';
1064  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup'])) {
1065  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup'] .= LF;
1066  }
1067  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup'] .= $content;
1068  }
1069 
1077  public static function ‪addTypoScriptConstants(string $content): void
1078  {
1079  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants'] ??= '';
1080  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants'])) {
1081  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants'] .= LF;
1082  }
1083  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants'] .= $content;
1084  }
1085 
1103  public static function ‪addTypoScript(string $key, string $type, string $content, int|string $afterStaticUid = 0): void
1104  {
1105  if ($type !== 'setup' && $type !== 'constants') {
1106  throw new \InvalidArgumentException('Argument $type must be set to either "setup" or "constants" when calling addTypoScript from extension "' . $key . '"', 1507321200);
1107  }
1108  $content = '
1109 
1110 [GLOBAL]
1111 #############################################
1112 ## TypoScript added by extension "' . $key . '"
1113 #############################################
1114 
1115 ' . $content;
1116  if ($afterStaticUid) {
1117  // If 'defaultContentRendering' is targeted (formerly static uid 43),
1118  // the content is added after TypoScript of type contentRendering, e.g. fluid_styled_content, see
1119  // EXT:core/Classes/TypoScript/IncludeTree/SysTemplateTreeBuilder.php for more information on how the code is parsed.
1120  if ($afterStaticUid === 'defaultContentRendering' || $afterStaticUid == 43) {
1121  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.']['defaultContentRendering'] ??= '';
1122  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.']['defaultContentRendering'] .= $content;
1123  } else {
1124  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.'][$afterStaticUid] ??= '';
1125  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.'][$afterStaticUid] .= $content;
1126  }
1127  } else {
1128  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type] ??= '';
1129  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type] .= $content;
1130  }
1131  }
1132 
1133  /***************************************
1134  *
1135  * Internal extension management methods
1136  *
1137  ***************************************/
1144  public static function ‪getExtensionIcon(string $extensionPath, bool $returnFullPath = false): string
1145  {
1146  $icon = '';
1147  $resourcePath = 'Resources/Public/Icons/Extension.';
1148  foreach (['svg', 'png', 'gif'] as $fileExtension) {
1149  if (file_exists($extensionPath . $resourcePath . $fileExtension)) {
1150  $icon = $resourcePath . $fileExtension;
1151  break;
1152  }
1153  }
1154  return $returnFullPath ? $extensionPath . $icon : $icon;
1155  }
1156 
1169  public static function ‪loadExtLocalconf(bool $allowCaching = true, ‪FrontendInterface $codeCache = null): void
1170  {
1171  if ($allowCaching) {
1172  $codeCache = $codeCache ?? ‪self::getCacheManager()->getCache('core');
1173  $cacheIdentifier = ‪self::getExtLocalconfCacheIdentifier();
1174  $hasCache = $codeCache->require($cacheIdentifier) !== false;
1175  if (!$hasCache) {
1178  }
1179  } else {
1181  }
1182  }
1183 
1187  protected static function ‪loadSingleExtLocalconfFiles(): void
1188  {
1189  foreach (static::$packageManager->getActivePackages() as $package) {
1190  $extLocalconfPath = $package->getPackagePath() . 'ext_localconf.php';
1191  if (file_exists($extLocalconfPath)) {
1192  require $extLocalconfPath;
1193  }
1194  }
1195  }
1196 
1202  public static function ‪createExtLocalconfCacheEntry(‪FrontendInterface $codeCache): void
1203  {
1204  $phpCodeToCache = [];
1205  // Set same globals as in loadSingleExtLocalconfFiles()
1206  $phpCodeToCache[] = '';
1209  $phpCodeToCache[] = '';
1210  // Iterate through loaded extensions and add ext_localconf content
1211  foreach (static::$packageManager->getActivePackages() as $package) {
1212  $extensionKey = $package->getPackageKey();
1213  $extLocalconfPath = $package->getPackagePath() . 'ext_localconf.php';
1214  if (@file_exists($extLocalconfPath)) {
1215  // Include a header per extension to make the cache file more readable
1216  $phpCodeToCache[] = '';
1220  $phpCodeToCache[] = '';
1221  // Add ext_localconf.php content of extension
1222  $phpCodeToCache[] = 'namespace {';
1223  $phpCodeToCache[] = trim((string)file_get_contents($extLocalconfPath));
1224  $phpCodeToCache[] = '}';
1225  $phpCodeToCache[] = '';
1226  $phpCodeToCache[] = '';
1227  }
1228  }
1229  $phpCodeToCache = implode(LF, $phpCodeToCache);
1230  // Remove all start and ending php tags from content
1231  $phpCodeToCache = preg_replace('/<\\?php|\\?>/is', '', $phpCodeToCache);
1232  $phpCodeToCache = preg_replace('/declare\\s?+\\(\\s?+strict_types\\s?+=\\s?+1\\s?+\\);/is', '', (string)$phpCodeToCache);
1233  $codeCache->‪set(self::getExtLocalconfCacheIdentifier(), $phpCodeToCache);
1234  }
1235 
1239  protected static function ‪getExtLocalconfCacheIdentifier(): string
1240  {
1241  return (new ‪PackageDependentCacheIdentifier(self::$packageManager))->withPrefix('ext_localconf')->toString();
1242  }
1243 
1257  public static function ‪loadBaseTca(bool $allowCaching = true, ‪FrontendInterface $codeCache = null): void
1258  {
1259  if ($allowCaching) {
1260  $codeCache = $codeCache ?? ‪self::getCacheManager()->getCache('core');
1261  $cacheIdentifier = static::getBaseTcaCacheIdentifier();
1262  $cacheData = $codeCache->require($cacheIdentifier);
1263  if ($cacheData) {
1264  ‪$GLOBALS['TCA'] = $cacheData['tca'];
1265  } else {
1266  static::buildBaseTcaFromSingleFiles();
1267  static::createBaseTcaCacheFile($codeCache);
1268  }
1269  } else {
1270  static::buildBaseTcaFromSingleFiles();
1271  }
1272 
1273  $allowedRecordTypesForDefault = [];
1274  foreach (‪$GLOBALS['TCA'] as $table => $tableConfiguration) {
1275  if ($tableConfiguration['ctrl']['security']['ignorePageTypeRestriction'] ?? false) {
1276  $allowedRecordTypesForDefault[] = $table;
1277  }
1278  }
1279  GeneralUtility::makeInstance(PageDoktypeRegistry::class)->addAllowedRecordTypes($allowedRecordTypesForDefault);
1280  }
1281 
1290  public static function ‪buildBaseTcaFromSingleFiles(): void
1291  {
1292  ‪$GLOBALS['TCA'] = [];
1293 
1294  $activePackages = static::$packageManager->getActivePackages();
1295 
1296  // To require TCA in a safe scoped environment avoiding local variable clashes.
1297  // @see TYPO3\CMS\Core\Tests\Functional\Utility\ExtensionManagementUtility\ExtensionManagementUtilityTcaRequireTest
1298  // Note: Return type 'mixed' is intended, otherwise broken TCA files with missing "return [];" statement would
1299  // emit a "return value must be of type array, int returned" PHP TypeError. This is mitigated by an array
1300  // check below.
1301  $scopedReturnRequire = static function (string $filename): mixed {
1302  return require $filename;
1303  };
1304  // First load "full table" files from Configuration/TCA
1305  foreach ($activePackages as $package) {
1306  try {
1307  ‪$finder = Finder::create()->files()->sortByName()->depth(0)->name('*.php')->in($package->getPackagePath() . 'Configuration/TCA');
1308  } catch (\InvalidArgumentException $e) {
1309  // No such directory in this package
1310  continue;
1311  }
1312  foreach (‪$finder as $fileInfo) {
1313  $tcaOfTable = $scopedReturnRequire($fileInfo->getPathname());
1314  if (is_array($tcaOfTable)) {
1315  $tcaTableName = substr($fileInfo->getBasename(), 0, -4);
1316  ‪$GLOBALS['TCA'][$tcaTableName] = $tcaOfTable;
1317  }
1318  }
1319  }
1320 
1321  // To require TCA Overrides in a safe scoped environment avoiding local variable clashes.
1322  // @see TYPO3\CMS\Core\Tests\Functional\Utility\ExtensionManagementUtility\ExtensionManagementUtilityTcaOverrideRequireTest
1323  $scopedRequire = static function (string $filename): void {
1324  require $filename;
1325  };
1326  // Execute override files from Configuration/TCA/Overrides
1327  foreach ($activePackages as $package) {
1328  try {
1329  ‪$finder = Finder::create()->files()->sortByName()->depth(0)->name('*.php')->in($package->getPackagePath() . 'Configuration/TCA/Overrides');
1330  } catch (\InvalidArgumentException $e) {
1331  // No such directory in this package
1332  continue;
1333  }
1334  foreach (‪$finder as $fileInfo) {
1335  $scopedRequire($fileInfo->getPathname());
1336  }
1337  }
1338 
1339  // Call the TcaMigration and log any deprecations.
1340  $tcaMigration = GeneralUtility::makeInstance(TcaMigration::class);
1341  ‪$GLOBALS['TCA'] = $tcaMigration->migrate(‪$GLOBALS['TCA']);
1342  $messages = $tcaMigration->getMessages();
1343  if (!empty($messages)) {
1344  $context = 'Automatic TCA migration done during bootstrap. Please adapt TCA accordingly, these migrations'
1345  . ' will be removed. The backend module "Configuration -> TCA" shows the modified values.'
1346  . ' Please adapt these areas:';
1347  array_unshift($messages, $context);
1348  trigger_error(implode(LF, $messages), E_USER_DEPRECATED);
1349  }
1350 
1351  // TCA preparation
1352  $tcaPreparation = GeneralUtility::makeInstance(TcaPreparation::class);
1353  ‪$GLOBALS['TCA'] = $tcaPreparation->prepare(‪$GLOBALS['TCA']);
1354 
1355  static::dispatchTcaIsBeingBuiltEvent(‪$GLOBALS['TCA']);
1356  }
1357 
1361  protected static function ‪dispatchTcaIsBeingBuiltEvent(array ‪$tca): void
1362  {
1363  ‪$GLOBALS['TCA'] = static::$eventDispatcher->dispatch(new ‪AfterTcaCompilationEvent(‪$tca))->getTca();
1364  }
1365 
1372  public static function ‪createBaseTcaCacheFile(‪FrontendInterface $codeCache): void
1373  {
1374  $codeCache->‪set(
1375  static::getBaseTcaCacheIdentifier(),
1376  'return '
1377  . var_export(['tca' => ‪$GLOBALS['TCA']], true)
1378  . ';'
1379  );
1380  }
1381 
1385  protected static function ‪getBaseTcaCacheIdentifier(): string
1386  {
1387  return (new ‪PackageDependentCacheIdentifier(self::$packageManager))->withPrefix('tca_base')->toString();
1388  }
1389 
1401  public static function ‪loadExtTables(bool $allowCaching = true, ‪FrontendInterface $codeCache = null): void
1402  {
1403  if ($allowCaching && !self::$extTablesWasReadFromCacheOnce) {
1404  self::$extTablesWasReadFromCacheOnce = true;
1405  $cacheIdentifier = ‪self::getExtTablesCacheIdentifier();
1406  $codeCache = $codeCache ?? ‪self::getCacheManager()->getCache('core');
1407  $hasCache = $codeCache->require($cacheIdentifier) !== false;
1408  if (!$hasCache) {
1411  }
1412  } else {
1414  }
1415  }
1416 
1420  protected static function ‪loadSingleExtTablesFiles(): void
1421  {
1422  // Load each ext_tables.php file of loaded extensions
1423  foreach (static::$packageManager->getActivePackages() as $package) {
1424  $extTablesPath = $package->getPackagePath() . 'ext_tables.php';
1425  if (@file_exists($extTablesPath)) {
1426  require $extTablesPath;
1427  }
1428  }
1429  }
1430 
1436  public static function ‪createExtTablesCacheEntry(‪FrontendInterface $codeCache): void
1437  {
1438  $phpCodeToCache = [];
1439  // Set same globals as in loadSingleExtTablesFiles()
1440  $phpCodeToCache[] = '';
1443  $phpCodeToCache[] = '';
1444  // Iterate through loaded extensions and add ext_tables content
1445  foreach (static::$packageManager->getActivePackages() as $package) {
1446  $extensionKey = $package->getPackageKey();
1447  $extTablesPath = $package->getPackagePath() . 'ext_tables.php';
1448  if (@file_exists($extTablesPath)) {
1449  // Include a header per extension to make the cache file more readable
1450  $phpCodeToCache[] = '';
1454  $phpCodeToCache[] = '';
1455  // Add ext_tables.php content of extension
1456  $phpCodeToCache[] = 'namespace {';
1457  $phpCodeToCache[] = trim((string)file_get_contents($extTablesPath));
1458  $phpCodeToCache[] = '}';
1459  $phpCodeToCache[] = '';
1460  }
1461  }
1462  $phpCodeToCache = implode(LF, $phpCodeToCache);
1463  // Remove all start and ending php tags from content
1464  $phpCodeToCache = preg_replace('/<\\?php|\\?>/is', '', $phpCodeToCache);
1465  $phpCodeToCache = preg_replace('/declare\\s?+\\(\\s?+strict_types\\s?+=\\s?+1\\s?+\\);/is', '', (string)$phpCodeToCache);
1466  $codeCache->‪set(self::getExtTablesCacheIdentifier(), $phpCodeToCache);
1467  }
1468 
1472  protected static function ‪getExtTablesCacheIdentifier(): string
1473  {
1474  return (new ‪PackageDependentCacheIdentifier(self::$packageManager))->withPrefix('ext_tables')->toString();
1475  }
1476 
1480  public static function ‪getLoadedExtensionListArray(): array
1481  {
1482  return array_keys(static::$packageManager->getActivePackages());
1483  }
1484 
1491  public static function ‪loadExtension(string $extensionKey): void
1492  {
1493  if (static::$packageManager->isPackageActive($extensionKey)) {
1494  throw new \RuntimeException('Extension already loaded', 1342345486);
1495  }
1496  static::$packageManager->activatePackage($extensionKey);
1497  }
1498 
1504  public static function ‪unloadExtension(string $extensionKey): void
1505  {
1506  if (!static::$packageManager->isPackageActive($extensionKey)) {
1507  throw new \RuntimeException('Extension not loaded', 1342345487);
1508  }
1509  static::$packageManager->deactivatePackage($extensionKey);
1510  }
1511 }
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addService
‪static addService(string $extKey, string $serviceType, string $serviceKey, array $info)
Definition: ExtensionManagementUtility.php:686
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPiFlexFormValue
‪static addPiFlexFormValue(string $piKeyToMatch, string $value, string $CTypeToMatch='list')
Definition: ExtensionManagementUtility.php:912
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\dispatchTcaIsBeingBuiltEvent
‪static dispatchTcaIsBeingBuiltEvent(array $tca)
Definition: ExtensionManagementUtility.php:1361
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addToInsertRecords
‪static addToInsertRecords(string $table, string $content_table='tt_content', string $content_field='records')
Definition: ExtensionManagementUtility.php:928
‪TYPO3\CMS\Core\DataHandling\PageDoktypeRegistry
Definition: PageDoktypeRegistry.php:35
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getLoadedExtensionListArray
‪static getLoadedExtensionListArray()
Definition: ExtensionManagementUtility.php:1480
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\findServiceByKey
‪static array findServiceByKey(string $serviceKey)
Definition: ExtensionManagementUtility.php:779
‪TYPO3\CMS\Core\Migrations\TcaMigration
Definition: TcaMigration.php:31
‪$finder
‪if(PHP_SAPI !=='cli') $finder
Definition: header-comment.php:22
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtensionIcon
‪static getExtensionIcon(string $extensionPath, bool $returnFullPath=false)
Definition: ExtensionManagementUtility.php:1144
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtensionVersion
‪static string getExtensionVersion(string $key)
Definition: ExtensionManagementUtility.php:151
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addToAllTCAtypes
‪static addToAllTCAtypes(string $table, string $newFieldsString, string $typeList='', string $position='')
Definition: ExtensionManagementUtility.php:204
‪TYPO3\CMS\Core\Configuration\Event\AfterTcaCompilationEvent
Definition: AfterTcaCompilationEvent.php:27
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadExtTables
‪static loadExtTables(bool $allowCaching=true, FrontendInterface $codeCache=null)
Definition: ExtensionManagementUtility.php:1401
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isServiceAvailable
‪static bool isServiceAvailable(string $serviceType, string $serviceKey, array $serviceDetails)
Definition: ExtensionManagementUtility.php:806
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\createExtLocalconfCacheEntry
‪static createExtLocalconfCacheEntry(FrontendInterface $codeCache)
Definition: ExtensionManagementUtility.php:1202
‪TYPO3\CMS\Core\Package\Cache\PackageDependentCacheIdentifier
Definition: PackageDependentCacheIdentifier.php:30
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTypoScriptSetup
‪static addTypoScriptSetup(string $content)
Definition: ExtensionManagementUtility.php:1061
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$eventDispatcher
‪static EventDispatcherInterface $eventDispatcher
Definition: ExtensionManagementUtility.php:52
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadSingleExtLocalconfFiles
‪static loadSingleExtLocalconfFiles()
Definition: ExtensionManagementUtility.php:1187
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPlugin
‪static addPlugin(array $itemArray, string $type='list_type', ?string $extensionKey=null)
Definition: ExtensionManagementUtility.php:853
‪TYPO3\CMS\Core\Utility
Definition: ArrayUtility.php:18
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadExtLocalconf
‪static loadExtLocalconf(bool $allowCaching=true, FrontendInterface $codeCache=null)
Definition: ExtensionManagementUtility.php:1169
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\createExtTablesCacheEntry
‪static createExtTablesCacheEntry(FrontendInterface $codeCache)
Definition: ExtensionManagementUtility.php:1436
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\deactivateService
‪static deactivateService(string $serviceType, string $serviceKey)
Definition: ExtensionManagementUtility.php:829
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addStaticFile
‪static addStaticFile(string $extKey, string $path, string $title)
Definition: ExtensionManagementUtility.php:1013
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTcaSelectItemGroup
‪static addTcaSelectItemGroup(string $table, string $field, string $groupId, string $groupLabel, ?string $position='bottom')
Definition: ExtensionManagementUtility.php:476
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPItoST43
‪static addPItoST43(string $key, string $_='', string $suffix='', string $type='list_type', bool $cacheable=false)
Definition: ExtensionManagementUtility.php:959
‪TYPO3\CMS\Core\Utility\CommandUtility\checkCommand
‪static bool int checkCommand(string $cmd, string $handler='')
Definition: CommandUtility.php:164
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static isLoaded(string $key)
Definition: ExtensionManagementUtility.php:93
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:40
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTCAcolumns
‪static addTCAcolumns(string $table, array $columnArray)
Definition: ExtensionManagementUtility.php:183
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtLocalconfCacheIdentifier
‪static getExtLocalconfCacheIdentifier()
Definition: ExtensionManagementUtility.php:1239
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\removeDuplicatesForInsertion
‪static string removeDuplicatesForInsertion(string $insertionList, string $list='')
Definition: ExtensionManagementUtility.php:619
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToAllPalettesOfField
‪static addFieldsToAllPalettesOfField(string $table, string $field, string $addFields, string $insertionPosition='')
Definition: ExtensionManagementUtility.php:332
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToPalette
‪static addFieldsToPalette(string $table, string $palette, string $addFields, string $insertionPosition='')
Definition: ExtensionManagementUtility.php:385
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadExtension
‪static loadExtension(string $extensionKey)
Definition: ExtensionManagementUtility.php:1491
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static extPath(string $key, string $script='')
Definition: ExtensionManagementUtility.php:120
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$extTablesWasReadFromCacheOnce
‪static bool $extTablesWasReadFromCacheOnce
Definition: ExtensionManagementUtility.php:50
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\setPackageManager
‪static setPackageManager(PackageManager $packageManager)
Definition: ExtensionManagementUtility.php:61
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\findService
‪static array false findService(string $serviceType, string $serviceSubType='', array $excludeServiceKeys=[])
Definition: ExtensionManagementUtility.php:729
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadBaseTca
‪static loadBaseTca(bool $allowCaching=true, FrontendInterface $codeCache=null)
Definition: ExtensionManagementUtility.php:1257
‪TYPO3\CMS\Core\Preparations\TcaPreparation
Definition: TcaPreparation.php:28
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getBaseTcaCacheIdentifier
‪static getBaseTcaCacheIdentifier()
Definition: ExtensionManagementUtility.php:1385
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadSingleExtTablesFiles
‪static loadSingleExtTablesFiles()
Definition: ExtensionManagementUtility.php:1420
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTypoScriptConstants
‪static addTypoScriptConstants(string $content)
Definition: ExtensionManagementUtility.php:1077
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addUserTSConfig
‪static addUserTSConfig(string $content)
Definition: ExtensionManagementUtility.php:664
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$packageManager
‪static PackageManager $packageManager
Definition: ExtensionManagementUtility.php:51
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtTablesCacheIdentifier
‪static getExtTablesCacheIdentifier()
Definition: ExtensionManagementUtility.php:1472
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getCacheManager
‪static getCacheManager()
Definition: ExtensionManagementUtility.php:79
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\registerPageTSConfigFile
‪static registerPageTSConfigFile(string $extKey, string $filePath, string $title)
Definition: ExtensionManagementUtility.php:1037
‪TYPO3\CMS\Core\Utility\ArrayUtility\filterByValueRecursive
‪static array filterByValueRecursive(mixed $needle='', array $haystack=[])
Definition: ArrayUtility.php:101
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToUserSettings
‪static addFieldsToUserSettings(string $addFields, string $insertionPosition='')
Definition: ExtensionManagementUtility.php:534
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTcaSelectItem
‪static addTcaSelectItem(string $table, string $field, array $item, string $relativeToField='', string $relativePosition='')
Definition: ExtensionManagementUtility.php:429
‪$tca
‪$tca
Definition: sys_file_metadata.php:5
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\unloadExtension
‪static unloadExtension(string $extensionKey)
Definition: ExtensionManagementUtility.php:1504
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\createBaseTcaCacheFile
‪static createBaseTcaCacheFile(FrontendInterface $codeCache)
Definition: ExtensionManagementUtility.php:1372
‪TYPO3\CMS\Core\Utility\GeneralUtility\inList
‪static bool inList($list, $item)
Definition: GeneralUtility.php:423
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\resolvePackagePath
‪static resolvePackagePath(string $path)
Definition: ExtensionManagementUtility.php:108
‪TYPO3\CMS\Core\Package\Exception
Definition: InvalidPackageKeyException.php:16
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\setEventDispatcher
‪static setEventDispatcher(EventDispatcherInterface $eventDispatcher)
Definition: ExtensionManagementUtility.php:71
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\executePositionedStringInsertion
‪static string executePositionedStringInsertion(string $list, string $insertionList, string $insertionPosition='')
Definition: ExtensionManagementUtility.php:556
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface\set
‪set($entryIdentifier, $data, array $tags=[], $lifetime=null)
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPageTSConfig
‪static addPageTSConfig(string $content)
Definition: ExtensionManagementUtility.php:650
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\buildBaseTcaFromSingleFiles
‪static buildBaseTcaFromSingleFiles()
Definition: ExtensionManagementUtility.php:1290
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$cacheManager
‪static CacheManager $cacheManager
Definition: ExtensionManagementUtility.php:53
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTypoScript
‪static addTypoScript(string $key, string $type, string $content, int|string $afterStaticUid=0)
Definition: ExtensionManagementUtility.php:1103
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getCN
‪static getCN(string $key)
Definition: ExtensionManagementUtility.php:134
‪TYPO3\CMS\Core\Core\Environment\isWindows
‪static isWindows()
Definition: Environment.php:276