Created
July 23, 2020 18:17
-
-
Save waqashassan98/0b6bf4ad00d7ec4c5929bd638ec13766 to your computer and use it in GitHub Desktop.
Custom Wordpress Rest API Schema Validator - Limited Cases
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class SchemaValidator{ | |
public function validate_structure($params, $schema){ | |
$errors = array(); | |
foreach($schema as $key => $object){ | |
//check if present if required | |
if(isset($object["required"]) && true == $object["required"]){ | |
if( !isset($params[$key]) || empty($params[$key])){ | |
//error and return | |
$errors[$key] = "Parameter not found"; | |
return $errors; | |
} | |
} | |
//If parameter is not set, then return, as it was not required Don't return in case of object | |
if( ("object" != $object["type"]) &&( !isset($params[$key]) || empty($params[$key]))){ | |
continue; | |
} | |
//Now that the value is set, we need to validate it | |
switch ($object["type"]) { | |
case 'string': | |
if(is_string($params[$key])){ | |
if( !isset($object['validate_callback']) || ( isset($object['validate_callback']) && call_user_func($object['validate_callback'], $params[$key], $key,""))){ | |
continue; | |
} | |
else{ | |
$errors[$key] = "Validation failed"; | |
} | |
} | |
else{ | |
$errors[$key] = "Parameter not string"; | |
} | |
return $errors; | |
break; | |
case 'integer': | |
if(is_int($params[$key])){ | |
if( !isset($object['validate_callback']) || ( isset($object['validate_callback']) && call_user_func($object['validate_callback'], $params[$key], $key,""))){ | |
continue; | |
} | |
else{ | |
$errors[$key] = "Validation failed"; | |
} | |
} | |
else{ | |
$errors[$key] = "Parameter not integer"; | |
} | |
return $errors; | |
break; | |
case 'enum': | |
if( isset($params[$key]) ){ | |
if((is_string($params[$key]) || is_int($params[$key])) && in_array($params[$key], $object["enum"])){ | |
continue; | |
} | |
else{ | |
$errors[$key] = "Parameter not one of: ".implode(", ",$object["enum"]); | |
return $errors; | |
} | |
} | |
break; | |
case 'array': | |
if(is_array($params[$key]) && count($params[$key])>0){ | |
$index = 0; | |
foreach($params[$key] as $arr_val){ | |
$result = $this->validate_structure( $arr_val, array("items" => $object["items"])); | |
if(count($result)>0){ | |
foreach($result as $k => $val){ | |
$result[$k] = $key."[".$index."][".$k."] ".lcfirst($result[$k]); | |
} | |
$errors = array_merge($errors,$result); | |
return $errors; | |
} | |
$index++; | |
continue; | |
} | |
} | |
else if(is_array($params[$key])){ | |
$errors[$key] = "Array is empty"; | |
} | |
else{ | |
$errors[$key] = "Parameter not of type array"; | |
} | |
return $errors; | |
break; | |
case 'object': | |
if(is_array($params)){ | |
foreach($object["properties"] as $property => $obj){ | |
$result = $this->validate_structure( | |
array($property => $params[$property]), | |
array($property => $obj) | |
); | |
if(is_array($result) && count($result)>0){ | |
$errors = array_merge($errors, $result); | |
return $errors; | |
} | |
} | |
} | |
else{ | |
$errors[$key] = "Parameter not of type object"; | |
} | |
return $errors; | |
break; | |
default: | |
break; | |
} | |
} | |
return $errors; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once( get_template_directory() ."/inc/api/SchemaValidator.php"); | |
$schema = array( | |
'request_id' => array( | |
'validate_callback' => function($param, $request, $key) { | |
return is_numeric( $param ); | |
}, | |
'required' => true, | |
'type' => 'integer', | |
'description' => 'Your internal request id', | |
), | |
'object' => array( | |
'required' => true, | |
'type' => 'enum', | |
"enum" => array( | |
"products" | |
), | |
'description' => 'The object type to run the call against.', | |
), | |
'total_count' => array( | |
'validate_callback' => function($param, $request, $key) { | |
return is_numeric( $param ); | |
}, | |
'required' => false, | |
'type' => 'integer', | |
'description' => 'Total count of the products', | |
), | |
'data' => array( | |
'type' => 'array', | |
'required' => true, | |
"items" => array( | |
"type" => "object", | |
"properties" => array( | |
'action' => array( | |
'required' => true, | |
"type" => "enum", | |
"enum" => array( | |
"add", "update", "delete" | |
) | |
), | |
'manufactured' => array( | |
'required' => false, | |
"type" => "enum", | |
"enum" => array( | |
"Manufactured", "Purchased", "" | |
) | |
), | |
), | |
) | |
) | |
); | |
$params = $request->get_json_params(); | |
$validator = new SchemaValidator(); | |
$errors = $validator->validate_structure($params, $this->schema); | |
if(is_array($errors) && count($errors)>0){ | |
foreach($errors as $key =>$value){ | |
$response = array( | |
"code" => "schema_validation_failed", | |
"message" => "Unable to process request because data did not pass validation tests.", | |
"data" => array( | |
"field" => $key, | |
"message" => $value | |
) | |
); | |
} | |
//retun response | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment