1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace EndorphinStudio\Detector\Detection; |
4
|
|
|
|
5
|
|
|
use EndorphinStudio\Detector\Data\AbstractData; |
6
|
|
|
use EndorphinStudio\Detector\Detector; |
7
|
|
|
use EndorphinStudio\Detector\Tools; |
8
|
|
|
|
9
|
|
|
abstract class AbstractDetection implements DetectionInterface |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* @var string Key in config (os, device, etc.) |
13
|
|
|
*/ |
14
|
|
|
protected $configKey = 'none'; |
15
|
|
|
|
16
|
|
|
/** @var array */ |
17
|
|
|
protected $config; |
18
|
|
|
/** @var Detector */ |
19
|
|
|
protected $detector; |
20
|
|
|
|
21
|
|
|
/** @var AbstractData */ |
22
|
|
|
protected $resultObject; |
23
|
|
|
|
24
|
|
|
public function init(Detector $detector) |
25
|
|
|
{ |
26
|
|
|
$this->detector = $detector; |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
protected function initResultObject() |
30
|
|
|
{ |
31
|
|
|
if(!array_key_exists('default', $this->config)) { |
32
|
|
|
return null; |
33
|
|
|
} |
34
|
|
|
// init default value from data |
35
|
|
|
foreach ($this->config['default'] as $defaultKey => $defaultValue) { |
36
|
|
|
Tools::runSetter($this->resultObject, $defaultKey, $defaultValue); |
37
|
|
|
} |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
public function detect(string $ua) |
41
|
|
|
{ |
42
|
|
|
if ($this->configKey !== 'none') { |
43
|
|
|
$this->config = $this->detector->getPatternList($this->detector->getDataProvider()->getConfig(), $this->configKey); |
44
|
|
|
$resultObject = $this->detector->getResultObject(); |
45
|
|
|
$this->resultObject = Tools::runGetter($resultObject, $this->configKey); |
46
|
|
|
} |
47
|
|
|
$this->initResultObject(); |
48
|
|
|
$this->setupResultObject(); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
protected abstract function setupResultObject(); |
52
|
|
|
|
53
|
|
|
protected function detectByPattern(array $patternList) |
54
|
|
|
{ |
55
|
|
|
foreach ($patternList as $patternId => $patternData) { |
56
|
|
|
$pattern = $this->getPattern($patternId, $patternData); |
57
|
|
|
|
58
|
|
|
if (preg_match($pattern['pattern'], $this->detector->getUserAgent())) { |
59
|
|
|
return ['name' => $patternId, 'version' => Tools::getVersion($pattern['version'], $this->detector->getUserAgent()), 'originalInfo' => $patternData]; |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
return null; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
private function getPattern(string $patternId, array $patternData): array |
66
|
|
|
{ |
67
|
|
|
if (array_key_exists('default', $patternData) && $patternData['default'] === true) { |
68
|
|
|
return ['pattern' => sprintf('/%s/', $patternId), 'version' => $patternId]; |
69
|
|
|
} |
70
|
|
|
return ['pattern' => sprintf('/%s/', $patternData['pattern']), 'version' => array_key_exists('version', $patternData) ? $patternData['version'] : $patternId]; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
protected function setAttributes($info) |
74
|
|
|
{ |
75
|
|
|
$result = $this->detector->getResultObject(); |
76
|
|
|
if (array_key_exists('attributes', $info)) { |
77
|
|
|
foreach ($info['attributes'] as $attributeKey => $attributeValue) { |
78
|
|
|
Tools::runSetter($result, $attributeKey, $attributeValue); |
79
|
|
|
} |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
protected function detectByType($key = 'none'): array |
84
|
|
|
{ |
85
|
|
|
$container = $key === 'none' ? $this->config : $this->config[$key]; |
86
|
|
|
foreach ($container as $type => $patternList) { |
87
|
|
|
if ($type === 'default') { |
88
|
|
|
continue; |
89
|
|
|
} |
90
|
|
|
$browser = $this->detectByPattern($patternList); |
91
|
|
|
if ($browser) { |
92
|
|
|
return array_merge($browser, ['type' => $type]); |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
return []; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
protected function detectByKey($keyName = 'family'): array |
99
|
|
|
{ |
100
|
|
|
foreach ($this->config as $key => $data) { |
101
|
|
|
if ($key === 'default') { |
102
|
|
|
continue; |
103
|
|
|
} |
104
|
|
|
$detectedData = $this->detectByType($key); |
105
|
|
|
if ($detectedData) { |
|
|
|
|
106
|
|
|
return array_merge($detectedData, [$keyName => $key]); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
return []; |
110
|
|
|
} |
111
|
|
|
} |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.