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