[TASK] Re-work/simplify copyright header in PHP files - Part 2
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Service / CoreVersionService.php
1 <?php
2 namespace TYPO3\CMS\Install\Service;
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\Utility\GeneralUtility;
18 use TYPO3\CMS\Core\Utility\VersionNumberUtility;
19
20 /**
21 * Core version service
22 */
23 class CoreVersionService {
24
25 /**
26 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
27 * @inject
28 */
29 protected $objectManager;
30
31 /**
32 * @var \TYPO3\CMS\Core\Registry
33 * @inject
34 */
35 protected $registry;
36
37 /**
38 * Base URI for TYPO3 downloads
39 *
40 * @var string
41 */
42 protected $downloadBaseUri;
43
44 /**
45 * @return mixed
46 */
47 public function getDownloadBaseUri() {
48 return $this->downloadBaseUri;
49 }
50
51 /**
52 * Initialize update URI
53 */
54 public function __construct() {
55 $this->downloadBaseUri = 'https://get.typo3.org/';
56 }
57
58 /**
59 * Update version matrix from remote and store in registry
60 *
61 * @return void
62 * @throws Exception\RemoteFetchException
63 */
64 public function updateVersionMatrix() {
65 $versionArray = $this->fetchVersionMatrixFromRemote();
66 // This is a 'hack' to keep the string stored in the registry small. We are usually only
67 // interested in information from 6.2 and up and older releases do not matter in current
68 // use cases. If this unset() is removed and everything is stored for some reason, the
69 // table sys_file field entry_value needs to be extended from blob to longblob.
70 unset($versionArray['6.1'], $versionArray['6.0'], $versionArray['4.7'], $versionArray['4.6'],
71 $versionArray['4.5'], $versionArray['4.4'], $versionArray['4.3'], $versionArray['4.2'],
72 $versionArray['4.1'], $versionArray['4.0'], $versionArray['3.8'], $versionArray['3.7'],
73 $versionArray['3.6'], $versionArray['3.5'], $versionArray['3.3']);
74 $this->registry->set('TYPO3.CMS.Install', 'coreVersionMatrix', $versionArray);
75 }
76
77 /**
78 * Development git checkout versions always end with '-dev'. They are
79 * not "released" as such and can not be updated.
80 *
81 * @return boolean FALSE If some development version is installed
82 */
83 public function isInstalledVersionAReleasedVersion() {
84 $version = $this->getInstalledVersion();
85 return substr($version, -4) !== '-dev';
86 }
87
88 /**
89 * Get sha1 of a version from version matrix
90 *
91 * @param string $version A version to get sha1 of
92 * @return string sha1 of version
93 * @throws Exception\CoreVersionServiceException
94 */
95 public function getTarGzSha1OfVersion($version) {
96 $this->ensureVersionExistsInMatrix($version);
97
98 $minorVersion = $this->getMinorVersion($version);
99 $versionMatrix = $this->getVersionMatrix();
100
101 if (empty($versionMatrix[$minorVersion]['releases'][$version]['checksums']['tar']['sha1'])) {
102 throw new Exception\CoreVersionServiceException(
103 'Release sha1 of version ' . $version . ' not found in version matrix.'
104 . ' This is probably a bug on get.typo3.org.',
105 1381263173
106 );
107 }
108
109 return $versionMatrix[$minorVersion]['releases'][$version]['checksums']['tar']['sha1'];
110 }
111
112 /**
113 * Get current installed version number
114 *
115 * @return string
116 */
117 public function getInstalledVersion() {
118 return VersionNumberUtility::getCurrentTypo3Version();
119 }
120
121 /**
122 * Returns TRUE if a younger patch level release exists in version matrix.
123 *
124 * @return boolean TRUE if younger patch release is exists
125 */
126 public function isYoungerPatchReleaseAvailable() {
127 $result = FALSE;
128 $version = $this->getInstalledVersion();
129 $youngestVersion = $this->getYoungestPatchRelease();
130 if ($youngestVersion !== $version) {
131 $result = TRUE;
132 }
133 return $result;
134 }
135
136 /**
137 * Returns TRUE if a younger patch level release exists in version matrix that may be a development release.
138 *
139 * @return boolean TRUE if younger patch release is exists
140 */
141 public function isYoungerPatchDevelopmentReleaseAvailable() {
142 $result = FALSE;
143 $version = $this->getInstalledVersion();
144 $youngestVersion = $this->getYoungestPatchDevelopmentRelease();
145 if ($youngestVersion !== $version) {
146 $result = TRUE;
147 }
148 return $result;
149 }
150
151 /**
152 * Returns TRUE if an upgrade from current version is security relevant
153 *
154 * @return boolean TRUE if there is a pending security update
155 */
156 public function isUpdateSecurityRelevant() {
157 $result = FALSE;
158 $version = $this->getInstalledVersion();
159 $youngestVersion = $this->getYoungestReleaseByType(array('security'));
160 if ($youngestVersion !== $version) {
161 $result = TRUE;
162 }
163 return $result;
164 }
165
166 /**
167 * Youngest patch release, eg. 6.2.2
168 *
169 * @return string Version string of youngest patch level release
170 */
171 public function getYoungestPatchRelease() {
172 return $this->getYoungestReleaseByType(array('release', 'security', 'regular'));
173 }
174
175 /**
176 * Youngest development patch release, eg. 6.2.0alpha3 or 6.2-snapshot-20131004
177 *
178 * @return string
179 */
180 public function getYoungestPatchDevelopmentRelease() {
181 return $this->getYoungestReleaseByType(array('release', 'security', 'regular', 'development'));
182 }
183
184 /**
185 * Get youngest release version string.
186 * Returns same version number if no younger release was found.
187 *
188 * @param array $types List of allowed types: development, release, security, regular
189 * @throws Exception\CoreVersionServiceException
190 * @return string Youngest release, eg. 6.2.3 or 6.2.alpha3
191 */
192 protected function getYoungestReleaseByType(array $types) {
193 $version = $this->getInstalledVersion();
194
195 $minorVersion = $this->getMinorVersion($version);
196 $versionMatrix = $this->getVersionMatrix();
197
198 $youngestRelease = $version;
199 $versionReleaseTimestamp = $this->getReleaseTimestampOfVersion($version);
200
201 $patchLevelVersions = $versionMatrix[$minorVersion]['releases'];
202 foreach ($patchLevelVersions as $aVersionNumber => $aVersionDetails) {
203 if (!array_key_exists('type', $aVersionDetails)) {
204 throw new Exception\CoreVersionServiceException(
205 'Release type of version ' . $aVersionNumber . ' not found in version matrix.'
206 . ' This is probably a bug on get.typo3.org.',
207 1380909029
208 );
209 }
210 $type = $aVersionDetails['type'];
211 $aVersionNumberReleaseTimestamp = $this->getReleaseTimestampOfVersion($aVersionNumber);
212 if (
213 $aVersionNumberReleaseTimestamp > $versionReleaseTimestamp
214 && in_array($type, $types)
215 ) {
216 $youngestRelease = $aVersionNumber;
217 $versionReleaseTimestamp = $aVersionNumberReleaseTimestamp;
218 }
219 }
220 return $youngestRelease;
221 }
222
223 /**
224 * Get 'minor version' from version string, eg '6.2' from '6.2.2'
225 *
226 * @return string For example 6.2
227 */
228 protected function getInstalledMinorVersion() {
229 return $this->getMinorVersion($this->getInstalledVersion());
230 }
231
232 /**
233 * Get 'minor version' of version, eg. '6.2' from '6.2.2'
234 *
235 * @param string $version to check
236 * @return string Minor version, eg. '6.2'
237 */
238 protected function getMinorVersion($version) {
239 $explodedVersion = explode('.', $version);
240 $minor = explode('-', $explodedVersion[1]);
241 return $explodedVersion[0] . '.' . $minor[0];
242 }
243
244 /**
245 * Get version matrix from registry
246 *
247 * @return array
248 * @throws Exception
249 */
250 protected function getVersionMatrix() {
251 $versionMatrix = $this->registry->get('TYPO3.CMS.Install', 'coreVersionMatrix');
252 if (empty($versionMatrix) || !is_array($versionMatrix)) {
253 throw new Exception\CoreVersionServiceException(
254 'No version matrix found in registry, call updateVersionMatrix() first.',
255 1380898792
256 );
257 }
258 return $versionMatrix;
259 }
260
261 /**
262 * Get available version string from get.typo3.org
263 *
264 * @return array
265 * @throws Exception\RemoteFetchException
266 */
267 protected function fetchVersionMatrixFromRemote() {
268 $url = $this->downloadBaseUri . 'json';
269 $versionJson = GeneralUtility::getUrl($url);
270 if (!$versionJson) {
271 throw new Exception\RemoteFetchException(
272 'Fetching ' . $url . ' failed. Maybe this instance can not connect to the remote system properly.',
273 1380897593
274 );
275 }
276 return json_decode($versionJson, TRUE);
277 }
278
279 /**
280 * Returns release timestamp of a specific version
281 *
282 * @param $version String to check in version matrix, eg. 6.2.0alpha3 or 6.2.2
283 * @throws Exception\CoreVersionServiceException
284 * @return integer Timestamp of release
285 */
286 protected function getReleaseTimestampOfVersion($version) {
287 $minorVersion = $this->getMinorVersion($version);
288 $versionMatrix = $this->getVersionMatrix();
289 $this->ensureVersionExistsInMatrix($version);
290 if (!array_key_exists('date', $versionMatrix[$minorVersion]['releases'][$version])) {
291 throw new Exception\CoreVersionServiceException(
292 'Release date of version ' . $version . ' not found in version matrix. This is probably a bug on get.typo3.org',
293 1380905853
294 );
295 }
296 $dateString = $versionMatrix[$minorVersion]['releases'][$version]['date'];
297 $date = new \DateTime($dateString);
298 return $date->getTimestamp();
299 }
300
301 /**
302 * Throws an exception if specified version does not exist in version matrix
303 *
304 * @param $version String to check in version matrix, eg. 6.2.0alpha3 or 6.2.2
305 * @throws Exception\CoreVersionServiceException
306 */
307 protected function ensureVersionExistsInMatrix($version) {
308 $minorVersion = $this->getMinorVersion($version);
309 $versionMatrix = $this->getVersionMatrix();
310 if (!array_key_exists($minorVersion, $versionMatrix)) {
311 throw new Exception\CoreVersionServiceException(
312 'Minor release ' . $minorVersion . ' not found in version matrix.',
313 1380905851
314 );
315 }
316 if (!array_key_exists($version, $versionMatrix[$minorVersion]['releases'])) {
317 throw new Exception\CoreVersionServiceException(
318 'Patch level release ' . $version . ' not found in version matrix.',
319 1380905852
320 );
321 }
322 }
323 }