objectManager = GeneralUtility::makeInstance(ObjectManager::class); $this->persistenceManager = $this->objectManager->get(PersistenceManager::class); $this->session = $this->objectManager->get(Session::class); $this->versionRepository = $this->objectManager->get(\T3o\TerFe2\Domain\Repository\VersionRepository::class); $this->coreVersions = json_decode( GeneralUtility::getURL(PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . 'currentcoredata.json'), true ); $this->solrIndexQueue = $this->objectManager->get(Queue::class); } /** * Execute Task * * @return bool */ public function execute() { $this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); $this->logger->info('Task CheckForOutdatedExtensions started'); $this->initializeTask(); // Find all extension versions which are not outdated. $versions = $this->getNotOutdatedAndSecureVersions(); $this->getLatestAndOldestSupportedTypo3Versions(); $this->releaseDateOfOldestSupportedTypo3Version = $this->getReleaseDateOfOldestSupportedTypo3Version(); // Foreach extension foreach ($versions as $version) { $this->checkVersion($version); } $this->logger->info('Task CheckForOutdatedExtensions finished'); return true; } /** * Get not outdated extensions * * @return mixed */ public function getNotOutdatedAndSecureVersions() { $tableName = 'tx_terfe2_domain_model_version'; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable($tableName); $queryBuilder->getRestrictions()->removeAll(); $statement = $queryBuilder ->select('uid') ->from($tableName) ->where( $queryBuilder->expr()->eq('deleted', 0), $queryBuilder->expr()->eq('hidden', 0), $queryBuilder->expr()->gte('review_state', 0) ) ->orderBy('upload_date', 'ASC') ->execute(); $statement->execute(); return $statement->fetchAll(\PDO::FETCH_ASSOC); } /** * Get the release date of the oldest supported TYPO3 Version. * * @return int */ public function getReleaseDateOfOldestSupportedTypo3Version() { $oldestMinorVersion = explode('.', $this->supportedCoreVersions['oldest']); $oldestMinorVersion = $oldestMinorVersion[0]; $releaseDate = $this->coreVersions[$oldestMinorVersion]['releases'][$this->supportedCoreVersions['oldest']]['date']; return strtotime($releaseDate); } /** * Get the latest and oldest supported TYPO3 Versions. * * @throws \RuntimeException */ public function getLatestAndOldestSupportedTypo3Versions() { if ($this->coreVersions === null) { throw new \RuntimeException('typo3.org JSON not accessible!', 1399140291); } // Collect currently supported core versions $oldestSupportedCoreVersion = '99.99.99'; $latestSupportedCoreVersion = '0.0.0'; $allSupportedCoreVersions = []; foreach ($this->coreVersions as $version => $coreInfo) { // Only use keys that represent a branch number if (preg_match('/^\d+\.\d+$/', $version) || preg_match('/^\d+$/', $version)) { if ($coreInfo['active'] == true) { $allSupportedCoreVersions[] = $version; // Checks the latest version $latestBranchVersion = $coreInfo['latest']; if (!preg_match('/dev|alpha/', $latestBranchVersion)) { if (version_compare($latestSupportedCoreVersion, $latestBranchVersion, '<')) { $latestSupportedCoreVersion = $latestBranchVersion; } } // Check the oldest active version if (version_compare($version . '.0', $oldestSupportedCoreVersion, '<')) { $oldestSupportedCoreVersion = $version; } } } } // get first beta of oldest active version $oldestSupportedCoreVersionReleases = array_reverse($this->coreVersions[$oldestSupportedCoreVersion]['releases']); foreach ($oldestSupportedCoreVersionReleases as $subVersion => $subVersionInfo) { if (!preg_match('/dev|alpha/', $subVersion)) { $oldestSupportedCoreVersion = $subVersion; break; } } $this->supportedCoreVersions = [ 'latest' => $latestSupportedCoreVersion, 'oldest' => $oldestSupportedCoreVersion, 'all' => $allSupportedCoreVersions, ]; } /** * @param \T3o\TerFe2\Domain\Model\Relation $dependency * * @return bool */ public function isVersionDependingOnAnActiveSupportedTypo3Version($dependency) { $result = false; if ($dependency instanceof \T3o\TerFe2\Domain\Model\Relation) { $extensionMinimumVersion = $dependency->getMinimumVersion(); $extensionMaximumVersion = $dependency->getMaximumVersion(); foreach ($this->supportedCoreVersions['all'] as $version) { $version = (string)$version; // gets core version x.x.0 $supportedMinimumVersion = VersionNumberUtility::convertVersionNumberToInteger($version . '.0'); $extensionMinimumVersionAsString = VersionNumberUtility::convertIntegerToVersionNumber($extensionMinimumVersion); /* * checks if extension dependency lies within the first release of the main release version * or extension minimum version begins with main release version */ if (($supportedMinimumVersion >= $extensionMinimumVersion || strpos($extensionMinimumVersionAsString, $version) === 0) && $supportedMinimumVersion <= $extensionMaximumVersion ) { $result = true; break; } } } return $result; } /** * check if the given version is outdated and mark it in database * * @param int $versionRecord */ protected function checkVersion($versionRecord) { /** @var \T3o\TerFe2\Domain\Model\Version $version */ $version = $this->versionRepository->findByUid($versionRecord['uid']); if (!$version instanceof \T3o\TerFe2\Domain\Model\Version) { return; } $isOutdated = false; if ($version->getUploadDate() === null) { $isOutdated = true; // Check if date is set } elseif ($version->getUploadDate() < $this->releaseDateOfOldestSupportedTypo3Version) { $isOutdated = true; // Check upload date against oldestActiveTYPO3Version first release date. } elseif (!$this->isVersionDependingOnAnActiveSupportedTypo3Version($version->getTypo3Dependency())) { $isOutdated = true; // Check against dependency against TYPO3 not actively supported } if ($isOutdated) { $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); $queryBuilder = $connectionPool->getQueryBuilderForTable('tx_terfe2_domain_model_version'); $queryBuilder ->update('tx_terfe2_domain_model_version') ->set('review_state', -2) ->where( $queryBuilder->expr()->eq('uid', $version->getUid()) ) ->execute(); if ($version->getExtension() && $version->getExtension()->getUid()) { $queryBuilder = $connectionPool->getQueryBuilderForTable('tx_terfe2_domain_model_extension'); $queryBuilder ->update('tx_terfe2_domain_model_extension') ->set('tstamp', time()) ->where( $queryBuilder->expr()->eq('uid', $version->getUid()) ) ->execute(); $this->solrIndexQueue->updateItem('tx_terfe2_domain_model_extension', $version->getExtension()->getUid()); } } $this->cleanupMemory($version); } /** * free some memory after checking a version * * prevent memory leaks on the long running scheduler task * * @param \T3o\TerFe2\Domain\Model\Version $version */ public function cleanupMemory($version) { $this->session->unregisterReconstitutedEntity($version); foreach ($version->getSoftwareRelations() as $relation) { /** @var $relation \T3o\TerFe2\Domain\Model\Relation */ $this->session->unregisterReconstitutedEntity($relation); } } }