1
|
|
|
<?php |
2
|
|
|
declare(strict_types = 1); |
3
|
|
|
namespace hexydec\agentzero; |
4
|
|
|
|
5
|
|
|
class versions { |
6
|
|
|
|
7
|
|
|
protected static ?array $versions = null; |
8
|
|
|
|
9
|
95 |
|
protected static function load(string $source, ?string $cache, int $life = 604800) : array|false { |
10
|
|
|
|
11
|
|
|
// cache for this session |
12
|
95 |
|
$data = self::$versions; |
13
|
95 |
|
if ($data === null) { |
14
|
|
|
|
15
|
|
|
// fetch from cache |
16
|
95 |
|
if (\file_exists($cache) && \filemtime($cache) > \time() - $life && ($json = \file_get_contents($cache)) !== false) { |
|
|
|
|
17
|
|
|
|
18
|
|
|
// fetch from server |
19
|
1 |
|
} elseif (($json = \file_get_contents($source)) === false) { |
20
|
|
|
return false; |
21
|
|
|
|
22
|
|
|
// update cache |
23
|
1 |
|
} elseif ($cache !== null) { |
24
|
|
|
|
25
|
|
|
// create directory |
26
|
1 |
|
$dir = \dirname($cache); |
27
|
1 |
|
if (!\is_dir($dir) && \mkdir($dir, 0755)) { |
28
|
|
|
|
29
|
|
|
// cache file |
30
|
1 |
|
\file_put_contents($cache, $json); |
31
|
|
|
} |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
// decode JSON |
35
|
95 |
|
$data = \json_decode($json, true); |
36
|
|
|
} |
37
|
95 |
|
return $data ?? false; |
38
|
|
|
} |
39
|
|
|
|
40
|
90 |
|
protected static function latest(array $versions, ?\DateTime $now = null) : string { |
41
|
|
|
|
42
|
|
|
// no date restriction |
43
|
90 |
|
if ($now === null) { |
44
|
90 |
|
return \strval(\array_key_first($versions)); |
45
|
|
|
} else { |
46
|
|
|
|
47
|
|
|
} |
|
|
|
|
48
|
|
|
} |
49
|
|
|
|
50
|
90 |
|
protected static function released(array $data, string $version) : ?string { |
51
|
90 |
|
$major = \intval($version); |
52
|
90 |
|
$len = 0; |
53
|
90 |
|
$i = 0; |
54
|
90 |
|
$vlen = \strlen($version); |
55
|
90 |
|
$released = null; |
56
|
90 |
|
foreach ($data AS $ver => $date) { |
57
|
90 |
|
if (\intval($ver) === $major) { |
58
|
89 |
|
$ver = \strval($ver); // cast as string to get letters, string keys cast to int when array keys |
59
|
89 |
|
$match = 0; |
60
|
89 |
|
for ($n = 0; $n < $vlen; $n++) { |
61
|
89 |
|
if ($version[$n] === ($ver[$n] ?? null)) { |
62
|
89 |
|
$match++; |
63
|
|
|
} else { |
64
|
82 |
|
break; |
65
|
|
|
} |
66
|
|
|
} |
67
|
89 |
|
if ($match > $len) { |
68
|
89 |
|
$len = $match; |
69
|
89 |
|
$released = $date; |
70
|
|
|
} |
71
|
|
|
} |
72
|
90 |
|
$i++; |
73
|
|
|
} |
74
|
90 |
|
return $released !== null ? (new \DateTime(\strval($released)))->format('Y-m-d') : null; |
|
|
|
|
75
|
|
|
} |
76
|
|
|
|
77
|
95 |
|
public static function get(string $browser, string $version, array $config) : array { |
78
|
95 |
|
if (($versions = self::load($config['source'], $config['cache'])) !== false) { |
79
|
95 |
|
$data = []; |
80
|
95 |
|
if (isset($versions[$browser])) { |
81
|
|
|
|
82
|
|
|
// get latest version of the browser |
83
|
90 |
|
$data['browserlatest'] = self::latest($versions[$browser]); |
84
|
|
|
|
85
|
|
|
// check if version is greater than latest version |
86
|
90 |
|
$major = \intval($version); |
87
|
90 |
|
$latest = \intval($data['browserlatest']); |
88
|
|
|
|
89
|
|
|
// version is way out of bounds (This happens sometimes, for example if the safari engine version is reported instead of the browser version) |
90
|
90 |
|
if ($latest + 3 < $major) { |
91
|
25 |
|
return []; |
92
|
|
|
|
93
|
|
|
// nightly build? |
94
|
90 |
|
} elseif ($latest + 3 === $major) { |
95
|
|
|
$data['browserstatus'] = 'nightly'; |
96
|
|
|
|
97
|
|
|
// canary build |
98
|
90 |
|
} elseif ($latest + 2 === $major) { |
99
|
|
|
$data['browserstatus'] = 'canary'; |
100
|
|
|
|
101
|
|
|
// beta release |
102
|
90 |
|
} elseif ($latest + 1 === $major) { |
103
|
|
|
$data['browserstatus'] = 'beta'; |
104
|
|
|
|
105
|
|
|
// find closes match for version |
106
|
|
|
} else { |
107
|
|
|
|
108
|
|
|
// get current version |
109
|
90 |
|
$data['browserreleased'] = self::released($versions[$browser], $version); |
|
|
|
|
110
|
|
|
|
111
|
|
|
// calculate status |
112
|
90 |
|
if (isset($data['browserreleased'])) { |
113
|
89 |
|
$current = \explode('.', $data['browserlatest'])[0] === \explode('.', $version)[0]; |
114
|
89 |
|
$released = new \DateTime($data['browserreleased']); |
115
|
|
|
|
116
|
|
|
// legacy |
117
|
89 |
|
if ($released < \date_create('-3 years')) { |
118
|
77 |
|
$data['browserstatus'] = 'legacy'; |
119
|
|
|
|
120
|
|
|
// current |
121
|
53 |
|
} elseif ($current && ($released >= \date_create('-1 year') || $data['browserlatest'] === $version)) { |
122
|
1 |
|
$data['browserstatus'] = 'current'; |
123
|
|
|
|
124
|
|
|
// previous |
125
|
|
|
} else { |
126
|
89 |
|
$data['browserstatus'] = 'previous'; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
// version wasn't listed - ancient |
130
|
|
|
} else { |
131
|
25 |
|
$data['browserstatus'] = 'legacy'; |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
} |
135
|
95 |
|
return $data; |
136
|
|
|
} |
137
|
|
|
return []; |
138
|
|
|
} |
139
|
|
|
} |