[TASK] Remove auto-creation of uploads folder
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Report / InstallStatusReport.php
1 <?php
2 namespace TYPO3\CMS\Install\Report;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Localization\LanguageService;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Install\Service\Exception;
20 use TYPO3\CMS\Reports\Status;
21
22 /**
23 * Provides an installation status report.
24 */
25 class InstallStatusReport implements \TYPO3\CMS\Reports\StatusProviderInterface
26 {
27 /**
28 * Compiles a collection of system status checks as a status report.
29 *
30 * @return Status[]
31 */
32 public function getStatus()
33 {
34 return [
35 'FileSystem' => $this->getFileSystemStatus(),
36 'RemainingUpdates' => $this->getRemainingUpdatesStatus(),
37 'NewVersion' => $this->getNewVersionStatus(),
38 ];
39 }
40
41 /**
42 * Checks for several directories being writable.
43 *
44 * @return Status Indicates status of the file system
45 */
46 protected function getFileSystemStatus()
47 {
48 $languageService = $this->getLanguageService();
49 $value = $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_writable');
50 $message = '';
51 $severity = Status::OK;
52 // Requirement level
53 // -1 = not required, but if it exists may be writable or not
54 // 0 = not required, if it exists the dir should be writable
55 // 1 = required, don't has to be writable
56 // 2 = required, has to be writable
57 $checkWritable = [
58 'typo3temp/' => 2,
59 'typo3temp/assets/' => 2,
60 'typo3temp/assets/compressed/' => 2,
61 // only needed when GraphicalFunctions is used
62 'typo3temp/assets/images/' => 0,
63 // used in PageGenerator (inlineStyle2Temp) and Backend + Language JS files
64 'typo3temp/assets/css/' => 2,
65 'typo3temp/assets/js/' => 2,
66 // fallback storage of FAL
67 'typo3temp/assets/_processed_/' => 0,
68 'typo3temp/var/' => 2,
69 'typo3temp/var/transient/' => 2,
70 'typo3temp/var/charset/' => 2,
71 'typo3temp/var/locks/' => 2,
72 'typo3conf/' => 2,
73 'typo3conf/ext/' => 0,
74 'typo3conf/l10n/' => 0,
75 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => -1,
76 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/' => 0,
77 ];
78
79 if ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall']) {
80 $checkWritable[TYPO3_mainDir . 'ext/'] = -1;
81 }
82
83 foreach ($checkWritable as $relPath => $requirementLevel) {
84 if (!@is_dir(PATH_site . $relPath)) {
85 // If the directory is missing, try to create it
86 GeneralUtility::mkdir(PATH_site . $relPath);
87 }
88 if (!@is_dir(PATH_site . $relPath)) {
89 if ($requirementLevel > 0) {
90 // directory is required
91 $value = $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_missingDirectory');
92 $message .= sprintf($languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_directoryDoesNotExistCouldNotCreate'), $relPath) . '<br />';
93 $severity = Status::ERROR;
94 } else {
95 $message .= sprintf($languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_directoryDoesNotExist'), $relPath);
96 if ($requirementLevel == 0) {
97 $message .= ' ' . $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_directoryShouldAlsoBeWritable');
98 }
99 $message .= '<br />';
100 if ($severity < Status::WARNING) {
101 $value = $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_nonExistingDirectory');
102 $severity = Status::WARNING;
103 }
104 }
105 } else {
106 if (!is_writable((PATH_site . $relPath))) {
107 switch ($requirementLevel) {
108 case 0:
109 $message .= sprintf($languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_directoryShouldBeWritable'), (PATH_site . $relPath)) . '<br />';
110 if ($severity < Status::WARNING) {
111 $value = $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_recommendedWritableDirectory');
112 $severity = Status::WARNING;
113 }
114 break;
115 case 2:
116 $value = $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_requiredWritableDirectory');
117 $message .= sprintf($languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_directoryMustBeWritable'), (PATH_site . $relPath)) . '<br />';
118 $severity = Status::ERROR;
119 break;
120 default:
121 }
122 }
123 }
124 }
125 return GeneralUtility::makeInstance(Status::class, $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_fileSystem'), $value, $message, $severity);
126 }
127
128 /**
129 * Checks if there are still updates to perform
130 *
131 * @return Status Represents whether the installation is completely updated yet
132 */
133 protected function getRemainingUpdatesStatus()
134 {
135 $languageService = $this->getLanguageService();
136 $value = $languageService->getLL('status_updateComplete');
137 $message = '';
138 $severity = Status::OK;
139 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
140 $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
141 // check if there are update wizards left to perform
142 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'])) {
143 $versionAsInt = \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version);
144 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'] as $identifier => $className) {
145 $updateObject = GeneralUtility::makeInstance($className, $identifier, $versionAsInt, null, $this);
146 if ($updateObject->shouldRenderWizard()) {
147 // at least one wizard was found
148 $value = $languageService->getLL('status_updateIncomplete');
149 $severity = Status::WARNING;
150 $url = (string)$uriBuilder->buildUriFromRoute('tools_toolsupgrade');
151 $message = sprintf($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:warning.install_update'), '<a href="' . htmlspecialchars($url) . '">', '</a>');
152 break;
153 }
154 }
155 }
156
157 return GeneralUtility::makeInstance(Status::class, $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_remainingUpdates'), $value, $message, $severity);
158 }
159
160 /**
161 * Checks if there is a new minor TYPO3 version to update to.
162 *
163 * @return Status Represents whether there is a new version available online
164 */
165 protected function getNewVersionStatus()
166 {
167 $languageService = $this->getLanguageService();
168 /** @var \TYPO3\CMS\Install\Service\CoreVersionService $coreVersionService */
169 $coreVersionService = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Service\CoreVersionService::class);
170
171 // No updates for development versions
172 if (!$coreVersionService->isInstalledVersionAReleasedVersion()) {
173 return GeneralUtility::makeInstance(Status::class, 'TYPO3', TYPO3_version, $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_isDevelopmentVersion'), Status::NOTICE);
174 }
175
176 // If fetching version matrix fails we can not do anything except print out the current version
177 try {
178 $coreVersionService->updateVersionMatrix();
179 } catch (Exception\RemoteFetchException $remoteFetchException) {
180 return GeneralUtility::makeInstance(Status::class, 'TYPO3', TYPO3_version, $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_remoteFetchException'), Status::NOTICE);
181 }
182
183 try {
184 $isUpdateAvailable = $coreVersionService->isYoungerPatchReleaseAvailable();
185 $isMaintainedVersion = $coreVersionService->isVersionActivelyMaintained();
186 } catch (Exception\CoreVersionServiceException $coreVersionServiceException) {
187 return GeneralUtility::makeInstance(Status::class, 'TYPO3', TYPO3_version, $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_patchLevelNotFoundInReleaseMatrix'), Status::WARNING);
188 }
189
190 if (!$isUpdateAvailable && $isMaintainedVersion) {
191 // Everything is fine, working with the latest version
192 $message = '';
193 $status = Status::OK;
194 } elseif ($isUpdateAvailable) {
195 // There is an update available
196 $newVersion = $coreVersionService->getYoungestPatchRelease();
197 if ($coreVersionService->isUpdateSecurityRelevant()) {
198 $message = sprintf($languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_newVersionSecurityRelevant'), $newVersion);
199 $status = Status::ERROR;
200 } else {
201 $message = sprintf($languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_newVersion'), $newVersion);
202 $status = Status::WARNING;
203 }
204 } else {
205 // Version is not maintained
206 $message = $languageService->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_versionOutdated');
207 $status = Status::ERROR;
208 }
209
210 return GeneralUtility::makeInstance(Status::class, 'TYPO3', TYPO3_version, $message, $status);
211 }
212
213 /**
214 * @return LanguageService
215 */
216 protected function getLanguageService()
217 {
218 return $GLOBALS['LANG'];
219 }
220 }