Completed
Push — master ( e28c49...c020e9 )
by
unknown
19:48
created

CoreVersionService::getTarGzSha1OfVersion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Install\Service;
19
20
use TYPO3\CMS\Core\Information\Typo3Version;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
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
     * Base URI for TYPO3 Version REST api
31
     *
32
     * @var string
33
     */
34
    protected $apiBaseUrl = 'https://get.typo3.org/v1/api/';
35
36
    /**
37
     * Development git checkout versions always end with '-dev'. They are
38
     * not "released" as such and can not be updated.
39
     *
40
     * @return bool FALSE If some development version is installed
41
     */
42
    public function isInstalledVersionAReleasedVersion(): bool
43
    {
44
        $version = $this->getInstalledVersion();
45
        return substr($version, -4) !== '-dev';
46
    }
47
48
    /**
49
     * Get sha1 of a version from version matrix
50
     *
51
     * @param string $version A version to get sha1 of
52
     * @return string sha1 of version
53
     * @throws Exception\CoreVersionServiceException
54
     */
55
    public function getTarGzSha1OfVersion(string $version): string
56
    {
57
        $url = 'release/' . $version;
58
        $result = $this->fetchFromRemote($url);
59
60
        return $result['tar_package']['sha1sum'] ?? '';
61
    }
62
63
    /**
64
     * Get current installed version number
65
     *
66
     * @return string
67
     */
68
    public function getInstalledVersion(): string
69
    {
70
        return (string)GeneralUtility::makeInstance(Typo3Version::class);
71
    }
72
73
    /**
74
     * Checks if TYPO3 version (e.g. 6.2) is an actively maintained version
75
     *
76
     * @return bool TRUE if version is actively maintained
77
     * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
78
     */
79
    public function isVersionActivelyMaintained(): bool
80
    {
81
        $url = 'major/' . $this->getInstalledMajorVersion();
82
        $result = $this->fetchFromRemote($url);
83
84
        return !isset($result['maintained_until']) ||
85
               (
86
                   new \DateTimeImmutable($result['maintained_until']) >=
87
                   new \DateTimeImmutable('now', new \DateTimeZone('UTC'))
88
               );
89
    }
90
91
    /**
92
     * Returns TRUE if a younger patch level release exists in version matrix.
93
     *
94
     * @return bool TRUE if younger patch release is exists
95
     * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
96
     */
97
    public function isYoungerPatchReleaseAvailable(): bool
98
    {
99
        return version_compare($this->getInstalledVersion(), $this->getYoungestPatchRelease()) === -1;
100
    }
101
102
    /**
103
     * Returns TRUE if an upgrade from current version is security relevant
104
     *
105
     * @return bool TRUE if there is a pending security update
106
     * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
107
     */
108
    public function isUpdateSecurityRelevant(): bool
109
    {
110
        $url = 'major/' . $this->getInstalledMajorVersion() . '/release/latest/security';
111
        $result = $this->fetchFromRemote($url);
112
113
        if (isset($result['version'])) {
114
            return version_compare($this->getInstalledVersion(), $result['version']) === -1;
115
        }
116
        return false;
117
    }
118
119
    /**
120
     * Youngest patch release, e.g., 6.2.2
121
     *
122
     * @return string Version string of youngest patch level release
123
     * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
124
     */
125
    public function getYoungestPatchRelease(): string
126
    {
127
        $url = 'major/' . $this->getInstalledMajorVersion() . '/release/latest';
128
        $result = $this->fetchFromRemote($url);
129
        return $result['version'];
130
    }
131
132
    /**
133
     * @param string $url
134
     * @return array
135
     * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
136
     */
137
    protected function fetchFromRemote(string $url): array
138
    {
139
        $url = $this->apiBaseUrl . $url;
140
        $json = GeneralUtility::getUrl($url);
141
142
        if (!$json) {
143
            $this->throwFetchException($url);
144
        }
145
        return json_decode($json, true);
146
    }
147
148
    /**
149
     * Get 'major version' from installed version of TYPO3, e.g., '7' from '7.3.0'
150
     *
151
     * @return string For example 7
152
     */
153
    protected function getInstalledMajorVersion(): string
154
    {
155
        return (string)GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion();
156
    }
157
158
    /**
159
     * Helper method to throw same exception in multiple places
160
     *
161
     * @param string $url
162
     * @throws \TYPO3\CMS\Install\Service\Exception\RemoteFetchException
163
     */
164
    protected function throwFetchException(string $url): void
165
    {
166
        throw new Exception\RemoteFetchException(
167
            'Fetching ' .
168
            $url .
169
            ' failed. Maybe this instance can not connect to the remote system properly.',
170
            1380897593
171
        );
172
    }
173
}
174