‪TYPO3CMS  ‪main
CoreVersionService.php
Go to the documentation of this file.
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 
19 
26 
31 class CoreVersionService
32 {
38  protected $apiBaseUrl = 'https://get.typo3.org/api/v1/';
39 
46  public function isInstalledVersionAReleasedVersion(): bool
47  {
48  $version = $this->getInstalledVersion();
49  return substr($version, -4) !== '-dev';
50  }
51 
55  public function getInstalledVersion(): string
56  {
57  return (string)GeneralUtility::makeInstance(Typo3Version::class);
58  }
59 
60  public function getMaintenanceWindow(): MaintenanceWindow
61  {
62  ‪$url = 'major/' . $this->getInstalledMajorVersion();
63  $result = $this->fetchFromRemote(‪$url);
64 
66  }
67 
72  public function getSupportedMajorReleases(): array
73  {
74  ‪$url = 'major';
75  $result = $this->fetchFromRemote(‪$url);
76 
77  $majorReleases = [
78  'community' => [],
79  'elts' => [],
80  ];
81  foreach ($result as $release) {
82  $majorRelease = ‪MajorRelease::fromApiResponse($release);
83  $maintenanceWindow = $majorRelease->getMaintenanceWindow();
84 
85  if ($maintenanceWindow->isSupportedByCommunity()) {
86  $group = 'community';
87  } elseif ($maintenanceWindow->isSupportedByElts()) {
88  $group = 'elts';
89  } else {
90  // Major version is unsupported
91  continue;
92  }
93 
94  $majorReleases[$group][] = $majorRelease->getLts() ?? $majorRelease->getVersion();
95  }
96 
97  return $majorReleases;
98  }
99 
100  public function isPatchReleaseSuitableForUpdate(CoreRelease $coreRelease): bool
101  {
102  return version_compare($this->getInstalledVersion(), $coreRelease->getVersion()) === -1;
103  }
104 
111  public function isUpdateSecurityRelevant(CoreRelease $releaseToCheck): bool
112  {
113  ‪$url = 'major/' . $this->getInstalledMajorVersion() . '/release';
114  $result = $this->fetchFromRemote(‪$url);
115 
116  $installedVersion = $this->getInstalledVersion();
117  foreach ($result as $release) {
118  $coreRelease = ‪CoreRelease::fromApiResponse($release);
119  if ($coreRelease->isSecurityUpdate()
120  && version_compare($installedVersion, $coreRelease->getVersion()) === -1 // installed version is lower than release
121  && version_compare($releaseToCheck->getVersion(), $coreRelease->getVersion()) > -1 // release to check is equal or higher than release
122  ) {
123  return true;
124  }
125  }
126 
127  return false;
128  }
129 
130  public function isCurrentInstalledVersionElts(): bool
131  {
132  ‪$url = 'major/' . $this->getInstalledMajorVersion() . '/release';
133  $result = $this->fetchFromRemote(‪$url);
134 
135  $installedVersion = $this->getInstalledVersion();
136  foreach ($result as $release) {
137  if (version_compare($installedVersion, $release['version']) === 0) {
138  return $release['elts'] ?? false;
139  }
140  }
141 
142  return false;
143  }
144 
150  public function getYoungestPatchRelease(): CoreRelease
151  {
152  ‪$url = 'major/' . $this->getInstalledMajorVersion() . '/release/latest';
153  $result = $this->fetchFromRemote(‪$url);
154  return ‪CoreRelease::fromApiResponse($result);
155  }
156 
157  public function getYoungestCommunityPatchRelease(): CoreRelease
158  {
159  ‪$url = 'major/' . $this->getInstalledMajorVersion() . '/release';
160  $result = $this->fetchFromRemote(‪$url);
161 
162  // Make sure all releases are sorted by their version
163  $columns = array_column($result, 'version');
164  array_multisort($columns, SORT_NATURAL, $result);
165 
166  // Remove any ELTS release
167  $releases = array_filter($result, static function (array $release) {
168  return ($release['elts'] ?? false) === false;
169  });
170 
171  $latestRelease = end($releases);
172 
173  return ‪CoreRelease::fromApiResponse($latestRelease);
174  }
175 
179  protected function fetchFromRemote(string ‪$url): array
180  {
181  ‪$url = $this->apiBaseUrl . ‪$url;
183 
184  if (!$json) {
185  $this->throwFetchException(‪$url);
186  }
187  return json_decode($json, true);
188  }
189 
195  protected function getInstalledMajorVersion(): string
196  {
197  return (string)GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion();
198  }
199 
205  protected function throwFetchException(string ‪$url): void
206  {
207  throw new RemoteFetchException(
208  'Fetching ' .
209  ‪$url .
210  ' failed. Maybe this instance can not connect to the remote system properly.',
211  1380897593
212  );
213  }
214 }
‪TYPO3\CMS\Core\Information\Typo3Version
Definition: Typo3Version.php:21
‪TYPO3\CMS\Install\CoreVersion\MajorRelease\fromApiResponse
‪static fromApiResponse(array $response)
Definition: MajorRelease.php:29
‪TYPO3\CMS\Install\CoreVersion\MaintenanceWindow
Definition: MaintenanceWindow.php:21
‪TYPO3\CMS\Install\CoreVersion\CoreRelease
Definition: CoreRelease.php:21
‪TYPO3\CMS\Core\Utility\GeneralUtility\getUrl
‪static string false getUrl(string $url)
Definition: GeneralUtility.php:1444
‪TYPO3\CMS\Install\CoreVersion\CoreRelease\fromApiResponse
‪static fromApiResponse(array $response)
Definition: CoreRelease.php:33
‪TYPO3\CMS\Install\CoreVersion\MaintenanceWindow\fromApiResponse
‪static fromApiResponse(array $response)
Definition: MaintenanceWindow.php:27
‪TYPO3\CMS\Install\Service\Exception\RemoteFetchException
Definition: RemoteFetchException.php:23
‪TYPO3\CMS\Webhooks\Message\$url
‪identifier readonly UriInterface $url
Definition: LoginErrorOccurredMessage.php:36
‪TYPO3\CMS\Install\CoreVersion\MajorRelease
Definition: MajorRelease.php:21
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Install\Service
Definition: ClearCacheService.php:16