[!!!][TASK] Remove deprecated code from EXT:install
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Service / CoreVersionService.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Install\Service;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use TYPO3\CMS\Core\Registry;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Core\Utility\VersionNumberUtility;
22
23 /**
24 * Core version service
25 * @internal This class is only meant to be used within EXT:install and is not part of the TYPO3 Core API.
26 */
27 class CoreVersionService
28 {
29 /**
30 * @var \TYPO3\CMS\Core\Registry
31 */
32 protected $registry;
33
34 /**
35 * Base URI for TYPO3 Version REST api
36 *
37 * @var string
38 */
39 protected $apiBaseUrl = 'https://get.typo3.org/v1/api/';
40
41 /**
42 * Initialize update URI
43 *
44 * @param Registry $registry Deprecated
45 */
46 public function __construct(Registry $registry = null)
47 {
48 if (null !== $registry) {
49 trigger_error(
50 'The constructor parameter $registry for CoreVersionService is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0.',
51 E_USER_DEPRECATED
52 );
53 $this->registry = $registry;
54 } else {
55 $this->registry = GeneralUtility::makeInstance(Registry::class);
56 }
57 }
58
59 /**
60 * Development git checkout versions always end with '-dev'. They are
61 * not "released" as such and can not be updated.
62 *
63 * @return bool FALSE If some development version is installed
64 */
65 public function isInstalledVersionAReleasedVersion(): bool
66 {
67 $version = $this->getInstalledVersion();
68 return substr($version, -4) !== '-dev';
69 }
70
71 /**
72 * Get sha1 of a version from version matrix
73 *
74 * @param string $version A version to get sha1 of
75 * @return string sha1 of version
76 * @throws Exception\CoreVersionServiceException
77 */
78 public function getTarGzSha1OfVersion(string $version): string
79 {
80 $url = 'release/' . $version;
81 $result = $this->fetchFromRemote($url);
82
83 return $result['tar_package']['sha1sum'] ?? '';
84 }
85
86 /**
87 * Get current installed version number
88 *
89 * @return string
90 */
91 public function getInstalledVersion(): string
92 {
93 return VersionNumberUtility::getCurrentTypo3Version();
94 }
95
96 /**
97 * Checks if TYPO3 version (e.g. 6.2) is an actively maintained version
98 *
99 * @return bool TRUE if version is actively maintained
100 * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
101 */
102 public function isVersionActivelyMaintained(): bool
103 {
104 $url = 'major/' . $this->getInstalledMajorVersion();
105 $result = $this->fetchFromRemote($url);
106
107 return !isset($result['maintained_until']) ||
108 (
109 new \DateTimeImmutable($result['maintained_until']) >=
110 new \DateTimeImmutable('now', new \DateTimeZone('UTC'))
111 );
112 }
113
114 /**
115 * Returns TRUE if a younger patch level release exists in version matrix.
116 *
117 * @return bool TRUE if younger patch release is exists
118 * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
119 */
120 public function isYoungerPatchReleaseAvailable(): bool
121 {
122 return version_compare($this->getInstalledVersion(), $this->getYoungestPatchRelease()) === -1;
123 }
124
125 /**
126 * Returns TRUE if an upgrade from current version is security relevant
127 *
128 * @return bool TRUE if there is a pending security update
129 * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
130 */
131 public function isUpdateSecurityRelevant(): bool
132 {
133 $url = 'major/' . $this->getInstalledMajorVersion() . '/release/latest/security';
134 $result = $this->fetchFromRemote($url);
135
136 if (isset($result['version'])) {
137 return version_compare($this->getInstalledVersion(), $result['version']) === -1;
138 }
139 return false;
140 }
141
142 /**
143 * Youngest patch release, e.g., 6.2.2
144 *
145 * @return string Version string of youngest patch level release
146 * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
147 */
148 public function getYoungestPatchRelease(): string
149 {
150 $url = 'major/' . $this->getInstalledMajorVersion() . '/release/latest';
151 $result = $this->fetchFromRemote($url);
152 return $result['version'];
153 }
154
155 /**
156 * @param string $url
157 * @return array
158 * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
159 */
160 protected function fetchFromRemote(string $url): array
161 {
162 $url = $this->apiBaseUrl . $url;
163 $json = GeneralUtility::getUrl($url);
164
165 if (!$json) {
166 $this->throwFetchException($url);
167 }
168 return json_decode($json, true);
169 }
170
171 /**
172 * Get 'major version' from installed version of TYPO3, e.g., '7' from '7.3.0'
173 *
174 * @return string For example 7
175 */
176 protected function getInstalledMajorVersion(): string
177 {
178 return $this->getMajorVersion($this->getInstalledVersion());
179 }
180
181 /**
182 * Get 'major version' of version, e.g., '7' from '7.3.0'
183 *
184 * @param string $version to check
185 * @return string Major version, e.g., '7'
186 */
187 protected function getMajorVersion(string $version): string
188 {
189 $explodedVersion = explode('.', $version);
190 return $explodedVersion[0];
191 }
192
193 /**
194 * Helper method to throw same exception in multiple places
195 *
196 * @param string $url
197 * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
198 */
199 protected function throwFetchException(string $url): void
200 {
201 throw new Exception\RemoteFetchException(
202 'Fetching ' .
203 $url .
204 ' failed. Maybe this instance can not connect to the remote system properly.',
205 1380897593
206 );
207 }
208 }