Completed
Push — master ( 605ec5...e9cc16 )
by Vitaly
02:18
created

VariableCG::compare()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php declare(strict_types=1);
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>.
4
 * on 06.04.17 at 07:34
5
 */
6
namespace samsonframework\stringconditiontree\string;
7
8
/**
9
 * This class describes character group with variable length.
10
 *
11
 * @author Vitaly Egorov <[email protected]>
12
 */
13
class VariableCG extends AbstractCG
14
{
15
    /** string Regular expression named filter group */
16
    const PATTERN_FILTER_GROUP = 'filter';
17
18
    /** string Variable string filter pattern */
19
    const PATTER_FILTER = '/.*?:(?<'.self::PATTERN_FILTER_GROUP.'>[^}]+)/';
20
21
    /** string Regular expression named character group group */
22
    const PATTERN_GROUP = 'variable';
23
24
    /** string Regular expression matching character group */
25
    const PATTERN_REGEXP = '{.*?}';
26
27
    /** string Character group matching regexp pattern */
28
    const PATTERN = '(?<'.self::PATTERN_GROUP.'>'.self::PATTERN_REGEXP.')';
29
30
    /** @var string Variable character group filter string */
31
    protected $filter;
32
33
    /**
34
     * @inheritdoc
35
     */
36 49
    public function __construct($string, $length = 0)
37
    {
38 49
        parent::__construct($string, $length);
39
40 49
        $this->filter = $this->getFilter();
41 49
    }
42
43
    /**
44
     * Get variable character group filter value.
45
     *
46
     * @return string Filter value or empty string
47
     */
48 49
    protected function getFilter(): string
49
    {
50 49
        if (preg_match(static::PATTER_FILTER, $this->string, $matches)) {
51 20
            return $matches[self::PATTERN_FILTER_GROUP];
52
        }
53
54 44
        return '';
55
    }
56
57
    /**
58
     * Whole variable length string should match.
59
     *
60
     * @inheritdoc
61
     */
62 2
    public function getCommonPrefix(AbstractCG $group): string
63
    {
64 2
        if ($this->isSameType($group)) {
65 2
            return $this->string === $group->string ? $this->string : '';
66
        }
67
68
        // Pass to compared
69 2
        return $group->getCommonPrefix($this);
70
    }
71
72
    /**
73
     * @inheritdoc
74
     */
75 22
    public function compare(AbstractCG $group): int
76
    {
77
        /**
78
         * Shorter fixed character group has higher priority
79
         */
80 22
        if ($this->isSameType($group)) {
81 17
            return $this->compareLength($group);
82
        }
83
84
        // Variable character group always has lower priority
85 9
        return -1;
86
    }
87
88
    /**
89
     * @inheritdoc
90
     */
91 17
    protected function compareLength(AbstractCG $group): int
92
    {
93
        /** @var VariableCG $group */
94 17
        $variableFiltered = $this->isFiltered();
95 17
        $comparedFiltered = $group->isFiltered();
96
97
        /**
98
         * Both variable character groups are filtered
99
         * longer variable character groups has higher priority.
100
         */
101 17
        if ($variableFiltered && $comparedFiltered) {
102 4
            return strlen($this->filter) <=> strlen($group->filter);
103
        }
104
105
        // Only this variable character group is filtered
106 13
        if ($variableFiltered && $comparedFiltered === false) {
107 5
            return 1;
108
        }
109
110
        // Only compared variable character group is filtered
111 13
        if ($variableFiltered === false && $comparedFiltered) {
112 5
            return -1;
113
        }
114
115
        // 1 - 1 - longest
116
        // 1 - 0 - 1
117
        // 0 - 1 - -1
118
        // 0 - 0 - 0
119
120
        // Consider both variable character groups are not filtered
121 9
        return 0;
122
    }
123
124
    /**
125
     * @return bool Return true if variable character group has filter
126
     */
127 17
    protected function isFiltered(): bool
128
    {
129 17
        return $this->filter !== '';
130
    }
131
}
132