/**
  * Models constructor.
  *
  * @param AbstractService $service
  * @param string $method
  */
 public function __construct(AbstractService $service, string $method)
 {
     $reflection = $service->getReflectionMethod($method);
     if ($reflection->getDefinition(Definition::RESPONSE)) {
         /* @var $response Response */
         foreach ($reflection->getDefinition(Definition::RESPONSE) as $response) {
             if (!$response->getType()) {
                 continue;
             }
             if (!$this->isPrimitive($response->getType())) {
                 foreach ($response->getType() as $type) {
                     $this->fetchModel($type);
                 }
             }
         }
     }
     foreach ($this->models as $name => $model) {
         $modelData = ['properties' => []];
         foreach ($model->getDefinitions() as $property => $definition) {
             $propertyData = ['subtype' => $definition->getSubType(), 'nullable' => $definition->isNullable(), 'comment' => $definition->getComment()];
             foreach ($definition->getType() as $type) {
                 if (!$this->isPrimitive($type)) {
                     $type = $this->normalizeType($type);
                 }
                 $propertyData['types'][] = $type;
             }
             $modelData['properties'][$property] = $propertyData;
         }
         $this->data['models'][$this->normalizeType($name)] = $modelData;
     }
 }
 public function __construct(AbstractService $service, string $method)
 {
     $reflection = $service->getReflectionMethod($method);
     if ($reflection->getDefinition(Definition::RESPONSE)) {
         /* @var $response Response */
         foreach ($reflection->getDefinition(Definition::RESPONSE) as $response) {
             $types = $response->getType();
             if ($types) {
                 foreach ($types as $i => $type) {
                     if (!$this->isPrimitive($type)) {
                         $type = $this->normalizeType($type);
                     }
                     $types[$i] = $type;
                 }
             }
             $this->data['responses'][$response->getStatusCode()] = ['type' => $types, 'comment' => $response->getComment()];
         }
     }
     if ($reflection->getDefinition(Definition::THROWS)) {
         /* @var $throw Throws */
         foreach ($reflection->getDefinition(Definition::THROWS) as $throw) {
             $this->data['responses'][$throw->getStatusCode()] = ['type' => [$throw->getType()], 'comment' => $throw->getComment()];
         }
     }
     if ($reflection->getDefinition(Definition::HEADER)) {
         /* @var $header Header */
         foreach ($reflection->getDefinition(Definition::HEADER) as $header) {
             $this->data['responses'][$header->getStatusCode()]['headers'][] = ['name' => $header->getHeaderName(), 'type' => $header->getType(), 'comment' => $header->getComment()];
         }
     }
 }
 public function __construct(AbstractService $service, string $method)
 {
     $reflection = $service->getReflectionMethod($method);
     $this->data['uri'] = $service->getUri($method);
     $this->data['method'] = $reflection->getDefinition(Definition::HTTP_METHOD)->getHttpMethod();
     if ($reflection->getDefinition(Definition::PARAM)) {
         /* @var $parameter Param */
         foreach ($reflection->getDefinition(Definition::PARAM) as $i => $parameter) {
             /* @var $reflectionParameter \ReflectionParameter */
             $reflectionParameter = $reflection->getParameters()[$i];
             $type = $parameter->getType();
             switch ($parameter->getType()) {
                 case 'int':
                 case 'int32':
                 case 'integer':
                     $inputType = 'number';
                     break;
                 case 'float':
                 case 'double':
                     $inputType = 'number';
                     $type = 'float';
                     break;
                 case 'bool':
                 case 'boolean':
                     $inputType = 'checkbox';
                     break;
                 case '\\Cawa\\SwaggerServer\\DateTime':
                     // $inputType = "datetime-local";
                     $inputType = 'text';
                     break;
                 default:
                     $inputType = 'text';
             }
             $parameterRow = ['name' => $parameter->getVar(), 'comment' => $parameter->getComment(), 'type' => $type, 'inputType' => $inputType, 'subtype' => $parameter->getSubType(), 'validation' => $parameter->getValidation(), 'required' => !$reflectionParameter->isOptional()];
             if ($reflectionParameter->isOptional() && $reflectionParameter->getDefaultValue()) {
                 $parameterRow['default'] = $reflectionParameter->getDefaultValue();
             }
             $this->data['parameters'][] = $parameterRow;
         }
     }
 }
 /**
  * @param string $serviceName
  * @param AbstractService $service
  * @param string $method
  *
  * @throws \Exception
  *
  * @return array
  */
 private function generateSwaggerForService(string $serviceName, AbstractService $service, string $method = null) : array
 {
     $path = $definition = [];
     foreach ($service->getMethods() as $currentMethod) {
         if (!is_null($method) && $currentMethod != $method) {
             continue;
         }
         $reflection = $service->getReflectionMethod($currentMethod);
         $currentPath = ['operationId' => $currentMethod, 'tags' => [str_replace('\\', ' ', $serviceName)], 'parameters' => [], 'responses' => []];
         $plainTextResponse = true;
         $comment = $reflection->getDefinition(Definition::COMMENT) ? $reflection->getDefinition(Definition::COMMENT)->getComment() : null;
         $comment .= $reflection->getDefinition(Definition::COMMENT_LONG) ? "\n\n" . $reflection->getDefinition(Definition::COMMENT_LONG)->getComment() : '';
         if ($comment) {
             $currentPath = ['description' => $comment] + $currentPath;
         }
         if ($reflection->getDefinition(Definition::AUTH)->getAuth() != 'None') {
             $currentPath['security'] = ['Auth' . $reflection->getDefinition(Definition::AUTH)->getAuth() => []];
         }
         $httpMethod = $reflection->getDefinition(Definition::HTTP_METHOD)->getHttpMethod();
         if ($httpMethod == 'POST') {
             $currentPath['consumes'] = ['application/x-www-form-urlencoded'];
         }
         // parameters
         if ($reflection->getDefinition(Definition::PARAM)) {
             /* @var $parameter Param */
             foreach ($reflection->getDefinition(Definition::PARAM) as $i => $parameter) {
                 /* @var $reflectionParameter \ReflectionParameter */
                 $reflectionParameter = $reflection->getParameters()[$i];
                 $parameterRow = ['name' => $parameter->getVar(), 'in' => $httpMethod == 'POST' ? 'formData' : 'query', 'required' => !$reflectionParameter->isOptional()];
                 if ($reflectionParameter->isOptional() && $reflectionParameter->getDefaultValue()) {
                     $parameterRow['default'] = $reflectionParameter->getDefaultValue();
                 }
                 if ($parameter->getComment()) {
                     $parameterRow['description'] = $parameter->getComment();
                 }
                 $parameterRow = array_merge($parameterRow, $this->getSwaggertype($parameter->getType(), $parameter->getSubType()));
                 if ($parameterRow['type'] == 'array') {
                     $parameterRow['collectionFormat'] = 'multi';
                 }
                 $currentPath['parameters'][] = $parameterRow;
             }
         } else {
             unset($currentPath['parameters']);
         }
         // response
         if ($reflection->getDefinition(Definition::RESPONSE)) {
             /* @var $response Response */
             foreach ($reflection->getDefinition(Definition::RESPONSE) as $i => $response) {
                 $swaggerResponse = ['headers' => ['X-Duration' => ['description' => 'Api Server ResponseTime', 'type' => 'number']]];
                 if ($response->getComment()) {
                     $swaggerResponse['description'] = $response->getComment();
                 }
                 if (sizeof($response->getType()) > 1) {
                     throw new \LogicException('Polymorphism is not yet supported');
                 }
                 if ($response->getType()[0] !== null) {
                     $return = $this->getSwaggertype($response->getType()[0]);
                     $swaggerResponse['schema'] = $return;
                 }
                 if (!$this->isPrimitive($response->getType())) {
                     $plainTextResponse = false;
                 }
                 $currentPath['responses'][$response->getStatusCode()] = $swaggerResponse;
             }
         }
         // headers
         if ($reflection->getDefinition(Definition::HEADER)) {
             /* @var $header Header */
             foreach ($reflection->getDefinition(Definition::HEADER) as $i => $header) {
                 $name = 'X-' . ucfirst($header->getHeaderName());
                 $value = $this->getSwaggertype($header->getType());
                 if ($header->getComment()) {
                     $value['description'] = $header->getComment();
                 }
                 $currentPath['responses'][$header->getStatusCode()]['headers'][$name] = $value;
             }
         }
         // exceptions
         if ($reflection->getDefinition(Definition::THROWS)) {
             /* @var $throw Throws */
             foreach ($reflection->getDefinition(Definition::THROWS) as $i => $throw) {
                 //@TODO: handle > 600 statusCode
             }
         }
         if ($plainTextResponse) {
             $currentPath['produces'] = ['application/json', 'application/problem+json', 'text/plain'];
         }
         $path['/' . str_replace('\\', '/', $serviceName) . '/' . $currentMethod][strtolower($httpMethod)] = $currentPath;
     }
     foreach ($this->models as $name => $model) {
         $swaggerDefinition = ['required' => [], 'properties' => []];
         foreach ($model->getDefinitions() as $property => $currentDefinition) {
             if (!$currentDefinition->isNullable()) {
                 $swaggerDefinition['required'][] = $property;
             }
             if (sizeof($currentDefinition->getType()) > 1) {
                 throw new \LogicException('Polymorphism is not yet supported');
             }
             $swaggerProperty = $this->getSwaggertype($currentDefinition->getType()[0], $currentDefinition->getSubType());
             if ($currentDefinition->getComment()) {
                 $swaggerProperty = ['description' => $currentDefinition->getComment()] + $swaggerProperty;
             }
             $swaggerDefinition['properties'][$property] = $swaggerProperty;
         }
         $definition[$this->normalizeType($name)] = $swaggerDefinition;
     }
     return [$path, $definition];
 }