Test Failed
Push — master ( 1c5165...b7ef6a )
by Kirill
03:37
created

Field::analyze()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 9
cts 10
cp 0.9
rs 9.7333
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3.009
1
<?php
2
/**
3
 * This file is part of Hydrogen package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace RDS\Hydrogen\Criteria\Common;
11
12
use Illuminate\Support\Str;
13
use RDS\Hydrogen\Query;
14
15
/**
16
 * Class Field
17
 */
18
class Field implements FieldInterface
19
{
20
    /**
21
     * Inherit value delimiter
22
     */
23
    public const DEEP_DELIMITER = '.';
24
25
    /**
26
     * Prefix using for disable aliasing field
27
     */
28
    public const NON_ALIASED_PREFIX = ':';
29
30
    /**
31
     * @var string
32
     */
33
    private $field;
34
35
    /**
36
     * @var string
37
     */
38
    private $wrapper;
39
40
    /**
41
     * @var string
42
     */
43
    private $alias;
44
45
    /**
46
     * @var Query
47
     */
48
    private $query;
49
50
    /**
51
     * @var bool
52
     */
53
    private $prefixed;
54
55
    /**
56
     * Field constructor.
57
     * @param string $query
58
     */
59 71
    public function __construct(string $query)
60
    {
61 71
        \assert(\strlen(\trim($query)) > 0);
62
63 71
        [$this->wrapper, $this->field, $this->prefixed] = $this->analyze(\trim($query));
64 71
    }
65
66
    /**
67
     * @param string $query
68
     * @return array
69
     */
70 71
    private function analyze(string $query): array
71
    {
72 71
        \preg_match('/^([\w\.\:\*]+)[\w\.\:\*\s]*?$/iu', $query, $m);
73 71
        if (\count($m)) {
74 56
            $wrapper = [\str_replace_first($m[1], '%s', $m[0])];
75 56
            return \array_merge($wrapper, $this->analyzePrefix((string)$m[1]));
76
        }
77
78 16
        \preg_match('/^.+?\(([\w\.\:\*]+).*?$/isu', $query, $m);
79 16
        if (\count($m)) {
80 16
            $wrapper = [\str_replace_first($m[1], '%s', $m[0])];
81 16
            return \array_merge($wrapper, $this->analyzePrefix((string)$m[1]));
82
        }
83
84
        return ['%s', (string)$query, false];
85
    }
86
87
    /**
88
     * @param string $field
89
     * @return array
90
     */
91 71
    private function analyzePrefix(string $field): array
92
    {
93 71
        $prefixed = true;
94
95 71
        if ($field === '*') {
96 1
            return [$field, false];
97
        }
98
99 70
        if (Str::startsWith($field, self::NON_ALIASED_PREFIX)) {
100 34
            return [\substr($field, 1), false];
101
        }
102
103 37
        return [$field, $prefixed];
104
    }
105
106
    /**
107
     * @param string $query
108
     * @return Field|static
109
     */
110 11
    public static function new(string $query): self
111
    {
112 11
        return new static($query);
113
    }
114
115
    /**
116
     * @return bool
117
     */
118 8
    public function isPrefixed(): bool
119
    {
120 8
        return $this->prefixed;
121
    }
122
123
    /**
124
     * @return string
125
     */
126 18
    public function getName(): string
127
    {
128 18
        return \array_first($this->getChunks());
129
    }
130
131
    /**
132
     * @return array|string[]
133
     */
134 22
    public function getChunks(): array
135
    {
136 22
        return \explode(self::DEEP_DELIMITER, $this->field);
137
    }
138
139
    /**
140
     * @return string
141
     */
142
    public function __toString(): string
143
    {
144
        return $this->toString();
145
    }
146
147
    /**
148
     * @return string
149
     */
150 66
    public function toString(): string
151
    {
152 66
        return \sprintf($this->wrapper, $this->getFieldWithPrefix());
153
    }
154
155
    /**
156
     * @return string
157
     */
158 66
    private function getFieldWithPrefix(): string
159
    {
160 66
        if ($this->prefixed) {
161 32
            $chunks = \array_filter([$this->getAlias(), $this->field]);
162
163 32
            return \implode(self::DEEP_DELIMITER, $chunks);
164
        }
165
166 35
        return $this->field;
167
    }
168
169
    /**
170
     * @return null|string
171
     */
172 33
    public function getAlias(): ?string
173
    {
174 33
        if ($this->alias) {
175 6
            return $this->alias;
176
        }
177
178 27
        if ($this->query) {
179 25
            return $this->query->getAlias();
180
        }
181
182 2
        return null;
183
    }
184
185
    /**
186
     * @param Query $query
187
     * @return Field|$this
188
     */
189 59
    public function withQuery(Query $query): self
190
    {
191 59
        $this->query = $query;
192
193 59
        return $this;
194
    }
195
196
    /**
197
     * @param string $alias
198
     * @return Field
199
     */
200 11
    public function withAlias(string $alias): self
201
    {
202 11
        $this->alias = $alias;
203
204 11
        return $this;
205
    }
206
}
207