2 declare(strict_types = 1);
30 class CoreVersionService
42 protected $apiBaseUrl =
'https://get.typo3.org/v1/api/';
49 public function __construct(Registry $registry =
null)
51 if (
null !== $registry) {
53 'The constructor parameter $registry for CoreVersionService is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0.',
56 $this->registry = $registry;
58 $this->registry = GeneralUtility::makeInstance(Registry::class);
68 public function isInstalledVersionAReleasedVersion(): bool
70 $version = $this->getInstalledVersion();
71 return substr($version, -4) !==
'-dev';
79 public function getInstalledVersion(): string
84 public function getMaintenanceWindow(): MaintenanceWindow
86 $url =
'major/' . $this->getInstalledMajorVersion();
87 $result = $this->fetchFromRemote($url);
95 public function getSupportedMajorReleases(): array
98 $result = $this->fetchFromRemote($url);
104 foreach ($result as $release) {
106 $maintenanceWindow = $majorRelease->getMaintenanceWindow();
108 if ($maintenanceWindow->isSupportedByCommunity()) {
109 $group =
'community';
110 } elseif ($maintenanceWindow->isSupportedByElts()) {
117 $majorReleases[$group][] = $majorRelease->getLts() ?? $majorRelease->getVersion();
120 return $majorReleases;
123 public function isPatchReleaseSuitableForUpdate(CoreRelease $coreRelease): bool
125 return version_compare($this->getInstalledVersion(), $coreRelease->getVersion()) === -1;
134 public function isYoungerPatchReleaseAvailable(): bool
136 return version_compare($this->getInstalledVersion(), $this->getYoungestPatchRelease()->getVersion()) === -1;
145 public function isUpdateSecurityRelevant(CoreRelease $releaseToCheck): bool
147 $url =
'major/' . $this->getInstalledMajorVersion() .
'/release';
148 $result = $this->fetchFromRemote($url);
150 $installedVersion = $this->getInstalledVersion();
151 foreach ($result as $release) {
153 if ($coreRelease->isSecurityUpdate()
154 && version_compare($installedVersion, $coreRelease->getVersion()) === -1
155 && version_compare($releaseToCheck->getVersion(), $coreRelease->getVersion()) > -1
164 public function isCurrentInstalledVersionElts(): bool
166 $url =
'major/' . $this->getInstalledMajorVersion() .
'/release';
167 $result = $this->fetchFromRemote($url);
169 $installedVersion = $this->getInstalledVersion();
170 foreach ($result as $release) {
171 if (version_compare($installedVersion, $release[
'version']) === 0) {
172 return $release[
'elts'] ??
false;
185 public function getYoungestPatchRelease(): CoreRelease
187 $url =
'major/' . $this->getInstalledMajorVersion() .
'/release/latest';
188 $result = $this->fetchFromRemote($url);
192 public function getYoungestCommunityPatchRelease(): CoreRelease
194 $url =
'major/' . $this->getInstalledMajorVersion() .
'/release';
195 $result = $this->fetchFromRemote($url);
198 $columns = array_column($result,
'version');
199 array_multisort($columns, SORT_NATURAL, $result);
202 $releases = array_filter($result,
static function (array $release) {
203 return ($release[
'elts'] ??
false) ===
false;
206 $latestRelease = end($releases);
216 protected function fetchFromRemote(
string $url): array
218 $url = $this->apiBaseUrl . $url;
219 $json = GeneralUtility::getUrl($url);
222 $this->throwFetchException($url);
224 return json_decode($json,
true);
232 protected function getInstalledMajorVersion(): string
234 return $this->getMajorVersion($this->getInstalledVersion());
243 protected function getMajorVersion(
string $version): string
245 $explodedVersion = explode(
'.', $version);
246 return $explodedVersion[0];
255 public function updateVersionMatrix(): void
257 trigger_error(
'Method updateVersionMatrix will be removed in TYPO3 v10.0, use new REST API directly (see https://get.typo3.org/v1/api/doc).', E_USER_DEPRECATED);
258 $url =
'https://get.typo3.org/json';
259 $versionJson = GeneralUtility::getUrl($url);
261 $this->throwFetchException($url);
263 $versionArray = json_decode($versionJson,
true);
264 $installedMajorVersion = (int)$this->getInstalledMajorVersion();
266 foreach ($versionArray as $versionNumber => $versionDetails) {
267 if (is_array($versionDetails) && (int)$this->getMajorVersion((
string)$versionNumber) < $installedMajorVersion) {
268 unset($versionArray[$versionNumber]);
272 $this->registry->set(
'TYPO3.CMS.Install',
'coreVersionMatrix', $versionArray);
282 public function getYoungestPatchDevelopmentRelease(): string
285 'Method getYoungestPatchDevelopmentRelease() is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0, use getYoungestPatchRelease() instead.',
288 return $this->getYoungestPatchRelease()->getVersion();
298 public function isYoungerPatchDevelopmentReleaseAvailable(): bool
301 'Method isYoungerPatchDevelopmentReleaseAvailable() is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0, use isYoungerPatchReleaseAvailable() instead.',
304 return $this->isYoungerPatchReleaseAvailable();
311 public function getDownloadBaseUrl(): string
314 'Method getDownloadBaseUrl() is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0, use https://get.typo3.org directly.',
317 return $this->apiBaseUrl;
326 protected function throwFetchException(
string $url): void
328 throw new Exception\RemoteFetchException(
331 ' failed. Maybe this instance can not connect to the remote system properly.',