isValidAnnotationClass($className)) { throw new \Exception($className . ' is not defined in OpenApi PHP Annotations'); } return $this->doDeserialize(json_decode($jsonString), $className); } /** * Deserialize a file. * * @return OA\AbstractAnnotation */ public function deserializeFile(string $filename, string $className = OA\OpenApi::class) { if (!$this->isValidAnnotationClass($className)) { throw new \Exception($className . ' is not defined in OpenApi PHP Annotations'); } return $this->doDeserialize(json_decode(file_get_contents($filename)), $className); } /** * Do deserialization. * * @return OA\AbstractAnnotation */ protected function doDeserialize(\stdClass $c, string $class) { $annotation = new $class([]); foreach ((array) $c as $property => $value) { if ($property === '$ref') { $property = 'ref'; } if (substr($property, 0, 2) === 'x-') { if ($annotation->x === Generator::UNDEFINED) { $annotation->x = []; } $custom = substr($property, 2); $annotation->x[$custom] = $value; } else { $annotation->$property = $this->doDeserializeProperty($annotation, $property, $value); } } return $annotation; } /** * Deserialize the annotation's property. */ protected function doDeserializeProperty(OA\AbstractAnnotation $annotation, string $property, $value) { // property is primitive type if (array_key_exists($property, $annotation::$_types)) { return $this->doDeserializeBaseProperty($annotation::$_types[$property], $value); } // property is embedded annotation // note: this does not support custom nested annotation classes foreach ($annotation::$_nested as $nestedClass => $declaration) { // property is an annotation if (is_string($declaration) && $declaration === $property) { if (is_object($value)) { return $this->doDeserialize($value, $nestedClass); } else { return $value; } } // property is an annotation array if (is_array($declaration) && count($declaration) === 1 && $declaration[0] === $property) { $annotationArr = []; foreach ($value as $v) { $annotationArr[] = $this->doDeserialize($v, $nestedClass); } return $annotationArr; } // property is an annotation hash map if (is_array($declaration) && count($declaration) === 2 && $declaration[0] === $property) { $key = $declaration[1]; $annotationHash = []; foreach ($value as $k => $v) { $annotation = $this->doDeserialize($v, $nestedClass); $annotation->$key = $k; $annotationHash[$k] = $annotation; } return $annotationHash; } } return $value; } /** * Deserialize base annotation property. * * @param array|string $type The property type * @param mixed $value The value to deserialization * * @return array|OA\AbstractAnnotation */ protected function doDeserializeBaseProperty($type, $value) { $isAnnotationClass = is_string($type) && is_subclass_of(trim($type, '[]'), OA\AbstractAnnotation::class); if ($isAnnotationClass) { $isArray = strpos($type, '[') === 0 && substr($type, -1) === ']'; if ($isArray) { $annotationArr = []; $class = trim($type, '[]'); foreach ($value as $v) { $annotationArr[] = $this->doDeserialize($v, $class); } return $annotationArr; } return $this->doDeserialize($value, $type); } return $value; } }