157 public function install(...$extensionKeys)
159 $flushCaches =
false;
160 foreach ($extensionKeys as $extensionKey) {
164 if (!empty($extension[
'clearcacheonload']) || !empty($extension[
'clearCacheOnLoad'])) {
170 $this->cacheManager->flushCaches();
172 $this->cacheManager->flushCachesInGroup(
'system');
177 foreach ($extensionKeys as $extensionKey) {
203 $dependentExtensions = $this->dependencyUtility->findInstalledExtensionsThatDependOnMe($extensionKey);
204 if (is_array($dependentExtensions) && !empty($dependentExtensions)) {
207 'extensionList.uninstall.dependencyError',
209 [$extensionKey, implode(
',', $dependentExtensions)]
225 return $this->packageManager->isPackageActive($extensionKey);
233 $this->listUtility->reloadAvailableExtensions();
243 $this->packageManager->activatePackage($extensionKey);
253 $this->packageManager->deactivatePackage($extensionKey);
255 $this->cacheManager->flushCachesInGroup(
'system');
265 $this->signalSlotDispatcher->dispatch(__CLASS__,
'afterExtensionInstall', [$extensionKey, $this]);
275 $this->signalSlotDispatcher->dispatch(__CLASS__,
'afterExtensionUninstall', [$extensionKey, $this]);
286 return $this->packageManager->isPackageAvailable($extensionKey);
300 if ($this->packageManager->isPackageAvailable($extensionKey)) {
302 $this->packageManager->reloadPackageInformation($extensionKey);
318 if (!$loadTerInformation) {
319 $availableAndInstalledExtensions = $this->listUtility->enrichExtensionsWithEmConfInformation([$extensionKey => $extension]);
321 $availableAndInstalledExtensions = $this->listUtility->enrichExtensionsWithEmConfAndTerInformation([$extensionKey => $extension]);
324 if (!isset($availableAndInstalledExtensions[$extensionKey])) {
325 throw new ExtensionManagerException(
326 'Please check your uploaded extension "' . $extensionKey .
'". The configuration file "ext_emconf.php" seems to be invalid.',
331 return $availableAndInstalledExtensions[$extensionKey];
341 $availableExtensions = $this->listUtility->getAvailableExtensions();
342 if (isset($availableExtensions[$extensionKey])) {
343 return $availableExtensions[$extensionKey];
355 $this->fileHandlingUtility->ensureConfiguredDirectoriesExist($extension);
367 trigger_error(
'This method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
369 $extTablesSqlContent =
'';
370 if (file_exists($extTablesSqlFile)) {
371 $extTablesSqlContent .= file_get_contents($extTablesSqlFile);
373 if ($extTablesSqlContent !==
'') {
376 }
catch (\
TYPO3\CMS\Core\Database\Schema\Exception\StatementException $e) {
377 throw new ExtensionManagerException(
399 $signalReturn = $this->signalSlotDispatcher->dispatch(__CLASS__,
'tablesDefinitionIsBeingBuilt', [[], $extensionKey]);
401 $signalReturn = array_values($signalReturn);
402 $sqlString = $signalReturn[0];
403 if (!is_array($sqlString)) {
404 throw new ExtensionManagerException(
406 'The signal %s of class %s returned a value of type %s, but array was expected.',
407 'tablesDefinitionIsBeingBuilt',
414 if (!empty($sqlString)) {
417 'The signal %s of class %s is deprecated and will be removed in TYPO3 v10.0.',
418 'tablesDefinitionIsBeingBuilt',
443 GeneralUtility::makeInstance(OpcodeCacheService::class)->clearAllActive();
454 $sqlReader = GeneralUtility::makeInstance(SqlReader::class);
455 $schemaMigrator = GeneralUtility::makeInstance(SchemaMigrator::class);
457 $sqlStatements[] = $sqlReader->getTablesDefinitionString();
458 foreach ($extensionKeys as $extensionKey) {
461 $sqlStatements = $sqlReader->getCreateTableStatementArray(implode(LF . LF, array_filter($sqlStatements)));
462 $updateStatements = $schemaMigrator->getUpdateSuggestions($sqlStatements);
464 $updateStatements = array_merge_recursive(...array_values($updateStatements));
465 $selectedStatements = [];
466 foreach ([
'add',
'change',
'create_table',
'change_table'] as $action) {
467 if (empty($updateStatements[$action])) {
470 $selectedStatements = array_merge(
472 array_combine(array_keys($updateStatements[$action]), array_fill(0, count($updateStatements[$action]),
true))
476 $schemaMigrator->migrate($sqlStatements, $selectedStatements);
486 $extensionConfiguration = $this->objectManager->get(ExtensionConfiguration::class);
487 $extensionConfiguration->synchronizeExtConfTemplateWithLocalConfiguration($extensionKey);
498 trigger_error(
'This method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
499 $sqlReader = GeneralUtility::makeInstance(SqlReader::class);
500 $statements = $sqlReader->getCreateTableStatementArray($rawDefinitions);
501 if (count($statements) !== 0) {
502 $schemaMigrationService = GeneralUtility::makeInstance(SchemaMigrator::class);
503 $schemaMigrationService->install($statements);
514 $sqlReader = GeneralUtility::makeInstance(SqlReader::class);
515 $statements = $sqlReader->getStatementArray($rawDefinitions);
517 $schemaMigrationService = GeneralUtility::makeInstance(SchemaMigrator::class);
518 $schemaMigrationService->importStaticData($statements,
true);
529 $absolutePath = $this->fileHandlingUtility->getAbsoluteExtensionPath($extension);
530 if ($this->fileHandlingUtility->isValidExtensionPath($absolutePath)) {
531 if ($this->packageManager->isPackageAvailable($extension)) {
533 $this->packageManager->deletePackage($extension);
536 $this->fileHandlingUtility->removeDirectory($absolutePath);
539 throw new ExtensionManagerException(
'No valid extension path given.', 1342875724);
568 $extensionUpdates = $this->extensionRepository->findByVersionRangeAndExtensionKeyOrderedByVersion(
574 if ($extensionUpdates->count() > 0) {
575 foreach ($extensionUpdates as $extensionUpdate) {
577 $this->dependencyUtility->checkDependencies($extensionUpdate);
578 if (!$this->dependencyUtility->hasDependencyErrors()) {
579 return $extensionUpdate;
596 $registryKeysToCheck = [
597 $extensionSiteRelPath .
'Initialisation/data.t3d',
598 $extensionSiteRelPath .
'Initialisation/dataImported',
600 foreach ($registryKeysToCheck as $registryKeyToCheck) {
601 if ($this->registry->get(
'extensionDataImport', $registryKeyToCheck)) {
606 $importFileToUse =
null;
607 $possibleImportFiles = [
608 $extensionSiteRelPath .
'Initialisation/data.t3d',
609 $extensionSiteRelPath .
'Initialisation/data.xml'
611 foreach ($possibleImportFiles as $possibleImportFile) {
615 $importFileToUse = $possibleImportFile;
617 if ($importFileToUse !==
null) {
619 $importExportUtility = $this->objectManager->get(ImportExportUtility::class);
622 $this->registry->set(
'extensionDataImport', $extensionSiteRelPath .
'Initialisation/dataImported', 1);
624 }
catch (\ErrorException $e) {
625 $logger = $this->objectManager->get(\
TYPO3\CMS\Core\Log\LogManager::class)->getLogger(__CLASS__);
626 $logger->log(\
TYPO3\CMS\Core\Log\LogLevel::WARNING, $e->getMessage());
639 $this->signalSlotDispatcher->dispatch(__CLASS__,
'afterExtensionT3DImport', [$importFileToUse, $importResult, $this]);
650 $extTablesStaticSqlRelFile = $extensionSiteRelPath .
'ext_tables_static+adt.sql';
651 if (!$this->registry->get(
'extensionDataImport', $extTablesStaticSqlRelFile)) {
654 if (file_exists($extTablesStaticSqlFile)) {
655 $extTablesStaticSqlContent = file_get_contents($extTablesStaticSqlFile);
656 $shortFileHash = md5($extTablesStaticSqlContent);
659 $this->registry->set(
'extensionDataImport', $extTablesStaticSqlRelFile, $shortFileHash);
671 $this->signalSlotDispatcher->dispatch(__CLASS__,
'afterExtensionStaticSqlImport', [$extTablesStaticSqlRelFile, $this]);
683 $importRelFolder = $extensionSiteRelPath .
'Initialisation/Files';
684 if (!$this->registry->get(
'extensionDataImport', $importRelFolder)) {
686 if (file_exists($importFolder)) {
687 $destinationRelPath =
$GLOBALS[
'TYPO3_CONF_VARS'][
'BE'][
'fileadminDir'] . $extensionKey;
689 if (!file_exists($destinationAbsolutePath) &&
690 GeneralUtility::isAllowedAbsPath($destinationAbsolutePath)
692 GeneralUtility::mkdir($destinationAbsolutePath);
694 GeneralUtility::copyDirectory($importRelFolder, $destinationRelPath);
695 $this->registry->set(
'extensionDataImport', $importRelFolder, 1);
708 $this->signalSlotDispatcher->dispatch(__CLASS__,
'afterExtensionFileImport', [$destinationAbsolutePath, $this]);