summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2022-01-02 16:27:51 +0100
committerDaniel Weipert <code@drogueronin.de>2022-01-10 11:29:13 +0100
commit9665f430438413391a9a8272d72fccbbe6c7b272 (patch)
tree32a6ecef9c1fb68128dc9bd8ebf70e9adc630a41
parentda0d49a8472a3472ed24c99ed08435bf43a2ca3f (diff)
Enable paged forms
-rw-r--r--src/App.php175
1 files 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,
@@ -105,36 +111,125 @@ class App
}
/**
+ * @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);
}
}
@@ -142,6 +237,20 @@ class App
}
/**
+ * @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
*/
public function buildConfig($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']));
+ }
}