From 2d58942cb103b8d989377b65b41e5cc4f0862e33 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Thu, 14 Mar 2024 17:16:26 +0100 Subject: [PATCH 1/2] refactor: Stop using array_merge to create associative arrays Signed-off-by: provokateurin --- generate-spec | 142 +++++++++++++++++++++++++------------------- src/Helpers.php | 11 ++-- src/OpenApiType.php | 106 +++++++++++++++++++++++---------- 3 files changed, 160 insertions(+), 99 deletions(-) diff --git a/generate-spec b/generate-spec index 0fc08b4..d3e680d 100755 --- a/generate-spec +++ b/generate-spec @@ -617,17 +617,17 @@ foreach ($routes as $scope => $scopeRoutes) { $schema["default"] = $route->defaults[$urlParameter]; } - $pathParameters[] = array_merge( - [ - "name" => $urlParameter, - "in" => "path", - ], - $description != null ? ["description" => $description] : [], - [ - "required" => true, - "schema" => $schema, - ], - ); + $parameter = [ + "name" => $urlParameter, + "in" => "path", + ]; + if ($description !== null) { + $parameter["description"] = $description; + } + $parameter["required"] = true; + $parameter["schema"] = $schema; + + $pathParameters[] = $parameter; } $queryParameters = []; @@ -688,25 +688,24 @@ foreach ($routes as $scope => $scopeRoutes) { } } - $mergedResponses[$statusCode] = array_merge( - [ - "description" => array_key_exists($statusCode, $route->controllerMethod->responseDescription) ? $route->controllerMethod->responseDescription[$statusCode] : "", - ], - count($headers) > 0 ? [ - "headers" => array_combine( - array_keys($headers), - array_map( - fn (OpenApiType $type) => [ - "schema" => $type->toArray($openapiVersion), - ], - array_values($headers), - ), + $response = [ + "description" => array_key_exists($statusCode, $route->controllerMethod->responseDescription) ? $route->controllerMethod->responseDescription[$statusCode] : "", + ]; + if (count($headers) > 0) { + $response["headers"] = array_combine( + array_keys($headers), + array_map( + fn (OpenApiType $type) => [ + "schema" => $type->toArray($openapiVersion), + ], + array_values($headers), ), - ] : [], - count($mergedContentTypeResponses) > 0 ? [ - "content" => $mergedContentTypeResponses, - ] : [], - ); + ); + } + if (count($mergedContentTypeResponses) > 0) { + $response["content"] = $mergedContentTypeResponses; + } + $mergedResponses[$statusCode] = $response; } $operationId = [...$route->tags, ...Helpers::splitOnUppercaseFollowedByNonUppercase($route->methodName)]; @@ -728,39 +727,58 @@ foreach ($routes as $scope => $scopeRoutes) { $security[] = ["basic_auth" => []]; } - $operation = array_merge( - ["operationId" => strtolower(implode("-", $operationId))], - $route->controllerMethod->summary != null ? ["summary" => $route->controllerMethod->summary] : [], - count($route->controllerMethod->description) > 0 ? ["description" => implode("\n", $route->controllerMethod->description)] : [], - $route->controllerMethod->isDeprecated ? ["deprecated" => true] : [], - $useTags ? ["tags" => $route->tags] : [], - count($security) > 0 ? ["security" => $security] : [], - count($queryParameters) > 0 || count($pathParameters) > 0 || $route->isOCS ? [ - "parameters" => array_merge( - array_map(fn (ControllerMethodParameter $parameter) => array_merge( - [ - "name" => $parameter->name . ($parameter->type->type == "array" ? "[]" : ""), - "in" => "query", - ], - $parameter->docType != null && $parameter->docType->description != "" ? ["description" => Helpers::cleanDocComment($parameter->docType->description)] : [], - !$parameter->type->nullable && !$parameter->type->hasDefaultValue ? ["required" => true] : [], - ["schema" => $parameter->type->toArray($openapiVersion, true),], - ), $queryParameters), - $pathParameters, - $route->isOCS ? [[ - "name" => "OCS-APIRequest", - "in" => "header", - "description" => "Required to be true for the API request to pass", - "required" => true, - "schema" => [ - "type" => "boolean", - "default" => true, - ], - ]] : [], - ), - ] : [], - ["responses" => $mergedResponses], - ); + $operation = [ + "operationId" => strtolower(implode("-", $operationId)), + ]; + if ($route->controllerMethod->summary !== null) { + $operation["summary"] = $route->controllerMethod->summary; + } + if (count($route->controllerMethod->description) > 0) { + $operation["description"] = implode("\n", $route->controllerMethod->description); + } + if ($route->controllerMethod->isDeprecated) { + $operation["deprecated"] = true; + } + if ($useTags) { + $operation["tags"] = $route->tags; + } + if (count($security) > 0) { + $operation["security"] = $security; + } + if (count($queryParameters) > 0 || count($pathParameters) > 0 || $route->isOCS) { + $parameters = [ + ...array_map(static function (ControllerMethodParameter $parameter) use ($openapiVersion) { + $out = [ + "name" => $parameter->name . ($parameter->type->type === "array" ? "[]" : ""), + "in" => "query", + ]; + if ($parameter->docType !== null && $parameter->docType->description !== "") { + $out["description"] = Helpers::cleanDocComment($parameter->docType->description); + } + if (!$parameter->type->nullable && !$parameter->type->hasDefaultValue) { + $out["required"] = true; + } + $out["schema"] = $parameter->type->toArray($openapiVersion, true); + + return $out; + }, $queryParameters), + ...$pathParameters, + ]; + if ($route->isOCS) { + $parameters[] = [ + "name" => "OCS-APIRequest", + "in" => "header", + "description" => "Required to be true for the API request to pass", + "required" => true, + "schema" => [ + "type" => "boolean", + "default" => true, + ], + ]; + } + $operation["parameters"] = $parameters; + } + $operation["responses"] = $mergedResponses; $scopePaths[$scope] ??= []; $scopePaths[$scope][$route->url] ??= []; diff --git a/src/Helpers.php b/src/Helpers.php index 2b81123..6f820e5 100644 --- a/src/Helpers.php +++ b/src/Helpers.php @@ -42,11 +42,14 @@ public static function license(string $openapiVersion, string $license): array { "agpl" => "AGPL-3.0-only", default => Logger::panic("license", "Unable to convert " . $license . " to SPDX identifier"), }; - return array_merge([ + + $out = [ "name" => "agpl", - ], - version_compare($openapiVersion, "3.1.0", ">=") ? ["identifier" => $identifier] : [], - ); + ]; + if (version_compare($openapiVersion, "3.1.0", ">=")) { + $out["identifier"] = $identifier; + } + return $out; } public static function jsonFlags(): int { diff --git a/src/OpenApiType.php b/src/OpenApiType.php index 67585e5..68849b9 100644 --- a/src/OpenApiType.php +++ b/src/OpenApiType.php @@ -58,15 +58,18 @@ public function toArray(string $openapiVersion, bool $isParameter = false): arra $this->anyOf !== null || $this->allOf !== null); if ($asContentString) { - return array_merge([ + $values = [ "type" => "string", - ], - $this->nullable ? ["nullable" => true] : [], - version_compare($openapiVersion, "3.1.0", ">=") ? [ - "contentMediaType" => "application/json", - "contentSchema" => $this->toArray($openapiVersion), - ] : [], - ); + ]; + if ($this->nullable) { + $values["nullable"] = true; + } + if (version_compare($openapiVersion, "3.1.0", ">=")) { + $values["contentMediaType"] = "application/json"; + $values["contentSchema"] = $this->toArray($openapiVersion); + } + + return $values; } $type = $this->type; @@ -80,31 +83,68 @@ public function toArray(string $openapiVersion, bool $isParameter = false): arra } } - $values = array_merge( - $this->ref != null ? ["\$ref" => $this->ref] : [], - $type != null ? ["type" => $type] : [], - $this->format != null ? ["format" => $this->format] : [], - $this->nullable ? ["nullable" => true] : [], - $this->hasDefaultValue && $defaultValue !== null ? ["default" => $defaultValue] : [], - $enum != null ? ["enum" => $enum] : [], - $this->description != null && $this->description != "" && !$isParameter ? ["description" => $this->description] : [], - $this->items != null ? ["items" => $this->items->toArray($openapiVersion)] : [], - $this->minLength !== null ? ["minLength" => $this->minLength] : [], - $this->maxLength !== null ? ["maxLength" => $this->maxLength] : [], - $this->minimum !== null ? ["minimum" => $this->minimum] : [], - $this->maximum !== null ? ["maximum" => $this->maximum] : [], - $this->required != null ? ["required" => $this->required] : [], - $this->properties != null ? ["properties" => - array_combine(array_keys($this->properties), - array_map(fn (OpenApiType $property) => $property->toArray($openapiVersion), array_values($this->properties)), - )] : [], - $this->additionalProperties != null ? [ - "additionalProperties" => $this->additionalProperties instanceof OpenApiType ? $this->additionalProperties->toArray($openapiVersion) : $this->additionalProperties, - ] : [], - $this->oneOf != null ? ["oneOf" => array_map(fn (OpenApiType $type) => $type->toArray($openapiVersion), $this->oneOf)] : [], - $this->anyOf != null ? ["anyOf" => array_map(fn (OpenApiType $type) => $type->toArray($openapiVersion), $this->anyOf)] : [], - $this->allOf != null ? ["allOf" => array_map(fn (OpenApiType $type) => $type->toArray($openapiVersion), $this->allOf)] : [], - ); + $values = []; + if ($this->ref !== null) { + $values["\$ref"] = $this->ref; + } + if ($type !== null) { + $values["type"] = $type; + } + if ($this->format !== null) { + $values["format"] = $this->format; + } + if ($this->nullable) { + $values["nullable"] = true; + } + if ($this->hasDefaultValue && $defaultValue !== null) { + $values["default"] = $defaultValue; + } + if ($enum !== null) { + $values["enum"] = $enum; + } + if ($this->description !== null && $this->description !== "" && !$isParameter) { + $values["description"] = $this->description; + } + if ($this->items !== null) { + $values["items"] = $this->items->toArray($openapiVersion); + } + if ($this->minLength !== null) { + $values["minLength"] = $this->minLength; + } + if ($this->maxLength !== null) { + $values["maxLength"] = $this->maxLength; + } + if ($this->minimum !== null) { + $values["minimum"] = $this->minimum; + } + if ($this->maximum !== null) { + $values["maximum"] = $this->maximum; + } + if ($this->required !== null) { + $values["required"] = $this->required; + } + if ($this->properties !== null && count($this->properties) > 0) { + $values["properties"] = array_combine(array_keys($this->properties), + array_map(static fn (OpenApiType $property) => $property->toArray($openapiVersion), array_values($this->properties)), + ); + } + if ($this->additionalProperties !== null) { + if ($this->additionalProperties instanceof OpenApiType) { + $values["additionalProperties"] = $this->additionalProperties->toArray($openapiVersion); + } else { + $values["additionalProperties"] = $this->additionalProperties; + } + } + if ($this->oneOf !== null) { + $values["oneOf"] = array_map(fn (OpenApiType $type) => $type->toArray($openapiVersion), $this->oneOf); + } + if ($this->anyOf !== null) { + $values["anyOf"] = array_map(fn (OpenApiType $type) => $type->toArray($openapiVersion), $this->anyOf); + } + if ($this->allOf !== null) { + $values["allOf"] = array_map(fn (OpenApiType $type) => $type->toArray($openapiVersion), $this->allOf); + } + return count($values) > 0 ? $values : new stdClass(); } From 6b0298915d6a5bdce6b11099a6080677123ea42d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Mar 2024 17:02:32 +0100 Subject: [PATCH 2/2] fix: Reduce complexity Signed-off-by: Joas Schilling --- generate-spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generate-spec b/generate-spec index d3e680d..abd1fdc 100755 --- a/generate-spec +++ b/generate-spec @@ -620,12 +620,12 @@ foreach ($routes as $scope => $scopeRoutes) { $parameter = [ "name" => $urlParameter, "in" => "path", + "required" => true, + "schema" => $schema, ]; if ($description !== null) { $parameter["description"] = $description; } - $parameter["required"] = true; - $parameter["schema"] = $schema; $pathParameters[] = $parameter; }