Skip to content

Instantly share code, notes, and snippets.

@waqashassan98
Created July 23, 2020 18:17
Show Gist options
  • Save waqashassan98/0b6bf4ad00d7ec4c5929bd638ec13766 to your computer and use it in GitHub Desktop.
Save waqashassan98/0b6bf4ad00d7ec4c5929bd638ec13766 to your computer and use it in GitHub Desktop.
Custom Wordpress Rest API Schema Validator - Limited Cases
<?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;
}
}
<?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