‪TYPO3CMS  9.5
ExtensionManagementUtility.php
Go to the documentation of this file.
1 <?php
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 Symfony\Component\Finder\Finder;
26 use TYPO3\CMS\Core\Package\PackageManager;
28 
36 {
40  protected static ‪$extensionKeyMap;
41 
52  protected static ‪$extTablesWasReadFromCacheOnce = false;
53 
57  protected static ‪$packageManager;
58 
66  public static function ‪setPackageManager(PackageManager ‪$packageManager)
67  {
68  static::$packageManager = ‪$packageManager;
69  }
70 
74  protected static ‪$cacheManager;
75 
81  protected static function ‪getCacheManager()
82  {
83  if (static::$cacheManager === null) {
84  static::$cacheManager = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Cache\CacheManager::class);
85  }
86  return static::$cacheManager;
87  }
88 
92  protected static ‪$signalSlotDispatcher;
93 
99  protected static function ‪getSignalSlotDispatcher()
100  {
101  if (‪static::$signalSlotDispatcher === null) {
102  ‪static::$signalSlotDispatcher = GeneralUtility::makeInstance(\‪TYPO3\CMS\‪Extbase\SignalSlot\Dispatcher::class);
103  }
105  }
106 
107  /**************************************
108  *
109  * PATHS and other evaluation
110  *
111  ***************************************/
120  public static function ‪isLoaded($key, $exitOnError = null)
121  {
122  // safety net for extensions checking for "EXT:version", can be removed in TYPO3 v10.0.
123  if ($key === 'version') {
124  trigger_error('EXT:version has been moved into EXT:workspaces, you should check against "workspaces", as this might lead to unexpected behaviour in the future.', E_USER_DEPRECATED);
125  $key = 'workspaces';
126  }
127  if ($key === 'sv') {
128  trigger_error('EXT:sv has been moved into EXT:core, you should remove your check as code is always loaded, as this might lead to unexpected behaviour in the future.', E_USER_DEPRECATED);
129  return true;
130  }
131  if ($key === 'saltedpasswords') {
132  trigger_error('EXT:saltedpasswords has been moved into EXT:core, you should remove your check as code is always loaded, as this might lead to unexpected behaviour in the future.', E_USER_DEPRECATED);
133  return true;
134  }
135  if ($exitOnError !== null) {
136  trigger_error('Calling ExtensionManagementUtility::isLoaded() with a second argument via "exitOnError" will be removed in TYPO3 v10.0, handle an unloaded package yourself in the future.', E_USER_DEPRECATED);
137  }
138  $isLoaded = static::$packageManager->isPackageActive($key);
139  if ($exitOnError && !$isLoaded) {
140  // @deprecated, once $exitOnError is gone, this check can be removed.
141  throw new \BadFunctionCallException('TYPO3 Fatal Error: Extension "' . $key . '" is not loaded!', 1270853910);
142  }
143  return $isLoaded;
144  }
145 
154  public static function ‪extPath($key, $script = '')
155  {
156  if (!static::$packageManager->isPackageActive($key)) {
157  throw new \BadFunctionCallException('TYPO3 Fatal Error: Extension key "' . $key . '" is NOT loaded!', 1365429656);
158  }
159  return static::$packageManager->getPackage($key)->getPackagePath() . $script;
160  }
161 
171  public static function ‪siteRelPath($key)
172  {
173  trigger_error('ExtensionManagementUtility::siteRelPath() will be removed in TYPO3 v10.0, use extPath() in conjunction with PathUtility::getAbsoluteWebPath() instead.', E_USER_DEPRECATED);
174  return ‪PathUtility::stripPathSitePrefix(self::extPath($key));
175  }
176 
184  public static function ‪getCN($key)
185  {
186  return strpos($key, 'user_') === 0 ? 'user_' . str_replace('_', '', substr($key, 5)) : 'tx_' . str_replace('_', '', $key);
187  }
188 
196  public static function ‪getExtensionKeyByPrefix($prefix)
197  {
198  trigger_error('ExtensionManagementUtility::getExtensionKeyByPrefix() will be removed in TYPO3 v10.0. Use extension keys directly.', E_USER_DEPRECATED);
199  $result = false;
200  // Build map of short keys referencing to real keys:
201  if (!isset(self::$extensionKeyMap)) {
202  self::$extensionKeyMap = [];
203  foreach (static::$packageManager->getActivePackages() as $package) {
204  $shortKey = str_replace('_', '', $package->getPackageKey());
205  self::$extensionKeyMap[$shortKey] = $package->getPackageKey();
206  }
207  }
208  // Lookup by the given short key:
209  $parts = explode('_', $prefix);
210  if (isset(self::$extensionKeyMap[$parts[1]])) {
211  $result = self::$extensionKeyMap[$parts[1]];
212  }
213  return $result;
214  }
215 
219  public static function ‪clearExtensionKeyMap()
220  {
221  self::$extensionKeyMap = null;
222  }
223 
234  public static function ‪getExtensionVersion($key)
235  {
236  if (!is_string($key) || empty($key)) {
237  throw new \InvalidArgumentException('Extension key must be a non-empty string.', 1294586096);
238  }
239  if (!static::isLoaded($key)) {
240  return '';
241  }
242  $version = static::$packageManager->getPackage($key)->getPackageMetaData()->getVersion();
243  if (empty($version)) {
244  throw new \TYPO3\CMS\Core\Package\Exception('Version number in composer manifest of package "' . $key . '" is missing or invalid', 1395614959);
245  }
246  return $version;
247  }
248 
249  /**************************************
250  *
251  * Adding BACKEND features
252  * (related to core features)
253  *
254  ***************************************/
265  public static function ‪addTCAcolumns($table, $columnArray)
266  {
267  if (is_array($columnArray) && is_array(‪$GLOBALS['TCA'][$table]) && is_array(‪$GLOBALS['TCA'][$table]['columns'])) {
268  // Candidate for array_merge() if integer-keys will some day make trouble...
269  ‪$GLOBALS['TCA'][$table]['columns'] = array_merge(‪$GLOBALS['TCA'][$table]['columns'], $columnArray);
270  }
271  }
272 
286  public static function ‪addToAllTCAtypes($table, $newFieldsString, $typeList = '', $position = '')
287  {
288  $newFieldsString = trim($newFieldsString);
289  if ($newFieldsString === '' || !is_array(‪$GLOBALS['TCA'][$table]['types'] ?? false)) {
290  return;
291  }
292  if ($position !== '') {
293  list($positionIdentifier, $entityName) = GeneralUtility::trimExplode(':', $position);
294  } else {
295  $positionIdentifier = '';
296  $entityName = '';
297  }
298  $palettesChanged = [];
299 
300  foreach (‪$GLOBALS['TCA'][$table]['types'] as $type => &$typeDetails) {
301  // skip if we don't want to add the field for this type
302  if ($typeList !== '' && !GeneralUtility::inList($typeList, $type)) {
303  continue;
304  }
305  // skip if fields were already added
306  if (!isset($typeDetails['showitem'])) {
307  continue;
308  }
309 
310  $fieldArray = GeneralUtility::trimExplode(',', $typeDetails['showitem'], true);
311  if (in_array($newFieldsString, $fieldArray, true)) {
312  continue;
313  }
314 
315  $fieldExists = false;
316  $newPosition = '';
317  if (is_array(‪$GLOBALS['TCA'][$table]['palettes'] ?? false)) {
318  // Get the palette names used in current showitem
319  $paletteCount = preg_match_all('/(?:^|,) # Line start or a comma
320  (?:
321  \\s*\\-\\-palette\\-\\-;[^;]*;([^,$]*)| # --palette--;label;paletteName
322  \\s*\\b[^;,]+\\b(?:;[^;]*;([^;,]+))?[^,]* # field;label;paletteName
323  )/x', $typeDetails['showitem'], $paletteMatches);
324  if ($paletteCount > 0) {
325  $paletteNames = array_filter(array_merge($paletteMatches[1], $paletteMatches[2]));
326  if (!empty($paletteNames)) {
327  foreach ($paletteNames as $paletteName) {
328  if (!isset(‪$GLOBALS['TCA'][$table]['palettes'][$paletteName])) {
329  continue;
330  }
331  $palette = ‪$GLOBALS['TCA'][$table]['palettes'][$paletteName];
332  switch ($positionIdentifier) {
333  case 'after':
334  case 'before':
335  if (preg_match('/\\b' . $entityName . '\\b/', $palette['showitem']) > 0) {
336  $newPosition = $positionIdentifier . ':--palette--;;' . $paletteName;
337  }
338  break;
339  case 'replace':
340  // check if fields have been added to palette before
341  if (isset($palettesChanged[$paletteName])) {
342  $fieldExists = true;
343  continue 2;
344  }
345  if (preg_match('/\\b' . $entityName . '\\b/', $palette['showitem']) > 0) {
346  ‪self::addFieldsToPalette($table, $paletteName, $newFieldsString, $position);
347  // Memorize that we already changed this palette, in case other types also use it
348  $palettesChanged[$paletteName] = true;
349  $fieldExists = true;
350  continue 2;
351  }
352  break;
353  default:
354  // Intentionally left blank
355  }
356  }
357  }
358  }
359  }
360  if ($fieldExists === false) {
361  $typeDetails['showitem'] = ‪self::executePositionedStringInsertion(
362  $typeDetails['showitem'],
363  $newFieldsString,
364  $newPosition !== '' ? $newPosition : $position
365  );
366  }
367  }
368  unset($typeDetails);
369  }
370 
414  public static function ‪addFieldsToAllPalettesOfField($table, $field, $addFields, $insertionPosition = '')
415  {
416  if (!isset(‪$GLOBALS['TCA'][$table]['columns'][$field])) {
417  return;
418  }
419  if (!is_array(‪$GLOBALS['TCA'][$table]['types'])) {
420  return;
421  }
422 
423  // Iterate through all types and search for the field that defines the palette to be extended
424  foreach (‪$GLOBALS['TCA'][$table]['types'] as $typeName => $typeArray) {
425  // Continue if types has no showitem at all or if requested field is not in it
426  if (!isset($typeArray['showitem']) || strpos($typeArray['showitem'], $field) === false) {
427  continue;
428  }
429  $fieldArrayWithOptions = GeneralUtility::trimExplode(',', $typeArray['showitem']);
430  // Find the field we're handling
431  $newFieldStringArray = [];
432  foreach ($fieldArrayWithOptions as $fieldNumber => $fieldString) {
433  $newFieldStringArray[] = $fieldString;
434  $fieldArray = GeneralUtility::trimExplode(';', $fieldString);
435  if ($fieldArray[0] !== $field) {
436  continue;
437  }
438  if (
439  isset($fieldArrayWithOptions[$fieldNumber + 1])
440  && strpos($fieldArrayWithOptions[$fieldNumber + 1], '--palette--') === 0
441  ) {
442  // Match for $field and next field is a palette - add fields to this one
443  $paletteName = GeneralUtility::trimExplode(';', $fieldArrayWithOptions[$fieldNumber + 1]);
444  $paletteName = $paletteName[2];
445  ‪self::addFieldsToPalette($table, $paletteName, $addFields, $insertionPosition);
446  } else {
447  // Match for $field but next field is no palette - create a new one
448  $newPaletteName = 'generatedFor-' . $field;
449  ‪self::addFieldsToPalette($table, 'generatedFor-' . $field, $addFields, $insertionPosition);
450  $newFieldStringArray[] = '--palette--;;' . $newPaletteName;
451  }
452  }
453  ‪$GLOBALS['TCA'][$table]['types'][$typeName]['showitem'] = implode(', ', $newFieldStringArray);
454  }
455  }
456 
467  public static function ‪addFieldsToPalette($table, $palette, $addFields, $insertionPosition = '')
468  {
469  if (isset(‪$GLOBALS['TCA'][$table])) {
470  $paletteData = &‪$GLOBALS['TCA'][$table]['palettes'][$palette];
471  // If palette already exists, merge the data:
472  if (is_array($paletteData)) {
473  $paletteData['showitem'] = ‪self::executePositionedStringInsertion($paletteData['showitem'], $addFields, $insertionPosition);
474  } else {
475  $paletteData['showitem'] = ‪self::removeDuplicatesForInsertion($addFields);
476  }
477  }
478  }
479 
508  public static function ‪addTcaSelectItem($table, $field, array $item, $relativeToField = '', $relativePosition = '')
509  {
510  if (!is_string($table)) {
511  throw new \InvalidArgumentException('Given table is of type "' . gettype($table) . '" but a string is expected.', 1303236963);
512  }
513  if (!is_string($field)) {
514  throw new \InvalidArgumentException('Given field is of type "' . gettype($field) . '" but a string is expected.', 1303236964);
515  }
516  if (!is_string($relativeToField)) {
517  throw new \InvalidArgumentException('Given relative field is of type "' . gettype($relativeToField) . '" but a string is expected.', 1303236965);
518  }
519  if (!is_string($relativePosition)) {
520  throw new \InvalidArgumentException('Given relative position is of type "' . gettype($relativePosition) . '" but a string is expected.', 1303236966);
521  }
522  if ($relativePosition !== '' && $relativePosition !== 'before' && $relativePosition !== 'after' && $relativePosition !== 'replace') {
523  throw new \InvalidArgumentException('Relative position must be either empty or one of "before", "after", "replace".', 1303236967);
524  }
525  if (!isset(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'])
526  || !is_array(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'])
527  ) {
528  throw new \RuntimeException('Given select field item list was not found.', 1303237468);
529  }
530  // Make sure item keys are integers
531  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'] = array_values(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items']);
532  if ($relativePosition !== '') {
533  // Insert at specified position
534  $matchedPosition = ‪ArrayUtility::filterByValueRecursive($relativeToField, ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items']);
535  if (!empty($matchedPosition)) {
536  $relativeItemKey = key($matchedPosition);
537  if ($relativePosition === 'replace') {
538  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'][$relativeItemKey] = $item;
539  } else {
540  if ($relativePosition === 'before') {
541  $offset = $relativeItemKey;
542  } else {
543  $offset = $relativeItemKey + 1;
544  }
545  array_splice(‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'], $offset, 0, [0 => $item]);
546  }
547  } else {
548  // Insert at new item at the end of the array if relative position was not found
549  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'][] = $item;
550  }
551  } else {
552  // Insert at new item at the end of the array
553  ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'][] = $item;
554  }
555  }
556 
567  public static function ‪getFileFieldTCAConfig($fieldName, array $customSettingOverride = [], $allowedFileExtensions = '', $disallowedFileExtensions = '')
568  {
569  $fileFieldTCAConfig = [
570  'type' => 'inline',
571  'foreign_table' => 'sys_file_reference',
572  'foreign_field' => 'uid_foreign',
573  'foreign_sortby' => 'sorting_foreign',
574  'foreign_table_field' => 'tablenames',
575  'foreign_match_fields' => [
576  'fieldname' => $fieldName
577  ],
578  'foreign_label' => 'uid_local',
579  'foreign_selector' => 'uid_local',
580  'overrideChildTca' => [
581  'columns' => [
582  'uid_local' => [
583  'config' => [
584  'appearance' => [
585  'elementBrowserType' => 'file',
586  'elementBrowserAllowed' => $allowedFileExtensions
587  ],
588  ],
589  ],
590  ],
591  ],
592  'filter' => [
593  [
594  'userFunc' => \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class . '->filterInlineChildren',
595  'parameters' => [
596  'allowedFileExtensions' => $allowedFileExtensions,
597  'disallowedFileExtensions' => $disallowedFileExtensions
598  ]
599  ]
600  ],
601  'appearance' => [
602  'useSortable' => true,
603  'headerThumbnail' => [
604  'field' => 'uid_local',
605  'width' => '45',
606  'height' => '45c',
607  ],
608 
609  'enabledControls' => [
610  'info' => true,
611  'new' => false,
612  'dragdrop' => true,
613  'sort' => false,
614  'hide' => true,
615  'delete' => true,
616  ],
617  ]
618  ];
619  ‪ArrayUtility::mergeRecursiveWithOverrule($fileFieldTCAConfig, $customSettingOverride);
620  return $fileFieldTCAConfig;
621  }
622 
631  public static function ‪addFieldsToUserSettings($addFields, $insertionPosition = '')
632  {
633  ‪$GLOBALS['TYPO3_USER_SETTINGS']['showitem'] = ‪self::executePositionedStringInsertion(‪$GLOBALS['TYPO3_USER_SETTINGS']['showitem'], $addFields, $insertionPosition);
634  }
635 
653  protected static function ‪executePositionedStringInsertion($list, $insertionList, $insertionPosition = '')
654  {
655  $list = $newList = trim($list, ", \t\n\r\0\x0B");
656 
657  if ($insertionPosition !== '') {
658  list($location, $positionName) = GeneralUtility::trimExplode(':', $insertionPosition, false, 2);
659  } else {
660  $location = '';
661  $positionName = '';
662  }
663 
664  if ($location !== 'replace') {
665  $insertionList = ‪self::removeDuplicatesForInsertion($insertionList, $list);
666  }
667 
668  if ($insertionList === '') {
669  return $list;
670  }
671  if ($list === '') {
672  return $insertionList;
673  }
674  if ($insertionPosition === '') {
675  return $list . ', ' . $insertionList;
676  }
677 
678  // The $insertPosition may be a palette: after:--palette--;;title
679  // In the $list the palette may contain a LLL string in between the ;;
680  // Adjust the regex to match that
681  $positionName = preg_quote($positionName, '/');
682  if (strpos($positionName, ';;') !== false) {
683  $positionName = str_replace(';;', ';[^;]*;', $positionName);
684  }
685 
686  $pattern = ('/(^|,\\s*)(' . $positionName . ')(;[^,$]+)?(,|$)/');
687  switch ($location) {
688  case 'after':
689  $newList = preg_replace($pattern, '$1$2$3, ' . $insertionList . '$4', $list);
690  break;
691  case 'before':
692  $newList = preg_replace($pattern, '$1' . $insertionList . ', $2$3$4', $list);
693  break;
694  case 'replace':
695  $newList = preg_replace($pattern, '$1' . $insertionList . '$4', $list);
696  break;
697  default:
698  }
699 
700  // When preg_replace did not replace anything; append the $insertionList.
701  if ($list === $newList) {
702  return $list . ', ' . $insertionList;
703  }
704  return $newList;
705  }
706 
722  protected static function ‪removeDuplicatesForInsertion($insertionList, $list = '')
723  {
724  $insertionListParts = preg_split('/\\s*,\\s*/', $insertionList);
725  $listMatches = [];
726  if ($list !== '') {
727  preg_match_all('/(?:^|,)\\s*\\b([^;,]+)\\b[^,]*/', $list, $listMatches);
728  $listMatches = $listMatches[1];
729  }
730 
731  $cleanInsertionListParts = [];
732  foreach ($insertionListParts as $fieldName) {
733  $fieldNameParts = explode(';', $fieldName, 2);
734  $cleanFieldName = $fieldNameParts[0];
735  if (
736  $cleanFieldName === '--linebreak--'
737  || (
738  !in_array($cleanFieldName, $cleanInsertionListParts, true)
739  && !in_array($cleanFieldName, $listMatches, true)
740  )
741  ) {
742  $cleanInsertionListParts[] = $fieldName;
743  }
744  }
745  return implode(', ', $cleanInsertionListParts);
746  }
747 
754  protected static function ‪explodeItemList($itemList)
755  {
756  $items = [];
757  $itemParts = GeneralUtility::trimExplode(',', $itemList, true);
758  foreach ($itemParts as $itemPart) {
759  $itemDetails = GeneralUtility::trimExplode(';', $itemPart, false, 5);
760  $key = $itemDetails[0];
761  if (strpos($key, '--') !== false) {
762  // If $key is a separator (--div--) or palette (--palette--) then it will be appended by a unique number. This must be removed again when using this value!
763  $key .= count($items);
764  }
765  if (!isset($items[$key])) {
766  $items[$key] = [
767  'rawData' => $itemPart,
768  'details' => []
769  ];
770  $details = [0 => 'field', 1 => 'label', 2 => 'palette'];
771  foreach ($details as $id => $property) {
772  $items[$key]['details'][$property] = $itemDetails[$id] ?? '';
773  }
774  }
775  }
776  return $items;
777  }
778 
787  protected static function ‪generateItemList(array $items, $useRawData = false)
788  {
789  $itemParts = [];
790  foreach ($items as $item => $itemDetails) {
791  if (strpos($item, '--') !== false) {
792  // If $item is a separator (--div--) or palette (--palette--) then it may have been appended by a unique number. This must be stripped away here.
793  $item = str_replace([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], '', $item);
794  }
795  if ($useRawData) {
796  $itemParts[] = $itemDetails['rawData'];
797  } else {
798  if (count($itemDetails['details']) > 1) {
799  $details = ['palette', 'label', 'field'];
800  $elements = [];
801  $addEmpty = false;
802  foreach ($details as $property) {
803  if ($itemDetails['details'][$property] !== '' || $addEmpty) {
804  $addEmpty = true;
805  array_unshift($elements, $itemDetails['details'][$property]);
806  }
807  }
808  $item = implode(';', $elements);
809  }
810  $itemParts[] = $item;
811  }
812  }
813  return implode(', ', $itemParts);
814  }
815 
823  public static function ‪allowTableOnStandardPages($table)
824  {
825  ‪$GLOBALS['PAGES_TYPES']['default']['allowedTables'] .= ',' . $table;
826  }
827 
836  public static function ‪configureModule($moduleSignature)
837  {
838  trigger_error('ExtensionManagementUtility::configureModule will be removed in TYPO3 v10.0, as the same functionality is found in addModule() as well.', E_USER_DEPRECATED);
839  $moduleConfiguration = ‪$GLOBALS['TBE_MODULES']['_configuration'][$moduleSignature];
840 
841  // Register the icon and move it too "iconIdentifier"
842  if (!empty($moduleConfiguration['icon'])) {
843  ‪$iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
844  $iconIdentifier = 'module-' . $moduleSignature;
845  $iconProvider = ‪$iconRegistry->detectIconProvider($moduleConfiguration['icon']);
846  ‪$iconRegistry->registerIcon(
847  $iconIdentifier,
848  $iconProvider,
849  ['source' => GeneralUtility::getFileAbsFileName($moduleConfiguration['icon'])]
850  );
851  $moduleConfiguration['iconIdentifier'] = $iconIdentifier;
852  unset($moduleConfiguration['icon']);
853  }
854 
855  return $moduleConfiguration;
856  }
857 
868  public static function ‪addModule($main, $sub = '', $position = '', $path = null, $moduleConfiguration = [])
869  {
870  if (($moduleConfiguration['navigationComponentId'] ?? '') === 'typo3-pagetree') {
871  trigger_error(
872  'Referencing the navigation component ID "typo3-pagetree" will be removed in TYPO3 v10.0.'
873  . 'Use "TYPO3/CMS/Backend/PageTree/PageTreeElement" instead. Module key: ' . $main . '-' . $sub,
874  E_USER_DEPRECATED
875  );
876  $moduleConfiguration['navigationComponentId'] = 'TYPO3/CMS/Backend/PageTree/PageTreeElement';
877  }
878 
879  // If there is already a main module by this name:
880  // Adding the submodule to the correct position:
881  if (isset(‪$GLOBALS['TBE_MODULES'][$main]) && $sub) {
882  list($place, $modRef) = array_pad(GeneralUtility::trimExplode(':', $position, true), 2, null);
883  $modules = ',' . ‪$GLOBALS['TBE_MODULES'][$main] . ',';
884  if ($place === null || ($modRef !== null && !GeneralUtility::inList($modules, $modRef))) {
885  $place = 'bottom';
886  }
887  $modRef = ',' . $modRef . ',';
888  if (!GeneralUtility::inList($modules, $sub)) {
889  switch (strtolower($place)) {
890  case 'after':
891  $modules = str_replace($modRef, $modRef . $sub . ',', $modules);
892  break;
893  case 'before':
894  $modules = str_replace($modRef, ',' . $sub . $modRef, $modules);
895  break;
896  case 'top':
897  $modules = $sub . $modules;
898  break;
899  case 'bottom':
900  default:
901  $modules = $modules . $sub;
902  }
903  }
904  // Re-inserting the submodule list:
905  ‪$GLOBALS['TBE_MODULES'][$main] = trim($modules, ',');
906  } else {
907  // Create new main modules with only one submodule, $sub (or none if $sub is blank)
908  ‪$GLOBALS['TBE_MODULES'][$main] = $sub;
909  }
910 
911  // add additional configuration
912  $fullModuleSignature = $main . ($sub ? '_' . $sub : '');
913  if (is_array($moduleConfiguration) && !empty($moduleConfiguration)) {
914  // remove default icon if an icon identifier is available
915  if (!empty($moduleConfiguration['iconIdentifier']) && $moduleConfiguration['icon'] === 'EXT:extbase/Resources/Public/Icons/Extension.png') {
916  unset($moduleConfiguration['icon']);
917  }
918  if (!empty($moduleConfiguration['icon'])) {
919  ‪$iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
920  $iconIdentifier = 'module-' . $fullModuleSignature;
921  $iconProvider = ‪$iconRegistry->detectIconProvider($moduleConfiguration['icon']);
922  ‪$iconRegistry->registerIcon(
923  $iconIdentifier,
924  $iconProvider,
925  ['source' => GeneralUtility::getFileAbsFileName($moduleConfiguration['icon'])]
926  );
927  $moduleConfiguration['iconIdentifier'] = $iconIdentifier;
928  unset($moduleConfiguration['icon']);
929  }
930 
931  ‪$GLOBALS['TBE_MODULES']['_configuration'][$fullModuleSignature] = $moduleConfiguration;
932  }
933 
934  // Also register the module as regular route
935  $routeName = $moduleConfiguration['id'] ?? $fullModuleSignature;
936  // Build Route objects from the data
937  $path = $moduleConfiguration['path'] ?? str_replace('_', '/', $fullModuleSignature);
938  $path = '/' . trim($path, '/') . '/';
939 
940  $options = [
941  'module' => true,
942  'moduleName' => $fullModuleSignature,
943  'access' => !empty($moduleConfiguration['access']) ? $moduleConfiguration['access'] : 'user,group'
944  ];
945  if (!empty($moduleConfiguration['routeTarget'])) {
946  $options['target'] = $moduleConfiguration['routeTarget'];
947  }
948 
949  $router = GeneralUtility::makeInstance(Router::class);
950  $router->addRoute($routeName, GeneralUtility::makeInstance(Route::class, $path, $options));
951  }
952 
967  public static function ‪insertModuleFunction($modname, $className, $_ = null, $title, $MM_key = 'function', $WS = '')
968  {
969  ‪$GLOBALS['TBE_MODULES_EXT'][$modname]['MOD_MENU'][$MM_key][$className] = [
970  'name' => $className,
971  'title' => $title,
972  'ws' => $WS
973  ];
974  }
975 
983  public static function ‪addPageTSConfig($content)
984  {
985  ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] .= '
986 [GLOBAL]
987 ' . $content;
988  }
989 
997  public static function ‪addUserTSConfig($content)
998  {
999  ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
1000 [GLOBAL]
1001 ' . $content;
1002  }
1003 
1012  public static function ‪addLLrefForTCAdescr($key, $file)
1013  {
1014  if (empty($key)) {
1015  throw new \RuntimeException('No description key set in addLLrefForTCAdescr(). Provide it as first parameter', 1507321596);
1016  }
1017  if (!is_array(‪$GLOBALS['TCA_DESCR'][$key] ?? false)) {
1018  ‪$GLOBALS['TCA_DESCR'][$key] = [];
1019  }
1020  if (!is_array(‪$GLOBALS['TCA_DESCR'][$key]['refs'] ?? false)) {
1021  ‪$GLOBALS['TCA_DESCR'][$key]['refs'] = [];
1022  }
1023  ‪$GLOBALS['TCA_DESCR'][$key]['refs'][] = $file;
1024  }
1025 
1034  public static function ‪addNavigationComponent($module, $componentId, $extensionKey)
1035  {
1036  if (empty($extensionKey)) {
1037  throw new \RuntimeException('No extensionKey set in addNavigationComponent(). Provide it as third parameter', 1404068039);
1038  }
1039  ‪$GLOBALS['TBE_MODULES']['_navigationComponents'][$module] = [
1040  'componentId' => $componentId,
1041  'extKey' => $extensionKey,
1042  'isCoreComponent' => false
1043  ];
1044  }
1045 
1052  public static function ‪addCoreNavigationComponent($module, $componentId)
1053  {
1054  ‪self::addNavigationComponent($module, $componentId, 'core');
1055  ‪$GLOBALS['TBE_MODULES']['_navigationComponents'][$module]['isCoreComponent'] = true;
1056  }
1057 
1058  /**************************************
1059  *
1060  * Adding SERVICES features
1061  *
1062  ***************************************/
1071  public static function ‪addService($extKey, $serviceType, $serviceKey, $info)
1072  {
1073  if (!$serviceType) {
1074  throw new \InvalidArgumentException('No serviceType given.', 1507321535);
1075  }
1076  if (!is_array($info)) {
1077  throw new \InvalidArgumentException('No information array given.', 1507321542);
1078  }
1079  $info['priority'] = max(0, min(100, $info['priority']));
1080  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey] = $info;
1081  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['extKey'] = $extKey;
1082  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceKey'] = $serviceKey;
1083  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceType'] = $serviceType;
1084  // Change the priority (and other values) from $GLOBALS['TYPO3_CONF_VARS']
1085  // $GLOBALS['TYPO3_CONF_VARS']['T3_SERVICES'][$serviceType][$serviceKey]['priority']
1086  // even the activation is possible (a unix service might be possible on windows for some reasons)
1087  if (is_array(‪$GLOBALS['TYPO3_CONF_VARS']['T3_SERVICES'][$serviceType][$serviceKey] ?? false)) {
1088  // No check is done here - there might be configuration values only the service type knows about, so
1089  // we pass everything
1090  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey] = array_merge(‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey], ‪$GLOBALS['TYPO3_CONF_VARS']['T3_SERVICES'][$serviceType][$serviceKey]);
1091  }
1092  // OS check
1093  // Empty $os means 'not limited to one OS', therefore a check is not needed
1094  if (‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['available'] && ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['os'] != '') {
1095  $os_type = ‪Environment::isWindows() ? 'WIN' : 'UNIX';
1096  $os = GeneralUtility::trimExplode(',', strtoupper(‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['os']));
1097  if (!in_array($os_type, $os, true)) {
1098  ‪self::deactivateService($serviceType, $serviceKey);
1099  }
1100  }
1101  // Convert subtype list to array for quicker access
1102  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceSubTypes'] = [];
1103  $serviceSubTypes = GeneralUtility::trimExplode(',', $info['subtype']);
1104  foreach ($serviceSubTypes as $subtype) {
1105  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['serviceSubTypes'][$subtype] = $subtype;
1106  }
1107  }
1108 
1117  public static function ‪findService($serviceType, $serviceSubType = '', $excludeServiceKeys = [])
1118  {
1119  $serviceKey = false;
1120  $serviceInfo = false;
1121  $priority = 0;
1122  $quality = 0;
1123  if (!is_array($excludeServiceKeys)) {
1124  $excludeServiceKeys = GeneralUtility::trimExplode(',', $excludeServiceKeys, true);
1125  }
1126  if (is_array(‪$GLOBALS['T3_SERVICES'][$serviceType])) {
1127  foreach (‪$GLOBALS['T3_SERVICES'][$serviceType] as $key => $info) {
1128  if (in_array($key, $excludeServiceKeys)) {
1129  continue;
1130  }
1131  // Select a subtype randomly
1132  // Useful to start a service by service key without knowing his subtypes - for testing purposes
1133  if ($serviceSubType === '*') {
1134  $serviceSubType = key($info['serviceSubTypes']);
1135  }
1136  // This matches empty subtype too
1137  if ($info['available'] && ($info['subtype'] == $serviceSubType || $info['serviceSubTypes'][$serviceSubType]) && $info['priority'] >= $priority) {
1138  // Has a lower quality than the already found, therefore we skip this service
1139  if ($info['priority'] == $priority && $info['quality'] < $quality) {
1140  continue;
1141  }
1142  // Check if the service is available
1143  $info['available'] = ‪self::isServiceAvailable($serviceType, $key, $info);
1144  // Still available after exec check?
1145  if ($info['available']) {
1146  $serviceKey = $key;
1147  $priority = $info['priority'];
1148  $quality = $info['quality'];
1149  }
1150  }
1151  }
1152  }
1153  if ($serviceKey) {
1154  $serviceInfo = ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey];
1155  }
1156  return $serviceInfo;
1157  }
1158 
1167  public static function ‪findServiceByKey($serviceKey)
1168  {
1169  if (is_array(‪$GLOBALS['T3_SERVICES'])) {
1170  // Loop on all service types
1171  // NOTE: we don't care about the actual type, we are looking for a specific key
1172  foreach (‪$GLOBALS['T3_SERVICES'] as $serviceType => $servicesPerType) {
1173  if (isset($servicesPerType[$serviceKey])) {
1174  $serviceDetails = $servicesPerType[$serviceKey];
1175  // Test if service is available
1176  if (self::isServiceAvailable($serviceType, $serviceKey, $serviceDetails)) {
1177  // We have found the right service, return its information
1178  return $serviceDetails;
1179  }
1180  }
1181  }
1182  }
1183  throw new \TYPO3\CMS\Core\Exception('Service not found for key: ' . $serviceKey, 1319217244);
1184  }
1185 
1194  public static function ‪isServiceAvailable($serviceType, $serviceKey, $serviceDetails)
1195  {
1196  // If the service depends on external programs - check if they exists
1197  if (trim($serviceDetails['exec'])) {
1198  $executables = GeneralUtility::trimExplode(',', $serviceDetails['exec'], true);
1199  foreach ($executables as $executable) {
1200  // If at least one executable file is not available, exit early returning FALSE
1201  if (!‪CommandUtility::checkCommand($executable)) {
1202  ‪self::deactivateService($serviceType, $serviceKey);
1203  return false;
1204  }
1205  }
1206  }
1207  // The service is available
1208  return true;
1209  }
1210 
1217  public static function ‪deactivateService($serviceType, $serviceKey)
1218  {
1219  // ... maybe it's better to move non-available services to a different array??
1220  ‪$GLOBALS['T3_SERVICES'][$serviceType][$serviceKey]['available'] = false;
1221  }
1222 
1223  /**************************************
1224  *
1225  * Adding FRONTEND features
1226  *
1227  ***************************************/
1241  public static function ‪addPlugin($itemArray, $type = 'list_type', $extensionKey = null)
1242  {
1243  if (!isset($extensionKey)) {
1244  throw new \InvalidArgumentException(
1245  'No extension key could be determined when calling addPlugin()!'
1246  . LF
1247  . 'This method is meant to be called from Configuration/TCA/Overrides files. '
1248  . 'The extension key needs to be specified as third parameter. '
1249  . 'Calling it from any other place e.g. ext_localconf.php does not work and is not supported.',
1250  1404068038
1251  );
1252  }
1253  if (!isset($itemArray[2]) || !$itemArray[2]) {
1254  // @todo do we really set $itemArray[2], even if we cannot find an icon? (as that means it's set to 'EXT:foobar/')
1255  $itemArray[2] = 'EXT:' . $extensionKey . '/' . static::getExtensionIcon(static::$packageManager->getPackage($extensionKey)->getPackagePath());
1256  }
1257  if (is_array(‪$GLOBALS['TCA']['tt_content']['columns']) && is_array(‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'])) {
1258  foreach (‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'] as $k => $v) {
1259  if ((string)$v[1] === (string)$itemArray[1]) {
1260  ‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'][$k] = $itemArray;
1261  return;
1262  }
1263  }
1264  ‪$GLOBALS['TCA']['tt_content']['columns'][$type]['config']['items'][] = $itemArray;
1265  }
1266  }
1267 
1278  public static function ‪addPiFlexFormValue($piKeyToMatch, $value, $CTypeToMatch = 'list')
1279  {
1280  if (is_array(‪$GLOBALS['TCA']['tt_content']['columns']) && is_array(‪$GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds'])) {
1281  ‪$GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds'][$piKeyToMatch . ',' . $CTypeToMatch] = $value;
1282  }
1283  }
1284 
1294  public static function ‪addToInsertRecords($table, $content_table = 'tt_content', $content_field = 'records')
1295  {
1296  if (is_array(‪$GLOBALS['TCA'][$content_table]['columns']) && isset(‪$GLOBALS['TCA'][$content_table]['columns'][$content_field]['config']['allowed'])) {
1297  ‪$GLOBALS['TCA'][$content_table]['columns'][$content_field]['config']['allowed'] .= ',' . $table;
1298  }
1299  }
1300 
1327  public static function ‪addPItoST43($key, $_ = '', $suffix = '', $type = 'list_type', $cacheable = false)
1328  {
1329  $cN = ‪self::getCN($key);
1330  // General plugin
1331  $pluginContent = trim('
1332 plugin.' . $cN . $suffix . ' = USER' . ($cacheable ? '' : '_INT') . '
1333 plugin.' . $cN . $suffix . '.userFunc = ' . $cN . $suffix . '->main
1334 ');
1335  ‪self::addTypoScript($key, 'setup', '
1336 # Setting ' . $key . ' plugin TypoScript
1337 ' . $pluginContent);
1338  // Add after defaultContentRendering
1339  switch ($type) {
1340  case 'list_type':
1341  $addLine = 'tt_content.list.20.' . $key . $suffix . ' = < plugin.' . $cN . $suffix;
1342  break;
1343  case 'menu_type':
1344  $addLine = 'tt_content.menu.20.' . $key . $suffix . ' = < plugin.' . $cN . $suffix;
1345  break;
1346  case 'CType':
1347  $addLine = trim('
1348 tt_content.' . $key . $suffix . ' =< lib.contentElement
1349 tt_content.' . $key . $suffix . ' {
1350  templateName = Generic
1351  20 =< plugin.' . $cN . $suffix . '
1352 }
1353 ');
1354  break;
1355  case 'header_layout':
1356  $addLine = 'lib.stdheader.10.' . $key . $suffix . ' = < plugin.' . $cN . $suffix;
1357  break;
1358  case 'includeLib':
1359  $addLine = 'page.1000 = < plugin.' . $cN . $suffix;
1360  break;
1361  default:
1362  $addLine = '';
1363  }
1364  if ($addLine) {
1365  ‪self::addTypoScript($key, 'setup', '
1366 # Setting ' . $key . ' plugin TypoScript
1367 ' . $addLine . '
1368 ', 'defaultContentRendering');
1369  }
1370  }
1371 
1382  public static function ‪addStaticFile($extKey, $path, $title)
1383  {
1384  if (!$extKey) {
1385  throw new \InvalidArgumentException('No extension key given.', 1507321291);
1386  }
1387  if (!$path) {
1388  throw new \InvalidArgumentException('No file path given.', 1507321297);
1389  }
1390  if (is_array(‪$GLOBALS['TCA']['sys_template']['columns'])) {
1391  $value = str_replace(',', '', 'EXT:' . $extKey . '/' . $path);
1392  $itemArray = [trim($title . ' (' . $extKey . ')'), $value];
1393  ‪$GLOBALS['TCA']['sys_template']['columns']['include_static_file']['config']['items'][] = $itemArray;
1394  }
1395  }
1396 
1406  public static function ‪registerPageTSConfigFile($extKey, $filePath, $title)
1407  {
1408  if (!$extKey) {
1409  throw new \InvalidArgumentException('No extension key given.', 1447789490);
1410  }
1411  if (!$filePath) {
1412  throw new \InvalidArgumentException('No file path given.', 1447789491);
1413  }
1414  if (!isset(‪$GLOBALS['TCA']['pages']['columns']) || !is_array(‪$GLOBALS['TCA']['pages']['columns'])) {
1415  throw new \InvalidArgumentException('No TCA definition for table "pages".', 1447789492);
1416  }
1417 
1418  $value = str_replace(',', '', 'EXT:' . $extKey . '/' . $filePath);
1419  $itemArray = [trim($title . ' (' . $extKey . ')'), $value];
1420  ‪$GLOBALS['TCA']['pages']['columns']['tsconfig_includes']['config']['items'][] = $itemArray;
1421  }
1422 
1430  public static function ‪addTypoScriptSetup($content)
1431  {
1432  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup'] .= '
1433 [GLOBAL]
1434 ' . $content;
1435  }
1436 
1444  public static function ‪addTypoScriptConstants($content)
1445  {
1446  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants'] .= '
1447 [GLOBAL]
1448 ' . $content;
1449  }
1450 
1468  public static function ‪addTypoScript(string $key, string $type, string $content, $afterStaticUid = 0)
1469  {
1470  if ($type !== 'setup' && $type !== 'constants') {
1471  throw new \InvalidArgumentException('Argument $type must be set to either "setup" or "constants" when calling addTypoScript from extension "' . $key . '"', 1507321200);
1472  }
1473  $content = '
1474 
1475 [GLOBAL]
1476 #############################################
1477 ## TypoScript added by extension "' . $key . '"
1478 #############################################
1479 
1480 ' . $content;
1481  if ($afterStaticUid) {
1482  // If 'content (default)' is targeted (static uid 43),
1483  // the content is added after typoscript of type contentRendering, eg. fluid_styled_content, see EXT:frontend/TemplateService for more information on how the code is parsed
1484  if ($afterStaticUid === 'defaultContentRendering' || $afterStaticUid == 43) {
1485  if (!isset(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.']['defaultContentRendering'])) {
1486  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.']['defaultContentRendering'] = '';
1487  }
1488  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.']['defaultContentRendering'] .= $content;
1489  } else {
1490  if (!isset(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.'][$afterStaticUid])) {
1491  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.'][$afterStaticUid] = '';
1492  }
1493  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.'][$afterStaticUid] .= $content;
1494  }
1495  } else {
1496  if (!isset(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type])) {
1497  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type] = '';
1498  }
1499  ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type] .= $content;
1500  }
1501  }
1502 
1503  /***************************************
1504  *
1505  * Internal extension management methods
1506  *
1507  ***************************************/
1516  public static function ‪getExtensionIcon($extensionPath, $returnFullPath = false)
1517  {
1518  $icon = '';
1519  $locationsToCheckFor = [
1520  'Resources/Public/Icons/Extension.svg',
1521  'Resources/Public/Icons/Extension.png',
1522  'Resources/Public/Icons/Extension.gif',
1523  'ext_icon.svg',
1524  'ext_icon.png',
1525  'ext_icon.gif',
1526  ];
1527  foreach ($locationsToCheckFor as $fileLocation) {
1528  if (file_exists($extensionPath . $fileLocation)) {
1529  $icon = $fileLocation;
1530  break;
1531  }
1532  }
1533  return $returnFullPath ? $extensionPath . $icon : $icon;
1534  }
1535 
1548  public static function ‪loadExtLocalconf($allowCaching = true, FrontendInterface $codeCache = null)
1549  {
1550  if ($allowCaching) {
1551  $codeCache = $codeCache ?? ‪self::getCacheManager()->‪getCache('cache_core');
1552  $cacheIdentifier = ‪self::getExtLocalconfCacheIdentifier();
1553  if ($codeCache->has($cacheIdentifier)) {
1554  $codeCache->require($cacheIdentifier);
1555  } else {
1558  }
1559  } else {
1561  }
1562  }
1563 
1567  protected static function ‪loadSingleExtLocalconfFiles()
1568  {
1569  // This is the main array meant to be manipulated in the ext_localconf.php files
1570  // In general it is recommended to not rely on it to be globally defined in that
1571  // scope but to use $GLOBALS['TYPO3_CONF_VARS'] instead.
1572  // Nevertheless we define it here as global for backwards compatibility.
1573  global $TYPO3_CONF_VARS;
1574  foreach (static::$packageManager->getActivePackages() as $package) {
1575  $extLocalconfPath = $package->getPackagePath() . 'ext_localconf.php';
1576  if (@file_exists($extLocalconfPath)) {
1577  // $_EXTKEY and $_EXTCONF are available in ext_localconf.php
1578  // and are explicitly set in cached file as well
1579  $_EXTKEY = $package->getPackageKey();
1580  $_EXTCONF = ‪$GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$_EXTKEY] ?? null;
1581  require $extLocalconfPath;
1582  }
1583  }
1584  }
1585 
1591  protected static function ‪createExtLocalconfCacheEntry(FrontendInterface $codeCache)
1592  {
1593  $phpCodeToCache = [];
1594  // Set same globals as in loadSingleExtLocalconfFiles()
1595  $phpCodeToCache[] = '';
1598  $phpCodeToCache[] = '';
1599  $phpCodeToCache[] = 'global $TYPO3_CONF_VARS, $T3_SERVICES, $T3_VAR;';
1600  $phpCodeToCache[] = '';
1601  // Iterate through loaded extensions and add ext_localconf content
1602  foreach (static::$packageManager->getActivePackages() as $package) {
1603  $extensionKey = $package->getPackageKey();
1604  $extLocalconfPath = $package->getPackagePath() . 'ext_localconf.php';
1605  if (@file_exists($extLocalconfPath)) {
1606  // Include a header per extension to make the cache file more readable
1607  $phpCodeToCache[] = '';
1611  $phpCodeToCache[] = '';
1612  // Set $_EXTKEY and $_EXTCONF for this extension
1613  $phpCodeToCache[] = '$_EXTKEY = \'' . $extensionKey . '\';';
1614  $phpCodeToCache[] = '$_EXTCONF = ‪$GLOBALS[\'TYPO3_CONF_VARS\'][\'EXT\'][\'extConf\'][$_EXTKEY] ?? null;';
1615  $phpCodeToCache[] = '';
1616  // Add ext_localconf.php content of extension
1617  $phpCodeToCache[] = trim(file_get_contents($extLocalconfPath));
1618  $phpCodeToCache[] = '';
1619  $phpCodeToCache[] = '';
1620  }
1621  }
1622  $phpCodeToCache = implode(LF, $phpCodeToCache);
1623  // Remove all start and ending php tags from content
1624  $phpCodeToCache = preg_replace('/<\\?php|\\?>/is', '', $phpCodeToCache);
1625  $codeCache->set(self::getExtLocalconfCacheIdentifier(), $phpCodeToCache);
1626  }
1627 
1633  protected static function ‪getExtLocalconfCacheIdentifier()
1634  {
1635  return 'ext_localconf_' . sha1(TYPO3_version . ‪Environment::getProjectPath() . 'extLocalconf' . serialize(‪$GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages']));
1636  }
1637 
1651  public static function ‪loadBaseTca($allowCaching = true, FrontendInterface $codeCache = null)
1652  {
1653  if ($allowCaching) {
1654  $codeCache = $codeCache ?? ‪self::getCacheManager()->‪getCache('cache_core');
1655  $cacheIdentifier = static::getBaseTcaCacheIdentifier();
1656  $cacheData = $codeCache->require($cacheIdentifier);
1657  if ($cacheData) {
1658  ‪$GLOBALS['TCA'] = $cacheData['tca'];
1659  GeneralUtility::setSingletonInstance(
1660  CategoryRegistry::class,
1661  unserialize(
1662  $cacheData['categoryRegistry'],
1663  ['allowed_classes' => [CategoryRegistry::class]]
1664  )
1665  );
1666  } else {
1667  static::buildBaseTcaFromSingleFiles();
1668  static::createBaseTcaCacheFile($codeCache);
1669  }
1670  } else {
1671  static::buildBaseTcaFromSingleFiles();
1672  }
1673  }
1674 
1682  protected static function ‪buildBaseTcaFromSingleFiles()
1683  {
1684  ‪$GLOBALS['TCA'] = [];
1685 
1686  $activePackages = static::$packageManager->getActivePackages();
1687 
1688  // First load "full table" files from Configuration/TCA
1689  foreach ($activePackages as $package) {
1690  try {
1691  ‪$finder = Finder::create()->files()->sortByName()->depth(0)->name('*.php')->in($package->getPackagePath() . 'Configuration/TCA');
1692  } catch (\InvalidArgumentException $e) {
1693  // No such directory in this package
1694  continue;
1695  }
1696  foreach (‪$finder as $fileInfo) {
1697  $tcaOfTable = require $fileInfo->getPathname();
1698  if (is_array($tcaOfTable)) {
1699  $tcaTableName = substr($fileInfo->getBasename(), 0, -4);
1700  ‪$GLOBALS['TCA'][$tcaTableName] = $tcaOfTable;
1701  }
1702  }
1703  }
1704 
1705  // Apply category stuff
1707 
1708  // Execute override files from Configuration/TCA/Overrides
1709  foreach ($activePackages as $package) {
1710  try {
1711  ‪$finder = Finder::create()->files()->sortByName()->depth(0)->name('*.php')->in($package->getPackagePath() . 'Configuration/TCA/Overrides');
1712  } catch (\InvalidArgumentException $e) {
1713  // No such directory in this package
1714  continue;
1715  }
1716  foreach (‪$finder as $fileInfo) {
1717  require $fileInfo->getPathname();
1718  }
1719  }
1720 
1721  // TCA migration
1722  // @deprecated since TYPO3 CMS 7. Not removed in TYPO3 CMS 8 though. This call will stay for now to allow further TCA migrations in 8.
1723  $tcaMigration = GeneralUtility::makeInstance(TcaMigration::class);
1724  ‪$GLOBALS['TCA'] = $tcaMigration->migrate(‪$GLOBALS['TCA']);
1725  $messages = $tcaMigration->getMessages();
1726  if (!empty($messages)) {
1727  $context = 'Automatic TCA migration done during bootstrap. Please adapt TCA accordingly, these migrations'
1728  . ' will be removed. The backend module "Configuration -> TCA" shows the modified values.'
1729  . ' Please adapt these areas:';
1730  array_unshift($messages, $context);
1731  trigger_error(implode(LF, $messages), E_USER_DEPRECATED);
1732  }
1733 
1734  // TCA preparation
1735  $tcaPreparation = GeneralUtility::makeInstance(TcaPreparation::class);
1736  ‪$GLOBALS['TCA'] = $tcaPreparation->prepare(‪$GLOBALS['TCA']);
1737 
1738  static::emitTcaIsBeingBuiltSignal(‪$GLOBALS['TCA']);
1739  }
1740 
1751  protected static function ‪emitTcaIsBeingBuiltSignal(array ‪$tca)
1752  {
1753  list(‪$tca) = static::getSignalSlotDispatcher()->dispatch(__CLASS__, 'tcaIsBeingBuilt', [‪$tca]);
1754  ‪$GLOBALS['TCA'] = ‪$tca;
1755  }
1756 
1763  protected static function ‪createBaseTcaCacheFile(FrontendInterface $codeCache)
1764  {
1765  $codeCache->set(
1766  static::getBaseTcaCacheIdentifier(),
1767  'return '
1768  . var_export(['tca' => ‪$GLOBALS['TCA'], 'categoryRegistry' => serialize(‪CategoryRegistry::getInstance())], true)
1769  . ';'
1770  );
1771  }
1772 
1778  protected static function ‪getBaseTcaCacheIdentifier()
1779  {
1780  return 'tca_base_' . sha1(TYPO3_version . ‪Environment::getProjectPath() . 'tca_code' . serialize(‪$GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages']));
1781  }
1782 
1794  public static function ‪loadExtTables($allowCaching = true)
1795  {
1796  if ($allowCaching && !self::$extTablesWasReadFromCacheOnce) {
1797  self::$extTablesWasReadFromCacheOnce = true;
1798  $cacheIdentifier = ‪self::getExtTablesCacheIdentifier();
1800  $codeCache = ‪self::getCacheManager()->‪getCache('cache_core');
1801  if ($codeCache->has($cacheIdentifier)) {
1802  $codeCache->require($cacheIdentifier);
1803  } else {
1806  }
1807  } else {
1809  }
1810  }
1811 
1815  protected static function ‪loadSingleExtTablesFiles()
1816  {
1817  // In general it is recommended to not rely on it to be globally defined in that
1818  // scope, but we can not prohibit this without breaking backwards compatibility
1819  global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
1820  global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
1821  global $PAGES_TYPES, $TBE_STYLES;
1822  global $_EXTKEY;
1823  // Load each ext_tables.php file of loaded extensions
1824  foreach (static::$packageManager->getActivePackages() as $package) {
1825  $extTablesPath = $package->getPackagePath() . 'ext_tables.php';
1826  if (@file_exists($extTablesPath)) {
1827  // $_EXTKEY and $_EXTCONF are available in ext_tables.php
1828  // and are explicitly set in cached file as well
1829  $_EXTKEY = $package->getPackageKey();
1830  $_EXTCONF = ‪$GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$_EXTKEY] ?? null;
1831  require $extTablesPath;
1832  }
1833  }
1834  }
1835 
1839  protected static function ‪createExtTablesCacheEntry()
1840  {
1841  $phpCodeToCache = [];
1842  // Set same globals as in loadSingleExtTablesFiles()
1843  $phpCodeToCache[] = '';
1846  $phpCodeToCache[] = '';
1847  $phpCodeToCache[] = 'global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;';
1848  $phpCodeToCache[] = 'global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;';
1849  $phpCodeToCache[] = 'global $PAGES_TYPES, $TBE_STYLES;';
1850  $phpCodeToCache[] = 'global $_EXTKEY;';
1851  $phpCodeToCache[] = '';
1852  // Iterate through loaded extensions and add ext_tables content
1853  foreach (static::$packageManager->getActivePackages() as $package) {
1854  $extensionKey = $package->getPackageKey();
1855  $extTablesPath = $package->getPackagePath() . 'ext_tables.php';
1856  if (@file_exists($extTablesPath)) {
1857  // Include a header per extension to make the cache file more readable
1858  $phpCodeToCache[] = '';
1862  $phpCodeToCache[] = '';
1863  // Set $_EXTKEY and $_EXTCONF for this extension
1864  $phpCodeToCache[] = '$_EXTKEY = \'' . $extensionKey . '\';';
1865  $phpCodeToCache[] = '$_EXTCONF = ‪$GLOBALS[\'TYPO3_CONF_VARS\'][\'EXT\'][\'extConf\'][$_EXTKEY] ?? null;';
1866  $phpCodeToCache[] = '';
1867  // Add ext_tables.php content of extension
1868  $phpCodeToCache[] = trim(file_get_contents($extTablesPath));
1869  $phpCodeToCache[] = '';
1870  }
1871  }
1872  $phpCodeToCache = implode(LF, $phpCodeToCache);
1873  // Remove all start and ending php tags from content
1874  $phpCodeToCache = preg_replace('/<\\?php|\\?>/is', '', $phpCodeToCache);
1875  ‪self::getCacheManager()->‪getCache('cache_core')->‪set(self::getExtTablesCacheIdentifier(), $phpCodeToCache);
1876  }
1877 
1883  protected static function ‪getExtTablesCacheIdentifier()
1884  {
1885  return 'ext_tables_' . sha1(TYPO3_version . ‪Environment::getProjectPath() . 'extTables' . serialize(‪$GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages']));
1886  }
1887 
1903  public static function ‪removeCacheFiles()
1904  {
1905  trigger_error('ExtensionManagementUtility::removeCacheFiles() will be removed in TYPO3 v10.0. Use CacheManager directly to flush all system caches.', E_USER_DEPRECATED);
1907  }
1908 
1914  public static function ‪getLoadedExtensionListArray()
1915  {
1916  return array_keys(static::$packageManager->getActivePackages());
1917  }
1918 
1928  public static function ‪loadExtension($extensionKey)
1929  {
1930  if (static::$packageManager->isPackageActive($extensionKey)) {
1931  throw new \RuntimeException('Extension already loaded', 1342345486);
1932  }
1933  static::$packageManager->activatePackage($extensionKey);
1934  }
1935 
1945  public static function ‪unloadExtension($extensionKey)
1946  {
1947  if (!static::$packageManager->isPackageActive($extensionKey)) {
1948  throw new \RuntimeException('Extension not loaded', 1342345487);
1949  }
1950  static::$packageManager->deactivatePackage($extensionKey);
1951  }
1952 
1965  public static function ‪makeCategorizable($extensionKey, $tableName, $fieldName = 'categories', array $options = [], $override = false)
1966  {
1967  // Update the category registry
1968  $result = ‪CategoryRegistry::getInstance()->‪add($extensionKey, $tableName, $fieldName, $options, $override);
1969  if ($result === false) {
1970  GeneralUtility::makeInstance(LogManager::class)
1971  ->getLogger(__CLASS__)
1972  ->warning(sprintf(
1973  CategoryRegistry::class . ': no category registered for table "%s". Key was already registered.',
1974  $tableName
1975  ));
1976  }
1977  }
1978 }
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\removeCacheFiles
‪static removeCacheFiles()
Definition: ExtensionManagementUtility.php:1898
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTypoScriptConstants
‪static addTypoScriptConstants($content)
Definition: ExtensionManagementUtility.php:1439
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addModule
‪static addModule($main, $sub='', $position='', $path=null, $moduleConfiguration=[])
Definition: ExtensionManagementUtility.php:863
‪TYPO3\CMS\Core\Migrations\TcaMigration
Definition: TcaMigration.php:27
‪TYPO3\CMS\Core\Cache\CacheManager\getCache
‪FrontendInterface getCache($identifier)
Definition: CacheManager.php:129
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtTablesCacheIdentifier
‪static string getExtTablesCacheIdentifier()
Definition: ExtensionManagementUtility.php:1878
‪TYPO3\CMS\Extbase\Annotation
Definition: IgnoreValidation.php:4
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\unloadExtension
‪static unloadExtension($extensionKey)
Definition: ExtensionManagementUtility.php:1940
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getCacheManager
‪static TYPO3 CMS Core Cache CacheManager getCacheManager()
Definition: ExtensionManagementUtility.php:77
‪TYPO3\CMS\Core\Utility\CommandUtility\checkCommand
‪static bool checkCommand($cmd, $handler='')
Definition: CommandUtility.php:159
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTypoScriptSetup
‪static addTypoScriptSetup($content)
Definition: ExtensionManagementUtility.php:1425
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\configureModule
‪static array configureModule($moduleSignature)
Definition: ExtensionManagementUtility.php:831
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getFileFieldTCAConfig
‪static array getFileFieldTCAConfig($fieldName, array $customSettingOverride=[], $allowedFileExtensions='', $disallowedFileExtensions='')
Definition: ExtensionManagementUtility.php:562
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$signalSlotDispatcher
‪static TYPO3 CMS Extbase SignalSlot Dispatcher $signalSlotDispatcher
Definition: ExtensionManagementUtility.php:87
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$cacheManager
‪static TYPO3 CMS Core Cache CacheManager $cacheManager
Definition: ExtensionManagementUtility.php:70
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:371
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\allowTableOnStandardPages
‪static allowTableOnStandardPages($table)
Definition: ExtensionManagementUtility.php:818
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\insertModuleFunction
‪static insertModuleFunction($modname, $className, $_=null, $title, $MM_key='function', $WS='')
Definition: ExtensionManagementUtility.php:962
‪TYPO3
‪$finder
‪$finder
Definition: annotationChecker.php:102
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\createExtLocalconfCacheEntry
‪static createExtLocalconfCacheEntry(FrontendInterface $codeCache)
Definition: ExtensionManagementUtility.php:1586
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadExtension
‪static loadExtension($extensionKey)
Definition: ExtensionManagementUtility.php:1923
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadSingleExtLocalconfFiles
‪static loadSingleExtLocalconfFiles()
Definition: ExtensionManagementUtility.php:1562
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToPalette
‪static addFieldsToPalette($table, $palette, $addFields, $insertionPosition='')
Definition: ExtensionManagementUtility.php:462
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTcaSelectItem
‪static addTcaSelectItem($table, $field, array $item, $relativeToField='', $relativePosition='')
Definition: ExtensionManagementUtility.php:503
‪TYPO3\CMS\Core\Core\Environment\isWindows
‪static bool isWindows()
Definition: Environment.php:266
‪TYPO3\CMS\Core\Utility
Definition: ArrayUtility.php:2
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\findService
‪static mixed findService($serviceType, $serviceSubType='', $excludeServiceKeys=[])
Definition: ExtensionManagementUtility.php:1112
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getBaseTcaCacheIdentifier
‪static string getBaseTcaCacheIdentifier()
Definition: ExtensionManagementUtility.php:1773
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPlugin
‪static addPlugin($itemArray, $type='list_type', $extensionKey=null)
Definition: ExtensionManagementUtility.php:1236
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addToAllTCAtypes
‪static addToAllTCAtypes($table, $newFieldsString, $typeList='', $position='')
Definition: ExtensionManagementUtility.php:281
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTCAcolumns
‪static addTCAcolumns($table, $columnArray)
Definition: ExtensionManagementUtility.php:260
‪TYPO3\CMS\Core\Utility\ArrayUtility\mergeRecursiveWithOverrule
‪static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
Definition: ArrayUtility.php:614
‪TYPO3\CMS\Backend\Routing\Route
Definition: Route.php:23
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPItoST43
‪static addPItoST43($key, $_='', $suffix='', $type='list_type', $cacheable=false)
Definition: ExtensionManagementUtility.php:1322
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\createExtTablesCacheEntry
‪static createExtTablesCacheEntry()
Definition: ExtensionManagementUtility.php:1834
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isServiceAvailable
‪static bool isServiceAvailable($serviceType, $serviceKey, $serviceDetails)
Definition: ExtensionManagementUtility.php:1189
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToAllPalettesOfField
‪static addFieldsToAllPalettesOfField($table, $field, $addFields, $insertionPosition='')
Definition: ExtensionManagementUtility.php:409
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:36
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPiFlexFormValue
‪static addPiFlexFormValue($piKeyToMatch, $value, $CTypeToMatch='list')
Definition: ExtensionManagementUtility.php:1273
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\makeCategorizable
‪static makeCategorizable($extensionKey, $tableName, $fieldName='categories', array $options=[], $override=false)
Definition: ExtensionManagementUtility.php:1960
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getSignalSlotDispatcher
‪static TYPO3 CMS Extbase SignalSlot Dispatcher getSignalSlotDispatcher()
Definition: ExtensionManagementUtility.php:94
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\generateItemList
‪static string generateItemList(array $items, $useRawData=false)
Definition: ExtensionManagementUtility.php:782
‪TYPO3\CMS\Core\Category\CategoryRegistry\getInstance
‪static CategoryRegistry getInstance()
Definition: CategoryRegistry.php:50
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\clearExtensionKeyMap
‪static clearExtensionKeyMap()
Definition: ExtensionManagementUtility.php:214
‪TYPO3\CMS\Core\Core\Environment\getProjectPath
‪static string getProjectPath()
Definition: Environment.php:142
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$extTablesWasReadFromCacheOnce
‪static bool $extTablesWasReadFromCacheOnce
Definition: ExtensionManagementUtility.php:50
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\deactivateService
‪static deactivateService($serviceType, $serviceKey)
Definition: ExtensionManagementUtility.php:1212
‪TYPO3\CMS\Core\Category\CategoryRegistry
Definition: CategoryRegistry.php:27
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\explodeItemList
‪static array explodeItemList($itemList)
Definition: ExtensionManagementUtility.php:749
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\setPackageManager
‪static setPackageManager(PackageManager $packageManager)
Definition: ExtensionManagementUtility.php:63
‪TYPO3\CMS\Core\Utility\ArrayUtility\filterByValueRecursive
‪static array filterByValueRecursive($needle='', array $haystack=[])
Definition: ArrayUtility.php:103
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtensionVersion
‪static string getExtensionVersion($key)
Definition: ExtensionManagementUtility.php:229
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addUserTSConfig
‪static addUserTSConfig($content)
Definition: ExtensionManagementUtility.php:992
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addStaticFile
‪static addStaticFile($extKey, $path, $title)
Definition: ExtensionManagementUtility.php:1377
‪TYPO3\CMS\Core\Preparations\TcaPreparation
Definition: TcaPreparation.php:28
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addLLrefForTCAdescr
‪static addLLrefForTCAdescr($key, $file)
Definition: ExtensionManagementUtility.php:1007
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\executePositionedStringInsertion
‪static string executePositionedStringInsertion($list, $insertionList, $insertionPosition='')
Definition: ExtensionManagementUtility.php:648
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadSingleExtTablesFiles
‪static loadSingleExtTablesFiles()
Definition: ExtensionManagementUtility.php:1810
‪TYPO3\CMS\Core\Imaging\IconRegistry
Definition: IconRegistry.php:34
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key, $exitOnError=null)
Definition: ExtensionManagementUtility.php:115
‪TYPO3\CMS\Core\Cache\CacheManager\flushCachesInGroup
‪flushCachesInGroup($groupIdentifier)
Definition: CacheManager.php:168
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getCN
‪static string getCN($key)
Definition: ExtensionManagementUtility.php:179
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$packageManager
‪static PackageManager $packageManager
Definition: ExtensionManagementUtility.php:54
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\registerPageTSConfigFile
‪static registerPageTSConfigFile($extKey, $filePath, $title)
Definition: ExtensionManagementUtility.php:1401
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\findServiceByKey
‪static array findServiceByKey($serviceKey)
Definition: ExtensionManagementUtility.php:1162
‪TYPO3\CMS\Core\Category\CategoryRegistry\add
‪bool add($extensionKey, $tableName, $fieldName='categories', array $options=[], $override=false)
Definition: CategoryRegistry.php:83
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:21
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\siteRelPath
‪static string siteRelPath($key)
Definition: ExtensionManagementUtility.php:166
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addTypoScript
‪static addTypoScript(string $key, string $type, string $content, $afterStaticUid=0)
Definition: ExtensionManagementUtility.php:1463
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Log\LogManager
Definition: LogManager.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:39
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addPageTSConfig
‪static addPageTSConfig($content)
Definition: ExtensionManagementUtility.php:978
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadExtTables
‪static loadExtTables($allowCaching=true)
Definition: ExtensionManagementUtility.php:1789
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addFieldsToUserSettings
‪static addFieldsToUserSettings($addFields, $insertionPosition='')
Definition: ExtensionManagementUtility.php:626
‪$tca
‪$tca
Definition: sys_file_metadata.php:4
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\emitTcaIsBeingBuiltSignal
‪static emitTcaIsBeingBuiltSignal(array $tca)
Definition: ExtensionManagementUtility.php:1746
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\createBaseTcaCacheFile
‪static createBaseTcaCacheFile(FrontendInterface $codeCache)
Definition: ExtensionManagementUtility.php:1758
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static string extPath($key, $script='')
Definition: ExtensionManagementUtility.php:149
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadBaseTca
‪static loadBaseTca($allowCaching=true, FrontendInterface $codeCache=null)
Definition: ExtensionManagementUtility.php:1646
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getLoadedExtensionListArray
‪static array getLoadedExtensionListArray()
Definition: ExtensionManagementUtility.php:1909
‪TYPO3\CMS\Core\Category\CategoryRegistry\applyTcaForPreRegisteredTables
‪applyTcaForPreRegisteredTables()
Definition: CategoryRegistry.php:223
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtLocalconfCacheIdentifier
‪static string getExtLocalconfCacheIdentifier()
Definition: ExtensionManagementUtility.php:1628
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtensionKeyByPrefix
‪static mixed getExtensionKeyByPrefix($prefix)
Definition: ExtensionManagementUtility.php:191
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface\set
‪set($entryIdentifier, $data, array $tags=[], $lifetime=null)
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtensionIcon
‪static string getExtensionIcon($extensionPath, $returnFullPath=false)
Definition: ExtensionManagementUtility.php:1511
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addNavigationComponent
‪static addNavigationComponent($module, $componentId, $extensionKey)
Definition: ExtensionManagementUtility.php:1029
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\loadExtLocalconf
‪static loadExtLocalconf($allowCaching=true, FrontendInterface $codeCache=null)
Definition: ExtensionManagementUtility.php:1543
‪TYPO3\CMS\Backend\Routing\Router
Definition: Router.php:32
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addToInsertRecords
‪static addToInsertRecords($table, $content_table='tt_content', $content_field='records')
Definition: ExtensionManagementUtility.php:1289
‪$iconRegistry
‪$iconRegistry
Definition: ext_localconf.php:76
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\$extensionKeyMap
‪static array $extensionKeyMap
Definition: ExtensionManagementUtility.php:39
‪$signalSlotDispatcher
‪$signalSlotDispatcher
Definition: ext_localconf.php:6
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\removeDuplicatesForInsertion
‪static string removeDuplicatesForInsertion($insertionList, $list='')
Definition: ExtensionManagementUtility.php:717
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addService
‪static addService($extKey, $serviceType, $serviceKey, $info)
Definition: ExtensionManagementUtility.php:1066
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\buildBaseTcaFromSingleFiles
‪static buildBaseTcaFromSingleFiles()
Definition: ExtensionManagementUtility.php:1677
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\addCoreNavigationComponent
‪static addCoreNavigationComponent($module, $componentId)
Definition: ExtensionManagementUtility.php:1047