/**
  * @param AvroSchema $schema The rules to conform to.
  * @param mixed $datum The value to validate against $schema.
  * @return string|string[] An error or list of errors in the
  *  provided $datum. When no errors exist the empty array is
  *  returned.
  */
 public static function getErrors(AvroSchema $schema, $datum)
 {
     switch ($schema->type) {
         case AvroSchema::NULL_TYPE:
             if (!is_null($datum)) {
                 return self::wrongType('null', $datum);
             }
             return array();
         case AvroSchema::BOOLEAN_TYPE:
             if (!is_bool($datum)) {
                 return self::wrongType('boolean', $datum);
             }
             return array();
         case AvroSchema::STRING_TYPE:
         case AvroSchema::BYTES_TYPE:
             if (!is_string($datum)) {
                 return self::wrongType('string', $datum);
             }
             return array();
         case AvroSchema::INT_TYPE:
             if (!is_int($datum)) {
                 return self::wrongType('integer', $datum);
             }
             if (AvroSchema::INT_MIN_VALUE > $datum || $datum > AvroSchema::INT_MAX_VALUE) {
                 return self::outOfRange(AvroSchema::INT_MIN_VALUE, AvroSchema::INT_MAX_VALUE, $datum);
             }
             return array();
         case AvroSchema::LONG_TYPE:
             if (!is_int($datum)) {
                 return self::wrongType('integer', $datum);
             }
             if (AvroSchema::LONG_MIN_VALUE > $datum || $datum > AvroSchema::LONG_MAX_VALUE) {
                 return self::outOfRange(AvroSchema::LONG_MIN_VALUE, AvroSchema::LONG_MAX_VALUE, $datum);
             }
             return array();
         case AvroSchema::FLOAT_TYPE:
         case AvroSchema::DOUBLE_TYPE:
             if (!is_float($datum) && !is_int($datum)) {
                 return self::wrongType('float or integer', $datum);
             }
             return array();
         case AvroSchema::ARRAY_SCHEMA:
             if (!is_array($datum)) {
                 return self::wrongType('array', $datum);
             }
             $errors = array();
             foreach ($datum as $d) {
                 $result = $this->validate($schema->items(), $d);
                 if ($result) {
                     $errors[] = $result;
                 }
             }
             if ($errors) {
                 return $errors;
             }
             return array();
         case AvroSchema::MAP_SCHEMA:
             if (!is_array($datum)) {
                 return self::wrongType('array', $datum);
             }
             $errors = array();
             foreach ($datum as $k => $v) {
                 if (!is_string($k)) {
                     $errors[] = self::wrongType('string key', $k);
                 }
                 $result = self::getErrors($schema->values(), $v);
                 if ($result) {
                     $errors[$k] = $result;
                 }
             }
             return $errors;
         case AvroSchema::UNION_SCHEMA:
             $errors = array();
             foreach ($schema->schemas() as $schema) {
                 $result = self::getErrors($schema, $datum);
                 if (!$result) {
                     return array();
                 }
                 $errors[] = $result;
             }
             if ($errors) {
                 return array("Expected any one of these to be true", $errors);
             }
             return "No schemas provided to union";
         case AvroSchema::ENUM_SCHEMA:
             if (!in_array($datum, $schema->symbols())) {
                 $symbols = implode(', ', $schema->symbols);
                 return "Expected one of {$symbols} but recieved {$datum}";
             }
             return array();
         case AvroSchema::FIXED_SCHEMA:
             if (!is_string($datum)) {
                 return self::wrongType('string', $datum);
             }
             $len = strlen($datum);
             if ($len !== $schema->size()) {
                 return "Expected string of length {$schema->size()}, " . "but recieved one of length {$len}";
             }
             return array();
         case AvroSchema::RECORD_SCHEMA:
         case AvroSchema::ERROR_SCHEMA:
         case AvroSchema::REQUEST_SCHEMA:
             if (!is_array($datum)) {
                 return self::wrongType('array', $datum);
             }
             $errors = array();
             foreach ($schema->fields() as $field) {
                 $name = $field->name();
                 if (!array_key_exists($name, $datum)) {
                     $errors[$name] = 'Missing expected field';
                     continue;
                 }
                 $result = self::getErrors($field->type(), $datum[$name]);
                 if ($result) {
                     $errors[$name] = $result;
                 }
             }
             return $errors;
         default:
             return "Unknown avro schema type: {$schema->type}";
     }
 }
Example #2
0
 /**
  * @param AvroSchema $field_schema
  * @param null|boolean|int|float|string|array $default_value
  * @return null|boolean|int|float|string|array
  *
  * @throws AvroException if $field_schema type is unknown.
  */
 public function read_default_value($field_schema, $default_value)
 {
     switch ($field_schema->type()) {
         case AvroSchema::NULL_TYPE:
             return null;
         case AvroSchema::BOOLEAN_TYPE:
             return $default_value;
         case AvroSchema::INT_TYPE:
         case AvroSchema::LONG_TYPE:
             return (int) $default_value;
         case AvroSchema::FLOAT_TYPE:
         case AvroSchema::DOUBLE_TYPE:
             return (double) $default_value;
         case AvroSchema::STRING_TYPE:
         case AvroSchema::BYTES_TYPE:
             return $default_value;
         case AvroSchema::ARRAY_SCHEMA:
             $array = array();
             foreach ($default_value as $json_val) {
                 $val = $this->read_default_value($field_schema->items(), $json_val);
                 $array[] = $val;
             }
             return $array;
         case AvroSchema::MAP_SCHEMA:
             $map = array();
             foreach ($default_value as $key => $json_val) {
                 $map[$key] = $this->read_default_value($field_schema->values(), $json_val);
             }
             return $map;
         case AvroSchema::UNION_SCHEMA:
             return $this->read_default_value($field_schema->schema_by_index(0), $default_value);
         case AvroSchema::ENUM_SCHEMA:
         case AvroSchema::FIXED_SCHEMA:
             return $default_value;
         case AvroSchema::RECORD_SCHEMA:
             $record = array();
             foreach ($field_schema->fields() as $field) {
                 $field_name = $field->name();
                 if (!($json_val = $default_value[$field_name])) {
                     $json_val = $field->default_value();
                 }
                 $record[$field_name] = $this->read_default_value($field->type(), $json_val);
             }
             return $record;
         default:
             throw new AvroException(sprintf('Unknown type: %s', $field_schema->type()));
     }
 }