Completed
Pull Request — master (#221)
by Thomas
28:24 queued 26:59
created

Ini::getBrowser()   C

Complexity

Conditions 8
Paths 5

Size

Total Lines 48
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
dl 0
loc 48
ccs 0
cts 25
cp 0
rs 5.9322
c 0
b 0
f 0
cc 8
eloc 25
nc 5
nop 1
crap 72
1
<?php
2
/**
3
 * This file is part of the browscap-php package.
4
 *
5
 * Copyright (c) 1998-2017, Browser Capabilities Project
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types = 1);
12
namespace BrowscapPHP\Parser;
13
14
use BrowscapPHP\Formatter\FormatterInterface;
15
use BrowscapPHP\Parser\Helper\GetDataInterface;
16
use BrowscapPHP\Parser\Helper\GetPatternInterface;
17
18
/**
19
 * Ini parser class (compatible with PHP 5.3+)
20
 */
21
final class Ini implements ParserInterface
22
{
23
    /**
24
     * @var Helper\GetPatternInterface
25
     */
26
    private $patternHelper;
27
28
    /**
29
     * @var Helper\GetDataInterface
30
     */
31
    private $dataHelper;
32
33
    /**
34
     * Formatter to use
35
     *
36
     * @var \BrowscapPHP\Formatter\FormatterInterface
37
     */
38
    private $formatter;
39
40
    /**
41
     * class constructor
42
     *
43
     * @param \BrowscapPHP\Parser\Helper\GetPatternInterface $patternHelper
44
     * @param \BrowscapPHP\Parser\Helper\GetDataInterface    $dataHelper
45
     * @param \BrowscapPHP\Formatter\FormatterInterface      $formatter
46
     */
47
    public function __construct(
48
        GetPatternInterface $patternHelper,
49
        GetDataInterface $dataHelper,
50
        FormatterInterface $formatter
51
    ) {
52
        $this->patternHelper = $patternHelper;
53
        $this->dataHelper = $dataHelper;
54
        $this->formatter = $formatter;
55
    }
56
57
    /**
58
     * Gets the browser data formatr for the given user agent
59
     * (or null if no data avaailble, no even the default browser)
60
     *
61
     * @param string $userAgent
62
     *
63
     * @return FormatterInterface|null
64
     */
65
    public function getBrowser(string $userAgent) : ?FormatterInterface
66
    {
67
        $userAgent = strtolower($userAgent);
68
        $formatter = null;
69
70
        foreach ($this->patternHelper->getPatterns($userAgent) as $patterns) {
71
            $patternToMatch = '/^(?:' . str_replace("\t", ')|(?:', $patterns) . ')$/i';
72
73
            if (! preg_match($patternToMatch, $userAgent)) {
74
                continue;
75
            }
76
77
            // strtok() requires less memory than explode()
78
            $pattern = strtok($patterns, "\t");
79
80
            while ($pattern !== false) {
81
                $pattern = str_replace('[\d]', '(\d)', $pattern);
82
                $quotedPattern = '/^' . $pattern . '$/i';
83
                $matches = [];
84
85
                if (preg_match($quotedPattern, $userAgent, $matches)) {
86
                    // Insert the digits back into the pattern, so that we can search the settings for it
87
                    if (count($matches) > 1) {
88
                        array_shift($matches);
89
                        foreach ($matches as $oneMatch) {
90
                            $numPos = strpos($pattern, '(\d)');
91
                            $pattern = substr_replace($pattern, $oneMatch, $numPos, 4);
92
                        }
93
                    }
94
95
                    // Try to get settings - as digits have been replaced to speed up the pattern search (up to 90 faster),
96
                    // we won't always find the data in the first step - so check if settings have been found and if not,
97
                    // search for the next pattern.
98
                    $settings = $this->dataHelper->getSettings($pattern);
99
100
                    if (count($settings) > 0) {
101
                        $formatter = $this->formatter;
102
                        $formatter->setData($settings);
103
                        break 2;
104
                    }
105
                }
106
107
                $pattern = strtok("\t");
108
            }
109
        }
110
111
        return $formatter;
112
    }
113
}
114