Completed
Pull Request — master (#28)
by Christopher
04:18 queued 01:53
created

PatternTrait   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 169
Duplicated Lines 15.98 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 10
Bugs 3 Features 1
Metric Value
wmc 19
c 10
b 3
f 1
lcom 1
cbo 1
dl 27
loc 169
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A checkRegexValidPattern() 0 4 1
A matchesRegexPattern() 0 5 2
A setPatternFacet() 0 15 4
A processRegex() 0 15 3
A processRegexSlashS() 8 8 1
A processRegexSlashI() 0 11 1
A processRegexSlashC() 0 11 1
A processRegexSlashD() 8 8 1
A processRegexSlashW() 10 10 1
A checkPattern() 0 11 4

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
namespace AlgoWeb\xsdTypes\Facets;
3
4
trait PatternTrait
5
{
6
    use XMLPatterns;
7
    /**
8
     * @Exclude
9
     * @var array defines the exact sequence of characters that are acceptable
10
     */
11
    public $pattern = array();
12
13
    /**
14
     * @param string $newPatternToAdd
15
     * @param mixed  $processMultiCharacterEscape
0 ignored issues
show
Documentation introduced by
There is no parameter named $processMultiCharacterEscape. Did you maybe mean $multiCharacterEscape?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
16
     * @param mixed  $multiCharacterEscape
17
     */
18
    protected function setPatternFacet($newPatternToAdd, $multiCharacterEscape = true)
19
    {
20
        if (null == self::$Letter) {
21
            self::init();
22
        }
23
        $newPatternToAdd = $this->processRegex($newPatternToAdd, $multiCharacterEscape);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $newPatternToAdd. This often makes code more readable.
Loading history...
24
        if (!$this->checkRegexValidPattern($newPatternToAdd)) {
25
            $newPatternToAdd = '/' . $newPatternToAdd . '/u';
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $newPatternToAdd. This often makes code more readable.
Loading history...
26
            if (!$this->checkRegexValidPattern($newPatternToAdd)) {
27
                throw new \InvalidArgumentException('Invalid regex pattern provided: ' . get_class($this) .
28
                    'pattern is: ' . $newPatternToAdd);
29
            }
30
        }
31
        $this->pattern[] = $newPatternToAdd;
32
    }
33
34
    /**
35
     * @param string $patternToProcess
36
     * @param bool   $processMultiCharacterEscape
0 ignored issues
show
Documentation introduced by
There is no parameter named $processMultiCharacterEscape. Did you maybe mean $multiCharacterEscape?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
37
     * @param mixed  $multiCharacterEscape
38
     *
39
     * @return string
40
     */
41
    private function processRegex($patternToProcess, $multiCharacterEscape)
42
    {
43
        if (!$multiCharacterEscape) {
44
            return $patternToProcess;
45
        }
46
        if (null == self::$NameChar) {
47
            init();
48
        }
49
        $patternToProcess = $this->processRegexSlashS($patternToProcess);
50
        $patternToProcess = $this->processRegexSlashI($patternToProcess);
51
        $patternToProcess = $this->processRegexSlashC($patternToProcess);
52
        $patternToProcess = $this->processRegexSlashD($patternToProcess);
53
        $patternToProcess = $this->processRegexSlashW($patternToProcess);
54
        return $patternToProcess;
55
    }
56
57
    /**
58
     * @param string $patternToProcess
59
     *
60
     * @return string
61
     */
62 View Code Duplication
    private function processRegexSlashS($patternToProcess)
63
    {
64
        // Any character except those matched by '\s'.
65
        $patternToProcess = str_replace('\S', '[^\s]', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
66
        // Whitespace, specifically '&#20;' (space), '\t' (tab), '\n' (newline) and '\r' (return).
67
        $patternToProcess = str_replace('\s', '([\x{20}\t\n\r])', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
68
        return $patternToProcess;
69
    }
70
71
    /**
72
     * @param string $patternToProcess
73
     *
74
     * @return string
75
     */
76
    private function processRegexSlashI($patternToProcess)
77
    {
78
        // Any character except those matched by '\i'.
79
        $patternToProcess = str_replace('\I', '[^\i]', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
80
        // The first character in an XML identifier. Specifically, any letter, the character '_', or the character ':',
81
        // See the XML Recommendation for the complex specification of a letter. This character represents a subset of
82
        // letter that might appear in '\c'.
83
        $patternToProcess = str_replace('\i-[:]', self::$Letter . '|_| ', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
84
        $patternToProcess = str_replace('\i', '(' . self::$Letter . '|_|:)', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
85
        return $patternToProcess;
86
    }
87
88
    /**
89
     * @param string $patternToProcess
90
     *
91
     * @return string
92
     */
93
    private function processRegexSlashC($patternToProcess)
94
    {
95
        // Any character except those matched by '\c'.
96
        $patternToProcess = str_replace('\C', '[^\c]', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
97
        // Any character that might appear in the built-in NMTOKEN datatype.
98
        // See the XML Recommendation for the complex specification of a NameChar.
99
        $patternToProcess = str_replace('\c-[:]', self::$Letter . '|' . self::$Digit . '|.|-|_|' . self::$CombiningChar . '|'
100
            . self::$Extender, $patternToProcess);
101
        $patternToProcess = str_replace('\c', '(' . self::$NameChar . ')', $patternToProcess);
102
        return $patternToProcess;
103
    }
104
105
    /**
106
     * @param string $patternToProcess
107
     *
108
     * @return string
109
     */
110 View Code Duplication
    private function processRegexSlashD($patternToProcess)
111
    {
112
        // Any character except those matched by '\d'.
113
        $patternToProcess = str_replace('\D', '[^(\d)]', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
114
        // Any Decimal digit. A shortcut for '\p{Nd}'.
115
        $patternToProcess = str_replace('\d', '\p{Nd)', $patternToProcess);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $patternToProcess. This often makes code more readable.
Loading history...
116
        return $patternToProcess;
117
    }
118
119
    /**
120
     * @param string $patternToProcess
121
     *
122
     * @return string
123
     */
124 View Code Duplication
    private function processRegexSlashW($patternToProcess)
125
    {
126
        // Any character except those matched by '\w'.
127
        $patternToProcess = str_replace('\W', '[^\w]', $patternToProcess);
128
        // Any character that might appear in a word. A shortcut for '[#X0000-#x10FFFF]-[\p{P}\p{Z}\p{C}]'
129
        // (all characters except the set of "punctuation", "separator", and "other" characters).
130
        $patternToProcess = str_replace('\w', '([\x{0000}-\x{10FFFF}]-[\p{P}\p{Z}\p{C}])',
131
            $patternToProcess);
132
        return $patternToProcess;
133
    }
134
135
    /**
136
     * @param string $pattern
137
     *
138
     * @return bool
139
     */
140
    private function checkRegexValidPattern($pattern)
141
    {
142
        return !(false === @preg_match($pattern, null));
143
    }
144
145
    /**
146
     * @param string $value
147
     */
148
    private function checkPattern($value)
149
    {
150
        if (!empty($this->pattern)) {
151
            foreach ($this->pattern as $pattern) {
152
                if (!$this->matchesRegexPattern($pattern, $value)) {
153
                    throw new \InvalidArgumentException('Assigned value for ' . get_class($this) .
154
                        ' does not match pattern ' . $pattern);
155
                }
156
            }
157
        }
158
    }
159
160
    /**
161
     * Checks a pattern against a string.
162
     *
163
     * @param  string $pattern the regex pattern
164
     * @param  string $string  the string to check
165
     * @return bool   true if string matches pattern
166
     */
167
    private function matchesRegexPattern($pattern, $string)
168
    {
169
        $matches = null;
170
        return (1 == preg_match($pattern, $string, $matches) && $string == $matches[0]);
171
    }
172
}
173