diff --git a/src/Metadata/ApiProperty.php b/src/Metadata/ApiProperty.php index 28c6d09870d..865738c81c7 100644 --- a/src/Metadata/ApiProperty.php +++ b/src/Metadata/ApiProperty.php @@ -57,7 +57,7 @@ final class ApiProperty * @param Type|null $nativeType The internal PHP type */ public function __construct( - private ?string $description = null, + private string|\Stringable|null $description = null, private ?bool $readable = null, private ?bool $writable = null, private ?bool $readableLink = null, @@ -256,10 +256,10 @@ public function withProperty(string $property): static public function getDescription(): ?string { - return $this->description; + return $this->description instanceof \Stringable ? (string) $this->description : $this->description; } - public function withDescription(string $description): static + public function withDescription(string|\Stringable $description): static { $self = clone $this; $self->description = $description; diff --git a/src/Metadata/ApiResource.php b/src/Metadata/ApiResource.php index 32922afb1d7..4b4ab076854 100644 --- a/src/Metadata/ApiResource.php +++ b/src/Metadata/ApiResource.php @@ -67,7 +67,7 @@ public function __construct( /** * A description for this resource that will show on documentations. */ - protected ?string $description = null, + protected string|\Stringable|null $description = null, /** * The RDF types of this resource. diff --git a/src/Metadata/Delete.php b/src/Metadata/Delete.php index 3674a5d6fe9..28b7fd36c30 100644 --- a/src/Metadata/Delete.php +++ b/src/Metadata/Delete.php @@ -64,7 +64,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/Error.php b/src/Metadata/Error.php index c7c34733459..1115bec890f 100644 --- a/src/Metadata/Error.php +++ b/src/Metadata/Error.php @@ -64,7 +64,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/ErrorResource.php b/src/Metadata/ErrorResource.php index c3700713617..f2cae8676c8 100644 --- a/src/Metadata/ErrorResource.php +++ b/src/Metadata/ErrorResource.php @@ -22,7 +22,7 @@ class ErrorResource extends ApiResource public function __construct( ?string $uriTemplate = null, ?string $shortName = null, - ?string $description = null, + string|\Stringable|null $description = null, array|string|null $types = null, $operations = null, array|string|null $formats = null, diff --git a/src/Metadata/Get.php b/src/Metadata/Get.php index 4c59d7ab957..f9c118b0888 100644 --- a/src/Metadata/Get.php +++ b/src/Metadata/Get.php @@ -64,7 +64,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/GetCollection.php b/src/Metadata/GetCollection.php index 6256366bd27..325bd8aa663 100644 --- a/src/Metadata/GetCollection.php +++ b/src/Metadata/GetCollection.php @@ -64,7 +64,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/GraphQl/Operation.php b/src/Metadata/GraphQl/Operation.php index 2dbbaa4fddf..63904ab2850 100644 --- a/src/Metadata/GraphQl/Operation.php +++ b/src/Metadata/GraphQl/Operation.php @@ -57,7 +57,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/GraphQl/Query.php b/src/Metadata/GraphQl/Query.php index b877afa5e57..106fcfe1b91 100644 --- a/src/Metadata/GraphQl/Query.php +++ b/src/Metadata/GraphQl/Query.php @@ -40,7 +40,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/GraphQl/QueryCollection.php b/src/Metadata/GraphQl/QueryCollection.php index 2054b519cfe..4b9eae08e68 100644 --- a/src/Metadata/GraphQl/QueryCollection.php +++ b/src/Metadata/GraphQl/QueryCollection.php @@ -41,7 +41,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/GraphQl/Subscription.php b/src/Metadata/GraphQl/Subscription.php index dbd54aff922..29212bac641 100644 --- a/src/Metadata/GraphQl/Subscription.php +++ b/src/Metadata/GraphQl/Subscription.php @@ -40,7 +40,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/HttpOperation.php b/src/Metadata/HttpOperation.php index 32dfa15bb7e..2e03faeefbd 100644 --- a/src/Metadata/HttpOperation.php +++ b/src/Metadata/HttpOperation.php @@ -185,7 +185,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/Link.php b/src/Metadata/Link.php index 478c1327b9b..fe3359db7ad 100644 --- a/src/Metadata/Link.php +++ b/src/Metadata/Link.php @@ -40,7 +40,7 @@ public function __construct( mixed $filter = null, ?string $property = null, ?array $properties = null, - ?string $description = null, + string|\Stringable|null $description = null, ?bool $required = null, array $extraProperties = [], diff --git a/src/Metadata/McpResource.php b/src/Metadata/McpResource.php index 5be8ab91f35..8e4986aa415 100644 --- a/src/Metadata/McpResource.php +++ b/src/Metadata/McpResource.php @@ -28,7 +28,7 @@ final class McpResource extends HttpOperation /** * @param string $uri The specific URI identifying this resource instance. Must be unique within the server. * @param ?string $name A human-readable name for this resource. If null, a default might be generated from the method name. - * @param ?string $description An optional description of the resource. Defaults to class DocBlock summary. + * @param string|\Stringable|null $description An optional description of the resource. Defaults to class DocBlock summary. * @param bool|null $structuredContent Whether to include structured content in the response (defaults to true) * @param ?string $mimeType the MIME type, if known and constant for this resource * @param ?int $size the size in bytes, if known and constant @@ -94,7 +94,7 @@ final class McpResource extends HttpOperation public function __construct( protected string $uri, ?string $name = null, - ?string $description = null, + string|\Stringable|null $description = null, protected ?bool $structuredContent = null, protected ?string $mimeType = null, protected ?int $size = null, diff --git a/src/Metadata/McpTool.php b/src/Metadata/McpTool.php index f46f7a297d8..4eac809c9db 100644 --- a/src/Metadata/McpTool.php +++ b/src/Metadata/McpTool.php @@ -28,7 +28,7 @@ class McpTool extends HttpOperation /** * @param string|null $name The name of the tool (defaults to the method name) * @param string|null $title Optional human-readable title for display in UI - * @param string|null $description The description of the tool (defaults to the DocBlock/inferred) + * @param string|\Stringable|null $description The description of the tool (defaults to the DocBlock/inferred) * @param bool|null $structuredContent Whether to include structured content in the response (defaults to true) * @param mixed|null $annotations Optional annotations describing tool behavior * @param array|null $icons Optional list of icon URLs representing the tool @@ -92,7 +92,7 @@ class McpTool extends HttpOperation public function __construct( ?string $name = null, protected ?string $title = null, - ?string $description = null, + string|\Stringable|null $description = null, protected ?bool $structuredContent = null, protected mixed $annotations = null, protected ?array $icons = null, diff --git a/src/Metadata/Metadata.php b/src/Metadata/Metadata.php index 009612c9900..6d30cdc05fc 100644 --- a/src/Metadata/Metadata.php +++ b/src/Metadata/Metadata.php @@ -39,7 +39,7 @@ abstract class Metadata public function __construct( protected ?string $shortName = null, protected ?string $class = null, - protected ?string $description = null, + protected string|\Stringable|null $description = null, protected ?int $urlGenerationStrategy = null, protected ?string $deprecationReason = null, protected ?array $normalizationContext = null, @@ -138,10 +138,10 @@ public function withClass(string $class): static public function getDescription(): ?string { - return $this->description; + return $this->description instanceof \Stringable ? (string) $this->description : $this->description; } - public function withDescription(?string $description = null): static + public function withDescription(string|\Stringable|null $description = null): static { $self = clone $this; $self->description = $description; diff --git a/src/Metadata/NotExposed.php b/src/Metadata/NotExposed.php index c3422bac243..c01823ab7e9 100644 --- a/src/Metadata/NotExposed.php +++ b/src/Metadata/NotExposed.php @@ -77,7 +77,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/Operation.php b/src/Metadata/Operation.php index cbd53751e59..d5d9ccb75b0 100644 --- a/src/Metadata/Operation.php +++ b/src/Metadata/Operation.php @@ -608,7 +608,7 @@ public function __construct( */ protected ?array $paginationViaCursor = null, protected ?array $order = null, - protected ?string $description = null, + protected string|\Stringable|null $description = null, protected ?array $normalizationContext = null, protected ?array $denormalizationContext = null, protected ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/Parameter.php b/src/Metadata/Parameter.php index 06684abd45c..5c2dbd04de8 100644 --- a/src/Metadata/Parameter.php +++ b/src/Metadata/Parameter.php @@ -54,7 +54,7 @@ public function __construct( protected mixed $provider = null, protected mixed $filter = null, protected ?string $property = null, - protected ?string $description = null, + protected string|\Stringable|null $description = null, protected ?array $properties = null, protected ?bool $required = null, protected ?int $priority = null, @@ -115,7 +115,7 @@ public function getFilter(): mixed public function getDescription(): ?string { - return $this->description; + return $this->description instanceof \Stringable ? (string) $this->description : $this->description; } public function getRequired(): ?bool @@ -258,7 +258,7 @@ public function withProperty(string $property): static return $self; } - public function withDescription(string $description): static + public function withDescription(string|\Stringable $description): static { $self = clone $this; $self->description = $description; diff --git a/src/Metadata/Patch.php b/src/Metadata/Patch.php index e6147a18dad..e1dc9160a3f 100644 --- a/src/Metadata/Patch.php +++ b/src/Metadata/Patch.php @@ -64,7 +64,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/Post.php b/src/Metadata/Post.php index e68e4b0ec66..4dafb1068e1 100644 --- a/src/Metadata/Post.php +++ b/src/Metadata/Post.php @@ -64,7 +64,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/Put.php b/src/Metadata/Put.php index 73632c786bc..627756ac4fe 100644 --- a/src/Metadata/Put.php +++ b/src/Metadata/Put.php @@ -64,7 +64,7 @@ public function __construct( ?bool $paginationFetchJoinCollection = null, ?bool $paginationUseOutputWalkers = null, ?array $order = null, - ?string $description = null, + string|\Stringable|null $description = null, ?array $normalizationContext = null, ?array $denormalizationContext = null, ?bool $collectDenormalizationErrors = null, diff --git a/src/Metadata/Tests/Resource/StringableDescriptionParameterTest.php b/src/Metadata/Tests/Resource/StringableDescriptionParameterTest.php new file mode 100644 index 00000000000..44656983b6e --- /dev/null +++ b/src/Metadata/Tests/Resource/StringableDescriptionParameterTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Metadata\Tests\Resource; + +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Error; +use ApiPlatform\Metadata\ErrorResource; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\GraphQl\Mutation; +use ApiPlatform\Metadata\GraphQl\Query; +use ApiPlatform\Metadata\GraphQl\QueryCollection; +use ApiPlatform\Metadata\GraphQl\Subscription; +use ApiPlatform\Metadata\Metadata; +use ApiPlatform\Metadata\NotExposed; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; +use ApiPlatform\Metadata\Tests\Fixtures\Metadata\RestfulApi; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; + +final class StringableDescriptionParameterTest extends TestCase +{ + #[DataProvider('metadataProvider')] + public function testOnMetadata(Metadata $metadata): void + { + $this->assertSame($metadata->getDescription(), 'stringable_description'); + } + + public static function metadataProvider(): \Generator + { + $stringableDescription = new class implements \Stringable { + public function __toString(): string + { + return 'stringable_description'; + } + }; + $args = [ + 'description' => $stringableDescription, + ]; + + yield [new Get(...$args)]; + yield [new GetCollection(...$args)]; + yield [new Post(...$args)]; + yield [new Put(...$args)]; + yield [new Patch(...$args)]; + yield [new Delete(...$args)]; + yield [new Error(...$args)]; + yield [new NotExposed(...$args)]; + yield [new Query(...$args)]; + yield [new QueryCollection(...$args)]; + yield [new Mutation(...$args)]; + yield [new Subscription(...$args)]; + yield [new ApiResource(...$args)]; + yield [new ErrorResource(...$args)]; + yield [new RestfulApi(...$args)]; + } + + public function testOnApiProperty(): void + { + $stringableDescription = new class implements \Stringable { + public function __toString(): string + { + return 'stringable_description'; + } + }; + + $metadata = new ApiProperty( + description: $stringableDescription, + ); + + $this->assertSame($metadata->getDescription(), 'stringable_description'); + } +}