Translated using Weblate (Portuguese)
[phpmyadmin.git] / src / VersionInformation.php
blob66a08fac474137aa6bb8a884e789bb0ac145efc5
1 <?php
2 /**
3 * Responsible for retrieving version information and notifying about latest version
4 */
6 declare(strict_types=1);
8 namespace PhpMyAdmin;
10 use PhpMyAdmin\Utils\HttpRequest;
12 use function count;
13 use function explode;
14 use function is_array;
15 use function is_numeric;
16 use function is_string;
17 use function json_decode;
18 use function preg_match;
19 use function str_starts_with;
20 use function strlen;
21 use function substr;
22 use function time;
23 use function version_compare;
25 use const PHP_VERSION;
27 /**
28 * Responsible for retrieving version information and notifying about latest version
30 class VersionInformation
32 /**
33 * Returns information with latest version from phpmyadmin.net
35 * @return Release[]|null JSON decoded object with the data
37 public function getLatestVersions(): array|null
39 if (! Config::getInstance()->settings['VersionCheck']) {
40 return null;
43 // Get response text from phpmyadmin.net or from the session
44 // Update cache every 6 hours
45 if (
46 isset($_SESSION['cache']['version_check'])
47 && time() < $_SESSION['cache']['version_check']['timestamp'] + 3600 * 6
48 ) {
49 $save = false;
50 $response = $_SESSION['cache']['version_check']['response'];
51 } else {
52 $save = true;
53 $file = 'https://www.phpmyadmin.net/home_page/version.json';
54 $httpRequest = new HttpRequest();
55 $response = $httpRequest->create($file, 'GET');
58 $response = $response ?: '{}';
59 /* Parse response */
60 $data = json_decode($response, true);
62 /* Basic sanity checking */
63 if (! is_array($data) || ! isset($data['releases']) || ! is_array($data['releases'])) {
64 return null;
67 if ($save) {
68 $_SESSION['cache']['version_check'] = ['response' => $response, 'timestamp' => time()];
71 $releases = [];
72 /** @var string[] $release */
73 foreach ($data['releases'] as $release) {
74 $releases[] = new Release(
75 $release['version'],
76 $release['date'],
77 $release['php_versions'],
78 $release['mysql_versions'],
82 return $releases;
85 /**
86 * Calculates numerical equivalent of phpMyAdmin version string
88 * @param string $version version
90 public function versionToInt(string $version): int
92 $parts = explode('-', $version);
93 $suffix = count($parts) > 1 ? $parts[1] : '';
95 $parts = explode('.', $parts[0]);
97 $result = 0;
99 if (count($parts) >= 1 && is_numeric($parts[0])) {
100 $result += 1000000 * (int) $parts[0];
103 if (count($parts) >= 2 && is_numeric($parts[1])) {
104 $result += 10000 * (int) $parts[1];
107 if (count($parts) >= 3 && is_numeric($parts[2])) {
108 $result += 100 * (int) $parts[2];
111 if (count($parts) >= 4 && is_numeric($parts[3])) {
112 $result += (int) $parts[3];
115 if ($suffix !== '') {
116 $matches = [];
117 if (preg_match('/^(\D+)(\d+)$/', $suffix, $matches)) {
118 $suffix = $matches[1];
119 $result += (int) $matches[2];
122 switch ($suffix) {
123 case 'pl':
124 $result += 60;
125 break;
126 case 'rc':
127 $result += 30;
128 break;
129 case 'beta':
130 $result += 20;
131 break;
132 case 'alpha':
133 $result += 10;
134 break;
135 case 'dev':
136 break;
138 } else {
139 $result += 50; // for final
142 return $result;
146 * Returns the version and date of the latest phpMyAdmin version compatible
147 * with the available PHP and MySQL versions
149 * @param Release[] $releases array of information related to each version
151 * @return Release|null containing the version and date of latest compatible version
153 public function getLatestCompatibleVersion(array $releases): Release|null
155 // Maintains the latest compatible version
156 $latestRelease = null;
157 foreach ($releases as $release) {
158 $phpVersions = $release->phpVersions;
159 $phpConditions = explode(',', $phpVersions);
160 foreach ($phpConditions as $phpCondition) {
161 if (! $this->evaluateVersionCondition('PHP', $phpCondition)) {
162 /** @infection-ignore-all */
163 continue 2;
167 // We evaluate MySQL version constraint if there are only
168 // one server configured.
169 if (count(Config::getInstance()->settings['Servers']) === 1) {
170 $mysqlVersions = $release->mysqlVersions;
171 $mysqlConditions = explode(',', $mysqlVersions);
172 foreach ($mysqlConditions as $mysqlCondition) {
173 if (! $this->evaluateVersionCondition('MySQL', $mysqlCondition)) {
174 continue 2;
179 // To compare the current release with the previous latest release or no release is set
180 if ($latestRelease !== null && ! version_compare($latestRelease->version, $release->version, '<')) {
181 continue;
184 $latestRelease = $release;
187 // no compatible version
188 return $latestRelease;
192 * Checks whether PHP or MySQL version meets supplied version condition
194 * @param string $type PHP or MySQL
195 * @param string $condition version condition
197 * @return bool whether the condition is met
199 public function evaluateVersionCondition(string $type, string $condition): bool
201 $operator = null;
202 $version = null;
203 $operators = ['<=', '>=', '!=', '<>', '<', '>', '=']; // preserve order
204 foreach ($operators as $oneOperator) {
205 if (str_starts_with($condition, $oneOperator)) {
206 $operator = $oneOperator;
207 $version = substr($condition, strlen($oneOperator));
208 break;
212 $myVersion = null;
213 if ($type === 'PHP') {
214 $myVersion = $this->getPHPVersion();
215 } elseif ($type === 'MySQL') {
216 $myVersion = $this->getMySQLVersion();
219 if (is_string($myVersion) && is_string($version) && is_string($operator)) {
220 return version_compare($myVersion, $version, $operator);
223 return false;
227 * Returns the PHP version
229 * @return string PHP version
231 protected function getPHPVersion(): string
233 return PHP_VERSION;
237 * Returns the MySQL version if connected to a database
239 * @return string|null MySQL version
241 protected function getMySQLVersion(): string|null
243 $dbi = DatabaseInterface::getInstance();
245 return $dbi->isConnected() ? $dbi->getVersionString() : null;