Skip to content

Commit

Permalink
fix(metadata): try to improve handling of stateOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
vinceAmstoutz committed Oct 15, 2024
1 parent 99262dc commit 11cc1e5
Show file tree
Hide file tree
Showing 6 changed files with 440 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
use ApiPlatform\OpenApi\Model\Parameter as OpenApiParameter;
use ApiPlatform\Serializer\Filter\FilterInterface as SerializerFilterInterface;
use ApiPlatform\State\OptionsInterface;
use Psr\Container\ContainerInterface;
use Symfony\Component\Validator\Constraints\Choice;
use Symfony\Component\Validator\Constraints\Count;
Expand Down Expand Up @@ -54,6 +55,17 @@ public function create(string $resourceClass): ResourceMetadataCollection
$resourceMetadataCollection = $this->decorated?->create($resourceClass) ?? new ResourceMetadataCollection($resourceClass);

foreach ($resourceMetadataCollection as $i => $resource) {
$stateOptions = $resource->getStateOptions();
if ($stateOptions instanceof OptionsInterface) {
if ($stateOptions instanceof \ApiPlatform\Doctrine\Orm\State\Options) {
$resourceClass = $resource->getStateOptions()->getEntityClass();
}

if ($stateOptions instanceof \ApiPlatform\Doctrine\Odm\State\Options) {
$resourceClass = $resource->getStateOptions()->getDocumentClass();
}
}

$operations = $resource->getOperations();

$internalPriority = -1;
Expand Down Expand Up @@ -118,6 +130,7 @@ private function setDefaults(string $key, Parameter $parameter, string $resource

// Read filter description to populate the Parameter
$description = $filter instanceof FilterInterface ? $filter->getDescription($resourceClass) : [];

if (($schema = $description[$key]['schema'] ?? null) && null === $parameter->getSchema()) {
$parameter = $parameter->withSchema($schema);
}
Expand Down Expand Up @@ -286,7 +299,7 @@ private function addFilterValidation(HttpOperation $operation): Parameters

$parameters->add($key, $this->addSchemaValidation(
// we disable openapi and hydra on purpose as their docs comes from filters see the condition for addFilterValidation above
new QueryParameter(key: $key, property: $definition['property'] ?? null, priority: $internalPriority--, schema: $schema, openApi: false, hydra: false),
new QueryParameter(key: $key, schema: $schema, openApi: false, property: $definition['property'] ?? null, priority: $internalPriority--, hydra: false),
$schema,
$required,
$openApi
Expand Down
6 changes: 6 additions & 0 deletions src/State/OptionsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace ApiPlatform\State;

/**
* Interface for state options used in API Platform.
*
* @method string getEntityClass() Gets the fully qualified class name of the entity associated with the state options.
* @method string getDocumentClass() Gets the fully qualified class name of the document associated with the state options.
*/
interface OptionsInterface
{
}
89 changes: 89 additions & 0 deletions tests/Fixtures/TestBundle/ApiResource/AgentApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* 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\Tests\Fixtures\TestBundle\ApiResource;

use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
use ApiPlatform\Doctrine\Orm\State\Options;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\QueryParameter;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Agent;
use Symfony\Component\Serializer\Attribute\Groups;

#[ApiFilter(DateFilter::class, properties: ['birthday'], alias: 'app_filter_date')]
#[ApiResource(
shortName: 'Agent',
operations: [
new GetCollection(parameters: [
'bla[:property]' => new QueryParameter(filter: 'app_filter_date'),
]),
],
stateOptions: new Options(entityClass: Agent::class)
)]
#[ApiFilter(DateFilter::class, properties: ['birthday'])]
#[ApiResource(
shortName: 'AgentSimple',
operations: [
new GetCollection(),
],
stateOptions: new Options(entityClass: Agent::class)
)]
class AgentApi
{
#[Groups(['agent:read'])]
private ?int $id = null;

#[Groups(['agent:read', 'agent:write'])]
private ?string $name = null;

#[Groups(['agent:read', 'agent:write'])]
private ?\DateTimeInterface $birthday = null;

public function getId(): ?int
{
return $this->id;
}

public function setId(?int $id): self
{
$this->id = $id;

return $this;
}

public function getName(): ?string
{
return $this->name;
}

public function setName(?string $name): self
{
$this->name = $name;

return $this;
}

public function getBirthday(): ?\DateTimeInterface
{
return $this->birthday;
}

public function setBirthday(?\DateTimeInterface $birthday): self
{
$this->birthday = $birthday;

return $this;
}
}
95 changes: 95 additions & 0 deletions tests/Fixtures/TestBundle/Document/AgentDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* 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\Tests\Fixtures\TestBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

#[ODM\Document]
class AgentDocument
{
#[ODM\Id(strategy: 'INCREMENT', type: 'int')]
public ?int $id = null;

#[ODM\Field]
public ?string $name = null;

#[ODM\Field]
public ?string $apiKey = null;

#[ODM\Field]
public ?\DateTimeImmutable $createdAt = null;

#[ODM\Field]
public ?\DateTimeImmutable $birthday = null;

public function getId(): ?int
{
return $this->id;
}

public function setId(int $id): static
{
$this->id = $id;

return $this;
}

public function getName(): ?string
{
return $this->name;
}

public function setName(string $name): static
{
$this->name = $name;

return $this;
}

public function getApiKey(): ?string
{
return $this->apiKey;
}

public function setApiKey(string $apiKey): static
{
$this->apiKey = $apiKey;

return $this;
}

public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}

public function setCreatedAt(\DateTimeImmutable $createdAt): static
{
$this->createdAt = $createdAt;

return $this;
}

public function getBirthday(): ?\DateTimeImmutable
{
return $this->birthday;
}

public function setBirthday(\DateTimeImmutable $birthday): static
{
$this->birthday = $birthday;

return $this;
}
}
97 changes: 97 additions & 0 deletions tests/Fixtures/TestBundle/Entity/Agent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* 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\Tests\Fixtures\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Agent
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
public ?int $id = null;

#[ORM\Column(length: 255)]
public ?string $name = null;

#[ORM\Column(length: 255)]
public ?string $apiKey = null;

#[ORM\Column]
public ?\DateTimeImmutable $createdAt = null;

#[ORM\Column]
public ?\DateTimeImmutable $birthday = null;

public function getId(): ?int
{
return $this->id;
}

public function setId(int $id): static
{
$this->id = $id;

return $this;
}

public function getName(): ?string
{
return $this->name;
}

public function setName(string $name): static
{
$this->name = $name;

return $this;
}

public function getApiKey(): ?string
{
return $this->apiKey;
}

public function setApiKey(string $apiKey): static
{
$this->apiKey = $apiKey;

return $this;
}

public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}

public function setCreatedAt(\DateTimeImmutable $createdAt): static
{
$this->createdAt = $createdAt;

return $this;
}

public function getBirthday(): ?\DateTimeImmutable
{
return $this->birthday;
}

public function setBirthday(\DateTimeImmutable $birthday): static
{
$this->birthday = $birthday;

return $this;
}
}
Loading

0 comments on commit 11cc1e5

Please sign in to comment.