Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
version_helper.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 namespace phpbb;
015
016 use phpbb\exception\version_check_exception;
017
018 /**
019 * Class to handle version checking and comparison
020 */
021 class version_helper
022 {
023 /**
024 * @var string Host
025 */
026 protected $host = 'version.phpbb.com';
027
028 /**
029 * @var string Path to file
030 */
031 protected $path = '/phpbb';
032
033 /**
034 * @var string File name
035 */
036 protected $file = 'versions.json';
037
038 /**
039 * @var bool Use SSL or not
040 */
041 protected $use_ssl = false;
042
043 /**
044 * @var string Current version installed
045 */
046 protected $current_version;
047
048 /**
049 * @var null|string Null to not force stability, 'unstable' or 'stable' to
050 * force the corresponding stability
051 */
052 protected $force_stability;
053
054 /** @var \phpbb\cache\service */
055 protected $cache;
056
057 /** @var \phpbb\config\config */
058 protected $config;
059
060 /** @var \phpbb\file_downloader */
061 protected $file_downloader;
062
063 protected $version_schema = array(
064 'stable' => array(
065 'current' => 'version',
066 'download' => 'url',
067 'announcement' => 'url',
068 'eol' => 'url',
069 'security' => 'bool',
070 ),
071 'unstable' => array(
072 'current' => 'version',
073 'download' => 'url',
074 'announcement' => 'url',
075 'eol' => 'url',
076 'security' => 'bool',
077 ),
078 );
079
080 /**
081 * Constructor
082 *
083 * @param \phpbb\cache\service $cache
084 * @param \phpbb\config\config $config
085 * @param \phpbb\file_downloader $file_downloader
086 */
087 public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\file_downloader $file_downloader)
088 {
089 $this->cache = $cache;
090 $this->config = $config;
091 $this->file_downloader = $file_downloader;
092
093 if (defined('PHPBB_QA'))
094 {
095 $this->force_stability = 'unstable';
096 }
097
098 $this->current_version = $this->config['version'];
099 }
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 $stability 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, 30);
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 }
510