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;
14
15/**
16 * Class Bot
17 *
18 * Parses a user agent for bot information
19 *
20 * Detected bots are defined in regexes/bots.yml
21 */
22class Bot extends AbstractBotParser
23{
24    /**
25     * @var string
26     */
27    protected $fixtureFile = 'regexes/bots.yml';
28
29    /**
30     * @var string
31     */
32    protected $parserName = 'bot';
33
34    /**
35     * @var bool
36     */
37    protected $discardDetails = false;
38
39    /**
40     * Enables information discarding
41     */
42    public function discardDetails(): void
43    {
44        $this->discardDetails = true;
45    }
46
47    /**
48     * Parses the current UA and checks whether it contains bot information
49     *
50     * @see bots.yml for list of detected bots
51     *
52     * Step 1: Build a big regex containing all regexes and match UA against it
53     * -> If no matches found: return
54     * -> Otherwise:
55     * Step 2: Walk through the list of regexes in bots.yml and try to match every one
56     * -> Return the matched data
57     *
58     * If $discardDetails is set to TRUE, the Step 2 will be skipped
59     * $bot will be set to TRUE instead
60     *
61     * NOTE: Doing the big match before matching every single regex speeds up the detection
62     *
63     * @return array|null
64     */
65    public function parse(): ?array
66    {
67        $result = null;
68
69        if ($this->preMatchOverall()) {
70            if ($this->discardDetails) {
71                return [true];
72            }
73
74            foreach ($this->getRegexes() as $regex) {
75                $matches = $this->matchUserAgent($regex['regex']);
76
77                if ($matches) {
78                    unset($regex['regex']);
79                    $result = $regex;
80
81                    break;
82                }
83            }
84        }
85
86        return $result;
87    }
88}
89