[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 namespace phpbb; 15 16 use phpbb\exception\version_check_exception; 17 18 /** 19 * Class to handle version checking and comparison 20 */ 21 class version_helper 22 { 23 /** 24 * @var string Host 25 */ 26 protected $host = 'version.phpbb.com'; 27 28 /** 29 * @var string Path to file 30 */ 31 protected $path = '/phpbb'; 32 33 /** 34 * @var string File name 35 */ 36 protected $file = 'versions.json'; 37 38 /** 39 * @var bool Use SSL or not 40 */ 41 protected $use_ssl = false; 42 43 /** 44 * @var string Current version installed 45 */ 46 protected $current_version; 47 48 /** 49 * @var null|string Null to not force stability, 'unstable' or 'stable' to 50 * force the corresponding stability 51 */ 52 protected $force_stability; 53 54 /** @var \phpbb\cache\service */ 55 protected $cache; 56 57 /** @var \phpbb\config\config */ 58 protected $config; 59 60 /** @var \phpbb\file_downloader */ 61 protected $file_downloader; 62 63 protected $version_schema = array( 64 'stable' => array( 65 'current' => 'version', 66 'download' => 'url', 67 'announcement' => 'url', 68 'eol' => 'url', 69 'security' => 'bool', 70 ), 71 'unstable' => array( 72 'current' => 'version', 73 'download' => 'url', 74 'announcement' => 'url', 75 'eol' => 'url', 76 'security' => 'bool', 77 ), 78 ); 79 80 /** 81 * Constructor 82 * 83 * @param \phpbb\cache\service $cache 84 * @param \phpbb\config\config $config 85 * @param \phpbb\file_downloader $file_downloader 86 */ 87 public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\file_downloader $file_downloader) 88 { 89 $this->cache = $cache; 90 $this->config = $config; 91 $this->file_downloader = $file_downloader; 92 93 if (defined('PHPBB_QA')) 94 { 95 $this->force_stability = 'unstable'; 96 } 97 98 $this->current_version = $this->config['version']; 99 } 100 101 /** 102 * Set location to the file 103 * 104 * @param string $host Host (e.g. version.phpbb.com) 105 * @param string $path Path to file (e.g. /phpbb) 106 * @param string $file File name (Default: versions.json) 107 * @param bool $use_ssl Use SSL or not (Default: false) 108 * @return version_helper 109 */ 110 public function set_file_location($host, $path, $file = 'versions.json', $use_ssl = false) 111 { 112 $this->host = $host; 113 $this->path = $path; 114 $this->file = $file; 115 $this->use_ssl = $use_ssl; 116 117 return $this; 118 } 119 120 /** 121 * Set current version 122 * 123 * @param string $version The current version 124 * @return version_helper 125 */ 126 public function set_current_version($version) 127 { 128 $this->current_version = $version; 129 130 return $this; 131 } 132 133 /** 134 * Over-ride the stability to force check to include unstable versions 135 * 136 * @param null|string Null to not force stability, 'unstable' or 'stable' to 137 * force the corresponding stability 138 * @return version_helper 139 */ 140 public function force_stability($stability) 141 { 142 $this->force_stability = $stability; 143 144 return $this; 145 } 146 147 /** 148 * Wrapper for version_compare() that allows using uppercase A and B 149 * for alpha and beta releases. 150 * 151 * See http://www.php.net/manual/en/function.version-compare.php 152 * 153 * @param string $version1 First version number 154 * @param string $version2 Second version number 155 * @param string $operator Comparison operator (optional) 156 * 157 * @return mixed Boolean (true, false) if comparison operator is specified. 158 * Integer (-1, 0, 1) otherwise. 159 */ 160 public function compare($version1, $version2, $operator = null) 161 { 162 return phpbb_version_compare($version1, $version2, $operator); 163 } 164 165 /** 166 * Check whether or not a version is "stable" 167 * 168 * Stable means only numbers OR a pl release 169 * 170 * @param string $version 171 * @return bool Bool true or false 172 */ 173 public function is_stable($version) 174 { 175 $matches = false; 176 preg_match('/^[\d\.]+/', $version, $matches); 177 178 if (empty($matches[0])) 179 { 180 return false; 181 } 182 183 return $this->compare($version, $matches[0], '>='); 184 } 185 186 /** 187 * Gets the latest version for the current branch the user is on 188 * 189 * @param bool $force_update Ignores cached data. Defaults to false. 190 * @param bool $force_cache Force the use of the cache. Override $force_update. 191 * @return string 192 * @throws version_check_exception 193 */ 194 public function get_latest_on_current_branch($force_update = false, $force_cache = false) 195 { 196 $versions = $this->get_versions_matching_stability($force_update, $force_cache); 197 198 $self = $this; 199 $current_version = $this->current_version; 200 201 // Filter out any versions less than the current version 202 $versions = array_filter($versions, function($data) use ($self, $current_version) { 203 return $self->compare($data['current'], $current_version, '>='); 204 }); 205 206 // Get the lowest version from the previous list. 207 return array_reduce($versions, function($value, $data) use ($self) { 208 if ($value === null || $self->compare($data['current'], $value, '<')) 209 { 210 return $data['current']; 211 } 212 213 return $value; 214 }); 215 } 216 217 /** 218 * Gets the latest update for the current branch the user is on 219 * Will suggest versions from newer branches when EoL has been reached 220 * and/or version from newer branch is needed for having all known security 221 * issues fixed. 222 * 223 * @param bool $force_update Ignores cached data. Defaults to false. 224 * @param bool $force_cache Force the use of the cache. Override $force_update. 225 * @return array Version info or empty array if there are no updates 226 * @throws \RuntimeException 227 */ 228 public function get_update_on_branch($force_update = false, $force_cache = false) 229 { 230 $versions = $this->get_versions_matching_stability($force_update, $force_cache); 231 232 $self = $this; 233 $current_version = $this->current_version; 234 235 // Filter out any versions less than the current version 236 $versions = array_filter($versions, function($data) use ($self, $current_version) { 237 return $self->compare($data['current'], $current_version, '>='); 238 }); 239 240 // Get the lowest version from the previous list. 241 $update_info = array_reduce($versions, function($value, $data) use ($self, $current_version) { 242 if ($value === null && $self->compare($data['current'], $current_version, '>=')) 243 { 244 if (!$data['eol'] && (!$data['security'] || $self->compare($data['security'], $data['current'], '<='))) 245 { 246 return ($self->compare($data['current'], $current_version, '>')) ? $data : array(); 247 } 248 else 249 { 250 return null; 251 } 252 } 253 254 return $value; 255 }); 256 257 return $update_info === null ? array() : $update_info; 258 } 259 260 /** 261 * Gets the latest extension update for the current phpBB branch the user is on 262 * Will suggest versions from newer branches when EoL has been reached 263 * and/or version from newer branch is needed for having all known security 264 * issues fixed. 265 * 266 * @param bool $force_update Ignores cached data. Defaults to false. 267 * @param bool $force_cache Force the use of the cache. Override $force_update. 268 * @return array Version info or empty array if there are no updates 269 * @throws \RuntimeException 270 */ 271 public function get_ext_update_on_branch($force_update = false, $force_cache = false) 272 { 273 $versions = $this->get_versions_matching_stability($force_update, $force_cache); 274 275 $self = $this; 276 $current_version = $this->current_version; 277 278 // Get current phpBB branch from version, e.g.: 3.2 279 preg_match('/^(\d+\.\d+).*$/', $this->config['version'], $matches); 280 $current_branch = $matches[1]; 281 282 // Filter out any versions less than the current version 283 $versions = array_filter($versions, function($data) use ($self, $current_version) { 284 return $self->compare($data['current'], $current_version, '>='); 285 }); 286 287 // Filter out any phpbb branches less than the current version 288 $branches = array_filter(array_keys($versions), function($branch) use ($self, $current_branch) { 289 return $self->compare($branch, $current_branch, '>='); 290 }); 291 if (!empty($branches)) 292 { 293 $versions = array_intersect_key($versions, array_flip($branches)); 294 } 295 else 296 { 297 // If branches are empty, it means the current phpBB branch is newer than any branch the 298 // extension was validated against. Reverse sort the versions array so we get the newest 299 // validated release available. 300 krsort($versions); 301 } 302 303 // Get the first available version from the previous list. 304 $update_info = array_reduce($versions, function($value, $data) use ($self, $current_version) { 305 if ($value === null && $self->compare($data['current'], $current_version, '>=')) 306 { 307 if (!$data['eol'] && (!$data['security'] || $self->compare($data['security'], $data['current'], '<='))) 308 { 309 return $self->compare($data['current'], $current_version, '>') ? $data : array(); 310 } 311 else 312 { 313 return null; 314 } 315 } 316 317 return $value; 318 }); 319 320 return $update_info === null ? array() : $update_info; 321 } 322 323 /** 324 * Obtains the latest version information 325 * 326 * @param bool $force_update Ignores cached data. Defaults to false. 327 * @param bool $force_cache Force the use of the cache. Override $force_update. 328 * @return array 329 * @throws version_check_exception 330 */ 331 public function get_suggested_updates($force_update = false, $force_cache = false) 332 { 333 $versions = $this->get_versions_matching_stability($force_update, $force_cache); 334 335 $self = $this; 336 $current_version = $this->current_version; 337 338 // Filter out any versions less than or equal to the current version 339 return array_filter($versions, function($data) use ($self, $current_version) { 340 return $self->compare($data['current'], $current_version, '>'); 341 }); 342 } 343 344 /** 345 * Obtains the latest version information matching the stability of the current install 346 * 347 * @param bool $force_update Ignores cached data. Defaults to false. 348 * @param bool $force_cache Force the use of the cache. Override $force_update. 349 * @return array Version info 350 * @throws version_check_exception 351 */ 352 public function get_versions_matching_stability($force_update = false, $force_cache = false) 353 { 354 $info = $this->get_versions($force_update, $force_cache); 355 356 if ($this->force_stability !== null) 357 { 358 return ($this->force_stability === 'unstable') ? $info['unstable'] : $info['stable']; 359 } 360 361 return ($this->is_stable($this->current_version)) ? $info['stable'] : $info['unstable']; 362 } 363 364 /** 365 * Obtains the latest version information 366 * 367 * @param bool $force_update Ignores cached data. Defaults to false. 368 * @param bool $force_cache Force the use of the cache. Override $force_update. 369 * @return array Version info, includes stable and unstable data 370 * @throws version_check_exception 371 */ 372 public function get_versions($force_update = false, $force_cache = false) 373 { 374 $cache_file = '_versioncheck_' . $this->host . $this->path . $this->file . $this->use_ssl; 375 376 $info = $this->cache->get($cache_file); 377 378 if ($info === false && $force_cache) 379 { 380 throw new version_check_exception('VERSIONCHECK_FAIL'); 381 } 382 else if ($info === false || $force_update) 383 { 384 $info = $this->file_downloader->get($this->host, $this->path, $this->file, $this->use_ssl ? 443 : 80); 385 $error_string = $this->file_downloader->get_error_string(); 386 387 if (!empty($error_string)) 388 { 389 throw new version_check_exception($error_string); 390 } 391 392 $info = json_decode($info, true); 393 394 // Sanitize any data we retrieve from a server 395 if (!empty($info)) 396 { 397 $json_sanitizer = function (&$value, $key) { 398 $type_cast_helper = new \phpbb\request\type_cast_helper(); 399 $type_cast_helper->set_var($value, $value, gettype($value), true); 400 }; 401 array_walk_recursive($info, $json_sanitizer); 402 } 403 404 if (empty($info['stable']) && empty($info['unstable'])) 405 { 406 throw new version_check_exception('VERSIONCHECK_FAIL'); 407 } 408 409 $info['stable'] = (empty($info['stable'])) ? array() : $info['stable']; 410 $info['unstable'] = (empty($info['unstable'])) ? $info['stable'] : $info['unstable']; 411 412 $info = $this->validate_versions($info); 413 414 $this->cache->put($cache_file, $info, 86400); // 24 hours 415 } 416 417 return $info; 418 } 419 420 /** 421 * Validate versions info input 422 * 423 * @param array $versions_info Decoded json data array. Will be modified 424 * and cleaned by this method 425 * 426 * @return array Versions info array 427 * @throws version_check_exception 428 */ 429 public function validate_versions($versions_info) 430 { 431 $array_diff = array_diff_key($versions_info, array($this->version_schema)); 432 433 // Remove excessive data 434 if (count($array_diff) > 0) 435 { 436 $old_versions_info = $versions_info; 437 $versions_info = array( 438 'stable' => !empty($old_versions_info['stable']) ? $old_versions_info['stable'] : array(), 439 'unstable' => !empty($old_versions_info['unstable']) ? $old_versions_info['unstable'] : array(), 440 ); 441 unset($old_versions_info); 442 } 443 444 foreach ($versions_info as $stability_type => &$versions_data) 445 { 446 foreach ($versions_data as $branch => &$version_data) 447 { 448 if (!preg_match('/^[0-9a-z\-\.]+$/i', $branch)) 449 { 450 unset($versions_data[$branch]); 451 continue; 452 } 453 454 $stability_diff = array_diff_key($version_data, $this->version_schema[$stability_type]); 455 456 if (count($stability_diff) > 0) 457 { 458 $old_version_data = $version_data; 459 $version_data = array(); 460 foreach ($this->version_schema[$stability_type] as $key => $value) 461 { 462 if (isset($old_version_data[$key])) 463 { 464 $version_data[$key] = $old_version_data[$key]; 465 } 466 } 467 unset($old_version_data); 468 } 469 470 foreach ($version_data as $key => &$value) 471 { 472 if (!isset($this->version_schema[$stability_type][$key])) 473 { 474 unset($version_data[$key]); 475 throw new version_check_exception('VERSIONCHECK_INVALID_ENTRY'); 476 } 477 478 switch ($this->version_schema[$stability_type][$key]) 479 { 480 case 'bool': 481 $value = (bool) $value; 482 break; 483 484 case 'url': 485 if (!empty($value) && !preg_match('#^' . get_preg_expression('url') . '$#iu', $value) && 486 !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $value)) 487 { 488 throw new version_check_exception('VERSIONCHECK_INVALID_URL'); 489 } 490 break; 491 492 case 'version': 493 if (!empty($value) && !preg_match(get_preg_expression('semantic_version'), $value)) 494 { 495 throw new version_check_exception('VERSIONCHECK_INVALID_VERSION'); 496 } 497 break; 498 499 default: 500 // Shouldn't be possible to trigger this 501 throw new version_check_exception('VERSIONCHECK_INVALID_ENTRY'); 502 } 503 } 504 } 505 } 506 507 return $versions_info; 508 } 509 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |