Pattern   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Test Coverage

Coverage 85.71%

Importance

Changes 0
Metric Value
wmc 8
lcom 0
cbo 0
dl 0
loc 89
ccs 18
cts 21
cp 0.8571
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getHashForPattern() 0 33 5
A getHashForParts() 0 4 1
A getPatternLength() 0 4 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace BrowscapPHP\Parser\Helper;
5
6
/**
7
 * includes general functions for the work with patterns
8
 */
9
final class Pattern
10
{
11
    private function __construct()
12
    {
13
    }
14
15
    /**
16
     * Gets a hash or an array of hashes from the first characters of a pattern/user agent, that can
17
     * be used for a fast comparison, by comparing only the hashes, without having to match the
18
     * complete pattern against the user agent.
19
     *
20
     * With the variants options, all variants from the maximum number of pattern characters to one
21
     * character will be returned. This is required in some cases, the a placeholder is used very
22
     * early in the pattern.
23
     *
24
     * Example:
25
     *
26
     * Pattern: "Mozilla/* (Nintendo 3DS; *) Version/*"
27
     * User agent: "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7567.US"
28
     *
29
     * In this case the has for the pattern is created for "Mozilla/" while the pattern
30
     * for the hash for user agent is created for "Mozilla/5.0". The variants option
31
     * results in an array with hashes for "Mozilla/5.0", "Mozilla/5.", "Mozilla/5",
32
     * "Mozilla/" ... "M", so that the pattern hash is included.
33
     *
34
     * @param  string       $pattern
35
     * @param  bool         $variants
36
     *
37
     * @return string[]
38
     */
39 2
    public static function getHashForPattern(string $pattern, bool $variants = false) : array
40
    {
41 2
        $regex = '/^([^\.\*\?\s\r\n\\\\]+).*$/';
42 2
        $pattern = substr($pattern, 0, 32);
43 2
        $matches = [];
44
45 2
        if (! preg_match($regex, $pattern, $matches)) {
46
            return [md5('')];
47
        }
48
49 2
        if (! isset($matches[1])) {
50
            return [md5('')];
51 2
        }
52 1
53
        $string = $matches[1];
54 1
55 1
        if (true === $variants) {
56 1
            $patternStarts = [];
57
58
            for ($i = strlen($string); 1 <= $i; --$i) {
59
                $string = substr($string, 0, $i);
60
                $patternStarts[] = md5($string);
61 1
            }
62
63 1
            // Add empty pattern start to include patterns that start with "*",
64
            // e.g. "*FAST Enterprise Crawler*"
65
            $patternStarts[] = md5('');
66 1
67
            return $patternStarts;
68
        }
69
70
        return [md5($string)];
71
    }
72
73
    /**
74
     * returns a hash for one pattern
75
     *
76 1
     * @param string $pattern
77
     *
78 1
     * @return string
79
     */
80
    public static function getHashForParts(string $pattern) : string
81
    {
82
        return md5($pattern);
83
    }
84
85
    /**
86
     * Gets the minimum length of the patern (used in the getPatterns() method to
87
     * check against the user agent length)
88
     *
89 1
     * @param  string $pattern
90
     *
91 1
     * @return int
92
     */
93
    public static function getPatternLength(string $pattern) : int
94
    {
95
        return strlen(str_replace('*', '', $pattern));
96
    }
97
}
98