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\Browser;
14
15use DeviceDetector\Parser\Client\AbstractClientParser;
16
17/**
18 * Class Engine
19 *
20 * Client parser for browser engine detection
21 */
22class Engine extends AbstractClientParser
23{
24    /**
25     * @var string
26     */
27    protected $fixtureFile = 'regexes/client/browser_engine.yml';
28
29    /**
30     * @var string
31     */
32    protected $parserName = 'browserengine';
33
34    /**
35     * Known browser engines mapped to their internal short codes
36     *
37     * @var array
38     */
39    protected static $availableEngines = [
40        'WebKit',
41        'Blink',
42        'Trident',
43        'Text-based',
44        'Dillo',
45        'iCab',
46        'Elektra',
47        'Presto',
48        'Clecko',
49        'Gecko',
50        'KHTML',
51        'NetFront',
52        'Edge',
53        'NetSurf',
54        'Servo',
55        'Goanna',
56        'EkiohFlow',
57        'Arachne',
58        'LibWeb',
59        'Maple',
60    ];
61
62    /**
63     * Returns list of all available browser engines
64     * @return array
65     */
66    public static function getAvailableEngines(): array
67    {
68        return self::$availableEngines;
69    }
70
71    /**
72     * @inheritdoc
73     */
74    public function parse(): ?array
75    {
76        $matches = false;
77
78        foreach ($this->getRegexes() as $regex) {
79            $matches = $this->matchUserAgent($regex['regex']);
80
81            if ($matches) {
82                break;
83            }
84        }
85
86        if (empty($matches) || empty($regex)) {
87            return null;
88        }
89
90        $name = $this->buildByMatch($regex['name'], $matches);
91
92        foreach (self::getAvailableEngines() as $engineName) {
93            if (\strtolower($name) === \strtolower($engineName)) {
94                return ['engine' => $engineName];
95            }
96        }
97
98        // This Exception should never be thrown. If so a defined browser name is missing in $availableEngines
99        throw new \Exception(\sprintf(
100            'Detected browser engine was not found in $availableEngines. Tried to parse user agent: %s',
101            $this->userAgent
102        )); // @codeCoverageIgnore
103    }
104}
105