[BUGFIX] Ensure manually updated slug is saved correctly
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Report / ExtensionStatus.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\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 /**
18 * Extension status reports
19 * @internal This class is a specific EXT:reports implementation and is not part of the Public TYPO3 API.
20 */
21 class ExtensionStatus implements \TYPO3\CMS\Reports\StatusProviderInterface
22 {
23 /**
24 * @var string
25 */
26 protected $ok = '';
27
28 /**
29 * @var string
30 */
31 protected $upToDate = '';
32
33 /**
34 * @var string
35 */
36 protected $error = '';
37
38 /**
39 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
40 */
41 protected $objectManager;
42
43 /**
44 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository
45 */
46 protected $repositoryRepository;
47
48 /**
49 * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
50 */
51 protected $listUtility;
52
53 /**
54 * @var \TYPO3\CMS\Core\Localization\LanguageService
55 */
56 protected $languageService;
57
58 /**
59 * Default constructor
60 */
61 public function __construct()
62 {
63 $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
64 $this->repositoryRepository = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository::class);
65 $this->listUtility = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Utility\ListUtility::class);
66 $this->languageService = $this->objectManager->get(\TYPO3\CMS\Core\Localization\LanguageService::class);
67 $this->languageService->includeLLFile('EXT:extensionmanager/Resources/Private/Language/locallang.xlf');
68 }
69
70 /**
71 * Determines extension manager status
72 *
73 * @return array List of statuses
74 */
75 public function getStatus()
76 {
77 $status = [];
78 $status['mainRepositoryStatus'] = $this->getMainRepositoryStatus();
79
80 $extensionStatus = $this->getSecurityStatusOfExtensions();
81 $status['extensionsSecurityStatusInstalled'] = $extensionStatus->loaded ?? [];
82 $status['extensionsSecurityStatusNotInstalled'] = $extensionStatus->existing ?? [];
83 $status['extensionsOutdatedStatusInstalled'] = $extensionStatus->loadedoutdated ?? [];
84 $status['extensionsOutdatedStatusNotInstalled'] = $extensionStatus->existingoutdated ?? [];
85
86 return $status;
87 }
88
89 /**
90 * Check main repository status: existence, has extensions, last update younger than 7 days
91 *
92 * @return \TYPO3\CMS\Reports\Status
93 */
94 protected function getMainRepositoryStatus()
95 {
96 /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Repository $mainRepository */
97 $mainRepository = $this->repositoryRepository->findOneTypo3OrgRepository();
98
99 if ($mainRepository === null) {
100 $value = $this->languageService->getLL('report.status.mainRepository.notFound.value');
101 $message = $this->languageService->getLL('report.status.mainRepository.notFound.message');
102 $severity = \TYPO3\CMS\Reports\Status::ERROR;
103 } elseif ($mainRepository->getLastUpdate()->getTimestamp() < $GLOBALS['EXEC_TIME'] - 24 * 60 * 60 * 7) {
104 $value = $this->languageService->getLL('report.status.mainRepository.notUpToDate.value');
105 $message = $this->languageService->getLL('report.status.mainRepository.notUpToDate.message');
106 $severity = \TYPO3\CMS\Reports\Status::NOTICE;
107 } else {
108 $value = $this->languageService->getLL('report.status.mainRepository.upToDate.value');
109 $message = '';
110 $severity = \TYPO3\CMS\Reports\Status::OK;
111 }
112
113 /** @var \TYPO3\CMS\Reports\Status $status */
114 $status = $this->objectManager->get(
115 \TYPO3\CMS\Reports\Status::class,
116 $this->languageService->getLL('report.status.mainRepository.title'),
117 $value,
118 $message,
119 $severity
120 );
121
122 return $status;
123 }
124
125 /**
126 * Get security status of loaded and installed extensions
127 *
128 * @return \stdClass with properties 'loaded' and 'existing' containing a TYPO3\CMS\Reports\Report\Status\Status object
129 */
130 protected function getSecurityStatusOfExtensions()
131 {
132 $extensionInformation = $this->listUtility->getAvailableAndInstalledExtensionsWithAdditionalInformation();
133 $loadedInsecure = [];
134 $existingInsecure = [];
135 $loadedOutdated = [];
136 $existingOutdated = [];
137 foreach ($extensionInformation as $extensionKey => $information) {
138 if (
139 array_key_exists('terObject', $information)
140 && $information['terObject'] instanceof \TYPO3\CMS\Extensionmanager\Domain\Model\Extension
141 ) {
142 /** @var \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $terObject */
143 $terObject = $information['terObject'];
144 $insecureStatus = $terObject->getReviewState();
145 if ($insecureStatus === -1) {
146 if (
147 array_key_exists('installed', $information)
148 && $information['installed'] === true
149 ) {
150 $loadedInsecure[] = [
151 'extensionKey' => $extensionKey,
152 'version' => $terObject->getVersion(),
153 ];
154 } else {
155 $existingInsecure[] = [
156 'extensionKey' => $extensionKey,
157 'version' => $terObject->getVersion(),
158 ];
159 }
160 } elseif ($insecureStatus === -2) {
161 if (
162 array_key_exists('installed', $information)
163 && $information['installed'] === true
164 ) {
165 $loadedOutdated[] = [
166 'extensionKey' => $extensionKey,
167 'version' => $terObject->getVersion(),
168 ];
169 } else {
170 $existingOutdated[] = [
171 'extensionKey' => $extensionKey,
172 'version' => $terObject->getVersion(),
173 ];
174 }
175 }
176 }
177 }
178
179 $result = new \stdClass();
180
181 if (empty($loadedInsecure)) {
182 $value = $this->languageService->getLL('report.status.loadedExtensions.noInsecureExtensionLoaded.value');
183 $message = '';
184 $severity = \TYPO3\CMS\Reports\Status::OK;
185 } else {
186 $value = sprintf(
187 $this->languageService->getLL('report.status.loadedExtensions.insecureExtensionLoaded.value'),
188 count($loadedInsecure)
189 );
190 $extensionList = [];
191 foreach ($loadedInsecure as $insecureExtension) {
192 $extensionList[] = sprintf(
193 $this->languageService->getLL('report.status.loadedExtensions.insecureExtensionLoaded.message.extension'),
194 $insecureExtension['extensionKey'],
195 $insecureExtension['version']
196 );
197 }
198 $message = sprintf(
199 $this->languageService->getLL('report.status.loadedExtensions.insecureExtensionLoaded.message'),
200 implode('', $extensionList)
201 );
202 $severity = \TYPO3\CMS\Reports\Status::ERROR;
203 }
204 $result->loaded = $this->objectManager->get(
205 \TYPO3\CMS\Reports\Status::class,
206 $this->languageService->getLL('report.status.loadedExtensions.title'),
207 $value,
208 $message,
209 $severity
210 );
211
212 if (empty($existingInsecure)) {
213 $value = $this->languageService->getLL('report.status.existingExtensions.noInsecureExtensionExists.value');
214 $message = '';
215 $severity = \TYPO3\CMS\Reports\Status::OK;
216 } else {
217 $value = sprintf(
218 $this->languageService->getLL('report.status.existingExtensions.insecureExtensionExists.value'),
219 count($existingInsecure)
220 );
221 $extensionList = [];
222 foreach ($existingInsecure as $insecureExtension) {
223 $extensionList[] = sprintf(
224 $this->languageService->getLL('report.status.existingExtensions.insecureExtensionExists.message.extension'),
225 $insecureExtension['extensionKey'],
226 $insecureExtension['version']
227 );
228 }
229 $message = sprintf(
230 $this->languageService->getLL('report.status.existingExtensions.insecureExtensionExists.message'),
231 implode('', $extensionList)
232 );
233 $severity = \TYPO3\CMS\Reports\Status::WARNING;
234 }
235 $result->existing = $this->objectManager->get(
236 \TYPO3\CMS\Reports\Status::class,
237 $this->languageService->getLL('report.status.existingExtensions.title'),
238 $value,
239 $message,
240 $severity
241 );
242
243 if (empty($loadedOutdated)) {
244 $value = $this->languageService->getLL('report.status.loadedOutdatedExtensions.noOutdatedExtensionLoaded.value');
245 $message = '';
246 $severity = \TYPO3\CMS\Reports\Status::OK;
247 } else {
248 $value = sprintf(
249 $this->languageService->getLL('report.status.loadedOutdatedExtensions.outdatedExtensionLoaded.value'),
250 count($loadedOutdated)
251 );
252 $extensionList = [];
253 foreach ($loadedOutdated as $outdatedExtension) {
254 $extensionList[] = sprintf(
255 $this->languageService->getLL('report.status.loadedOutdatedExtensions.outdatedExtensionLoaded.message.extension'),
256 $outdatedExtension['extensionKey'],
257 $outdatedExtension['version']
258 );
259 }
260 $message = sprintf(
261 $this->languageService->getLL('report.status.loadedOutdatedExtensions.outdatedExtensionLoaded.message'),
262 implode('', $extensionList)
263 );
264 $severity = \TYPO3\CMS\Reports\Status::WARNING;
265 }
266 $result->loadedoutdated = $this->objectManager->get(
267 \TYPO3\CMS\Reports\Status::class,
268 $this->languageService->getLL('report.status.loadedOutdatedExtensions.title'),
269 $value,
270 $message,
271 $severity
272 );
273
274 if (empty($existingOutdated)) {
275 $value = $this->languageService->getLL('report.status.existingOutdatedExtensions.noOutdatedExtensionExists.value');
276 $message = '';
277 $severity = \TYPO3\CMS\Reports\Status::OK;
278 } else {
279 $value = sprintf(
280 $this->languageService->getLL('report.status.existingOutdatedExtensions.outdatedExtensionExists.value'),
281 count($existingOutdated)
282 );
283 $extensionList = [];
284 foreach ($existingOutdated as $outdatedExtension) {
285 $extensionList[] = sprintf(
286 $this->languageService->getLL('report.status.existingOutdatedExtensions.outdatedExtensionExists.message.extension'),
287 $outdatedExtension['extensionKey'],
288 $outdatedExtension['version']
289 );
290 }
291 $message = sprintf(
292 $this->languageService->getLL('report.status.existingOutdatedExtensions.outdatedExtensionExists.message'),
293 implode('', $extensionList)
294 );
295 $severity = \TYPO3\CMS\Reports\Status::WARNING;
296 }
297 $result->existingoutdated = $this->objectManager->get(
298 \TYPO3\CMS\Reports\Status::class,
299 $this->languageService->getLL('report.status.existingOutdatedExtensions.title'),
300 $value,
301 $message,
302 $severity
303 );
304
305 return $result;
306 }
307 }