Completed
Push — master ( 7014bb...a38bcf )
by James
15s
created

Ini   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 9
lcom 1
cbo 3
dl 0
loc 92
ccs 0
cts 30
cp 0
rs 10
c 1
b 1
f 0

2 Methods

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