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