summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.example.toml1
-rw-r--r--public/index.php1
-rw-r--r--src/App.php333
-rw-r--r--tests/Test.php205
4 files changed, 268 insertions, 272 deletions
diff --git a/config.example.toml b/config.example.toml
index a943c4f..64ecc4a 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -1,3 +1,2 @@
[app]
contentFolderPath = './content'
-
diff --git a/public/index.php b/public/index.php
index 3d82924..b943298 100644
--- a/public/index.php
+++ b/public/index.php
@@ -34,4 +34,3 @@ foreach ($config as $key => $value) {
}
new App();
-
diff --git a/src/App.php b/src/App.php
index bad2412..92ceb4a 100644
--- a/src/App.php
+++ b/src/App.php
@@ -33,152 +33,152 @@ class App
// check api key
$apiKey = $_GET['key'] ?? $_POST['key'] ?? null;
if (empty($apiKey)) {
- $response->setStatusCode(Response::HTTP_BAD_REQUEST);
- throw new \Exception('API key missing');
+ $response->setStatusCode(Response::HTTP_BAD_REQUEST);
+ throw new \Exception('API key missing');
}
if (! in_array($apiKey, $config['api']['keys'])) {
- $response->setStatusCode(Response::HTTP_UNAUTHORIZED);
- throw new \Exception('API key does not match');
+ $response->setStatusCode(Response::HTTP_UNAUTHORIZED);
+ throw new \Exception('API key does not match');
}
// GET
if ($method == 'GET') {
- if (str_ends_with($path, '/fields')) {
- $this->formPath = $formPath = $contentRoot . str_replace('/fields', '', $path);
-
- $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 if (str_ends_with($path, '/entries')) {
- if (! isset($_GET['dateFrom'])) {
- $response->setStatusCode(Response::HTTP_BAD_REQUEST);
- throw new \Exception('dateFrom parameter missing');
- }
-
- $this->formPath = $formPath = $contentRoot . str_replace('/entries', '', $path);
-
- $entries = [];
-
- $dateFrom = new \DateTime($_GET['dateFrom']);
- $dateTo = new \DateTime($_GET['dateTo'] ?? 'now');
-
- $dateRangeYears = range($dateFrom->format('Y'), $dateTo->format('Y'));
- $dateRangeYearsCount = count($dateRangeYears);
- foreach ($dateRangeYears as $dateRangeYearIdx => $dateRangeYear) {
- $yearPath = "$formPath/entries/$dateRangeYear";
- if (! is_dir($yearPath)) {
- continue;
- }
-
- if ($dateRangeYearsCount === 1) {
- $dateRangeMonths = range($dateFrom->format('m'), $dateTo->format('m'));
- }
- else if ($dateRangeYearIdx === 0) {
- $dateRangeMonths = range($dateFrom->format('m'), 12);
- }
- else if ($dateRangeYearIdx === $dateRangeYearsCount - 1) {
- $dateRangeMonths = range(1, $dateTo->format('m'));
- }
- else {
- $dateRangeMonths = range(1, 12);
- }
-
- $dateRangeMonthsCount = count($dateRangeMonths);
- foreach ($dateRangeMonths as $dateRangeMonthIdx => $dateRangeMonth) {
- $monthPath = "$yearPath/" . sprintf('%02d', $dateRangeMonth);
- if (! is_dir($monthPath)) {
- continue;
- }
-
- if ($dateRangeMonthsCount === 1) {
- $dateRangeDays = range($dateFrom->format('d'), $dateTo->format('d'));
- }
- else if ($dateRangeYearIdx === 0 && $dateRangeMonthIdx === 0) {
- $dateRangeDays = range($dateFrom->format('d'), 31);
- }
- else if ($dateRangeYearIdx === $dateRangeYearsCount - 1 && $dateRangeMonthIdx === $dateRangeMonthsCount - 1) {
- $dateRangeDays = range(1, $dateTo->format('d'));
- }
- else {
- $dateRangeDays = range(1, 31);
- }
-
- foreach ($dateRangeDays as $dateRangeDay) {
- $dayPath = "$monthPath/" . sprintf('%02d', $dateRangeDay);
- if (! is_dir($dayPath)) {
- continue;
- }
-
- $entriesForDay = $this->scandir($dayPath);
- foreach ($entriesForDay as $entryForDay) {
- $entry = Toml::parseFile("$dayPath/$entryForDay");
- if (isset($_GET['flat'])) {
- $entries[] = $entry;
- } else {
- $entries[$dateRangeYear][$dateRangeMonth][$dateRangeDay][] = $entry;
- }
- }
- }
-
- }
- }
-
- $content['data'] = $entries;
- }
-
- else {
- $content['data'] = Toml::parseFile($contentRoot . $path . '.toml');
- }
+ if (str_ends_with($path, '/fields')) {
+ $this->formPath = $formPath = $contentRoot . str_replace('/fields', '', $path);
+
+ $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 if (str_ends_with($path, '/entries')) {
+ if (! isset($_GET['dateFrom'])) {
+ $response->setStatusCode(Response::HTTP_BAD_REQUEST);
+ throw new \Exception('dateFrom parameter missing');
+ }
+
+ $this->formPath = $formPath = $contentRoot . str_replace('/entries', '', $path);
+
+ $entries = [];
+
+ $dateFrom = new \DateTime($_GET['dateFrom']);
+ $dateTo = new \DateTime($_GET['dateTo'] ?? 'now');
+
+ $dateRangeYears = range($dateFrom->format('Y'), $dateTo->format('Y'));
+ $dateRangeYearsCount = count($dateRangeYears);
+ foreach ($dateRangeYears as $dateRangeYearIdx => $dateRangeYear) {
+ $yearPath = "$formPath/entries/$dateRangeYear";
+ if (! is_dir($yearPath)) {
+ continue;
+ }
+
+ if ($dateRangeYearsCount === 1) {
+ $dateRangeMonths = range($dateFrom->format('m'), $dateTo->format('m'));
+ }
+ else if ($dateRangeYearIdx === 0) {
+ $dateRangeMonths = range($dateFrom->format('m'), 12);
+ }
+ else if ($dateRangeYearIdx === $dateRangeYearsCount - 1) {
+ $dateRangeMonths = range(1, $dateTo->format('m'));
+ }
+ else {
+ $dateRangeMonths = range(1, 12);
+ }
+
+ $dateRangeMonthsCount = count($dateRangeMonths);
+ foreach ($dateRangeMonths as $dateRangeMonthIdx => $dateRangeMonth) {
+ $monthPath = "$yearPath/" . sprintf('%02d', $dateRangeMonth);
+ if (! is_dir($monthPath)) {
+ continue;
+ }
+
+ if ($dateRangeMonthsCount === 1) {
+ $dateRangeDays = range($dateFrom->format('d'), $dateTo->format('d'));
+ }
+ else if ($dateRangeYearIdx === 0 && $dateRangeMonthIdx === 0) {
+ $dateRangeDays = range($dateFrom->format('d'), 31);
+ }
+ else if ($dateRangeYearIdx === $dateRangeYearsCount - 1 && $dateRangeMonthIdx === $dateRangeMonthsCount - 1) {
+ $dateRangeDays = range(1, $dateTo->format('d'));
+ }
+ else {
+ $dateRangeDays = range(1, 31);
+ }
+
+ foreach ($dateRangeDays as $dateRangeDay) {
+ $dayPath = "$monthPath/" . sprintf('%02d', $dateRangeDay);
+ if (! is_dir($dayPath)) {
+ continue;
+ }
+
+ $entriesForDay = $this->scandir($dayPath);
+ foreach ($entriesForDay as $entryForDay) {
+ $entry = Toml::parseFile("$dayPath/$entryForDay");
+ if (isset($_GET['flat'])) {
+ $entries[] = $entry;
+ } else {
+ $entries[$dateRangeYear][$dateRangeMonth][$dateRangeDay][] = $entry;
+ }
+ }
+ }
+
+ }
+ }
+
+ $content['data'] = $entries;
+ }
+
+ else {
+ $content['data'] = Toml::parseFile($contentRoot . $path . '.toml');
+ }
}
// POST
else if ($method == 'POST') {
- if (str_ends_with($path, '/validate')) {
- $this->formPath = $formPath = $contentRoot . str_replace('/validate', '', $path);
-
- $fields = $this->buildFields($formPath, $_GET['page'] ?? null);
-
- $content = $this->validateRequest($fields);
- }
-
- else if (str_ends_with($path, '/submit')) {
- $this->formPath = $formPath = $contentRoot . str_replace('/submit', '', $path);
-
- $fields = $this->buildFields($formPath);
-
- $content = $this->validateRequest($fields);
-
- // if there were no validation errors then add entry
- if (empty($content['error'])) {
- $date = new \Datetime();
- $entry = [
- 'fields' => $_POST,
- 'date' => $date->format('c'),
- ];
-
- $builder = new TomlBuilder();
- $builder->addValue('date', $entry['date']);
- $builder->addTable('fields');
- foreach ($entry['fields'] as $entryKey => $entryValue) {
- $builder->addValue($entryKey, $entryValue);
- }
-
- $entryDirectory = $formPath . '/entries/' . $date->format('Y/m/d');
- @mkdir($entryDirectory, 0774, true);
- $entryFilename = $date->format('Ymd_Hi_') . hash('adler32', serialize($entry)) . '.toml';
- file_put_contents(
- $entryDirectory . '/' . $entryFilename,
- $builder->getTomlString()
- );
- }
- }
+ if (str_ends_with($path, '/validate')) {
+ $this->formPath = $formPath = $contentRoot . str_replace('/validate', '', $path);
+
+ $fields = $this->buildFields($formPath, $_GET['page'] ?? null);
+
+ $content = $this->validateRequest($fields);
+ }
+
+ else if (str_ends_with($path, '/submit')) {
+ $this->formPath = $formPath = $contentRoot . str_replace('/submit', '', $path);
+
+ $fields = $this->buildFields($formPath);
+
+ $content = $this->validateRequest($fields);
+
+ // if there were no validation errors then add entry
+ if (empty($content['error'])) {
+ $date = new \Datetime();
+ $entry = [
+ 'fields' => $_POST,
+ 'date' => $date->format('c'),
+ ];
+
+ $builder = new TomlBuilder();
+ $builder->addValue('date', $entry['date']);
+ $builder->addTable('fields');
+ foreach ($entry['fields'] as $entryKey => $entryValue) {
+ $builder->addValue($entryKey, $entryValue);
+ }
+
+ $entryDirectory = $formPath . '/entries/' . $date->format('Y/m/d');
+ @mkdir($entryDirectory, 0774, true);
+ $entryFilename = $date->format('Ymd_Hi_') . hash('adler32', serialize($entry)) . '.toml';
+ file_put_contents(
+ $entryDirectory . '/' . $entryFilename,
+ $builder->getTomlString()
+ );
+ }
+ }
}
} catch (\Exception $exception) {
$content['error'] = basename(get_class($exception)) . ': ' . $exception->getMessage();
@@ -202,11 +202,11 @@ class App
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);
+ return array_map(function ($field) {
+ return array_intersect_key($field, array_flip([
+ 'is_valid',
+ ]));
+ }, $page);
}, $fields);
$flattened = array_merge(...array_values($fields));
@@ -214,9 +214,9 @@ class App
} else {
// remove surplus field values from response
$fields = array_map(function ($field) {
- return array_intersect_key($field, array_flip([
- 'is_valid',
- ]));
+ return array_intersect_key($field, array_flip([
+ 'is_valid',
+ ]));
}, $fields);
$hasInvalidFields = in_array(false, array_column($fields, 'is_valid'));
@@ -243,11 +243,11 @@ class App
// if a page is requested
if ($page) {
if (! isset($parsed['page'])) {
- throw new \Exception('Form has no pages');
+ throw new \Exception('Form has no pages');
}
if (! isset($parsed['page'][$page])) {
- throw new \Exception('Form has no page ' . $page);
+ throw new \Exception('Form has no page ' . $page);
}
$fields = $this->buildSinglePageFields($parsed['page'][$page], $formPath);
@@ -257,17 +257,17 @@ class App
else {
// if form is paged
if (isset($parsed['page'])) {
- $pages = $parsed['page'];
- foreach ($pages as $pageKey => $pageFields) {
- $fields[$pageKey] = $this->buildSinglePageFields($pageFields, $formPath);
- }
+ $pages = $parsed['page'];
+ foreach ($pages as $pageKey => $pageFields) {
+ $fields[$pageKey] = $this->buildSinglePageFields($pageFields, $formPath);
+ }
}
// if form is not paged
else {
- foreach ($parsed['field'] as $key => $field) {
- $fields[$key] = $this->buildSingleField($formPath, $key, $field);
- }
+ foreach ($parsed['field'] as $key => $field) {
+ $fields[$key] = $this->buildSingleField($formPath, $key, $field);
+ }
}
}
@@ -318,13 +318,13 @@ class App
{
if ($this->isPagedFieldSet($fields)) {
foreach ($fields as $pageKey => &$pageFields) {
- foreach ($pageFields as $key => &$field) {
- $field = $this->validateSingleField($field);
- }
+ foreach ($pageFields as $key => &$field) {
+ $field = $this->validateSingleField($field);
+ }
}
} else {
foreach ($fields as $key => &$field) {
- $field = $this->validateSingleField($field);
+ $field = $this->validateSingleField($field);
}
}
@@ -365,21 +365,21 @@ class App
while (true) {
$configFile = $currentDirectory . '/config/config.toml';
if (file_exists($configFile)) {
- $parsedConfig = Toml::parseFile($configFile);
+ $parsedConfig = Toml::parseFile($configFile);
- $apiKeys = array_merge($parsedConfig['api']['keys'] ?? [], $config['api']['keys'] ?? []);
- $config = array_replace_recursive($parsedConfig, $config);
- $config['api']['keys'] = $apiKeys;
+ $apiKeys = array_merge($parsedConfig['api']['keys'] ?? [], $config['api']['keys'] ?? []);
+ $config = array_replace_recursive($parsedConfig, $config);
+ $config['api']['keys'] = $apiKeys;
}
// include custom functions
$functionsFile = $currentDirectory . '/config/functions.php';
if (file_exists($functionsFile)) {
- include_once $functionsFile;
+ include_once $functionsFile;
}
if (str_ends_with($currentDirectory, '/' . basename($_ENV['app']['contentFolderPath'])) || $currentDirectory == '/') {
- break;
+ break;
}
$currentDirectory = dirname($currentDirectory);
@@ -408,9 +408,9 @@ class App
$scanned = [];
foreach ($paths as $path) {
$filtered = array_values(
- array_filter(
- scandir($path), fn ($item) => ! in_array($item, ['.', '..'])
- )
+ array_filter(
+ scandir($path), fn ($item) => ! in_array($item, ['.', '..'])
+ )
);
array_push($scanned, ...$filtered);
}
@@ -418,4 +418,3 @@ class App
return $scanned;
}
}
-
diff --git a/tests/Test.php b/tests/Test.php
index 0543c1f..2888d81 100644
--- a/tests/Test.php
+++ b/tests/Test.php
@@ -27,118 +27,118 @@ class Test extends TestCase
# root config
file_put_contents($contentRoot . '/config/config.toml', <<<EOF
- [app]
- title = "Flat-File Forms"
+ [app]
+ title = "Flat-File Forms"
- [email]
- host = "localhost"
- user = "root"
- password = "123456"
+ [email]
+ host = "localhost"
+ user = "root"
+ password = "123456"
- [api]
- keys = ["1234"]
+ [api]
+ keys = ["1234"]
- [api.cors]
- origins = ["http://localhost:8081"]
- EOF);
+ [api.cors]
+ origins = ["http://localhost:8081"]
+ EOF);
# formname config
file_put_contents($contentRoot . '/customername/formname/config/config.toml', <<<EOF
- [api]
- keys = ["asdfghjklö0987654321", "123"]
+ [api]
+ keys = ["asdfghjklö0987654321", "123"]
- [email]
- host = "gmx"
- EOF);
+ [email]
+ host = "gmx"
+ EOF);
# formname fields
file_put_contents($contentRoot . '/customername/formname/fields/_fields.toml', <<<EOF
- [field.name]
- file = "name.toml"
+ [field.name]
+ file = "name.toml"
- [field.email]
- file = "email.toml"
- required = true
+ [field.email]
+ file = "email.toml"
+ required = true
- [field.date]
- required = true
- EOF);
+ [field.date]
+ required = true
+ EOF);
file_put_contents($contentRoot . '/customername/formname/fields/email.toml', <<<EOF
- type = "email"
- name = "email"
- placeholder = "E-Mail"
+ type = "email"
+ name = "email"
+ placeholder = "E-Mail"
- [attributes]
- data-email = "test@example.org"
- EOF);
+ [attributes]
+ data-email = "test@example.org"
+ EOF);
file_put_contents($contentRoot . '/customername/formname/fields/name.toml', <<<EOF
- type = "text"
- name = "name"
-
- [attributes]
- data-value = 123
- EOF);
-
- file_put_contents($contentRoot . '/customername/formname/config/functions.php', '
- <?php
- function validate_formname_name($field, $value)
- {
- if ($value !== \'Harry\') {
- $field[\'is_valid\'] = false;
+ type = "text"
+ name = "name"
+
+ [attributes]
+ data-value = 123
+ EOF);
+
+ file_put_contents($contentRoot . '/customername/formname/config/functions.php', <<<EOF
+ <?php
+ function validate_formname_name(\$field, \$value)
+ {
+ if (\$value !== 'Harry') {
+ \$field['is_valid'] = false;
+ }
+
+ return \$field;
}
-
- return $field;
- }
- ');
+ EOF);
# pagedform fields
file_put_contents($contentRoot . '/customername/pagedform/fields/_fields.toml', <<<EOF
- [page.one.field.name]
- file = "name.toml"
+ [page.one.field.name]
+ file = "name.toml"
- [page.one.field.email]
- file = "email.toml"
- required = true
+ [page.one.field.email]
+ file = "email.toml"
+ required = true
- [page.second]
- file = "second.toml"
+ [page.second]
+ file = "second.toml"
- [page.second.field.date]
- required = true
- EOF);
+ [page.second.field.date]
+ required = true
+ EOF);
file_put_contents($contentRoot . '/customername/pagedform/fields/second.toml', <<<EOF
- [field.text]
- placeholder = "Text placeholder"
+ [field.text]
+ placeholder = "Text placeholder"
- [field.text.validation]
- pattern = "\\\d+"
+ [field.text.validation]
+ pattern = "\\\d+"
- [field.manythings]
- type = "select"
+ [field.manythings]
+ type = "select"
- [field.manythings.options]
- first = "First level"
- second = "Second level"
+ [field.manythings.options]
+ first = "First level"
+ second = "Second level"
- [field.multiplethings]
- type = "checkbox"
- options = ["thing-1", "thing-2", "thing-3"]
- EOF);
+ [field.multiplethings]
+ type = "checkbox"
+ options = ["thing-1", "thing-2", "thing-3"]
+ EOF);
file_put_contents($contentRoot . '/customername/pagedform/fields/email.toml', <<<EOF
- type = "email"
- name = "email"
- placeholder = "E-Mail"
+ type = "email"
+ name = "email"
+ placeholder = "E-Mail"
- [attributes]
- data-email = "test@example.org"
- EOF);
+ [attributes]
+ data-email = "test@example.org"
+ EOF);
file_put_contents($contentRoot . '/customername/pagedform/fields/name.toml', <<<EOF
- type = "text"
- name = "name"
+ type = "text"
+ name = "name"
- [attributes]
- data-value = 123
- EOF);
+ [attributes]
+ data-value = 123
+ EOF);
}
public function request($method, $path, $options = []): GuzzleHttpResponse
@@ -225,14 +225,14 @@ class Test extends TestCase
// valid response
$response = $this->request('POST', 'customername/pagedform/submit?key=' . $this->apiKey, [
'form_params' => [
- 'name' => 'NAME',
- 'email' => 'EMAIL',
- 'date' => 'DATE',
- 'text' => '123',
- 'manythings' => 'second',
- 'multiplethings' => [
- 'thing-1', 'thing-3',
- ],
+ 'name' => 'NAME',
+ 'email' => 'EMAIL',
+ 'date' => 'DATE',
+ 'text' => '123',
+ 'manythings' => 'second',
+ 'multiplethings' => [
+ 'thing-1', 'thing-3',
+ ],
],
]);
$body = json_decode((string)$response->getBody(), true);
@@ -245,9 +245,9 @@ class Test extends TestCase
// invalid response
$response = $this->request('POST', 'customername/pagedform/submit?key=' . $this->apiKey, [
'form_params' => [
- 'name' => 'NAME',
- 'date' => 'DATE',
- 'text' => 'einszweidrei',
+ 'name' => 'NAME',
+ 'date' => 'DATE',
+ 'text' => 'einszweidrei',
],
]);
$body = json_decode((string)$response->getBody(), true);
@@ -260,8 +260,8 @@ class Test extends TestCase
// valid response "one" page
$response = $this->request('POST', 'customername/pagedform/validate?page=one&key=' . $this->apiKey, [
'form_params' => [
- 'name' => 'NAME',
- 'email' => 'EMAIL',
+ 'name' => 'NAME',
+ 'email' => 'EMAIL',
],
]);
$body = json_decode((string)$response->getBody(), true);
@@ -275,8 +275,8 @@ class Test extends TestCase
// valid response "second" page
$response = $this->request('POST', 'customername/pagedform/validate?page=second&key=' . $this->apiKey, [
'form_params' => [
- 'date' => 'DATE',
- 'text' => '123',
+ 'date' => 'DATE',
+ 'text' => '123',
],
]);
$body = json_decode((string)$response->getBody(), true);
@@ -290,9 +290,9 @@ class Test extends TestCase
// valid response validation_function
$response = $this->request('POST', 'customername/formname/submit?key=' . $this->apiKey, [
'form_params' => [
- 'name' => 'Harry',
- 'email' => 'EMAIL',
- 'date' => 'DATE',
+ 'name' => 'Harry',
+ 'email' => 'EMAIL',
+ 'date' => 'DATE',
],
]);
$body = json_decode((string)$response->getBody(), true);
@@ -305,9 +305,9 @@ class Test extends TestCase
// invalid response validation_function
$response = $this->request('POST', 'customername/formname/submit?key=' . $this->apiKey, [
'form_params' => [
- 'name' => 'NAME',
- 'email' => 'EMAIL',
- 'date' => 'DATE',
+ 'name' => 'NAME',
+ 'email' => 'EMAIL',
+ 'date' => 'DATE',
],
]);
$body = json_decode((string)$response->getBody(), true);
@@ -318,4 +318,3 @@ class Test extends TestCase
$this->assertEquals(true, $body['date']['is_valid']);
}
}
-