2 namespace TYPO3\CMS\Install\Service;
23 use TYPO3\CMS\Install\Service\Exception\RemoteFetchException;
102 $this->downloadBaseUri = $this->coreVersionService->getDownloadBaseUri();
112 $coreUpdateDisabled = getenv(
'TYPO3_DISABLE_CORE_UPDATER') ?: (getenv(
'REDIRECT_TYPO3_DISABLE_CORE_UPDATER') ?:
false);
123 return PATH_site .
'typo3_src';
155 public function updateVersionMatrix()
159 $this->coreVersionService->updateVersionMatrix();
160 }
catch (RemoteFetchException $e) {
163 $message = $this->objectManager->get(ErrorStatus::class);
164 $message->setTitle(
'Version matrix could not be fetched from get.typo3.org');
165 $message->setMessage(
166 'Current version specification could not be fetched from http://get.typo3.org/json.'
167 .
' This is probably a network issue, please fix it.'
169 $this->messages = array($message);
181 public function checkPreConditions($version)
187 $statusUtility = $this->objectManager->get(StatusUtility::class);
191 $folderStructureFacade = $this->objectManager->get(DefaultFactory::class)->getStructure();
192 $folderStructureErrors = $statusUtility->filterBySeverity($folderStructureFacade->getStatus(),
'error');
193 $folderStructureWarnings = $statusUtility->filterBySeverity($folderStructureFacade->getStatus(),
'warning');
194 if (!empty($folderStructureErrors) || !empty($folderStructureWarnings)) {
197 $message = $this->objectManager->get(ErrorStatus::class);
198 $message->setTitle(
'Automatic TYPO3 CMS core update not possible: Folder structure has errors or warnings');
199 $message->setMessage(
200 'To perform an update, the folder structure of this TYPO3 CMS instance must'
201 .
' stick to the conventions, or the update process could lead to unexpected'
202 .
' results and may be hazardous to your system'
208 if (TYPO3_OS ===
'WIN') {
211 $message = $this->objectManager->get(ErrorStatus::class);
212 $message->setTitle(
'Automatic TYPO3 CMS core update not possible: Update not supported on Windows OS');
219 $result = @touch($file);
223 $message = $this->objectManager->get(ErrorStatus::class);
224 $message->setTitle(
'Automatic TYPO3 CMS core update not possible: No write access to document root');
225 $message->setMessage(
'Could not write a file in path "' . PATH_site .
'"!');
233 $coreLocation = @realPath($this->symlinkToCoreFiles .
'/../');
235 $result = @touch($file);
239 $message = $this->objectManager->get(ErrorStatus::class);
240 $message->setTitle(
'Automatic TYPO3 CMS core update not possible: No write access to TYPO3 CMS core location');
241 $message->setMessage(
242 'New TYPO3 CMS core should be installed in "' . $coreLocation .
'", but this directory is not writable!'
251 if ($success && !$this->coreVersionService->isInstalledVersionAReleasedVersion()) {
254 $message = $this->objectManager->get(ErrorStatus::class);
255 $message->setTitle(
'Automatic TYPO3 CMS core update not possible: You are running a development version of TYPO3');
256 $message->setMessage(
257 'Your current version is specified as ' . $this->coreVersionService->getInstalledVersion() .
'.'
258 .
' This is a development version and can not be updated automatically. If this is a "git"'
259 .
' checkout, please update using git directly.'
274 public function downloadVersion($version)
281 $message = $this->objectManager->get(NoticeStatus::class);
282 $message->setTitle(
'Skipped download of TYPO3 CMS core. A core source directory already exists in destination path. Using this instead.');
285 $downloadUri = $this->downloadBaseUri . $version;
288 if (@file_exists($fileLocation)) {
291 $message = $this->objectManager->get(ErrorStatus::class);
299 $message = $this->objectManager->get(ErrorStatus::class);
300 $message->setTitle(
'Download not successful');
303 $fileStoreResult = file_put_contents($fileLocation, $fileContent);
304 if (!$fileStoreResult) {
307 $message = $this->objectManager->get(ErrorStatus::class);
308 $message->setTitle(
'Unable to store download content');
311 $message = $this->objectManager->get(OkStatus::class);
312 $message->setTitle(
'TYPO3 CMS core download finished');
328 public function verifyFileChecksum($version)
335 $message = $this->objectManager->get(WarningStatus::class);
336 $message->setTitle(
'Verifying existing TYPO3 CMS core checksum is not possible');
340 $expectedChecksum = $this->coreVersionService->getTarGzSha1OfVersion($version);
342 if (!file_exists($fileLocation)) {
345 $message = $this->objectManager->get(ErrorStatus::class);
346 $message->setTitle(
'Downloaded TYPO3 CMS core not found');
349 $actualChecksum = sha1_file($fileLocation);
350 if ($actualChecksum !== $expectedChecksum) {
353 $message = $this->objectManager->get(ErrorStatus::class);
354 $message->setTitle(
'New TYPO3 CMS core checksum mismatch');
355 $message->setMessage(
356 'The official TYPO3 CMS version system on https://get.typo3.org expects a sha1 checksum of '
357 . $expectedChecksum .
' from the content of the downloaded new TYPO3 CMS core version ' . $version .
'.'
358 .
' The actual checksum is ' . $actualChecksum .
'. The update is stopped. This may be a'
359 .
' failed download, an attack, or an issue with the typo3.org infrastructure.'
363 $message = $this->objectManager->get(OkStatus::class);
364 $message->setTitle(
'Checksum verified');
379 public function unpackVersion($version)
386 $message = $this->objectManager->get(NoticeStatus::class);
387 $message->setTitle(
'Unpacking TYPO3 CMS core files skipped');
390 $fileLocation = $this->downloadTargetPath . $version .
'.tar.gz';
392 if (!@is_file($fileLocation)) {
395 $message = $this->objectManager->get(ErrorStatus::class);
396 $message->setTitle(
'Downloaded TYPO3 CMS core not found');
398 }
elseif (@file_exists($this->downloadTargetPath .
'typo3_src-' . $version)) {
401 $message = $this->objectManager->get(ErrorStatus::class);
405 $unpackCommand =
'tar xf ' . escapeshellarg($fileLocation) .
' -C ' . escapeshellarg($this->downloadTargetPath) .
' 2>&1';
406 exec($unpackCommand, $output, $errorCode);
410 $message = $this->objectManager->get(ErrorStatus::class);
411 $message->setTitle(
'Unpacking TYPO3 CMS core not successful');
414 $removePackedFileResult = unlink($fileLocation);
415 if (!$removePackedFileResult) {
418 $message = $this->objectManager->get(ErrorStatus::class);
419 $message->setTitle(
'Removing packed TYPO3 CMS core not successful');
422 $message = $this->objectManager->get(OkStatus::class);
423 $message->setTitle(
'Unpacking TYPO3 CMS core successful');
439 public function moveVersion($version)
446 $message = $this->objectManager->get(NoticeStatus::class);
447 $message->setTitle(
'Moving TYPO3 CMS core files skipped');
450 $downloadedCoreLocation = $this->downloadTargetPath .
'typo3_src-' . $version;
451 $newCoreLocation = @realPath($this->symlinkToCoreFiles .
'/../') .
'/typo3_src-' . $version;
453 if (!@is_dir($downloadedCoreLocation)) {
456 $message = $this->objectManager->get(ErrorStatus::class);
457 $message->setTitle(
'Unpacked TYPO3 CMS core not found');
460 $moveResult = rename($downloadedCoreLocation, $newCoreLocation);
464 $message = $this->objectManager->get(ErrorStatus::class);
465 $message->setTitle(
'Moving TYPO3 CMS core to ' . $newCoreLocation .
' failed');
468 $message = $this->objectManager->get(OkStatus::class);
469 $message->setTitle(
'Moved TYPO3 CMS core to final location');
485 public function activateVersion($version)
487 $newCoreLocation = @realPath($this->symlinkToCoreFiles .
'/../') .
'/typo3_src-' . $version;
492 if (!is_dir($newCoreLocation)) {
495 $message = $this->objectManager->get(ErrorStatus::class);
496 $message->setTitle(
'New TYPO3 CMS core not found');
498 }
elseif (!is_link($this->symlinkToCoreFiles)) {
501 $message = $this->objectManager->get(ErrorStatus::class);
502 $message->setTitle(
'TYPO3 CMS core source directory (typo3_src) is not a link');
506 $unlinkResult = unlink($this->symlinkToCoreFiles);
507 if (!$unlinkResult) {
510 $message = $this->objectManager->get(ErrorStatus::class);
511 $message->setTitle(
'Removing old symlink failed');
514 if (!$isCurrentCoreSymlinkAbsolute) {
517 $symlinkResult = symlink($newCoreLocation, $this->symlinkToCoreFiles);
518 if ($symlinkResult) {
523 $message = $this->objectManager->get(ErrorStatus::class);
524 $message->setTitle(
'Linking new TYPO3 CMS core failed');
542 return $this->downloadTargetPath . $version .
'.tar.gz';
553 $sourcePath = explode(DIRECTORY_SEPARATOR, rtrim(PATH_site, DIRECTORY_SEPARATOR));
554 $targetPath = explode(DIRECTORY_SEPARATOR, rtrim($absolutePath, DIRECTORY_SEPARATOR));
555 while (count($sourcePath) && count($targetPath) && $sourcePath[0] === $targetPath[0]) {
556 array_shift($sourcePath);
557 array_shift($targetPath);
559 return str_pad(
'', count($sourcePath) * 3,
'..' . DIRECTORY_SEPARATOR) . implode(DIRECTORY_SEPARATOR, $targetPath);
571 $newCoreLocation = @realPath($this->symlinkToCoreFiles .
'/../') .
'/typo3_src-' . $version;
572 return @is_dir($newCoreLocation);