1<?php
2
3/**
4 * Device Detector - The Universal Device Detection library for parsing User Agents
5 *
6 * @link https://matomo.org
7 *
8 * @license http://www.gnu.org/licenses/lgpl.html LGPL v3 or later
9 */
10
11declare(strict_types=1);
12
13namespace DeviceDetector\Parser\Client;
14
15use DeviceDetector\Cache\CacheInterface;
16use DeviceDetector\ClientHints;
17use DeviceDetector\Parser\Client\Hints\AppHints;
18use DeviceDetector\Yaml\ParserInterface as YamlParser;
19
20/**
21 * Class MobileApp
22 *
23 * Client parser for mobile app detection
24 */
25class MobileApp extends AbstractClientParser
26{
27    /**
28     * @var AppHints
29     */
30    private $appHints;
31
32    /**
33     * @var string
34     */
35    protected $fixtureFile = 'regexes/client/mobile_apps.yml';
36
37    /**
38     * @var string
39     */
40    protected $parserName = 'mobile app';
41
42    /**
43     * MobileApp constructor.
44     *
45     * @param string           $ua
46     * @param ClientHints|null $clientHints
47     */
48    public function __construct(string $ua = '', ?ClientHints $clientHints = null)
49    {
50        $this->appHints = new AppHints($ua, $clientHints);
51        parent::__construct($ua, $clientHints);
52    }
53
54    /**
55     * Sets the client hints to parse
56     *
57     * @param ?ClientHints $clientHints client hints
58     */
59    public function setClientHints(?ClientHints $clientHints): void
60    {
61        parent::setClientHints($clientHints);
62        $this->appHints->setClientHints($clientHints);
63    }
64
65    /**
66     * Sets the user agent to parse
67     *
68     * @param string $ua user agent
69     */
70    public function setUserAgent(string $ua): void
71    {
72        parent::setUserAgent($ua);
73        $this->appHints->setUserAgent($ua);
74    }
75
76    /**
77     * Sets the Cache class
78     *
79     * @param CacheInterface $cache
80     */
81    public function setCache(CacheInterface $cache): void
82    {
83        parent::setCache($cache);
84        $this->appHints->setCache($cache);
85    }
86
87    /**
88     * Sets the YamlParser class
89     *
90     * @param YamlParser $yamlParser
91     */
92    public function setYamlParser(YamlParser $yamlParser): void
93    {
94        parent::setYamlParser($yamlParser);
95        $this->appHints->setYamlParser($this->getYamlParser());
96    }
97
98    /**
99     * Parses the current UA and checks whether it contains any client information
100     * See parent::parse() for more details.
101     *
102     * @return array|null
103     */
104    public function parse(): ?array
105    {
106        $result  = parent::parse();
107        $name    = $result['name'] ?? '';
108        $version = $result['version'] ?? '';
109        $appHash = $this->appHints->parse();
110
111        if (null !== $appHash && $appHash['name'] !== $name) {
112            $name    = $appHash['name'];
113            $version = '';
114        }
115
116        if (empty($name)) {
117            return null;
118        }
119
120        return [
121            'type'    => $this->parserName,
122            'name'    => $name,
123            'version' => $version,
124        ];
125    }
126}
127