/** * Generates the action menu * * @return void */ protected function generateMenu() { $menuItems = ['installedExtensions' => ['controller' => 'List', 'action' => 'index', 'label' => $this->translate('installedExtensions')]]; if (!$this->settings['offlineMode'] && !Bootstrap::usesComposerClassLoading()) { $menuItems['getExtensions'] = ['controller' => 'List', 'action' => 'ter', 'label' => $this->translate('getExtensions')]; $menuItems['distributions'] = ['controller' => 'List', 'action' => 'distributions', 'label' => $this->translate('distributions')]; if ($this->actionMethodName === 'showAllVersionsAction') { $menuItems['showAllVersions'] = ['controller' => 'List', 'action' => 'showAllVersions', 'label' => $this->translate('showAllVersions') . ' ' . $this->request->getArgument('extensionKey')]; } } $uriBuilder = $this->objectManager->get(UriBuilder::class); $uriBuilder->setRequest($this->request); $menu = $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->makeMenu(); $menu->setIdentifier('ExtensionManagerModuleMenu'); foreach ($menuItems as $menuItemConfig) { if ($this->request->getControllerName() === $menuItemConfig['controller']) { $isActive = $this->request->getControllerActionName() === $menuItemConfig['action'] ? true : false; } else { $isActive = false; } $menuItem = $menu->makeMenuItem()->setTitle($menuItemConfig['label'])->setHref($this->getHref($menuItemConfig['controller'], $menuItemConfig['action']))->setActive($isActive); $menu->addMenuItem($menuItem); } $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu); $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue()); }
/** * Updates class loading information. * * This command is only needed during development. The extension manager takes care * creating or updating this info properly during extension (de-)activation. * * @return void * @cli */ public function dumpClassLoadingInformationCommand() { if (Bootstrap::usesComposerClassLoading()) { $this->output->outputLine('<error>Class loading information is managed by composer. Use "composer dump-autoload" command to update the information.</error>'); $this->quit(1); } else { ClassLoadingInformation::dumpClassLoadingInformation(); $this->output->outputLine('Class Loading information has been updated.'); } }
/** * clear Cache ajax handler * * @param array $ajaxParams * @param AjaxRequestHandler $ajaxObj */ public function clear($ajaxParams, AjaxRequestHandler $ajaxObj) { if ($this->isProduction() || !$this->isAdmin()) { return; } /** @var \TYPO3\CMS\Core\Cache\CacheManager $cacheManager */ $cacheManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Cache\\CacheManager'); $cacheManager->getCache('autoloader')->flush(); // Dump new class loading information if (GeneralUtility::compat_version('7.0') && !\TYPO3\CMS\Core\Core\Bootstrap::usesComposerClassLoading()) { ClassLoadingInformation::dumpClassLoadingInformation(); } }
/** * Default definition of folder and file structure with dynamic * permission settings * * @return array */ protected function getDefaultStructureDefinition() { $filePermission = $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask']; $directoryPermission = $GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask']; if (Bootstrap::usesComposerClassLoading()) { // In composer mode the links are configurable and might even be actual files // Ignore this structure in this case $structureAdditional = array(); } else { $structureAdditional = array(array('name' => 'index.php', 'type' => LinkNode::class, 'target' => 'typo3_src/index.php'), array('name' => 'typo3', 'type' => LinkNode::class, 'target' => 'typo3_src/typo3'), array('name' => 'typo3_src', 'type' => LinkNode::class)); } $structureBase = array(array('name' => 'typo3temp', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContent' => ''), array('name' => 'assets', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => 'compressed', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission), array('name' => 'css', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission), array('name' => 'js', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission), array('name' => 'images', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission), array('name' => '_processed_', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission))), array('name' => 'var', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => '.htaccess', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContentFile' => PATH_site . 'typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/typo3temp-var-htaccess'), array('name' => 'charset', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission), array('name' => 'Cache', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission), array('name' => 'locks', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission))))), array('name' => 'typo3conf', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => 'ext', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission), array('name' => 'l10n', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission))), array('name' => 'uploads', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContentFile' => PATH_site . 'typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/uploads-index.html'), array('name' => 'media', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContent' => ''))), array('name' => 'pics', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContent' => ''))), array('name' => 'tx_felogin', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission))), array('name' => !empty($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir']) ? rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') : 'fileadmin', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => '_temp_', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => '.htaccess', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContentFile' => PATH_site . 'typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/fileadmin-temp-htaccess'), array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContentFile' => PATH_site . 'typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/fileadmin-temp-index.html'))), array('name' => 'user_upload', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => '_temp_', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContent' => ''), array('name' => 'importexport', 'type' => DirectoryNode::class, 'targetPermission' => $directoryPermission, 'children' => array(array('name' => '.htaccess', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContentFile' => PATH_site . 'typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/fileadmin-user_upload-temp-importexport-htaccess'), array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContentFile' => PATH_site . 'typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/fileadmin-temp-index.html'))))), array('name' => 'index.html', 'type' => FileNode::class, 'targetPermission' => $filePermission, 'targetContent' => '')))))); return array('name' => substr(PATH_site, 0, -1), 'targetPermission' => $directoryPermission, 'children' => array_merge($structureAdditional, $structureBase)); }
/** * Fetches an extension from the given mirror * * @param string $extensionKey Extension Key * @param string $version Version to install * @param string $expectedMd5 Expected MD5 hash of extension file * @param string $mirrorUrl URL of mirror to use * @throws ExtensionManagerException * @return array T3X data */ public function fetchExtension($extensionKey, $version, $expectedMd5, $mirrorUrl) { if (!empty($this->configurationUtility->getCurrentConfiguration('extensionmanager')['offlineMode']['value']) || Bootstrap::usesComposerClassLoading()) { throw new ExtensionManagerException('Extension Manager is in offline mode. No TER connection available.', 1437078620); } $extensionPath = strtolower($extensionKey); $mirrorUrl .= $extensionPath[0] . '/' . $extensionPath[1] . '/' . $extensionPath . '_' . $version . '.t3x'; $t3x = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($mirrorUrl); $md5 = md5($t3x); if ($t3x === false) { throw new ExtensionManagerException(sprintf('The T3X file "%s" could not be fetched. Possible reasons: network problems, allow_url_fopen is off, cURL is not enabled in Install Tool.', $mirrorUrl), 1334426097); } if ($md5 === $expectedMd5) { // Fetch and return: $extensionData = $this->decodeExchangeData($t3x); } else { throw new ExtensionManagerException('Error: MD5 hash of downloaded file not as expected: ' . $md5 . ' != ' . $expectedMd5, 1334426098); } return $extensionData; }
/** * Executes the tool * * @return string Rendered content */ protected function executeAction() { if (isset($this->postValues['set']['changeEncryptionKey'])) { $this->setNewEncryptionKeyAndLogOut(); } $actionMessages = array(); if (isset($this->postValues['set']['changeInstallToolPassword'])) { $actionMessages[] = $this->changeInstallToolPassword(); } if (isset($this->postValues['set']['changeSiteName'])) { $actionMessages[] = $this->changeSiteName(); } if (isset($this->postValues['set']['createAdministrator'])) { $actionMessages[] = $this->createAdministrator(); } if (isset($this->postValues['set']['clearAllCache'])) { $actionMessages[] = $this->clearAllCache(); } if (isset($this->postValues['set']['clearOpcodeCache'])) { $actionMessages[] = $this->clearOpcodeCache(); } // Database analyzer handling if (isset($this->postValues['set']['databaseAnalyzerExecute']) || isset($this->postValues['set']['databaseAnalyzerAnalyze'])) { $this->loadExtLocalconfDatabaseAndExtTables(); } if (isset($this->postValues['set']['databaseAnalyzerExecute'])) { $actionMessages = array_merge($actionMessages, $this->databaseAnalyzerExecute()); } if (isset($this->postValues['set']['databaseAnalyzerAnalyze'])) { $actionMessages[] = $this->databaseAnalyzerAnalyze(); } $this->view->assign('actionMessages', $actionMessages); $operatingSystem = TYPO3_OS === 'WIN' ? 'Windows' : 'Unix'; $opcodeCacheService = GeneralUtility::makeInstance(OpcodeCacheService::class); /** @var \TYPO3\CMS\Install\Service\CoreUpdateService $coreUpdateService */ $coreUpdateService = $this->objectManager->get(\TYPO3\CMS\Install\Service\CoreUpdateService::class); $this->view->assign('enableCoreUpdate', $coreUpdateService->isCoreUpdateEnabled())->assign('composerMode', Bootstrap::usesComposerClassLoading())->assign('operatingSystem', $operatingSystem)->assign('cgiDetected', GeneralUtility::isRunningOnCgiServerApi())->assign('databaseName', $GLOBALS['TYPO3_CONF_VARS']['DB']['database'])->assign('databaseUsername', $GLOBALS['TYPO3_CONF_VARS']['DB']['username'])->assign('databaseHost', $GLOBALS['TYPO3_CONF_VARS']['DB']['host'])->assign('databasePort', $GLOBALS['TYPO3_CONF_VARS']['DB']['port'])->assign('databaseSocket', $GLOBALS['TYPO3_CONF_VARS']['DB']['socket'])->assign('databaseNumberOfTables', count($this->getDatabaseConnection()->admin_get_tables()))->assign('extensionCompatibilityTesterProtocolFile', GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3temp/ExtensionCompatibilityTester.txt')->assign('extensionCompatibilityTesterErrorProtocolFile', GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3temp/ExtensionCompatibilityTesterErrors.json')->assign('extensionCompatibilityTesterMessages', $this->getExtensionCompatibilityTesterMessages())->assign('listOfOpcodeCaches', $opcodeCacheService->getAllActive()); return $this->view->render(); }
/** * Check if this installation wants to enable the core updater * * @return bool */ public function isCoreUpdateEnabled() { $coreUpdateDisabled = getenv('TYPO3_DISABLE_CORE_UPDATER') ?: (getenv('REDIRECT_TYPO3_DISABLE_CORE_UPDATER') ?: false); return !Bootstrap::usesComposerClassLoading() && !$coreUpdateDisabled; }
/** * Adds the information if the Composer mode is enabled or disabled to the displayed system information */ protected function getComposerMode() { if (!Bootstrap::usesComposerClassLoading()) { return; } $languageService = $this->getLanguageService(); $this->systemInformation[] = array('title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.composerMode')), 'value' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.enabled')), 'icon' => $this->iconFactory->getIcon('sysinfo-composer-mode', Icon::SIZE_SMALL)->render()); }
/** * Registers the Icons into the docheader * * @throws \InvalidArgumentException */ protected function registerDocheaderButtons() { if (Bootstrap::usesComposerClassLoading()) { return; } if (!in_array($this->actionMethodName, ['indexAction', 'terAction', 'showAllVersionsAction'], true)) { return; } /** @var ButtonBar $buttonBar */ $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar(); $uriBuilder = $this->controllerContext->getUriBuilder(); if ($this->actionMethodName === 'showAllVersionsAction') { $uri = $uriBuilder->reset()->uriFor('ter', [], 'List'); $title = $this->translate('extConfTemplate.backToList'); $icon = $this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL); $classes = ''; } else { $uri = $uriBuilder->reset()->uriFor('form', [], 'UploadExtensionFile'); $title = $this->translate('extensionList.uploadExtension'); $icon = $this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-edit-upload', Icon::SIZE_SMALL); $classes = 't3js-upload'; } $button = $buttonBar->makeLinkButton()->setHref($uri)->setTitle($title)->setClasses($classes)->setIcon($icon); $buttonBar->addButton($button, ButtonBar::BUTTON_POSITION_LEFT); }
/** * Extract an uploaded file and install the matching extension * * @param bool $overwrite Overwrite existing extension if TRUE * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException * @return void */ public function extractAction($overwrite = false) { if (Bootstrap::usesComposerClassLoading()) { throw new ExtensionManagerException('Composer mode is active. You are not allowed to upload any extension file.', 1444725853814); } $file = $_FILES['tx_extensionmanager_tools_extensionmanagerextensionmanager']; $fileName = pathinfo($file['name']['extensionFile'], PATHINFO_BASENAME); try { // If the file name isn't valid an error will be thrown $this->checkFileName($fileName); if (!empty($file['tmp_name']['extensionFile'])) { $tempFile = GeneralUtility::upload_to_tempfile($file['tmp_name']['extensionFile']); } else { throw new ExtensionManagerException('Creating temporary file failed. Check your upload_max_filesize and post_max_size limits.', 1342864339); } $extensionData = $this->extractExtensionFromFile($tempFile, $fileName, $overwrite); $emConfiguration = $this->configurationUtility->getCurrentConfiguration('extensionmanager'); if (!$emConfiguration['automaticInstallation']['value']) { $this->addFlashMessage($this->translate('extensionList.uploadFlashMessage.message', array($extensionData['extKey'])), $this->translate('extensionList.uploadFlashMessage.title'), FlashMessage::OK); } else { if ($this->activateExtension($extensionData['extKey'])) { $this->addFlashMessage($this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey'])), '', FlashMessage::OK); } else { $this->redirect('unresolvedDependencies', 'List', null, array('extensionKey' => $extensionData['extKey'])); } } } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $exception) { throw $exception; } catch (DependencyConfigurationNotFoundException $exception) { $this->addFlashMessage($exception->getMessage(), '', FlashMessage::ERROR); } catch (\Exception $exception) { $this->removeExtensionAndRestoreFromBackup($fileName); $this->addFlashMessage($exception->getMessage(), '', FlashMessage::ERROR); } $this->redirect('index', 'List', null, array(self::TRIGGER_RefreshModuleMenu => true)); }
/** * Adds an information about composer mode */ protected function addComposerModeNotification() { if (Bootstrap::usesComposerClassLoading()) { $this->addFlashMessage(LocalizationUtility::translate('composerMode.message', 'extensionmanager'), LocalizationUtility::translate('composerMode.title', 'extensionmanager'), FlashMessage::WARNING); } }
<?php defined('TYPO3_MODE') or die; /** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */ $signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class); if (TYPO3_MODE === 'BE' && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) { // FAL SECURITY CHECKS $signalSlotDispatcher->connect(\TYPO3\CMS\Core\Resource\ResourceFactory::class, \TYPO3\CMS\Core\Resource\ResourceFactoryInterface::SIGNAL_PostProcessStorage, \TYPO3\CMS\Core\Resource\Security\StoragePermissionsAspect::class, 'addUserPermissionsToStorage'); $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = 'TYPO3\\CMS\\Core\\Resource\\Security\\FileMetadataPermissionsAspect'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_doc.php']['makeEditForm_accessCheck'][] = 'TYPO3\\CMS\\Core\\Resource\\Security\\FileMetadataPermissionsAspect->isAllowedToShowEditForm'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tceforms_inline.php']['checkAccess'][] = 'TYPO3\\CMS\\Core\\Resource\\Security\\FileMetadataPermissionsAspect->isAllowedToShowEditForm'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = 'TYPO3\\CMS\\Core\\Resource\\Security\\FileMetadataPermissionsAspect'; // PACKAGE MANAGEMENT $signalSlotDispatcher->connect('PackageManagement', 'packagesMayHaveChanged', \TYPO3\CMS\Core\Package\PackageManager::class, 'scanAvailablePackages'); } $signalSlotDispatcher->connect(\TYPO3\CMS\Core\Resource\ResourceStorage::class, \TYPO3\CMS\Core\Resource\ResourceStorageInterface::SIGNAL_PostFileDelete, \TYPO3\CMS\Core\Resource\Processing\FileDeletionAspect::class, 'removeFromRepository'); $signalSlotDispatcher->connect(\TYPO3\CMS\Core\Resource\ResourceStorage::class, \TYPO3\CMS\Core\Resource\ResourceStorageInterface::SIGNAL_PostFileAdd, \TYPO3\CMS\Core\Resource\Processing\FileDeletionAspect::class, 'cleanupProcessedFilesPostFileAdd'); $signalSlotDispatcher->connect(\TYPO3\CMS\Core\Resource\ResourceStorage::class, \TYPO3\CMS\Core\Resource\ResourceStorageInterface::SIGNAL_PostFileReplace, \TYPO3\CMS\Core\Resource\Processing\FileDeletionAspect::class, 'cleanupProcessedFilesPostFileReplace'); if (!\TYPO3\CMS\Core\Core\Bootstrap::usesComposerClassLoading()) { $signalSlotDispatcher->connect(\TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService::class, 'hasInstalledExtensions', \TYPO3\CMS\Core\Core\ClassLoadingInformation::class, 'writeClassLoadingInformation'); $signalSlotDispatcher->connect(\TYPO3\CMS\Extensionmanager\Utility\InstallUtility::class, 'afterExtensionUninstall', \TYPO3\CMS\Core\Core\ClassLoadingInformation::class, 'writeClassLoadingInformation'); } unset($signalSlotDispatcher); $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['dumpFile'] = 'EXT:core/Resources/PHP/FileDumpEID.php'; /** @var \TYPO3\CMS\Core\Resource\Rendering\RendererRegistry $rendererRegistry */ $rendererRegistry = \TYPO3\CMS\Core\Resource\Rendering\RendererRegistry::getInstance(); $rendererRegistry->registerRendererClass(\TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer::class); $rendererRegistry->registerRendererClass(\TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer::class); $textExtractorRegistry = \TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry::getInstance(); $textExtractorRegistry->registerTextExtractor(\TYPO3\CMS\Core\Resource\TextExtraction\PlainTextExtractor::class);
/** * @param PackageInterface $package * @throws \TYPO3\CMS\Core\Exception */ protected function registerTransientClassLoadingInformationForPackage(PackageInterface $package) { if (Bootstrap::usesComposerClassLoading()) { return; } ClassLoadingInformation::registerTransientClassLoadingInformationForPackage($package); }
/** * Adds the information if the Composer mode is enabled or disabled to the displayed system information */ protected function getComposerMode() { if (!Bootstrap::usesComposerClassLoading()) { return; } $languageService = $this->getLanguageService(); $this->systemInformation[] = array('title' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.composerMode', true), 'value' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.enabled', true), 'icon' => '<span class="fa fa-music"></span>'); }
/** * Dumps Extension Autoload Information * * @return \TYPO3\CMS\Install\Status\StatusInterface */ protected function dumpAutoload() : \TYPO3\CMS\Install\Status\StatusInterface { if (Bootstrap::usesComposerClassLoading()) { $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\NoticeStatus::class); $message->setTitle('Skipped generating additional class loading information in composer mode.'); } else { ClassLoadingInformation::dumpClassLoadingInformation(); $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class); $message->setTitle('Successfully dumped class loading information for extensions.'); } return $message; }