Completed
Push — master ( 41d47b...c28fef )
by James
10s
created

GetData   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 141
Duplicated Lines 3.55 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 10.42%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 7
dl 5
loc 141
ccs 5
cts 48
cp 0.1042
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
B getSettings() 0 41 6
C getIniPart() 5 49 8

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
declare(strict_types = 1);
3
4
namespace BrowscapPHP\Parser\Helper;
5
6
use BrowscapPHP\Cache\BrowscapCacheInterface;
7
use BrowscapPHP\Data\PropertyFormatter;
8
use BrowscapPHP\Data\PropertyHolder;
9
use BrowscapPHP\Helper\Quoter;
10
use Psr\Log\LoggerInterface;
11
12
/**
13
 * extracts the data and the data for theses pattern from the ini content, optimized for PHP 5.5+
14
 */
15
final class GetData implements GetDataInterface
16
{
17
    /**
18
     * The cache instance
19
     *
20
     * @var \BrowscapPHP\Cache\BrowscapCacheInterface
21
     */
22
    private $cache;
23
24
    /**
25
     * a logger instance
26
     *
27
     * @var \Psr\Log\LoggerInterface
28
     */
29
    private $logger;
30
31
    /**
32
     * @var \BrowscapPHP\Helper\Quoter
33
     */
34
    private $quoter;
35
36
    /**
37
     * class contsructor
38
     *
39
     * @param \BrowscapPHP\Cache\BrowscapCacheInterface $cache
40
     * @param \Psr\Log\LoggerInterface                  $logger
41
     * @param \BrowscapPHP\Helper\Quoter                $quoter
42
     */
43 1
    public function __construct(BrowscapCacheInterface $cache, LoggerInterface $logger, Quoter $quoter)
44
    {
45 1
        $this->cache = $cache;
46 1
        $this->logger = $logger;
47 1
        $this->quoter = $quoter;
48 1
    }
49
50
    /**
51
     * Gets the settings for a given pattern (method calls itself to
52
     * get the data from the parent patterns)
53
     *
54
     * @param  string $pattern
55
     * @param  array  $settings
56
     * @return array
57
     */
58
    public function getSettings(string $pattern, array $settings = []) : array
59
    {
60
        // The pattern has been pre-quoted on generation to speed up the pattern search,
61
        // but for this check we need the unquoted version
62
        $unquotedPattern = $this->quoter->pregUnQuote($pattern);
63
64
        // Try to get settings for the pattern
65
        $addedSettings = $this->getIniPart($unquotedPattern);
66
67
        // set some additional data
68
        if (count($settings) === 0) {
69
            // The optimization with replaced digits get can now result in setting searches, for which we
70
            // won't find a result - so only add the pattern information, is settings have been found.
71
            //
72
            // If not an empty array will be returned and the calling function can easily check if a pattern
73
            // has been found.
74
            if (count($addedSettings) > 0) {
75
                $settings['browser_name_regex'] = '/^' . $pattern . '$/';
76
                $settings['browser_name_pattern'] = $unquotedPattern;
77
            }
78
        }
79
80
        // check if parent pattern set, only keep the first one
81
        $parentPattern = null;
82
        if (isset($addedSettings['Parent'])) {
83
            $parentPattern = $addedSettings['Parent'];
84
85
            if (isset($settings['Parent'])) {
86
                unset($addedSettings['Parent']);
87
            }
88
        }
89
90
        // merge settings
91
        $settings += $addedSettings;
92
93
        if ($parentPattern !== null) {
94
            return $this->getSettings($this->quoter->pregQuote($parentPattern), $settings);
95
        }
96
97
        return $settings;
98
    }
99
100
    /**
101
     * Gets the relevant part (array of settings) of the ini file for a given pattern.
102
     *
103
     * @param  string $pattern
104
     * @return array
105
     */
106
    private function getIniPart(string $pattern) : array
107
    {
108
        $pattern = strtolower($pattern);
109
        $patternhash = Pattern::getHashForParts($pattern);
110
        $subkey = SubKey::getIniPartCacheSubKey($patternhash);
111
112 View Code Duplication
        if (! $this->cache->hasItem('browscap.iniparts.' . $subkey, true)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
            $this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" not found');
114
115
            return [];
116
        }
117
118
        $success = null;
119
        $file = $this->cache->getItem('browscap.iniparts.' . $subkey, true, $success);
120
121
        if (! $success) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $success of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
122
            $this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" not found');
123
124
            return [];
125
        }
126
127
        if (! is_array($file) || ! count($file)) {
128
            $this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" was empty');
129
130
            return [];
131
        }
132
133
        $propertyFormatter = new PropertyFormatter(new PropertyHolder());
134
        $return = [];
135
136
        foreach ($file as $buffer) {
137
            list($tmpBuffer, $patterns) = explode("\t", $buffer, 2);
138
139
            if ($tmpBuffer === $patternhash) {
140
                $return = json_decode($patterns, true);
141
142
                foreach (array_keys($return) as $property) {
143
                    $return[$property] = $propertyFormatter->formatPropertyValue(
144
                        $return[$property],
145
                        $property
146
                    );
147
                }
148
149
                break;
150
            }
151
        }
152
153
        return $return;
154
    }
155
}
156