From 1ad37c4ca37610ba13048576d22c00ab91066228 Mon Sep 17 00:00:00 2001 From: dturopoli Date: Sun, 28 Apr 2024 12:01:44 +0200 Subject: [PATCH 1/3] complex array support --- .../Service/DocBlockParserInterface.php | 2 +- src/Model/Doc/Request/RequestDoc.php | 13 ++++++++----- src/Service/ControllerMethodParser.php | 11 +++++++++-- src/Service/DataTypeParser/ArrayParser.php | 6 ++++-- src/Service/DocBlockParser.php | 18 +++++++++++++----- src/Service/DocsGenerator.php | 5 +---- 6 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/Contract/Service/DocBlockParserInterface.php b/src/Contract/Service/DocBlockParserInterface.php index 0ab8ff6..2b4a879 100644 --- a/src/Contract/Service/DocBlockParserInterface.php +++ b/src/Contract/Service/DocBlockParserInterface.php @@ -11,7 +11,7 @@ interface DocBlockParserInterface /** * @return array */ - public function parseDocBlock(string $docBlock): array; + public function parseDocBlock(string $docBlock, ?string $parameterName = null): array; /** * @return string[] diff --git a/src/Model/Doc/Request/RequestDoc.php b/src/Model/Doc/Request/RequestDoc.php index ea64be5..68e5045 100644 --- a/src/Model/Doc/Request/RequestDoc.php +++ b/src/Model/Doc/Request/RequestDoc.php @@ -8,7 +8,8 @@ class RequestDoc { - private ?ComponentSchemaDoc $componentSchemaDoc = null; + /** @var ComponentSchemaDoc[] */ + private array $componentSchemaDocs = []; /** @var ParameterDoc[] */ private array $parameters = []; @@ -16,14 +17,16 @@ class RequestDoc /** @var mixed[] */ private array $requestBody = []; - public function getComponentSchemaDoc(): ?ComponentSchemaDoc + public function getComponentSchemaDocs(): array { - return $this->componentSchemaDoc; + return $this->componentSchemaDocs; } - public function setComponentSchemaDoc(?ComponentSchemaDoc $componentSchemaDoc): self + public function addComponentSchemaDoc(?ComponentSchemaDoc $componentSchemaDoc): self { - $this->componentSchemaDoc = $componentSchemaDoc; + if ($componentSchemaDoc !== null) { + $this->componentSchemaDocs[$componentSchemaDoc->getName()] = $componentSchemaDoc; + } return $this; } diff --git a/src/Service/ControllerMethodParser.php b/src/Service/ControllerMethodParser.php index 49a3380..368717e 100644 --- a/src/Service/ControllerMethodParser.php +++ b/src/Service/ControllerMethodParser.php @@ -10,6 +10,7 @@ use Symfony\Component\Routing\Annotation\Route as RouteAnnotation; use Symfony\Component\Routing\Attribute\Route as RouteAttribute; use Symfony\Component\Routing\RouterInterface; +use Valantic\PimcoreApiDocumentationBundle\Contract\Model\Component\Property\ComponentSchemaPropertyInterface; use Valantic\PimcoreApiDocumentationBundle\Contract\Service\ControllerMethodParserInterface; use Valantic\PimcoreApiDocumentationBundle\Contract\Service\DataTypeParserInterface; use Valantic\PimcoreApiDocumentationBundle\Contract\Service\SchemaGeneratorInterface; @@ -160,11 +161,11 @@ private function parseRequest(\ReflectionMethod $method): ?RequestDoc if (!is_subclass_of($requestClass, ApiRequestInterface::class)) { return null; } + $requestDoc = new RequestDoc(); foreach ($requestParameter->getAttributes() as $attribute) { if ($attribute->getName() === MapQueryString::class) { - // TODO: parse nested $requestReflection = new \ReflectionClass($requestClass); $requestProperties = $requestReflection->getProperties(\ReflectionProperty::IS_PUBLIC); @@ -174,6 +175,12 @@ private function parseRequest(\ReflectionMethod $method): ?RequestDoc $propertyDoc = $this->getDataTypeParser($property)->parse($property); + if ($propertyDoc instanceof ComponentSchemaPropertyInterface) { + foreach ($propertyDoc->getSchemas() as $schema) { + $requestDoc->addComponentSchemaDoc($schema); + } + } + $parameterDoc ->setName($property->getName()) ->setIn(ParameterDoc::IN_QUERY) @@ -187,7 +194,7 @@ private function parseRequest(\ReflectionMethod $method): ?RequestDoc } if (($attribute->getName() === MapRequestPayload::class) && is_subclass_of($requestClass, HasJsonPayload::class)) { - $requestDoc->setComponentSchemaDoc($this->schemaGenerator->generateForRequest($requestClass)); + $requestDoc->addComponentSchemaDoc($this->schemaGenerator->generateForRequest($requestClass)); $requestDoc->setRequestBody([ 'content' => [ 'application/json' => [ diff --git a/src/Service/DataTypeParser/ArrayParser.php b/src/Service/DataTypeParser/ArrayParser.php index e690c30..0812677 100644 --- a/src/Service/DataTypeParser/ArrayParser.php +++ b/src/Service/DataTypeParser/ArrayParser.php @@ -26,7 +26,6 @@ public function __construct( public function parse(\ReflectionProperty $reflectionProperty): AbstractPropertyDoc { $typeHints = $this->determineTypeHints($reflectionProperty); - $arrayItems = []; foreach ($typeHints as $typeHint) { @@ -45,6 +44,7 @@ public function parse(\ReflectionProperty $reflectionProperty): AbstractProperty } } + $propertyDoc = new ArrayPropertyDoc(); if (count($arrayItems) > 1) { @@ -79,9 +79,11 @@ private function determineTypeHints(\ReflectionProperty $reflectionProperty): ar $docBlocksTypeHints = []; $docBlock = null; + $parameterName = null; if ($reflectionProperty->getDocComment()) { $docBlock = $reflectionProperty->getDocComment(); + $parameterName = $propertyName; } elseif ( $declaringClassReflection->hasMethod('__construct') && $declaringClassReflection->getMethod('__construct')->getDocComment() !== false @@ -90,7 +92,7 @@ private function determineTypeHints(\ReflectionProperty $reflectionProperty): ar } if ($docBlock !== null) { - $docBlocksTypeHints = $this->docBlockParser->parseDocBlock($docBlock); + $docBlocksTypeHints = $this->docBlockParser->parseDocBlock($docBlock, $parameterName); } $typeHints = []; diff --git a/src/Service/DocBlockParser.php b/src/Service/DocBlockParser.php index a363695..ac40979 100644 --- a/src/Service/DocBlockParser.php +++ b/src/Service/DocBlockParser.php @@ -33,7 +33,7 @@ public function __construct() $this->phpDocParser = new PhpDocParser($typeParser, $constExprParser); } - public function parseDocBlock(string $docBlock): array + public function parseDocBlock(string $docBlock, ?string $parameterName = null): array { $docBlockData = []; $tokens = new TokenIterator($this->lexer->tokenize($docBlock)); @@ -41,16 +41,24 @@ public function parseDocBlock(string $docBlock): array foreach ($parsedDocBlock->children as $docBlockItem) { if ($docBlockItem->value instanceof ParamTagValueNode) { - $parameterName = ltrim($docBlockItem->value->parameterName, '$'); + $docBlockParamName = ltrim($docBlockItem->value->parameterName, '$'); } if ($docBlockItem->value instanceof VarTagValueNode) { - $parameterName = ltrim($docBlockItem->value->variableName, '$'); + $docBlockParamName = ltrim($docBlockItem->value->variableName, '$'); } - if (isset($parameterName)) { - $docBlockData[$parameterName] = $docBlockItem; + if ( + ( + !isset($docBlockParamName) || + $docBlockParamName === '' + ) && + $parameterName !== null + ) { + $docBlockParamName = $parameterName; } + + $docBlockData[$docBlockParamName] = $docBlockItem; } return $docBlockData; diff --git a/src/Service/DocsGenerator.php b/src/Service/DocsGenerator.php index 9f0bb64..63c2d02 100644 --- a/src/Service/DocsGenerator.php +++ b/src/Service/DocsGenerator.php @@ -44,10 +44,7 @@ public function generate(string $docsPath): void foreach ($controllerDoc->getMethodsDocs() as $methodDoc) { $paths[$methodDoc->getRouteDoc()->getPath()][$methodDoc->getRouteDoc()->getMethod()] = $methodDoc; - if ($methodDoc->getRequestDoc()?->getComponentSchemaDoc() !== null) { - $requestSchema = $methodDoc->getRequestDoc()->getComponentSchemaDoc(); - $schemas[$requestSchema->getName()] = $requestSchema; - } + $schemas = array_merge($schemas, $methodDoc->getRequestDoc()?->getComponentSchemaDocs() ?: []); foreach ($methodDoc->getResponsesDoc() as $responseDoc) { $schemas = array_merge($schemas, $responseDoc->getComponentSchemas()); From 3d927ae144c71e3d76d5d457ce56c10bc7fe5655 Mon Sep 17 00:00:00 2001 From: dturopoli Date: Sun, 28 Apr 2024 10:03:31 +0000 Subject: [PATCH 2/3] Fix styling --- src/Service/DataTypeParser/ArrayParser.php | 1 - src/Service/DocBlockParser.php | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Service/DataTypeParser/ArrayParser.php b/src/Service/DataTypeParser/ArrayParser.php index 0812677..5627593 100644 --- a/src/Service/DataTypeParser/ArrayParser.php +++ b/src/Service/DataTypeParser/ArrayParser.php @@ -44,7 +44,6 @@ public function parse(\ReflectionProperty $reflectionProperty): AbstractProperty } } - $propertyDoc = new ArrayPropertyDoc(); if (count($arrayItems) > 1) { diff --git a/src/Service/DocBlockParser.php b/src/Service/DocBlockParser.php index ac40979..4049d54 100644 --- a/src/Service/DocBlockParser.php +++ b/src/Service/DocBlockParser.php @@ -50,10 +50,10 @@ public function parseDocBlock(string $docBlock, ?string $parameterName = null): if ( ( - !isset($docBlockParamName) || - $docBlockParamName === '' - ) && - $parameterName !== null + !isset($docBlockParamName) + || $docBlockParamName === '' + ) + && $parameterName !== null ) { $docBlockParamName = $parameterName; } From a173d1d597c1917dc2d0506f25dbdb5423c9b17a Mon Sep 17 00:00:00 2001 From: dturopoli Date: Sun, 28 Apr 2024 12:09:46 +0200 Subject: [PATCH 3/3] array parser fix --- src/Model/Doc/Request/RequestDoc.php | 3 +++ src/Service/DocBlockParser.php | 14 ++++---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Model/Doc/Request/RequestDoc.php b/src/Model/Doc/Request/RequestDoc.php index 68e5045..1103576 100644 --- a/src/Model/Doc/Request/RequestDoc.php +++ b/src/Model/Doc/Request/RequestDoc.php @@ -17,6 +17,9 @@ class RequestDoc /** @var mixed[] */ private array $requestBody = []; + /** + * @return ComponentSchemaDoc[] + */ public function getComponentSchemaDocs(): array { return $this->componentSchemaDocs; diff --git a/src/Service/DocBlockParser.php b/src/Service/DocBlockParser.php index 4049d54..0e31404 100644 --- a/src/Service/DocBlockParser.php +++ b/src/Service/DocBlockParser.php @@ -40,6 +40,8 @@ public function parseDocBlock(string $docBlock, ?string $parameterName = null): $parsedDocBlock = $this->phpDocParser->parse($tokens); foreach ($parsedDocBlock->children as $docBlockItem) { + $docBlockParamName = $parameterName; + if ($docBlockItem->value instanceof ParamTagValueNode) { $docBlockParamName = ltrim($docBlockItem->value->parameterName, '$'); } @@ -48,17 +50,9 @@ public function parseDocBlock(string $docBlock, ?string $parameterName = null): $docBlockParamName = ltrim($docBlockItem->value->variableName, '$'); } - if ( - ( - !isset($docBlockParamName) - || $docBlockParamName === '' - ) - && $parameterName !== null - ) { - $docBlockParamName = $parameterName; + if (isset($docBlockParamName) && $docBlockParamName !== '') { + $docBlockData[$docBlockParamName] = $docBlockItem; } - - $docBlockData[$docBlockParamName] = $docBlockItem; } return $docBlockData;