Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp WriteValidatorBase #49

Open
RyanNerd opened this issue Jun 17, 2021 · 0 comments
Open

Revamp WriteValidatorBase #49

RyanNerd opened this issue Jun 17, 2021 · 0 comments

Comments

@RyanNerd
Copy link
Owner

RyanNerd commented Jun 17, 2021

<?php
declare(strict_types=1);

namespace Willow\Controllers;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Respect\Validation\Validator as V;
use Willow\Middleware\ResponseBody;

abstract class WriteValidatorBase
{
    public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
    {
        $responseBody = $this->processValidation($request->getAttribute('response_body'));

        // If there are any missing or required data points then we short circuit and return invalid request.
        if ($responseBody->hasMissingRequiredOrInvalid()) {
            $responseBody = $responseBody
                ->setStatus(ResponseBody::HTTP_BAD_REQUEST)
                ->setMessage('Missing or invalid request');
            return $responseBody();
        }

            return $handler->handle($request);
    }

    /**
     * You should override this function to perform the validations
     * @param ResponseBody $responseBody
     * @return ResponseBody
     */
    protected function processValidation(ResponseBody $responseBody): ResponseBody {
        return $responseBody;
    }

    /**
     * Default processValidation() for generic validations
     * @param ResponseBody $responseBody
     * @param array $fields
     * @return ResponseBody
     */
    protected function defaultValidation(ResponseBody $responseBody, array $fields): ResponseBody {
        $parsedRequest = $responseBody->getParsedRequest();
        // Iterate all the model fields
        foreach($fields as $field => $dataType) {
            $protectedField = $dataType[0] === '*';
            // Is the model field NOT in the request?
            if (!V::key($field)->validate($parsedRequest)) {
                // Any dataType proceeded with an * are protected fields and can not be changed (e.g. password_hash)
                if ($protectedField) {
                    continue;
                }
                // If the request is missing this field so register it as optional
                $responseBody->registerParam('optional', $field, $dataType);
            } else {
                // If Datatype is proceeded with an * it means the field is protected and can not be changed (e.g. password_hash)
                if ($protectedField) {
                    $responseBody->registerParam('invalid', $field, null);
                }
                // Don't allow emoji characters -- this prevents SQL Errors
                if ($dataType === 'string') {
                    $fieldValue = $parsedRequest[$field];
                    if (V::notEmpty()->validate($fieldValue) && !V::notEmoji()->validate($fieldValue)) {
                        $responseBody->registerParam('invalid', $field, 'alpha-numeric. Value given: ' . $fieldValue);
                    }
                }
            }
        }
        return $responseBody;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant