diff --git a/CHANGELOG.md b/CHANGELOG.md index 957b18ca3..23affb966 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,8 @@ 1. [](#bugfix) * Fixed fatal error when calling `{{ grav.undefined }}` * Fixed multiple issues when there are no pages in the site - * PHP 7.4 fix for [#2750](https://github.com/getgrav/grav/issues/2750) + * PHP 7.4 fix for [#2750](https://github.com/getgrav/grav/issues/2750) + * Fixed `validation: strict` not working in blueprints [#1273](https://github.com/getgrav/grav/issues/1273) # v1.6.18 ## 12/02/2019 diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php index 898450d28..f7c716780 100644 --- a/system/src/Grav/Common/Data/BlueprintSchema.php +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -53,7 +53,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface public function validate(array $data) { try { - $messages = $this->validateArray($data, $this->nested); + $messages = $this->validateArray($data, $this->nested, $this->items['']['form'] ?? []); } catch (\RuntimeException $e) { throw (new ValidationException($e->getMessage(), $e->getCode(), $e))->setMessages(); @@ -129,14 +129,15 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface /** * @param array $data * @param array $rules + * @param array $parent * @return array * @throws \RuntimeException */ - protected function validateArray(array $data, array $rules) + protected function validateArray(array $data, array $rules, array $parent) { $messages = $this->checkRequired($data, $rules); - foreach ($data as $key => $field) { + foreach ($data as $key => $child) { $val = $rules[$key] ?? $rules['*'] ?? null; $rule = \is_string($val) ? $this->items[$val] : null; @@ -147,11 +148,11 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface continue; } - $messages += Validation::validate($field, $rule); - } elseif (\is_array($field) && \is_array($val)) { + $messages += Validation::validate($child, $rule); + } elseif (\is_array($child) && \is_array($val)) { // Array has been defined in blueprints. - $messages += $this->validateArray($field, $val); - } elseif (isset($rules['validation']) && $rules['validation'] === 'strict') { + $messages += $this->validateArray($child, $val, $rule); + } elseif (isset($parent['validation']) && $parent['validation'] === 'strict') { // Undefined/extra item. throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); } diff --git a/tests/unit/Grav/Common/Data/BlueprintTest.php b/tests/unit/Grav/Common/Data/BlueprintTest.php new file mode 100644 index 000000000..b27b0a961 --- /dev/null +++ b/tests/unit/Grav/Common/Data/BlueprintTest.php @@ -0,0 +1,54 @@ +loadBlueprint('strict'); + + $blueprint->validate(['test' => 'string']); + } + + /** + * @depends testValidateStrict + * @expectedException Grav\Common\Data\ValidationException + */ + public function testValidateStrictRequired() + { + $blueprint = $this->loadBlueprint('strict'); + + $blueprint->validate([]); + } + + /** + * @depends testValidateStrict + * @expectedException Grav\Common\Data\ValidationException + */ + public function testValidateStrictExtra() + { + $blueprint = $this->loadBlueprint('strict'); + + $blueprint->validate(['test' => 'string', 'wrong' => 'field']); + die(); + } + + /** + * @param string $filename + * @return Blueprint + */ + protected function loadBlueprint($filename) + { + $blueprint = new Blueprint('strict'); + $blueprint->setContext(dirname(__DIR__, 3). '/data/blueprints'); + $blueprint->load()->init(); + + return $blueprint; + } +} diff --git a/tests/unit/data/blueprints/strict.yaml b/tests/unit/data/blueprints/strict.yaml new file mode 100644 index 000000000..6121753af --- /dev/null +++ b/tests/unit/data/blueprints/strict.yaml @@ -0,0 +1,9 @@ +form: + validation: strict + + fields: + test: + type: text + label: Test + validate: + required: true