From 9665f430438413391a9a8272d72fccbbe6c7b272 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Sun, 2 Jan 2022 16:27:51 +0100 Subject: Enable paged forms --- src/App.php | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 147 insertions(+), 28 deletions(-) diff --git a/src/App.php b/src/App.php index 7e0cabd..b2c877e 100644 --- a/src/App.php +++ b/src/App.php @@ -44,8 +44,16 @@ class App if (str_ends_with($path, '/fields')) { $formPath = $contentRoot . str_replace('/fields', '', $path); - $content['data'] = $this->buildFields($formPath); + $fields = $this->buildFields($formPath, $_GET['page'] ?? null); + + // flatten paged form + if ($this->isPagedFieldSet($fields) && isset($_GET['flat'])) { + $fields = array_merge(...array_values($fields)); + } + + $content['data'] = $fields; } + else { $content['data'] = Toml::parseFile($contentRoot . $path . '.toml'); } @@ -53,25 +61,23 @@ class App // POST else if ($method == 'POST') { - if (str_ends_with($path, '/submit')) { + if (str_ends_with($path, '/validate')) { + $formPath = $contentRoot . str_replace('/validate', '', $path); + + $fields = $this->buildFields($formPath, $_GET['page'] ?? null); + + $content = $this->validateRequest($fields); + } + + else if (str_ends_with($path, '/submit')) { $formPath = $contentRoot . str_replace('/submit', '', $path); $fields = $this->buildFields($formPath); - $fields = $this->validateFields($fields); - - // remove surplus fields from response - $fields = array_map(function ($field) { - return array_intersect_key($field, array_flip([ - 'is_valid', - ])); - }, $fields); - $content['data'] = $fields; + $content = $this->validateRequest($fields); - $hasInvalidFields = in_array(false, array_column($fields, 'is_valid')); - if ($hasInvalidFields) { - $content['error'] = 'Invalid fields'; - } else { + // if there were no validation errors then add entry + if (empty($content['error'])) { $date = new \Datetime(); $entry = [ 'fields' => $_POST, @@ -104,43 +110,146 @@ class App $response->send(); } + /** + * @param array $fields + */ + public function validateRequest($fields) { + $content = []; + $hasInvalidFields = false; + + $fields = $this->validateFields($fields); + + if ($this->isPagedFieldSet($fields)) { + // remove surplus field values from response + $fields = array_map(function ($page) { + return array_map(function ($field) { + return array_intersect_key($field, array_flip([ + 'is_valid', + ])); + }, $page); + }, $fields); + + $flattened = array_merge(...array_values($fields)); + $hasInvalidFields = in_array(false, array_column($flattened, 'is_valid')); + } else { + // remove surplus field values from response + $fields = array_map(function ($field) { + return array_intersect_key($field, array_flip([ + 'is_valid', + ])); + }, $fields); + + $hasInvalidFields = in_array(false, array_column($fields, 'is_valid')); + } + + $content['data'] = $fields; + + if ($hasInvalidFields) { + $content['error'] = 'Invalid fields'; + } + + return $content; + } + /** * @param string $formPath + * @param mixed $page */ - public function buildFields($formPath) + public function buildFields($formPath, $page = null) { - $fields = Toml::parseFile($formPath . '/fields/_fields.toml')['field'] ?? []; - foreach ($fields as $key => $field) { - if (! empty($field['file'])) { - $field = array_replace_recursive($field, Toml::parseFile($formPath . '/fields/' . $field['file'])); + $parsed = Toml::parseFile($formPath . '/fields/_fields.toml'); + $fields = []; + + // if a page is requested + if ($page) { + if (! isset($parsed['page'])) { + throw new \Exception('Form has no pages'); } - if (empty($field['name'])) { - $field['name'] = $key; + if (! isset($parsed['page'][$page])) { + throw new \Exception('Form has no page ' . $page); } - $fields[$key] = $field; + foreach ($parsed['page'][$page]['field'] as $key => $field) { + $fields[$key] = $this->buildSingleField($formPath, $key, $field); + } + } + + // else get all fields + else { + // if form is paged + if (isset($parsed['page'])) { + $pages = $parsed['page']; + foreach ($pages as $pageKey => $pageFields) { + foreach ($pageFields['field'] as $key => $field) { + $fields[$pageKey][$key] = $this->buildSingleField($formPath, $key, $field); + } + } + } + + // if form is not paged + else { + foreach ($parsed['field'] as $key => $field) { + $fields[$key] = $this->buildSingleField($formPath, $key, $field); + } + } } return $fields; } + /** + * @param string $formPath + * @param string $key + * @param string $field + */ + public function buildSingleField($formPath, $key, $field) + { + if (! empty($field['file'])) { + $field = array_replace_recursive($field, Toml::parseFile($formPath . '/fields/' . $field['file'])); + } + + if (empty($field['name'])) { + $field['name'] = $key; + } + + return $field; + } + /** * @param array $fields */ public function validateFields($fields) { - foreach ($fields as $key => &$field) { - $field['is_valid'] = true; - - if (($field['required'] ?? false) && empty($_POST[$field['name']])) { - $field['is_valid'] = false; + if ($this->isPagedFieldSet($fields)) { + foreach ($fields as $pageKey => &$pageFields) { + foreach ($pageFields as $key => &$field) { + $field = $this->validateSingleField($field); + } + } + } else { + foreach ($fields as $key => &$field) { + $field = $this->validateSingleField($field); } } return $fields; } + /** + * @param array $field + */ + public function validateSingleField($field) + { + $field['is_valid'] = true; + + if (($field['required'] ?? false) && empty($_POST[$field['name']])) { + $field['is_valid'] = false; + } + + return $field; + } + /** * @param string $formPath */ @@ -167,5 +276,15 @@ class App return $config; } + + /** + * @param array $fields + */ + public function isPagedFieldSet($fields) + { + $firstItem = reset($fields); + + return ! (isset($firstItem['name']) && ! is_array($firstItem['name'])); + } } -- cgit v1.2.3