Chunk::getParameters()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace AmaTeam\Image\Projection\Filesystem\Pattern;
4
5
/**
6
 * TODO: implement proper tokenization/parsing mechanism
7
 */
8
class Chunk
9
{
10
    const TYPE_EXACT_MATCH = 'exact';
11
    const TYPE_EXPRESSION = 'match';
12
    const PATTERN = '/\{([\w\-]+)\}/';
13
14
    /**
15
     * Chunk type, one of Chunk::TYPE_* constants
16
     *
17
     * @var string
18
     */
19
    private $type;
20
    /**
21
     * Original chunk text value
22
     *
23
     * @var string
24
     */
25
    private $source;
26
    /**
27
     * Regular expression built to match the chunk
28
     *
29
     * @var string
30
     */
31
    private $expression;
32
    /**
33
     * List of parameters specified in chunk
34
     *
35
     * @var string[]
36
     */
37
    private $parameters = [];
38
39
    public function __construct($chunk)
40
    {
41
        $this->source = $chunk;
42
        $this->expression = $chunk;
43
        $this->type = self::TYPE_EXACT_MATCH;
44
        $expression = preg_replace_callback(self::PATTERN, function ($match) {
45
            $parameter = $match[1];
46
            if (in_array($parameter, $this->parameters)) {
47
                return '(?:[\w\-]+)';
48
            }
49
            $this->parameters[] = $parameter;
50
            return sprintf('(?<%s>[\w\-]+)', $parameter);
51
        }, $chunk);
52
        if ($expression === $chunk) {
53
            return;
54
        }
55
        $this->type = self::TYPE_EXPRESSION;
56
        $this->expression = '/^' . $expression . '$/';
57
    }
58
59
    /**
60
     * @param string $segment
61
     * @return bool
62
     */
63
    public function matches($segment)
64
    {
65
        if ($this->type === self::TYPE_EXACT_MATCH) {
66
            return $segment === $this->expression;
67
        }
68
        return !!preg_match($this->expression, $segment);
69
    }
70
71
    /**
72
     * @param string $segment
73
     * @return string[]
74
     */
75
    public function getParameters($segment)
76
    {
77
        if ($this->type === self::TYPE_EXACT_MATCH) {
78
            return [];
79
        }
80
        if (!preg_match($this->expression, $segment, $matches)) {
81
            return [];
82
        }
83
        $target = [];
84
        foreach ($this->parameters as $parameter) {
85
            $target[$parameter] = $matches[$parameter];
86
        }
87
        return $target;
88
    }
89
90
    /**
91
     * @param array $parameters
92
     * @return Chunk
93
     */
94
    public function resolve(array $parameters)
95
    {
96
        $chunk = $this->source;
97
        foreach ($parameters as $key => $value) {
98
            $needle = "{{$key}}";
99
            if (strpos($chunk, $needle) !== false) {
100
                $chunk = str_replace($needle, $value, $chunk);
101
            }
102
        }
103
        return new Chunk($chunk);
104
    }
105
106
    /**
107
     * @return string
108
     */
109
    public function getType()
110
    {
111
        return $this->type;
112
    }
113
114
    /**
115
     * @return string
116
     */
117
    public function getExpression()
118
    {
119
        return $this->expression;
120
    }
121
122
    /**
123
     * @return string
124
     */
125
    public function getSource()
126
    {
127
        return $this->source;
128
    }
129
130
    /**
131
     * @return string
132
     */
133
    public function __toString()
134
    {
135
        return $this->source;
136
    }
137
}
138