diff options
| author | David T. Sadler <davidtsadler@googlemail.com> | 2021-10-20 20:59:55 +0100 |
|---|---|---|
| committer | David T. Sadler <davidtsadler@googlemail.com> | 2021-10-20 20:59:55 +0100 |
| commit | d4122f116c937e0ec509d8cefe540146ec27a0cd (patch) | |
| tree | 481f90c4d774d32c89e612594158fe4a2d7328a4 | |
| parent | 1a112ab14becaf6d41cd34c176cbe563d4ca9742 (diff) | |
Validate fields
| -rw-r--r-- | public/create/index.php | 12 | ||||
| -rw-r--r-- | public/delete/confirm/index.php | 1 | ||||
| -rw-r--r-- | public/delete/index.php | 1 | ||||
| -rw-r--r-- | public/edit/index.php | 12 | ||||
| -rw-r--r-- | public/index.php | 1 | ||||
| -rw-r--r-- | public/store/index.php | 18 | ||||
| -rw-r--r-- | public/update/index.php | 18 | ||||
| -rw-r--r-- | src/DTS/Errors.php | 30 | ||||
| -rw-r--r-- | src/DTS/Session.php | 6 | ||||
| -rw-r--r-- | src/DTS/Validated.php | 14 | ||||
| -rw-r--r-- | src/DTS/Validator.php | 81 | ||||
| -rw-r--r-- | src/templates/create.php | 9 | ||||
| -rw-r--r-- | src/templates/edit.php | 9 |
13 files changed, 201 insertions, 11 deletions
diff --git a/public/create/index.php b/public/create/index.php index 00ce794..786b8f2 100644 --- a/public/create/index.php +++ b/public/create/index.php @@ -3,21 +3,31 @@ declare(strict_types=1); use DTS\Bookmark; +use DTS\Errors; +use DTS\Session; use DTS\Template; + use function DTS\Functions\respondAndExit; require_once(__DIR__.'/../../autoload.php'); $config = require_once(__DIR__.'/../../config.php'); +$session = Session::getInstance(); + if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') !== 'GET') { respondAndExit(405, 'Method Not Allowed'); } +$errors = $session->get('errors', new Errors()); + $template = new Template($config['path_to_templates']); $bookmark = new Bookmark(); -$html = $template->render('create', compact('bookmark')); +$html = $template->render('create', compact( + 'bookmark', + 'errors' +)); respondAndExit(200, 'OK', $html); diff --git a/public/delete/confirm/index.php b/public/delete/confirm/index.php index 6636fe9..46c70f3 100644 --- a/public/delete/confirm/index.php +++ b/public/delete/confirm/index.php @@ -4,6 +4,7 @@ declare(strict_types=1); use DTS\BookmarkRepository; use DTS\Template; + use function DTS\Functions\respondAndExit; require_once(__DIR__.'/../../../autoload.php'); diff --git a/public/delete/index.php b/public/delete/index.php index 9864c9a..fc677f3 100644 --- a/public/delete/index.php +++ b/public/delete/index.php @@ -4,6 +4,7 @@ declare(strict_types=1); use DTS\BookmarkRepository; use DTS\Session; + use function DTS\Functions\respondAndExit; use function DTS\Functions\redirectAndExit; diff --git a/public/edit/index.php b/public/edit/index.php index 9d3d4c0..fba5a90 100644 --- a/public/edit/index.php +++ b/public/edit/index.php @@ -3,17 +3,24 @@ declare(strict_types=1); use DTS\BookmarkRepository; +use DTS\Errors; +use DTS\Session; use DTS\Template; + use function DTS\Functions\respondAndExit; require_once(__DIR__.'/../../autoload.php'); $config = require_once(__DIR__.'/../../config.php'); +$session = Session::getInstance(); + if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') !== 'GET') { respondAndExit(405, 'Method Not Allowed'); } +$errors = $session->get('errors', new Errors()); + $id = filter_input(INPUT_GET, 'id'); $bookmarks = new BookmarkRepository($config['path_to_repository']); @@ -26,6 +33,9 @@ if ($bookmark === null) { respondAndExit(404, 'Not Found'); } -$html = $template->render('edit', compact('bookmark')); +$html = $template->render('edit', compact( + 'bookmark', + 'errors' +)); respondAndExit(200, 'OK', $html); diff --git a/public/index.php b/public/index.php index 025c9ec..248a3ec 100644 --- a/public/index.php +++ b/public/index.php @@ -5,6 +5,7 @@ declare(strict_types=1); use DTS\BookmarkRepository; use DTS\Session; use DTS\Template; + use function DTS\Functions\respondAndExit; require_once(__DIR__.'/../autoload.php'); diff --git a/public/store/index.php b/public/store/index.php index 45765d5..5279e69 100644 --- a/public/store/index.php +++ b/public/store/index.php @@ -5,6 +5,8 @@ declare(strict_types=1); use DTS\Bookmark; use DTS\BookmarkRepository; use DTS\Session; +use DTS\Validator; + use function DTS\Functions\redirectAndExit; use function DTS\Functions\respondAndExit; @@ -18,14 +20,24 @@ if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') !== 'POST') { respondAndExit(405, 'Method Not Allowed'); } +$validator = new Validator($_REQUEST); + +if ($validator->errors->count()) { + $session->set('errors', $validator->errors); + + redirectAndExit('/create'); +} + +$validated = $validator->validated; + $bookmarks = new BookmarkRepository($config['path_to_repository']); $bookmark = new Bookmark(); $bookmark->id = bin2hex(random_bytes(32)); -$bookmark->url = $_POST['url']; -$bookmark->title = $_POST['title']; -$bookmark->tag = $_POST['tag']; +$bookmark->url = $validated->url; +$bookmark->title = $validated->title; +$bookmark->tag = $validated->tag; $bookmark->addedAt = date('Y-m-d H:i:s'); $bookmark->unread = true; diff --git a/public/update/index.php b/public/update/index.php index 50d0dcf..d194dbd 100644 --- a/public/update/index.php +++ b/public/update/index.php @@ -4,6 +4,8 @@ declare(strict_types=1); use DTS\BookmarkRepository; use DTS\Session; +use DTS\Validator; + use function DTS\Functions\respondAndExit; use function DTS\Functions\redirectAndExit; @@ -27,9 +29,19 @@ if ($bookmark === null) { respondAndExit(404, 'Not Found'); } -$bookmark->url = $_POST['url']; -$bookmark->title = $_POST['title']; -$bookmark->tag = $_POST['tag']; +$validator = new Validator($_REQUEST); + +if ($validator->errors->count()) { + $session->set('errors', $validator->errors); + + redirectAndExit("/edit?id=$bookmark->id"); +} + +$validated = $validator->validated; + +$bookmark->url = $validated->url; +$bookmark->title = $validated->title; +$bookmark->tag = $validated->tag; if (!$bookmarks->update($bookmark)) { respondAndExit(500, 'Internal Server Error'); diff --git a/src/DTS/Errors.php b/src/DTS/Errors.php new file mode 100644 index 0000000..3c1dd5d --- /dev/null +++ b/src/DTS/Errors.php @@ -0,0 +1,30 @@ +<?php + +declare(strict_types=1); + +namespace DTS; + +class Errors +{ + private $errors = []; + + public function add(string $key, string $value): void + { + $this->errors[$key][] = $value; + } + + public function get(string $key): array + { + return $this->errors[$key]; + } + + public function has(string $key): bool + { + return array_key_exists($key, $this->errors); + } + + public function count(): int + { + return count($this->errors); + } +} diff --git a/src/DTS/Session.php b/src/DTS/Session.php index 956f4e5..e5da42f 100644 --- a/src/DTS/Session.php +++ b/src/DTS/Session.php @@ -29,13 +29,13 @@ class Session } } - public function set(string $key, string $value): void + public function set(string $key, mixed $value): void { $this->session[$key] = $_SESSION[$key] = $value; } - public function get(string $key): ?string + public function get(string $key, mixed $default = null): mixed { - return $this->session[$key] ?? null; + return $this->session[$key] ?? $default; } } diff --git a/src/DTS/Validated.php b/src/DTS/Validated.php new file mode 100644 index 0000000..5df8af7 --- /dev/null +++ b/src/DTS/Validated.php @@ -0,0 +1,14 @@ +<?php + +declare(strict_types=1); + +namespace DTS; + +class Validated +{ + public ?string $url; + + public ?string $title; + + public ?string $tag; +} diff --git a/src/DTS/Validator.php b/src/DTS/Validator.php new file mode 100644 index 0000000..7629e3b --- /dev/null +++ b/src/DTS/Validator.php @@ -0,0 +1,81 @@ +<?php + +declare(strict_types=1); + +namespace DTS; + +use DTS\Errors; +use DTS\Validated; + +class Validator +{ + public Errors $errors; + + public Validated $validated; + + function __construct(array $request) { + $this->errors = new Errors(); + + $this->validated = new Validated(); + + $this->validateUrl($request['url'], 8, 512); + + $this->validateTitle($request['title'], 8, 256); + + $this->validateTag($request['tag'], 2, 8); + } + + private function validateUrl(string $url, int $minLength, int $maxLength): void + { + $url = trim($url); + + if (filter_var($url, FILTER_VALIDATE_URL) === false) { + $this->errors->add('url', 'Must be a URL'); + } + + if (strlen($url) < $minLength || strlen($url) > $maxLength) { + $this->errors->add('url', "Must be between $minLength and $maxLength in characters in length"); + } + + if (!$this->errors->has('url')) { + $this->validated->url = $url; + } + } + + private function validateTitle(string $title, int $minLength, int $maxLength): void + { + $title = trim($title); + + if ($title === '') { + return; + } + + if (strlen($title) < $minLength || strlen($title) > $maxLength) { + $this->errors->add('title', "Must be between $minLength and $maxLength in characters in length"); + } + + if (!$this->errors->has('tite')) { + $this->validated->title = $title; + } + } + + private function validateTag(string $tag, int $minLength, int $maxLength): void + { + $tag = trim($tag); + + if ($tag === '') { + return; + } + + if (strlen($tag) < $minLength || strlen($tag) > $maxLength) { + $this->errors->add('tag', "Must be between $minLength and $maxLength in characters in length"); + } + if (preg_match('/\W/', $tag) === 1) { + $this->errors->add('tag', 'May only contain word characters'); + } + + if (!$this->errors->has('tag')) { + $this->validated->tag = strtolower($tag); + } + } +} diff --git a/src/templates/create.php b/src/templates/create.php index 483e49e..2769290 100644 --- a/src/templates/create.php +++ b/src/templates/create.php @@ -9,8 +9,17 @@ <a href="/">Back</a> <form action="/store" method="POST"> <input type="text" name="url" maxlength="512" autofocus><br> + <?php if ($errors->has('url')) { ?> + <p><?php echo implode(', ', $errors->get('url')); ?></p> + <?php } ?> <input type="text" name="title" maxlength="256" ><br> + <?php if ($errors->has('title')) { ?> + <p><?php echo implode(', ', $errors->get('title')); ?></p> + <?php } ?> <input type="text" name="tag" maxlength="8" ><br> + <?php if ($errors->has('tag')) { ?> + <p><?php echo implode(', ', $errors->get('tag')); ?></p> + <?php } ?> <button type="submit">Add</button> </form> </body> diff --git a/src/templates/edit.php b/src/templates/edit.php index d5f5a08..c1b7bda 100644 --- a/src/templates/edit.php +++ b/src/templates/edit.php @@ -10,8 +10,17 @@ <form action="/update" method="POST"> <input type="hidden" name="id" value="<?php echo $bookmark->id; ?>"/> <input type="text" name="url" maxlength="512" autofocus value="<?php echo $bookmark->url; ?>"><br> + <?php if ($errors->has('url')) { ?> + <p><?php echo implode(', ', $errors->get('url')); ?></p> + <?php } ?> <input type="text" name="title" maxlength="256" value="<?php echo $bookmark->title; ?>"><br> + <?php if ($errors->has('title')) { ?> + <p><?php echo implode(', ', $errors->get('title')); ?></p> + <?php } ?> <input type="text" name="tag" maxlength="8" value="<?php echo $bookmark->tag; ?>"><br> + <?php if ($errors->has('tag')) { ?> + <p><?php echo implode(', ', $errors->get('tag')); ?></p> + <?php } ?> <button type="submit">Update</button> </form> </body> |
