1
|
|
|
<?php |
2
|
|
|
declare(strict_types = 1); |
3
|
|
|
|
4
|
|
|
namespace BrowscapPHP\Parser\Helper; |
5
|
|
|
|
6
|
|
|
use BrowscapPHP\Cache\BrowscapCacheInterface; |
7
|
|
|
use BrowscapPHP\Data\PropertyFormatter; |
8
|
|
|
use BrowscapPHP\Data\PropertyHolder; |
9
|
|
|
use BrowscapPHP\Helper\QuoterInterface; |
10
|
|
|
use ExceptionalJSON\DecodeErrorException; |
11
|
|
|
use Psr\Log\LoggerInterface; |
12
|
|
|
use Psr\SimpleCache\InvalidArgumentException; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* extracts the data and the data for theses pattern from the ini content, optimized for PHP 5.5+ |
16
|
|
|
*/ |
17
|
|
|
final class GetData implements GetDataInterface |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* The cache instance |
21
|
|
|
* |
22
|
|
|
* @var \BrowscapPHP\Cache\BrowscapCacheInterface |
23
|
|
|
*/ |
24
|
|
|
private $cache; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* a logger instance |
28
|
|
|
* |
29
|
|
|
* @var \Psr\Log\LoggerInterface |
30
|
|
|
*/ |
31
|
|
|
private $logger; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var \BrowscapPHP\Helper\QuoterInterface |
35
|
|
|
*/ |
36
|
|
|
private $quoter; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* class contsructor |
40
|
|
|
* |
41
|
|
|
* @param \BrowscapPHP\Cache\BrowscapCacheInterface $cache |
42
|
|
|
* @param \Psr\Log\LoggerInterface $logger |
43
|
|
|
* @param \BrowscapPHP\Helper\QuoterInterface $quoter |
44
|
|
|
*/ |
45
|
|
|
public function __construct(BrowscapCacheInterface $cache, LoggerInterface $logger, QuoterInterface $quoter) |
46
|
|
|
{ |
47
|
|
|
$this->cache = $cache; |
48
|
|
|
$this->logger = $logger; |
49
|
|
|
$this->quoter = $quoter; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Gets the settings for a given pattern (method calls itself to |
54
|
|
|
* get the data from the parent patterns) |
55
|
|
|
* |
56
|
|
|
* @param string $pattern |
57
|
|
|
* @param array $settings |
58
|
|
|
* |
59
|
|
|
* @throws \UnexpectedValueException |
60
|
|
|
* |
61
|
|
|
* @return array |
62
|
|
|
*/ |
63
|
|
|
public function getSettings(string $pattern, array $settings = []) : array |
64
|
|
|
{ |
65
|
|
|
// The pattern has been pre-quoted on generation to speed up the pattern search, |
66
|
|
|
// but for this check we need the unquoted version |
67
|
|
|
$unquotedPattern = $this->quoter->pregUnQuote($pattern); |
68
|
|
|
|
69
|
|
|
// Try to get settings for the pattern |
70
|
|
|
$addedSettings = $this->getIniPart($unquotedPattern); |
71
|
|
|
|
72
|
|
|
// set some additional data |
73
|
|
|
if (0 === count($settings)) { |
74
|
|
|
// The optimization with replaced digits get can now result in setting searches, for which we |
75
|
|
|
// won't find a result - so only add the pattern information, is settings have been found. |
76
|
|
|
// |
77
|
|
|
// If not an empty array will be returned and the calling function can easily check if a pattern |
78
|
|
|
// has been found. |
79
|
|
|
if (0 < count($addedSettings)) { |
80
|
|
|
$settings['browser_name_regex'] = '/^' . $pattern . '$/'; |
81
|
|
|
$settings['browser_name_pattern'] = $unquotedPattern; |
82
|
|
|
} |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
// check if parent pattern set, only keep the first one |
86
|
|
|
$parentPattern = null; |
87
|
|
|
|
88
|
|
|
if (isset($addedSettings['Parent'])) { |
89
|
|
|
$parentPattern = $addedSettings['Parent']; |
90
|
|
|
|
91
|
|
|
if (isset($settings['Parent'])) { |
92
|
|
|
unset($addedSettings['Parent']); |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
// merge settings |
97
|
|
|
$settings += $addedSettings; |
98
|
|
|
|
99
|
|
|
if (is_string($parentPattern)) { |
100
|
|
|
return $this->getSettings($this->quoter->pregQuote($parentPattern), $settings); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
return $settings; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Gets the relevant part (array of settings) of the ini file for a given pattern. |
108
|
|
|
* |
109
|
|
|
* @param string $pattern |
110
|
|
|
* |
111
|
|
|
* @return array |
112
|
|
|
*/ |
113
|
|
|
private function getIniPart(string $pattern) : array |
114
|
|
|
{ |
115
|
|
|
$pattern = strtolower($pattern); |
116
|
|
|
$patternhash = Pattern::getHashForParts($pattern); |
117
|
|
|
$subkey = SubKey::getIniPartCacheSubKey($patternhash); |
118
|
|
|
|
119
|
|
|
try { |
120
|
|
|
if (! $this->cache->hasItem('browscap.iniparts.' . $subkey, true)) { |
121
|
|
|
$this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" not found'); |
122
|
|
|
|
123
|
|
|
return []; |
124
|
|
|
} |
125
|
|
|
} catch (InvalidArgumentException $e) { |
|
|
|
|
126
|
|
|
$this->logger->error(new \InvalidArgumentException('an error occured while checking a inipart in the cache', 0, $e)); |
127
|
|
|
|
128
|
|
|
return []; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
$success = null; |
132
|
|
|
|
133
|
|
|
try { |
134
|
|
|
$file = $this->cache->getItem('browscap.iniparts.' . $subkey, true, $success); |
135
|
|
|
} catch (InvalidArgumentException $e) { |
|
|
|
|
136
|
|
|
$this->logger->error(new \InvalidArgumentException('an error occured while reading a inipart from the cache', 0, $e)); |
137
|
|
|
|
138
|
|
|
return []; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
if (! $success) { |
|
|
|
|
142
|
|
|
$this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" not found'); |
143
|
|
|
|
144
|
|
|
return []; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
if (! is_array($file) || ! count($file)) { |
148
|
|
|
$this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" was empty'); |
149
|
|
|
|
150
|
|
|
return []; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
$propertyFormatter = new PropertyFormatter(new PropertyHolder()); |
154
|
|
|
$return = []; |
155
|
|
|
|
156
|
|
|
foreach ($file as $buffer) { |
157
|
|
|
[$tmpBuffer, $patterns] = explode("\t", $buffer, 2); |
|
|
|
|
158
|
|
|
|
159
|
|
|
if ($tmpBuffer === $patternhash) { |
|
|
|
|
160
|
|
|
try { |
161
|
|
|
$return = \ExceptionalJSON\decode($patterns, true); |
|
|
|
|
162
|
|
|
} catch (DecodeErrorException $e) { |
|
|
|
|
163
|
|
|
$this->logger->error('data for cache key "browscap.iniparts.' . $subkey . '" are not valid json'); |
164
|
|
|
|
165
|
|
|
return []; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
foreach (array_keys($return) as $property) { |
169
|
|
|
$return[$property] = $propertyFormatter->formatPropertyValue( |
170
|
|
|
$return[$property], |
171
|
|
|
(string) $property |
172
|
|
|
); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
break; |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
return $return; |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.