|
2 | 2 |
|
3 | 3 | namespace Coduo\PHPMatcher\Matcher;
|
4 | 4 |
|
| 5 | +use Coduo\PHPMatcher\Exception\Exception; |
5 | 6 | use Coduo\PHPMatcher\Parser;
|
6 | 7 | use Coduo\ToString\StringConverter;
|
7 | 8 | use Symfony\Component\PropertyAccess\PropertyAccess;
|
@@ -144,19 +145,56 @@ private function iterateMatch(array $values, array $patterns, $parentPath = "")
|
144 | 145 | private function isPatternValid(array $pattern, array $values, $parentPath)
|
145 | 146 | {
|
146 | 147 | if (is_array($pattern)) {
|
147 |
| - $notExistingKeys = array_diff_key($pattern, $values); |
| 148 | + $skipPattern = static::UNBOUNDED_PATTERN; |
| 149 | + |
| 150 | + $pattern = array_filter( |
| 151 | + $pattern, |
| 152 | + function ($item) use ($skipPattern) { |
| 153 | + return $item !== $skipPattern; |
| 154 | + } |
| 155 | + ); |
| 156 | + |
| 157 | + $notExistingKeys = $this->findNotExistingKeys($pattern, $values); |
148 | 158 |
|
149 | 159 | if (count($notExistingKeys) > 0) {
|
150 | 160 | $keyNames = array_keys($notExistingKeys);
|
151 | 161 | $path = $this->formatFullPath($parentPath, $this->formatAccessPath($keyNames[0]));
|
152 | 162 | $this->setMissingElementInError('value', $path);
|
| 163 | + |
153 | 164 | return false;
|
154 | 165 | }
|
155 | 166 | }
|
156 | 167 |
|
157 | 168 | return true;
|
158 | 169 | }
|
159 | 170 |
|
| 171 | + /** |
| 172 | + * Finds not existing keys |
| 173 | + * Excludes keys with pattern which includes Optional Expander |
| 174 | + * |
| 175 | + * @param $pattern |
| 176 | + * @param $values |
| 177 | + * @return array |
| 178 | + */ |
| 179 | + private function findNotExistingKeys($pattern, $values) |
| 180 | + { |
| 181 | + $notExistingKeys = array_diff_key($pattern, $values); |
| 182 | + |
| 183 | + return array_filter($notExistingKeys, function ($pattern) use ($values) { |
| 184 | + if (is_array($pattern)) { |
| 185 | + return !$this->match($values, $pattern); |
| 186 | + } |
| 187 | + |
| 188 | + try { |
| 189 | + $typePattern = $this->parser->parse($pattern); |
| 190 | + } catch (Exception $e) { |
| 191 | + return true; |
| 192 | + } |
| 193 | + |
| 194 | + return !$typePattern->hasExpander('optional'); |
| 195 | + }); |
| 196 | + } |
| 197 | + |
160 | 198 | /**
|
161 | 199 | * @param $value
|
162 | 200 | * @param $pattern
|
|
0 commit comments