Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.67% |
58 / 60 |
|
95.00% |
19 / 20 |
CRAP | |
0.00% |
0 / 1 |
ClosureExpressionBuilder | |
96.67% |
58 / 60 |
|
95.00% |
19 / 20 |
34 | |
0.00% |
0 / 1 |
getObjectFieldValue | |
90.91% |
20 / 22 |
|
0.00% |
0 / 1 |
9.06 | |||
getSupportedTokenType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
parameter | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
string | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isNull | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
eq | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
neq | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
gt | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
gte | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
lt | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
lte | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
in | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
notIn | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
contains | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
notContains | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
andX | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
nandX | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
orX | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
norX | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
xorX | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Symftony\Xpression\Expr; |
6 | |
7 | use Symftony\Xpression\Lexer; |
8 | |
9 | class ClosureExpressionBuilder implements ExpressionBuilderInterface |
10 | { |
11 | public static function getObjectFieldValue(mixed $object, mixed $field): mixed |
12 | { |
13 | if (\is_array($object)) { |
14 | return $object[$field]; |
15 | } |
16 | |
17 | $accessors = ['get', 'is']; |
18 | |
19 | foreach ($accessors as $accessor) { |
20 | $accessor .= $field; |
21 | |
22 | if (!method_exists($object, $accessor)) { |
23 | continue; |
24 | } |
25 | |
26 | return $object->{$accessor}(); |
27 | } |
28 | |
29 | // __call should be triggered for get. |
30 | $accessor = $accessors[0].$field; |
31 | |
32 | if (method_exists($object, '__call')) { |
33 | return $object->{$accessor}(); |
34 | } |
35 | |
36 | if ($object instanceof \ArrayAccess) { |
37 | return $object[$field]; |
38 | } |
39 | |
40 | if (isset($object->{$field})) { |
41 | return $object->{$field}; |
42 | } |
43 | |
44 | // camelcase field name to support different variable naming conventions |
45 | $ccField = preg_replace_callback('/_(.?)/', static fn ($matches) => strtoupper($matches[1]), $field); |
46 | |
47 | foreach ($accessors as $accessor) { |
48 | $accessor .= $ccField; |
49 | |
50 | if (!method_exists($object, $accessor)) { |
51 | continue; |
52 | } |
53 | |
54 | return $object->{$accessor}(); |
55 | } |
56 | |
57 | return $object->{$field}; |
58 | } |
59 | |
60 | public function getSupportedTokenType(): int |
61 | { |
62 | return Lexer::T_ALL; |
63 | } |
64 | |
65 | /** |
66 | * @param bool $isValue |
67 | * @param mixed $value |
68 | */ |
69 | public function parameter($value, $isValue = false): mixed |
70 | { |
71 | return $value; |
72 | } |
73 | |
74 | public function string(mixed $value): mixed |
75 | { |
76 | return $value; |
77 | } |
78 | |
79 | public function isNull(string $field): mixed |
80 | { |
81 | return static fn ($object) => null === ClosureExpressionBuilder::getObjectFieldValue($object, $field); |
82 | } |
83 | |
84 | public function eq(string $field, mixed $value): mixed |
85 | { |
86 | return static fn ($object) => ClosureExpressionBuilder::getObjectFieldValue($object, $field) === $value; |
87 | } |
88 | |
89 | public function neq(string $field, mixed $value): mixed |
90 | { |
91 | return static fn ($object) => ClosureExpressionBuilder::getObjectFieldValue($object, $field) !== $value; |
92 | } |
93 | |
94 | public function gt(string $field, mixed $value): mixed |
95 | { |
96 | return static fn ($object) => ClosureExpressionBuilder::getObjectFieldValue($object, $field) > $value; |
97 | } |
98 | |
99 | public function gte(string $field, mixed $value): mixed |
100 | { |
101 | return static fn ($object) => ClosureExpressionBuilder::getObjectFieldValue($object, $field) >= $value; |
102 | } |
103 | |
104 | public function lt(string $field, mixed $value): mixed |
105 | { |
106 | return static fn ($object) => ClosureExpressionBuilder::getObjectFieldValue($object, $field) < $value; |
107 | } |
108 | |
109 | public function lte(string $field, mixed $value): mixed |
110 | { |
111 | return static fn ($object) => ClosureExpressionBuilder::getObjectFieldValue($object, $field) <= $value; |
112 | } |
113 | |
114 | public function in(string $field, array $values): mixed |
115 | { |
116 | return static fn ($object) => \in_array(ClosureExpressionBuilder::getObjectFieldValue($object, $field), $values, true); |
117 | } |
118 | |
119 | public function notIn(string $field, array $values): mixed |
120 | { |
121 | return static fn ($object) => !\in_array(ClosureExpressionBuilder::getObjectFieldValue($object, $field), $values, true); |
122 | } |
123 | |
124 | public function contains(string $field, mixed $value): mixed |
125 | { |
126 | return static fn ($object) => str_contains(ClosureExpressionBuilder::getObjectFieldValue($object, $field), $value); |
127 | } |
128 | |
129 | public function notContains(string $field, mixed $value): mixed |
130 | { |
131 | return static fn ($object) => !str_contains(ClosureExpressionBuilder::getObjectFieldValue($object, $field), $value); |
132 | } |
133 | |
134 | public function andX(array $expressions): mixed |
135 | { |
136 | return static function ($object) use ($expressions) { |
137 | foreach ($expressions as $expression) { |
138 | if (!$expression($object)) { |
139 | return false; |
140 | } |
141 | } |
142 | |
143 | return true; |
144 | }; |
145 | } |
146 | |
147 | public function nandX(array $expressions): mixed |
148 | { |
149 | $self = $this; |
150 | |
151 | return static fn ($object) => !$self->andX($expressions)($object); |
152 | } |
153 | |
154 | public function orX(array $expressions): mixed |
155 | { |
156 | return static function ($object) use ($expressions) { |
157 | foreach ($expressions as $expression) { |
158 | if ($expression($object)) { |
159 | return true; |
160 | } |
161 | } |
162 | |
163 | return false; |
164 | }; |
165 | } |
166 | |
167 | public function norX(array $expressions): mixed |
168 | { |
169 | $self = $this; |
170 | |
171 | return static fn ($object) => !$self->orX($expressions)($object); |
172 | } |
173 | |
174 | public function xorX(array $expressions): mixed |
175 | { |
176 | return static function ($object) use ($expressions) { |
177 | $result = 0; |
178 | foreach ($expressions as $expression) { |
179 | if ($expression($object)) { |
180 | ++$result; |
181 | } |
182 | } |
183 | |
184 | $countExpressions = \count($expressions); |
185 | |
186 | return 1 === $result | (2 < $countExpressions & $result === $countExpressions); |
187 | }; |
188 | } |
189 | } |