From a23cbd02571fc7e7b1ca7a2fb304ea0f5983aec2 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 21 Dec 2018 12:37:08 +0200 Subject: [PATCH] Added `Blueprint::processForm()` method to filter form inputs in Flex form --- CHANGELOG.md | 3 +- system/src/Grav/Common/Data/Blueprint.php | 16 +++++- .../src/Grav/Common/Data/BlueprintSchema.php | 56 +++++++++++++++++++ system/src/Grav/Framework/Flex/FlexForm.php | 16 ++++-- 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6435cdd0..2517149fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ * Added `Grav\Framework\Form\Interfaces\FormInterface` * Added `Grav\Framework\Form\Interfaces\FormFactoryInterface` * Added `Page::forms()` method to get normalized list of all form headers defined in the page - * Added `onPageAction`, `onPageTask`, `onPageAction.{$action}` and `onPageTask.{$action}` events + * Added `onPageAction`, `onPageTask`, `onPageAction.{$action}` and `onPageTask.{$task}` events + * Added `Blueprint::processForm()` method to filter form inputs # v1.6.0-beta.7 ## 12/14/2018 diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index bd2f19298..99793bfa4 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -74,6 +74,20 @@ class Blueprint extends BlueprintForm return $this->blueprintSchema->mergeData($data1, $data2, $name, $separator); } + /** + * Process data coming from a form. + * + * @param array $data + * @param array $toggles + * @return array + */ + public function processForm(array $data, array $toggles = []) + { + $this->initInternals(); + + return $this->blueprintSchema->processForm($data, $toggles); + } + /** * Return data fields that do not exist in blueprints. * @@ -268,7 +282,7 @@ class Blueprint extends BlueprintForm */ protected function dynamicSecurity(array &$field, $property, array &$call) { - if ($property) { + if ($property || !empty($field['validate']['ignore'])) { return; } diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php index c6e82c9da..f4c72fc79 100644 --- a/system/src/Grav/Common/Data/BlueprintSchema.php +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -63,6 +63,16 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface } } + /** + * @param array $data + * @param array $toggles + * @return array + */ + public function processForm(array $data, array $toggles = []) + { + return $this->processFormRecursive($data, $toggles, $this->nested); + } + /** * Filter data by using blueprints. * @@ -160,6 +170,52 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface return $results; } + + /** + * @param array $data + * @param array $toggles + * @param array $nested + * @return array + */ + protected function processFormRecursive(array $data, array $toggles, array $nested) + { + foreach ($nested as $key => $value) { + if ($key === '') { + continue; + } + if ($key === '*') { + // TODO: Add support to collections. + continue; + } + if (is_array($value)) { + // Recursively fetch the items. + $array = $this->processFormRecursive($data[$key] ?? [], $toggles[$key] ?? [], $value); + + if (!empty($array)) { + $data[$key] = $array; + } + } else { + $field = $this->get($value); + // Do not add the field if: + if ( + // Not an input field + !$field + // Field validation is set to be ignored + || !empty($field['validate']['ignore']) + // Field is toggleable and the toggle is turned off + || (!empty($field['toggleable']) && empty($toggles[$key])) + ) { + continue; + } + if (!isset($data[$key])) { + $data[$key] = null; + } + } + } + + return $data; + } + /** * @param array $data * @param array $fields diff --git a/system/src/Grav/Framework/Flex/FlexForm.php b/system/src/Grav/Framework/Flex/FlexForm.php index 8c8d60938..ceda6431f 100644 --- a/system/src/Grav/Framework/Flex/FlexForm.php +++ b/system/src/Grav/Framework/Flex/FlexForm.php @@ -213,9 +213,12 @@ class FlexForm implements FlexFormInterface $flash = $this->getFlash(); - $includeOriginal = (bool)($this->getBlueprint()->form()['images']['original'] ?? null); + $blueprint = $this->getBlueprint(); + $includeOriginal = (bool)($blueprint->form()['images']['original'] ?? null); $files = $flash->getFilesByFields($includeOriginal); - $data = $request->getParsedBody(); + $body = $request->getParsedBody(); + + $data = $blueprint->processForm($this->decodeData($body['data'] ?? []), $body['toggleable_data'] ?? []); $this->submit($data, $files); @@ -236,12 +239,15 @@ class FlexForm implements FlexFormInterface $flash = $this->getFlash(); - $includeOriginal = (bool)($this->getBlueprint()->form()['images']['original'] ?? null); + $blueprint = $this->getBlueprint(); + $includeOriginal = (bool)($blueprint->form()['images']['original'] ?? null); $files = $flash->getFilesByFields($includeOriginal); $body = $request->getParsedBody(); + $data = $blueprint->processForm($this->decodeData($body['data'] ?? []), $body['toggleable_data'] ?? []); + $this->files = $files ?? []; - $this->data = new Data($this->decodeData($body['data'] ?? []), $this->getBlueprint()); + $this->data = new Data($data, $this->getBlueprint()); return $this; } @@ -315,7 +321,7 @@ class FlexForm implements FlexFormInterface } $this->files = $files ?? []; - $this->data = new Data($this->decodeData($data['data'] ?? []), $this->getBlueprint()); + $this->data = new Data($data, $this->getBlueprint()); if (!$this->validate()) { return $this;