From f853ffc07ca5af02621922e33f92cb983dab1108 Mon Sep 17 00:00:00 2001 From: logmanoriginal Date: Sat, 22 Sep 2018 16:42:04 +0200 Subject: [PATCH] [ParameterValidator] Refactor 'validation' into 'ParameterValidator' Adds a new class 'ParameterValidator' to replace the functions from 'validator.php', separating private functions from 'validateData' to class private functions in the process. Instead of echoing error messages, adds messages to a private variable, accessible via 'getInvalidParameters'. BridgeAbstract now adds invalid parameter names to the error message. --- lib/BridgeAbstract.php | 14 ++++- lib/ParameterValidator.php | 123 +++++++++++++++++++++++++++++++++++++ lib/RssBridge.php | 2 +- lib/validation.php | 95 ---------------------------- 4 files changed, 136 insertions(+), 98 deletions(-) create mode 100644 lib/ParameterValidator.php delete mode 100644 lib/validation.php diff --git a/lib/BridgeAbstract.php b/lib/BridgeAbstract.php index 95ef3572..dd6e3ec7 100644 --- a/lib/BridgeAbstract.php +++ b/lib/BridgeAbstract.php @@ -195,8 +195,18 @@ abstract class BridgeAbstract implements BridgeInterface { return; } - if(!validateData($inputs, static::PARAMETERS)) { - returnClientError('Invalid parameters value(s)'); + $validator = new ParameterValidator(); + + if(!$validator->validateData($inputs, static::PARAMETERS)) { + $parameters = array_map( + function($i){ return $i['name']; }, // Just display parameter names + $validator->getInvalidParameters() + ); + + returnClientError( + 'Invalid parameters value(s): ' + . implode(', ', $parameters) + ); } // Guess the paramter context from input data diff --git a/lib/ParameterValidator.php b/lib/ParameterValidator.php new file mode 100644 index 00000000..47f0c604 --- /dev/null +++ b/lib/ParameterValidator.php @@ -0,0 +1,123 @@ +invalid[] = array( + 'name' => $name, + 'reason' => $reason + ); + } + + /** + * Returns an array of invalid parameters, where each element is an + * array of 'name' and 'reason'. + */ + public function getInvalidParameters() { + return $this->invalid; + } + + private function validateTextValue($value, $pattern = null){ + if(!is_null($pattern)) { + $filteredValue = filter_var($value, + FILTER_VALIDATE_REGEXP, + array('options' => array( + 'regexp' => '/^' . $pattern . '$/' + ) + )); + } else { + $filteredValue = filter_var($value); + } + + if($filteredValue === false) + return null; + + return $filteredValue; + } + + private function validateNumberValue($value){ + $filteredValue = filter_var($value, FILTER_VALIDATE_INT); + + if($filteredValue === false) + return null; + + return $filteredValue; + } + + private function validateCheckboxValue($value){ + return filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + } + + private function validateListValue($value, $expectedValues){ + $filteredValue = filter_var($value); + + if($filteredValue === false) + return null; + + if(!in_array($filteredValue, $expectedValues)) { // Check sub-values? + foreach($expectedValues as $subName => $subValue) { + if(is_array($subValue) && in_array($filteredValue, $subValue)) + return $filteredValue; + } + return null; + } + + return $filteredValue; + } + + /** + * Checks if all required parameters are supplied by the user + * @param $data An array of parameters provided by the user + * @param $parameters An array of bridge parameters + */ + public function validateData(&$data, $parameters){ + + if(!is_array($data)) + return false; + + foreach($data as $name => $value) { + $registered = false; + foreach($parameters as $context => $set) { + if(array_key_exists($name, $set)) { + $registered = true; + if(!isset($set[$name]['type'])) { + $set[$name]['type'] = 'text'; + } + + switch($set[$name]['type']) { + case 'number': + $data[$name] = $this->validateNumberValue($value); + break; + case 'checkbox': + $data[$name] = $this->validateCheckboxValue($value); + break; + case 'list': + $data[$name] = $this->validateListValue($value, $set[$name]['values']); + break; + default: + case 'text': + if(isset($set[$name]['pattern'])) { + $data[$name] = $this->validateTextValue($value, $set[$name]['pattern']); + } else { + $data[$name] = $this->validateTextValue($value); + } + break; + } + + if(is_null($data[$name]) && isset($set[$name]['required']) && $set[$name]['required']) { + $this->addInvalidParameter($name, 'Parameter is invalid!'); + } + } + } + + if(!$registered) { + $this->addInvalidParameter($name, 'Parameter is not registered!'); + } + } + + return empty($this->invalid); + } +} diff --git a/lib/RssBridge.php b/lib/RssBridge.php index 281e201d..04e5fb31 100644 --- a/lib/RssBridge.php +++ b/lib/RssBridge.php @@ -18,8 +18,8 @@ require __DIR__ . '/Authentication.php'; require __DIR__ . '/Configuration.php'; require __DIR__ . '/BridgeCard.php'; require __DIR__ . '/BridgeList.php'; +require __DIR__ . '/ParameterValidator.php'; -require __DIR__ . '/validation.php'; require __DIR__ . '/html.php'; require __DIR__ . '/error.php'; require __DIR__ . '/contents.php'; diff --git a/lib/validation.php b/lib/validation.php deleted file mode 100644 index fdcb51c5..00000000 --- a/lib/validation.php +++ /dev/null @@ -1,95 +0,0 @@ - array( - 'regexp' => '/^' . $pattern . '$/' - ) - )); - } else { - $filteredValue = filter_var($value); - } - - if($filteredValue === false) - return null; - - return $filteredValue; - }; - - $validateNumberValue = function($value){ - $filteredValue = filter_var($value, FILTER_VALIDATE_INT); - - if($filteredValue === false) - return null; - - return $filteredValue; - }; - - $validateCheckboxValue = function($value){ - return filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); - }; - - $validateListValue = function($value, $expectedValues){ - $filteredValue = filter_var($value); - - if($filteredValue === false) - return null; - - if(!in_array($filteredValue, $expectedValues)) { // Check sub-values? - foreach($expectedValues as $subName => $subValue) { - if(is_array($subValue) && in_array($filteredValue, $subValue)) - return $filteredValue; - } - return null; - } - - return $filteredValue; - }; - - if(!is_array($data)) - return false; - - foreach($data as $name => $value) { - $registered = false; - foreach($parameters as $context => $set) { - if(array_key_exists($name, $set)) { - $registered = true; - if(!isset($set[$name]['type'])) { - $set[$name]['type'] = 'text'; - } - - switch($set[$name]['type']) { - case 'number': - $data[$name] = $validateNumberValue($value); - break; - case 'checkbox': - $data[$name] = $validateCheckboxValue($value); - break; - case 'list': - $data[$name] = $validateListValue($value, $set[$name]['values']); - break; - default: - case 'text': - if(isset($set[$name]['pattern'])) { - $data[$name] = $validateTextValue($value, $set[$name]['pattern']); - } else { - $data[$name] = $validateTextValue($value); - } - break; - } - - if(is_null($data[$name]) && isset($set[$name]['required']) && $set[$name]['required']) { - echo 'Parameter \'' . $name . '\' is invalid!' . PHP_EOL; - return false; - } - } - } - - if(!$registered) - return false; - } - - return true; -}