2 namespace TYPO3\CMS\Core\Utility;
75 if (static::$cacheManager === null) {
78 return static::$cacheManager;
112 public static function isLoaded($key, $exitOnError =
false)
114 $isLoaded = static::$packageManager->isPackageActive($key);
115 if ($exitOnError && !$isLoaded) {
116 throw new \BadFunctionCallException(
'TYPO3 Fatal Error: Extension "' . $key .
'" is not loaded!', 1270853910);
129 public static function extPath($key, $script =
'')
131 if (!static::$packageManager->isPackageActive($key)) {
132 throw new \BadFunctionCallException(
'TYPO3 Fatal Error: Extension key "' . $key .
'" is NOT loaded!', 1365429656);
134 return static::$packageManager->getPackage($key)->getPackagePath() . $script;
149 if (!static::$packageManager->isPackageActive($key)) {
150 throw new \BadFunctionCallException(
'TYPO3 Fatal Error: Extension key "' . $key .
'" is NOT loaded!', 1365429673);
152 $relativePathToSiteRoot = self::siteRelPath($key);
153 $typo3MainDirLength = strlen(TYPO3_mainDir);
154 if (substr($relativePathToSiteRoot, 0, $typo3MainDirLength) === TYPO3_mainDir) {
155 $relativePathToSiteRoot = substr($relativePathToSiteRoot, $typo3MainDirLength);
157 $relativePathToSiteRoot =
'../' . $relativePathToSiteRoot;
159 return $relativePathToSiteRoot;
184 return strpos($key,
'user_') === 0 ?
'user_' . str_replace(
'_',
'', substr($key, 5)) :
'tx_' . str_replace(
'_',
'', $key);
197 if (!isset(self::$extensionKeyMap)) {
198 self::$extensionKeyMap = array();
199 foreach (static::$packageManager->getActivePackages() as $package) {
200 $shortKey = str_replace(
'_',
'', $package->getPackageKey());
201 self::$extensionKeyMap[$shortKey] = $package->getPackageKey();
205 $parts = explode(
'_', $prefix);
206 if (isset(self::$extensionKeyMap[$parts[1]])) {
207 $result = self::$extensionKeyMap[$parts[1]];
219 self::$extensionKeyMap = null;
234 if (!is_string($key) || empty($key)) {
235 throw new \InvalidArgumentException(
'Extension key must be a non-empty string.', 1294586096);
237 if (!static::isLoaded($key)) {
240 $version = static::$packageManager->getPackage($key)->getPackageMetaData()->getVersion();
241 if (empty($version)) {
242 throw new \TYPO3\CMS\Core\Package\Exception(
'Version number in composer manifest of package "' . $key .
'" is missing or invalid', 1395614959);
265 public static function addTCAcolumns($table, $columnArray, $addTofeInterface =
false)
267 if (is_array($columnArray) && is_array(
$GLOBALS[
'TCA'][$table]) && is_array(
$GLOBALS[
'TCA'][$table][
'columns'])) {
269 $GLOBALS[
'TCA'][$table][
'columns'] = array_merge(
$GLOBALS[
'TCA'][$table][
'columns'], $columnArray);
270 if ($addTofeInterface) {
272 'Usage of feInterface is no longer part of the TYPO3 CMS Core. Please check EXT:' .
$GLOBALS[
'_EXTKEY'] .
'.'
292 public static function addToAllTCAtypes($table, $newFieldsString, $typeList =
'', $position =
'')
294 $newFieldsString = trim($newFieldsString);
295 if ($newFieldsString ===
'' || !is_array(
$GLOBALS[
'TCA'][$table][
'types'])) {
299 $palettesChanged = array();
301 foreach (
$GLOBALS[
'TCA'][$table][
'types'] as $type => &$typeDetails) {
307 if (!isset($typeDetails[
'showitem']) || strpos($typeDetails[
'showitem'], $newFieldsString) !==
false) {
311 $fieldExists =
false;
313 if (is_array(
$GLOBALS[
'TCA'][$table][
'palettes'])) {
315 $paletteCount = preg_match_all(
'/(?:^|,) # Line start or a comma
317 \\s*\\-\\-palette\\-\\-;[^;]*;([^,$]*)| # --palette--;label;paletteName
318 \\s*\\b[^;,]+\\b(?:;[^;]*;([^;,]+);?[^;,]*;?)?[^,]* # @deprecated since TYPO3 CMS 7: field;label;paletteName[;options[;colors]]
319 )/x', $typeDetails[
'showitem'], $paletteMatches);
320 if ($paletteCount > 0) {
321 $paletteNames = array_filter(array_merge($paletteMatches[1], $paletteMatches[2]));
322 if (!empty($paletteNames)) {
323 foreach ($paletteNames as $paletteName) {
324 $palette =
$GLOBALS[
'TCA'][$table][
'palettes'][$paletteName];
325 switch ($positionIdentifier) {
328 if (preg_match(
'/\\b' . $entityName .
'\\b/', $palette[
'showitem']) > 0) {
329 $newPosition = $positionIdentifier .
':--palette--;;' . $paletteName;
334 if (isset($palettesChanged[$paletteName])) {
338 if (preg_match(
'/\\b' . $entityName .
'\\b/', $palette[
'showitem']) > 0) {
339 self::addFieldsToPalette($table, $paletteName, $newFieldsString, $position);
341 $palettesChanged[$paletteName] =
true;
353 if ($fieldExists ===
false) {
354 $typeDetails[
'showitem'] = self::executePositionedStringInsertion(
355 $typeDetails[
'showitem'],
357 $newPosition !==
'' ? $newPosition : $position
409 if (!isset(
$GLOBALS[
'TCA'][$table][
'columns'][$field])) {
412 if (!is_array(
$GLOBALS[
'TCA'][$table][
'types'])) {
417 foreach (
$GLOBALS[
'TCA'][$table][
'types'] as $typeName => $typeArray) {
419 if (!isset($typeArray[
'showitem']) || strpos($typeArray[
'showitem'], $field) ===
false) {
424 $newFieldStringArray = array();
425 foreach ($fieldArrayWithOptions as $fieldNumber => $fieldString) {
426 $newFieldStringArray[] = $fieldString;
428 if ($fieldArray[0] !== $field) {
432 isset($fieldArrayWithOptions[$fieldNumber + 1])
437 $paletteName = $paletteName[2];
438 self::addFieldsToPalette($table, $paletteName, $addFields, $insertionPosition);
441 $newPaletteName =
'generatedFor-' . $field;
442 self::addFieldsToPalette($table,
'generatedFor-' . $field, $addFields, $insertionPosition);
443 $newFieldStringArray[] =
'--palette--;;' . $newPaletteName;
446 $GLOBALS[
'TCA'][$table][
'types'][$typeName][
'showitem'] = implode(
', ', $newFieldStringArray);
462 if (isset(
$GLOBALS[
'TCA'][$table])) {
463 $paletteData = &
$GLOBALS[
'TCA'][$table][
'palettes'][$palette];
465 if (is_array($paletteData)) {
466 $paletteData[
'showitem'] = self::executePositionedStringInsertion($paletteData[
'showitem'], $addFields, $insertionPosition);
468 $paletteData[
'showitem'] = self::removeDuplicatesForInsertion($addFields);
501 public static function addTcaSelectItem($table, $field, array $item, $relativeToField =
'', $relativePosition =
'')
503 if (!is_string($table)) {
504 throw new \InvalidArgumentException(
'Given table is of type "' . gettype($table) .
'" but a string is expected.', 1303236963);
506 if (!is_string($field)) {
507 throw new \InvalidArgumentException(
'Given field is of type "' . gettype($field) .
'" but a string is expected.', 1303236964);
509 if (!is_string($relativeToField)) {
510 throw new \InvalidArgumentException(
'Given relative field is of type "' . gettype($relativeToField) .
'" but a string is expected.', 1303236965);
512 if (!is_string($relativePosition)) {
513 throw new \InvalidArgumentException(
'Given relative position is of type "' . gettype($relativePosition) .
'" but a string is expected.', 1303236966);
515 if ($relativePosition !==
'' && $relativePosition !==
'before' && $relativePosition !==
'after' && $relativePosition !==
'replace') {
516 throw new \InvalidArgumentException(
'Relative position must be either empty or one of "before", "after", "replace".', 1303236967);
518 if (!is_array(
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'items'])) {
519 throw new \RuntimeException(
'Given select field item list was not found.', 1303237468);
522 $GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'items'] = array_values(
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'items']);
523 if ($relativePosition !==
'') {
526 if (!empty($matchedPosition)) {
527 $relativeItemKey = key($matchedPosition);
528 if ($relativePosition ===
'replace') {
529 $GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'items'][$relativeItemKey] = $item;
531 if ($relativePosition ===
'before') {
532 $offset = $relativeItemKey;
534 $offset = $relativeItemKey + 1;
536 array_splice(
$GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'items'], $offset, 0, array(0 => $item));
540 $GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'items'][] = $item;
544 $GLOBALS[
'TCA'][$table][
'columns'][$field][
'config'][
'items'][] = $item;
558 public static function getFileFieldTCAConfig($fieldName, array $customSettingOverride = array(), $allowedFileExtensions =
'', $disallowedFileExtensions =
'')
560 $fileFieldTCAConfig = array(
562 'foreign_table' =>
'sys_file_reference',
563 'foreign_field' =>
'uid_foreign',
564 'foreign_sortby' =>
'sorting_foreign',
565 'foreign_table_field' =>
'tablenames',
566 'foreign_match_fields' => array(
567 'fieldname' => $fieldName
569 'foreign_label' =>
'uid_local',
570 'foreign_selector' =>
'uid_local',
571 'foreign_selector_fieldTcaOverride' => array(
573 'appearance' => array(
574 'elementBrowserType' =>
'file',
575 'elementBrowserAllowed' => $allowedFileExtensions
581 'userFunc' => \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class .
'->filterInlineChildren',
582 'parameters' => array(
583 'allowedFileExtensions' => $allowedFileExtensions,
584 'disallowedFileExtensions' => $disallowedFileExtensions
588 'appearance' => array(
589 'useSortable' =>
true,
590 'headerThumbnail' => array(
591 'field' =>
'uid_local',
595 'showPossibleLocalizationRecords' =>
false,
596 'showRemovedLocalizationRecords' =>
false,
597 'showSynchronizationLink' =>
false,
598 'showAllLocalizationLink' =>
false,
600 'enabledControls' => array(
610 'behaviour' => array(
611 'localizationMode' =>
'select',
612 'localizeChildrenAtParentLocalization' =>
true,
616 return $fileFieldTCAConfig;
630 $GLOBALS[
'TYPO3_USER_SETTINGS'][
'showitem'] = self::executePositionedStringInsertion(
$GLOBALS[
'TYPO3_USER_SETTINGS'][
'showitem'], $addFields, $insertionPosition);
652 $list = $newList = trim(
$list,
", \t\n\r\0\x0B");
656 if ($location !==
'replace') {
657 $insertionList = self::removeDuplicatesForInsertion($insertionList,
$list);
660 if ($insertionList ===
'') {
664 return $insertionList;
666 if ($insertionPosition ===
'') {
667 return $list .
', ' . $insertionList;
673 if (strpos($positionName,
';;') !==
false) {
674 $positionName = str_replace(
';;',
';[^;]*;', $positionName);
677 $pattern = (
'/(^|,\\s*)(' . $positionName .
')(;[^,$]+)?(,|$)/');
680 $newList = preg_replace($pattern,
'$1$2$3, ' . $insertionList .
'$4',
$list);
683 $newList = preg_replace($pattern,
'$1' . $insertionList .
', $2$3$4',
$list);
686 $newList = preg_replace($pattern,
'$1' . $insertionList .
'$4',
$list);
692 if (
$list === $newList) {
693 return $list .
', ' . $insertionList;
715 $insertionListParts = preg_split(
'/\\s*,\\s*/', $insertionList);
716 $listMatches = array();
718 preg_match_all(
'/(?:^|,)\\s*\\b([^;,]+)\\b[^,]*/',
$list, $listMatches);
719 $listMatches = $listMatches[1];
722 $cleanInsertionListParts = array();
723 foreach ($insertionListParts as $fieldName) {
724 $fieldNameParts = explode(
';', $fieldName, 2);
725 $cleanFieldName = $fieldNameParts[0];
727 $cleanFieldName ===
'--linebreak--'
729 !in_array($cleanFieldName, $cleanInsertionListParts,
true)
730 && !in_array($cleanFieldName, $listMatches,
true)
733 $cleanInsertionListParts[] = $fieldName;
736 return implode(
', ', $cleanInsertionListParts);
749 foreach ($itemParts as $itemPart) {
751 $key = $itemDetails[0];
752 if (strpos($key,
'--') !==
false) {
754 $key .= count($items);
756 if (!isset($items[$key])) {
757 $items[$key] = array(
758 'rawData' => $itemPart,
761 $details = array(0 =>
'field', 1 =>
'label', 2 =>
'palette');
762 foreach ($details as $id => $property) {
763 $items[$key][
'details'][$property] = isset($itemDetails[$id]) ? $itemDetails[$id] :
'';
780 $itemParts = array();
781 foreach ($items as $item => $itemDetails) {
782 if (strpos($item,
'--') !==
false) {
784 $item = str_replace(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
'', $item);
787 $itemParts[] = $itemDetails[
'rawData'];
789 if (count($itemDetails[
'details']) > 1) {
790 $details = array(
'palette',
'label',
'field');
793 foreach ($details as $property) {
794 if ($itemDetails[
'details'][$property] !==
'' || $addEmpty) {
796 array_unshift($elements, $itemDetails[
'details'][$property]);
799 $item = implode(
';', $elements);
801 $itemParts[] = $item;
804 return implode(
', ', $itemParts);
817 $GLOBALS[
'PAGES_TYPES'][
'default'][
'allowedTables'] .=
',' . $table;
832 public static function addExtJSModule($extensionName, $mainModuleName, $subModuleName =
'', $position =
'', array $moduleConfiguration = array())
834 if (empty($extensionName)) {
835 throw new \InvalidArgumentException(
'The extension name must not be empty', 1325938973);
838 $extensionName = str_replace(
' ',
'', ucwords(str_replace(
'_',
' ', $extensionName)));
839 $defaultModuleConfiguration = array(
841 'icon' =>
'sysext/backend/Resources/Public/Images/Logo.png',
843 'extRelPath' => self::extRelPath($extensionKey) .
'Classes/'
846 if ($mainModuleName ===
'web') {
847 $defaultModuleConfiguration[
'navigationComponentId'] =
'typo3-pagetree';
850 $moduleConfiguration = $defaultModuleConfiguration;
851 if ($subModuleName !==
'') {
852 $moduleSignature = $mainModuleName .
'_' . $subModuleName;
854 $moduleSignature = $mainModuleName;
856 $moduleConfiguration[
'name'] = $moduleSignature;
857 $moduleConfiguration[
'script'] =
'extjspaneldummy.html';
858 $moduleConfiguration[
'extensionName'] = $extensionName;
859 $moduleConfiguration[
'configureModuleFunction'] = array(ExtensionManagementUtility::class,
'configureModule');
860 $GLOBALS[
'TBE_MODULES'][
'_configuration'][$moduleSignature] = $moduleConfiguration;
861 self::addModule($mainModuleName, $subModuleName, $position);
874 $moduleConfiguration =
$GLOBALS[
'TBE_MODULES'][
'_configuration'][$moduleSignature];
875 $iconPathAndFilename = $moduleConfiguration[
'icon'];
876 if (substr($iconPathAndFilename, 0, 4) ===
'EXT:') {
877 list($extensionKey, $relativePath) = explode(
'/', substr($iconPathAndFilename, 4), 2);
878 $iconPathAndFilename = self::extPath($extensionKey) . $relativePath;
881 $moduleLabels = array(
882 'tabs_images' => array(
883 'tab' => $iconPathAndFilename
886 'tablabel' =>
$GLOBALS[
'LANG']->sL($moduleConfiguration[
'labels'] .
':mlang_labels_tablabel'),
887 'tabdescr' =>
$GLOBALS[
'LANG']->sL($moduleConfiguration[
'labels'] .
':mlang_labels_tabdescr')
890 'tab' =>
$GLOBALS[
'LANG']->sL($moduleConfiguration[
'labels'] .
':mlang_tabs_tab')
893 $GLOBALS[
'LANG']->addModuleLabels($moduleLabels, $moduleSignature .
'_');
894 return $moduleConfiguration;
908 public static function addModule($main, $sub =
'', $position =
'', $path =
'', $moduleConfiguration = array())
912 if (isset(
$GLOBALS[
'TBE_MODULES'][$main]) && $sub) {
914 $modules =
',' .
$GLOBALS[
'TBE_MODULES'][$main] .
',';
918 $modRef =
',' . $modRef .
',';
920 switch (strtolower($place)) {
922 $modules = str_replace($modRef, $modRef . $sub .
',', $modules);
925 $modules = str_replace($modRef,
',' . $sub . $modRef, $modules);
928 $modules = $sub . $modules;
932 $modules = $modules . $sub;
936 $GLOBALS[
'TBE_MODULES'][$main] = trim($modules,
',');
939 $GLOBALS[
'TBE_MODULES'][$main] = $sub;
941 $fullModuleSignature = $main . ($sub ?
'_' . $sub :
'');
944 GeneralUtility::deprecationLog(
'Registered "' . $fullModuleSignature .
'" as a script-based module. Script-based modules are deprecated since TYPO3 CMS 7. Support will be removed with TYPO3 CMS 8, use the "routeTarget" option or dispatched modules instead.');
945 self::addModulePath($fullModuleSignature, $path);
949 if (is_array($moduleConfiguration) && !empty($moduleConfiguration)) {
950 $GLOBALS[
'TBE_MODULES'][
'_configuration'][$fullModuleSignature] = $moduleConfiguration;
965 $GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'ExtDirect'][$endpointName] = array(
966 'callbackClass' => $callbackClass,
967 'moduleName' => $moduleName,
968 'accessLevel' => $accessLevel
981 $GLOBALS[
'TYPO3_CONF_VARS'][
'BE'][
'AJAX'][$ajaxId] = array(
982 'callbackMethod' => $callbackMethod,
983 'csrfTokenCheck' => $csrfTokenCheck
1003 list($extensionKey, $relativePath) = explode(
'/', substr($path, 4), 2);
1006 $GLOBALS[
'TBE_MODULES'][
'_PATHS'][$name] = $path;
1024 public static function insertModuleFunction($modname, $className, $classPath = null, $title, $MM_key =
'function', $WS =
'')
1026 $GLOBALS[
'TBE_MODULES_EXT'][$modname][
'MOD_MENU'][$MM_key][$className] = array(
1027 'name' => $className,
1048 $GLOBALS[
'TYPO3_CONF_VARS_extensionAdded'][$group][$key] .= $content;
1049 $GLOBALS[
'TYPO3_CONF_VARS'][$group][$key] .= $content;
1062 self::appendToTypoConfVars(
'BE',
'defaultPageTSconfig',
'
1077 self::appendToTypoConfVars(
'BE',
'defaultUserTSconfig',
'
1093 if ($tca_descr_key) {
1094 if (!is_array(
$GLOBALS[
'TCA_DESCR'][$tca_descr_key])) {
1095 $GLOBALS[
'TCA_DESCR'][$tca_descr_key] = array();
1097 if (!is_array(
$GLOBALS[
'TCA_DESCR'][$tca_descr_key][
'refs'])) {
1098 $GLOBALS[
'TCA_DESCR'][$tca_descr_key][
'refs'] = array();
1100 $GLOBALS[
'TCA_DESCR'][$tca_descr_key][
'refs'][] = $file_ref;
1115 $extensionKey = $extensionKey ?:
$GLOBALS[
'_EXTKEY'];
1116 if (!isset($extensionKey)) {
1117 throw new \RuntimeException(
'No extensionKey set in addNavigationComponent(). Provide it as third Parameter', 1404068039);
1119 $GLOBALS[
'TBE_MODULES'][
'_navigationComponents'][$module] = array(
1120 'componentId' => $componentId,
1121 'extKey' => $extensionKey,
1122 'isCoreComponent' =>
false
1135 self::addNavigationComponent($module, $componentId);
1136 $GLOBALS[
'TBE_MODULES'][
'_navigationComponents'][$module][
'isCoreComponent'] =
true;
1153 public static function addService($extKey, $serviceType, $serviceKey, $info)
1155 if ($serviceType && is_array($info)) {
1156 $info[
'priority'] = max(0, min(100, $info[
'priority']));
1157 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey] = $info;
1158 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'extKey'] = $extKey;
1159 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'serviceKey'] = $serviceKey;
1160 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'serviceType'] = $serviceType;
1164 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'T3_SERVICES'][$serviceType][$serviceKey])) {
1167 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey] = array_merge(
$GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey],
$GLOBALS[
'TYPO3_CONF_VARS'][
'T3_SERVICES'][$serviceType][$serviceKey]);
1171 if (
$GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'available'] &&
$GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'os'] !=
'') {
1173 $os_type = stripos(PHP_OS,
'win') !==
false && !stripos(PHP_OS,
'darwin') !==
false ?
'WIN' :
'UNIX';
1175 if (!in_array($os_type, $os)) {
1176 self::deactivateService($serviceType, $serviceKey);
1180 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'serviceSubTypes'] = array();
1182 foreach ($serviceSubTypes as $subtype) {
1183 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'serviceSubTypes'][$subtype] = $subtype;
1196 public static function findService($serviceType, $serviceSubType =
'', $excludeServiceKeys = array())
1198 $serviceKey =
false;
1199 $serviceInfo =
false;
1202 if (!is_array($excludeServiceKeys)) {
1205 if (is_array(
$GLOBALS[
'T3_SERVICES'][$serviceType])) {
1206 foreach (
$GLOBALS[
'T3_SERVICES'][$serviceType] as $key => $info) {
1207 if (in_array($key, $excludeServiceKeys)) {
1212 if ($serviceSubType ==
'*') {
1213 $serviceSubType = key($info[
'serviceSubTypes']);
1216 if ($info[
'available'] && ($info[
'subtype'] == $serviceSubType || $info[
'serviceSubTypes'][$serviceSubType]) && $info[
'priority'] >= $priority) {
1218 if ($info[
'priority'] == $priority && $info[
'quality'] < $quality) {
1222 $info[
'available'] = self::isServiceAvailable($serviceType, $key, $info);
1224 if ($info[
'available']) {
1226 $priority = $info[
'priority'];
1227 $quality = $info[
'quality'];
1233 $serviceInfo =
$GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey];
1235 return $serviceInfo;
1248 if (is_array(
$GLOBALS[
'T3_SERVICES'])) {
1251 foreach (
$GLOBALS[
'T3_SERVICES'] as $serviceType => $servicesPerType) {
1252 if (isset($servicesPerType[$serviceKey])) {
1253 $serviceDetails = $servicesPerType[$serviceKey];
1255 if (self::isServiceAvailable($serviceType, $serviceKey, $serviceDetails)) {
1257 return $serviceDetails;
1262 throw new \TYPO3\CMS\Core\Exception(
'Service not found for key: ' . $serviceKey, 1319217244);
1276 if (trim($serviceDetails[
'exec'])) {
1278 foreach ($executables as $executable) {
1281 self::deactivateService($serviceType, $serviceKey);
1300 $GLOBALS[
'T3_SERVICES'][$serviceType][$serviceKey][
'available'] =
false;
1321 public static function addPlugin($itemArray, $type =
'list_type', $extensionKey = null)
1323 $extensionKey = $extensionKey ?:
$GLOBALS[
'_EXTKEY'];
1324 if (!isset($extensionKey)) {
1325 throw new \RuntimeException(
1326 'No extension key could be determined when calling addPlugin()!'
1328 .
'This method is meant to be called from an ext_tables.php or Configuration/TCA/Overrides file. '
1329 .
'If you call it from Configuration/TCA/Overrides, the extension key needs to be specified as third parameter. '
1330 .
'Calling it from any other place e.g. ext_localconf.php does not work and is not supported.',
1334 if ($extensionKey && !$itemArray[2] && isset(
$GLOBALS[
'TYPO3_LOADED_EXT'][$extensionKey][
'ext_icon'])) {
1335 $itemArray[2] =
'EXT:' . $extensionKey .
'/' .
$GLOBALS[
'TYPO3_LOADED_EXT'][$extensionKey][
'ext_icon'];
1337 if (is_array(
$GLOBALS[
'TCA'][
'tt_content'][
'columns']) && is_array(
$GLOBALS[
'TCA'][
'tt_content'][
'columns'][$type][
'config'][
'items'])) {
1338 foreach (
$GLOBALS[
'TCA'][
'tt_content'][
'columns'][$type][
'config'][
'items'] as $k => $v) {
1339 if ((
string)$v[1] === (
string)$itemArray[1]) {
1340 $GLOBALS[
'TCA'][
'tt_content'][
'columns'][$type][
'config'][
'items'][$k] = $itemArray;
1344 $GLOBALS[
'TCA'][
'tt_content'][
'columns'][$type][
'config'][
'items'][] = $itemArray;
1360 if (is_array(
$GLOBALS[
'TCA'][
'tt_content'][
'columns']) && is_array(
$GLOBALS[
'TCA'][
'tt_content'][
'columns'][
'pi_flexform'][
'config'][
'ds'])) {
1361 $GLOBALS[
'TCA'][
'tt_content'][
'columns'][
'pi_flexform'][
'config'][
'ds'][$piKeyToMatch .
',' . $CTypeToMatch] = $value;
1375 public static function addToInsertRecords($table, $content_table =
'tt_content', $content_field =
'records')
1377 if (is_array(
$GLOBALS[
'TCA'][$content_table][
'columns']) && isset(
$GLOBALS[
'TCA'][$content_table][
'columns'][$content_field][
'config'][
'allowed'])) {
1378 $GLOBALS[
'TCA'][$content_table][
'columns'][$content_field][
'config'][
'allowed'] .=
',' . $table;
1410 public static function addPItoST43($key, $classFile =
'', $suffix =
'', $type =
'list_type', $cached = 0)
1412 $classFile = $classFile ? $classFile :
'pi/class.tx_' . str_replace(
'_',
'', $key) . $suffix .
'.php';
1413 $cN = self::getCN($key);
1415 $pluginContent = trim(
'
1416 plugin.' . $cN . $suffix .
' = USER' . ($cached ?
'' :
'_INT') .
'
1417 plugin.' . $cN . $suffix .
' {
1418 includeLibs = ' .
$GLOBALS[
'TYPO3_LOADED_EXT'][$key][
'siteRelPath'] . $classFile .
'
1419 userFunc = ' . $cN . $suffix .
'->main
1421 self::addTypoScript($key,
'setup',
'
1422 # Setting ' . $key .
' plugin TypoScript
1423 ' . $pluginContent);
1427 $addLine =
'tt_content.list.20.' . $key . $suffix .
' = < plugin.' . $cN . $suffix;
1430 $addLine =
'tt_content.menu.20.' . $key . $suffix .
' = < plugin.' . $cN . $suffix;
1434 tt_content.' . $key . $suffix .
' = COA
1435 tt_content.' . $key . $suffix .
' {
1436 10 = < lib.stdheader
1437 20 = < plugin.' . $cN . $suffix .
'
1441 case 'header_layout':
1442 $addLine =
'lib.stdheader.10.' . $key . $suffix .
' = < plugin.' . $cN . $suffix;
1445 $addLine =
'page.1000 = < plugin.' . $cN . $suffix;
1451 self::addTypoScript($key,
'setup',
'
1452 # Setting ' . $key .
' plugin TypoScript
1454 ',
'defaultContentRendering');
1470 if ($extKey && $path && is_array(
$GLOBALS[
'TCA'][
'sys_template'][
'columns'])) {
1471 $value = str_replace(
',',
'',
'EXT:' . $extKey .
'/' . $path);
1472 $itemArray = array(trim($title .
' (' . $extKey .
')'), $value);
1473 $GLOBALS[
'TCA'][
'sys_template'][
'columns'][
'include_static_file'][
'config'][
'items'][] = $itemArray;
1488 if ($extKey && $file && is_array(
$GLOBALS[
'TCA'][
'pages'][
'columns'])) {
1489 $value = str_replace(
',',
'',
'EXT:' . $extKey .
'/' . $file);
1490 $itemArray = array(trim($title .
' (' . $extKey .
')'), $value);
1491 $GLOBALS[
'TCA'][
'pages'][
'columns'][
'tsconfig_includes'][
'config'][
'items'][] = $itemArray;
1505 self::appendToTypoConfVars(
'FE',
'defaultTypoScript_setup',
'
1520 self::appendToTypoConfVars(
'FE',
'defaultTypoScript_constants',
'
1543 public static function addTypoScript($key, $type, $content, $afterStaticUid = 0)
1545 if ($type ===
'setup' || $type ===
'constants') {
1549 #############################################
1550 ## TypoScript added by extension "' . $key .
'"
1551 #############################################
1554 if ($afterStaticUid) {
1557 if ($afterStaticUid ===
'defaultContentRendering' || $afterStaticUid == 43) {
1558 $GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'defaultTypoScript_' . $type .
'.'][
'defaultContentRendering'] .= $content;
1560 $GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'defaultTypoScript_' . $type .
'.'][$afterStaticUid] .= $content;
1563 $GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'defaultTypoScript_' . $type] .= $content;
1584 $iconFileTypesToCheckFor = array(
'png',
'svg',
'gif');
1585 foreach ($iconFileTypesToCheckFor as $fileType) {
1586 if (file_exists($extensionPath .
'ext_icon.' . $fileType)) {
1587 $icon =
'ext_icon.' . $fileType;
1591 return $returnFullPath ? $extensionPath . $icon : $icon;
1606 public static function loadExtLocalconf($allowCaching =
true)
1608 if ($allowCaching) {
1609 $cacheIdentifier = self::getExtLocalconfCacheIdentifier();
1611 $codeCache = self::getCacheManager()->getCache(
'cache_core');
1612 if ($codeCache->has($cacheIdentifier)) {
1613 $codeCache->requireOnce($cacheIdentifier);
1615 self::loadSingleExtLocalconfFiles();
1616 self::createExtLocalconfCacheEntry();
1619 self::loadSingleExtLocalconfFiles();
1634 global $TYPO3_CONF_VARS;
1635 foreach (
$GLOBALS[
'TYPO3_LOADED_EXT'] as $_EXTKEY => $extensionInformation) {
1636 if ((is_array($extensionInformation) || $extensionInformation instanceof \ArrayAccess) && isset($extensionInformation[
'ext_localconf.php'])) {
1639 $_EXTCONF = isset(
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXT'][
'extConf'][$_EXTKEY]) ?
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXT'][
'extConf'][$_EXTKEY] : null;
1640 require $extensionInformation[
'ext_localconf.php'];
1652 $extensionInformation =
$GLOBALS[
'TYPO3_LOADED_EXT'];
1653 $phpCodeToCache = array();
1655 $phpCodeToCache[] =
'';
1658 $phpCodeToCache[] =
'';
1659 $phpCodeToCache[] =
'global $TYPO3_CONF_VARS, $T3_SERVICES, $T3_VAR;';
1660 $phpCodeToCache[] =
'';
1662 foreach ($extensionInformation as $extensionKey => $extensionDetails) {
1663 if (isset($extensionDetails[
'ext_localconf.php']) && $extensionDetails[
'ext_localconf.php']) {
1665 $phpCodeToCache[] =
'';
1669 $phpCodeToCache[] =
'';
1671 $phpCodeToCache[] =
'$_EXTKEY = \'' . $extensionKey .
'\';
';
1672 $phpCodeToCache[] = '$_EXTCONF =
$GLOBALS[\
'TYPO3_CONF_VARS\'][\'EXT\'][\'extConf\'][$_EXTKEY];';
1673 $phpCodeToCache[] =
'';
1676 $phpCodeToCache[] =
'';
1677 $phpCodeToCache[] =
'';
1680 $phpCodeToCache = implode(LF, $phpCodeToCache);
1682 $phpCodeToCache = preg_replace(
'/<\\?php|\\?>/is',
'', $phpCodeToCache);
1683 self::getCacheManager()->getCache(
'cache_core')->set(self::getExtLocalconfCacheIdentifier(), $phpCodeToCache);
1693 return 'ext_localconf_' . sha1(TYPO3_version . PATH_site .
'extLocalconf' . serialize(
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXT'][
'runtimeActivatedPackages']));
1710 public static function loadBaseTca($allowCaching =
true)
1712 if ($allowCaching) {
1713 $cacheIdentifier = static::getBaseTcaCacheIdentifier();
1715 $codeCache = static::getCacheManager()->getCache(
'cache_core');
1716 if ($codeCache->has($cacheIdentifier)) {
1718 $cacheData = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
1719 $GLOBALS[
'TCA'] = $cacheData[
'tca'];
1722 static::buildBaseTcaFromSingleFiles();
1723 static::createBaseTcaCacheFile();
1726 static::buildBaseTcaFromSingleFiles();
1742 $activePackages = static::$packageManager->getActivePackages();
1745 foreach ($activePackages as $package) {
1746 $tcaConfigurationDirectory = $package->getPackagePath() .
'Configuration/TCA';
1747 if (is_dir($tcaConfigurationDirectory)) {
1748 $files = scandir($tcaConfigurationDirectory);
1749 foreach ($files as $file) {
1751 is_file($tcaConfigurationDirectory .
'/' . $file)
1754 && (substr($file, -4, 4) ===
'.php')
1756 $tcaOfTable = require($tcaConfigurationDirectory .
'/' . $file);
1757 if (is_array($tcaOfTable)) {
1759 $tcaTableName = substr($file, 0, -4);
1760 $GLOBALS[
'TCA'][$tcaTableName] = $tcaOfTable;
1771 foreach ($activePackages as $package) {
1772 $tcaOverridesPathForPackage = $package->getPackagePath() .
'Configuration/TCA/Overrides';
1773 if (is_dir($tcaOverridesPathForPackage)) {
1774 $files = scandir($tcaOverridesPathForPackage);
1775 foreach ($files as $file) {
1777 is_file($tcaOverridesPathForPackage .
'/' . $file)
1780 && (substr($file, -4, 4) ===
'.php')
1782 require($tcaOverridesPathForPackage .
'/' . $file);
1792 $messages = $tcaMigration->getMessages();
1793 if (!empty($messages)) {
1794 $context =
'Automatic TCA migration done during bootstrap. Please adapt TCA accordingly, these migrations'
1795 .
' will be removed with TYPO3 CMS 8. The backend module "Configuration -> TCA" shows the modified values.'
1796 .
' Please adapt these areas:';
1797 array_unshift($messages, $context);
1801 static::emitTcaIsBeingBuiltSignal(
$GLOBALS[
'TCA']);
1816 list($tca) = static::getSignalSlotDispatcher()->dispatch(__CLASS__,
'tcaIsBeingBuilt', array($tca));
1826 protected static function createBaseTcaCacheFile()
1829 $codeCache = self::getCacheManager()->getCache(
'cache_core');
1840 return 'tca_base_' . sha1(TYPO3_version . PATH_site .
'tca_with_category_registry' . serialize(
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXT'][
'runtimeActivatedPackages']));
1855 public static function loadExtTables($allowCaching =
true)
1857 if ($allowCaching && !self::$extTablesWasReadFromCacheOnce) {
1858 self::$extTablesWasReadFromCacheOnce =
true;
1859 $cacheIdentifier = self::getExtTablesCacheIdentifier();
1861 $codeCache = self::getCacheManager()->getCache(
'cache_core');
1862 if ($codeCache->has($cacheIdentifier)) {
1863 $codeCache->requireOnce($cacheIdentifier);
1865 self::loadSingleExtTablesFiles();
1866 self::createExtTablesCacheEntry();
1869 self::loadSingleExtTablesFiles();
1882 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
1883 global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
1884 global $PAGES_TYPES, $TBE_STYLES;
1887 foreach (
$GLOBALS[
'TYPO3_LOADED_EXT'] as $_EXTKEY => $extensionInformation) {
1888 if ((is_array($extensionInformation) || $extensionInformation instanceof \ArrayAccess) && $extensionInformation[
'ext_tables.php']) {
1892 require $extensionInformation[
'ext_tables.php'];
1893 static::loadNewTcaColumnsConfigFiles();
1905 $extensionInformation =
$GLOBALS[
'TYPO3_LOADED_EXT'];
1906 $phpCodeToCache = array();
1908 $phpCodeToCache[] =
'';
1911 $phpCodeToCache[] =
'';
1912 $phpCodeToCache[] =
'global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;';
1913 $phpCodeToCache[] =
'global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;';
1914 $phpCodeToCache[] =
'global $PAGES_TYPES, $TBE_STYLES;';
1915 $phpCodeToCache[] =
'global $_EXTKEY;';
1916 $phpCodeToCache[] =
'';
1918 foreach ($extensionInformation as $extensionKey => $extensionDetails) {
1919 if (isset($extensionDetails[
'ext_tables.php']) && $extensionDetails[
'ext_tables.php']) {
1921 $phpCodeToCache[] =
'';
1925 $phpCodeToCache[] =
'';
1927 $phpCodeToCache[] =
'$_EXTKEY = \'' . $extensionKey .
'\';
';
1928 $phpCodeToCache[] = '$_EXTCONF =
$GLOBALS[\
'TYPO3_CONF_VARS\'][\'EXT\'][\'extConf\'][$_EXTKEY];';
1929 $phpCodeToCache[] =
'';
1932 $phpCodeToCache[] =
'';
1933 $phpCodeToCache[] = ExtensionManagementUtility::class .
'::loadNewTcaColumnsConfigFiles();';
1934 $phpCodeToCache[] =
'';
1937 $phpCodeToCache = implode(LF, $phpCodeToCache);
1939 $phpCodeToCache = preg_replace(
'/<\\?php|\\?>/is',
'', $phpCodeToCache);
1940 self::getCacheManager()->getCache(
'cache_core')->set(self::getExtTablesCacheIdentifier(), $phpCodeToCache);
1968 foreach ($TCA as $tableName => $_) {
1969 if (!isset($TCA[$tableName][
'columns'])) {
1970 $columnsConfigFile = $TCA[$tableName][
'ctrl'][
'dynamicConfigFile'];
1971 if ($columnsConfigFile) {
1974 include($columnsConfigFile);
1976 throw new \RuntimeException(
1977 'Columns configuration file not found',
1993 return 'ext_tables_' . sha1(TYPO3_version . PATH_site .
'extTables' . serialize(
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXT'][
'runtimeActivatedPackages']));
2013 self::getCacheManager()->flushCachesInGroup(
'system');
2023 return array_keys(static::$packageManager->getActivePackages());
2038 if (static::$packageManager->isPackageActive($extensionKey)) {
2039 throw new \RuntimeException(
'Extension already loaded', 1342345486);
2041 static::$packageManager->activatePackage($extensionKey);
2056 if (!static::$packageManager->isPackageActive($extensionKey)) {
2057 throw new \RuntimeException(
'Extension not loaded', 1342345487);
2059 static::$packageManager->deactivatePackage($extensionKey);
2074 public static function makeCategorizable($extensionKey, $tableName, $fieldName =
'categories', array $options = array(), $override =
false)
2078 if ($result ===
false) {
2079 $message = CategoryRegistry::class .
': no category registered for table "%s". Key was already registered.';
2083 sprintf($message, $tableName)