GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

TextMatcher   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 7
dl 0
loc 151
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
C match() 0 38 7
A canMatch() 0 16 4
A replaceTypePatternsWithPlaceholders() 0 17 2
A replacePlaceholderWithPatternRegexes() 0 13 2
A prepareRegex() 0 4 1
1
<?php
2
3
namespace Coduo\PHPMatcher\Matcher;
4
5
use Coduo\PHPMatcher\Exception\UnknownTypeException;
6
use Coduo\PHPMatcher\Matcher\Pattern\Assert\Json;
7
use Coduo\PHPMatcher\Matcher\Pattern\Assert\Xml;
8
use Coduo\PHPMatcher\Matcher\Pattern\TypePattern;
9
use Coduo\PHPMatcher\Parser;
10
use Coduo\PHPMatcher\Matcher\Pattern\RegexConverter;
11
use Coduo\ToString\StringConverter;
12
13
final class TextMatcher extends Matcher
14
{
15
    const PATTERN_REGEXP = "/@[a-zA-Z\\.]+@(\\.[a-zA-Z0-9_]+\\([a-zA-Z0-9{},:@\\.\"'\\(\\)]*\\))*/";
16
17
    const PATTERN_REGEXP_PLACEHOLDER_TEMPLATE = "__PLACEHOLDER%d__";
18
19
    /**
20
     * @var Parser
21
     */
22
    private $parser;
23
24
    /**
25
     * @var ValueMatcher
26
     */
27
    private $matcher;
28
29
    /**
30
     * @param ValueMatcher $matcher
31
     * @param Parser $parser
32
     */
33
    public function __construct(ValueMatcher $matcher, Parser $parser)
34
    {
35
        $this->parser = $parser;
36
        $this->matcher = $matcher;
37
    }
38
39
    /**
40
     * {@inheritDoc}
41
     */
42
    public function match($value, $pattern)
43
    {
44
        if (!is_string($value)) {
45
            $this->error = sprintf("%s \"%s\" is not a valid string.", gettype($value), new StringConverter($value));
46
            return false;
47
        }
48
49
        $patternRegex = $pattern;
50
        $patternsReplacedWithRegex = $this->replaceTypePatternsWithPlaceholders($patternRegex);
51
        $patternRegex = $this->prepareRegex($patternRegex);
52
        try {
53
            $patternRegex = $this->replacePlaceholderWithPatternRegexes($patternRegex, $patternsReplacedWithRegex);
54
        } catch (UnknownTypeException $exception) {
55
            $this->error = sprintf(sprintf("Type pattern \"%s\" is not supported by TextMatcher.", $exception->getType()));
56
            return false;
57
        }
58
59
        if (!preg_match($patternRegex, $value, $matchedValues)) {
60
            $this->error = sprintf("\"%s\" does not match \"%s\" pattern", $value, $pattern);
61
            return false;
62
        }
63
64
        array_shift($matchedValues); // remove matched string
65
66
        if (count($patternsReplacedWithRegex) !== count($matchedValues)) {
67
            $this->error = "Unexpected TextMatcher error.";
68
            return false;
69
        }
70
71
        foreach ($patternsReplacedWithRegex as $index => $typePattern) {
72
            if (!$typePattern->matchExpanders($matchedValues[$index])) {
73
                $this->error = $typePattern->getError();
74
                return false;
75
            }
76
        }
77
78
        return true;
79
    }
80
81
    /**
82
     * {@inheritDoc}
83
     */
84
    public function canMatch($pattern)
85
    {
86
        if (!is_string($pattern)) {
87
            return false;
88
        }
89
90
        if (Json::isValidPattern($pattern)) {
91
            return false;
92
        }
93
94
        if (Xml::isValid($pattern)) {
95
            return false;
96
        }
97
98
        return true;
99
    }
100
101
    /**
102
     * Reaplce each type pattern (@[email protected]("lorem")) with placeholder, in order
103
     * to use preg_quote without destroying pattern & expanders.
104
     *
105
     * before replacement: "/users/@[email protected](200)/active"
106
     * after replacement:  "/users/__PLACEHOLDER0__/active"
107
     *
108
     * @param string $patternRegex
109
     * @return TypePattern[]|array
110
     */
111
    private function replaceTypePatternsWithPlaceholders(&$patternRegex)
112
    {
113
        $patternsReplacedWithRegex = array();
114
        preg_match_all(self::PATTERN_REGEXP, $patternRegex, $matches);
115
116
        foreach ($matches[0] as $index => $typePatternString) {
117
            $typePattern = $this->parser->parse($typePatternString);
118
            $patternsReplacedWithRegex[] = $typePattern;
119
            $patternRegex = str_replace(
120
                $typePatternString,
121
                sprintf(self::PATTERN_REGEXP_PLACEHOLDER_TEMPLATE, $index),
122
                $patternRegex
123
            );
124
        }
125
126
        return $patternsReplacedWithRegex;
127
    }
128
129
130
    /**
131
     * Replace placeholders with type pattern regular expressions
132
     * before replacement: "/users/__PLACEHOLDER0__/active"
133
     * after replacement:  "/^\/users\/(\-?[0-9]*)\/active$/"
134
     *
135
     * @param $patternRegex
136
     * @return string
137
     * @throws \Coduo\PHPMatcher\Exception\UnknownTypeException
138
     */
139
    private function replacePlaceholderWithPatternRegexes($patternRegex, array $patternsReplacedWithRegex)
140
    {
141
        $regexConverter = new RegexConverter();
142
        foreach ($patternsReplacedWithRegex as $index => $typePattern) {
143
            $patternRegex = str_replace(
144
                sprintf(self::PATTERN_REGEXP_PLACEHOLDER_TEMPLATE, $index),
145
                $regexConverter->toRegex($typePattern),
146
                $patternRegex
147
            );
148
        }
149
150
        return $patternRegex;
151
    }
152
153
    /**
154
     * Prepare regular expression
155
     *
156
     * @param string $patternRegex
157
     * @return string
158
     */
159
    private function prepareRegex($patternRegex)
160
    {
161
        return "/^" . preg_quote($patternRegex, '/') . "$/";
162
    }
163
}
164