diff --git a/Classes/Domain/Model/ApiResource.php b/Classes/Domain/Model/ApiResource.php index 0941591..1c76e40 100644 --- a/Classes/Domain/Model/ApiResource.php +++ b/Classes/Domain/Model/ApiResource.php @@ -34,15 +34,20 @@ class ApiResource protected UploadSettings $uploadSettings; - public function __construct(string $entity, ApiResourceAnnotation $apiResourceAnnotation) + protected OpenApiSettings $openApiSettings; + + public function __construct(string $entity, ?ApiResourceAnnotation $apiResourceAnnotation = null) { $this->entity = $entity; $this->routes = new RouteCollection(); + $apiResourceAnnotation = $apiResourceAnnotation ?? new ApiResourceAnnotation([]); + $attributes = $apiResourceAnnotation->getAttributes(); $this->pagination = Pagination::create($attributes); $this->persistenceSettings = PersistenceSettings::create($attributes['persistence'] ?? []); $this->uploadSettings = UploadSettings::create($attributes['upload'] ?? []); + $this->openApiSettings = OpenApiSettings::create($attributes['openApi'] ?? [], null, $entity); foreach ($apiResourceAnnotation->getItemOperations() as $operationKey => $operationData) { $this->itemOperations[] = new ItemOperation($operationKey, $this, $operationData); @@ -151,4 +156,9 @@ public function getUploadSettings(): UploadSettings { return $this->uploadSettings; } + + public function getOpenApiSettings(): OpenApiSettings + { + return $this->openApiSettings; + } } diff --git a/Classes/Domain/Model/OpenApiSettings.php b/Classes/Domain/Model/OpenApiSettings.php new file mode 100644 index 0000000..c9c3019 --- /dev/null +++ b/Classes/Domain/Model/OpenApiSettings.php @@ -0,0 +1,58 @@ +entityName = $entityName; + $settings->tagName = $attributes['tagName'] ?? $settings->tagName; + $settings->tagDescription = $attributes['tagDescription'] ?? $settings->tagDescription; + $settings->schemaIdentifier = $attributes['schemaIdentifier'] ?? $settings->schemaIdentifier; + + return $settings; + } + + public function getTagName(): string + { + if ($this->tagName !== '') { + return $this->tagName; + } + return $this->entityName; + } + + public function getTagDescription(): string + { + if ($this->tagDescription !== '') { + return $this->tagDescription; + } + return sprintf('Operations about %s', $this->entityName); + } + + public function getSchemaIdentifierForMode(string $mode): string + { + if ($this->schemaIdentifier !== '') { + return $this->schemaIdentifier . '__' . $mode; + } + return str_replace('\\', '.', $this->entityName) . '__' . $mode; + } +} diff --git a/Classes/Service/OpenApiBuilder.php b/Classes/Service/OpenApiBuilder.php index f13b005..c5c1511 100644 --- a/Classes/Service/OpenApiBuilder.php +++ b/Classes/Service/OpenApiBuilder.php @@ -94,8 +94,8 @@ protected static function getTag(ApiResource $apiResource): Tag { // @todo caching because it is used in few places return Tag::create() - ->name($apiResource->getEntity()) - ->description(sprintf('Operations about %s', $apiResource->getEntity())); + ->name($apiResource->getOpenApiSettings()->getTagName()) + ->description($apiResource->getOpenApiSettings()->getTagDescription()); } /** @@ -311,16 +311,16 @@ protected static function getOperationSchema(OperationInterface $operation): Sch $collectionResponseClass = Configuration::getCollectionResponseClass(); return $collectionResponseClass::getOpenApiSchema( - self::getComponentsSchemaReference($operation->getApiResource()->getEntity()) + self::getComponentsSchemaReference($operation->getApiResource()) ); } - return Schema::ref(self::getComponentsSchemaReference($operation->getApiResource()->getEntity())); + return Schema::ref(self::getComponentsSchemaReference($operation->getApiResource())); } - protected static function getComponentsSchemaReference(string $class, string $mode = 'READ'): string + protected static function getComponentsSchemaReference(ApiResource $apiResource, string $mode = 'READ'): string { - $schemaIdentifier = str_replace('\\', '.', $class) . '__' . $mode; + $schemaIdentifier = $apiResource->getOpenApiSettings()->getSchemaIdentifierForMode($mode); $referencePath = '#/components/schemas/' . $schemaIdentifier; $definedSchemas = array_map( @@ -331,7 +331,7 @@ static function (Schema $schema): ?string { ); if (!in_array($schemaIdentifier, $definedSchemas, true)) { - self::setComponentsSchema($schemaIdentifier, $class, $mode); + self::setComponentsSchema($schemaIdentifier, $apiResource->getEntity(), $mode); } return $referencePath; @@ -441,7 +441,8 @@ protected static function getPropertySchemaFromPropertyType(string $type, string } else { // NOTICE! because of a bug https://github.com/swagger-api/swagger-ui/issues/3325 reference to itself // will not be displayed correctly - $schema = Schema::ref(self::getComponentsSchemaReference($type, $mode)); + $apiResource = self::getApiResourceByClassName($type); + $schema = Schema::ref(self::getComponentsSchemaReference($apiResource, $mode)); } } elseif (in_array($type, ['int', 'integer'], true)) { $schema = Schema::integer(); @@ -477,9 +478,20 @@ protected static function getOperationRequestBody(OperationInterface $operation) ->content( MediaType::json()->schema( Schema::ref( - self::getComponentsSchemaReference($operation->getApiResource()->getEntity(), 'WRITE') + self::getComponentsSchemaReference($operation->getApiResource(), 'WRITE') ) ) ); } + + protected static function getApiResourceByClassName(string $entity): ApiResource + { + foreach (self::$apiResources as $apiResource) { + if ($apiResource->getEntity() === $entity) { + return $apiResource; + } + } + + return new ApiResource($entity); + } }