Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@
]);

$services->set('api_platform.doctrine.odm.metadata.resource.parameter_metadata_collection_factory', DoctrineMongoDbOdmParameterResourceMetadataCollectionFactory::class)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 999)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 789)
->args([
service('doctrine_mongodb'),
service('api_platform.doctrine.odm.metadata.resource.parameter_metadata_collection_factory.inner'),
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/Resources/config/doctrine_orm.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@
]);

$services->set('api_platform.doctrine.orm.metadata.resource.parameter_metadata_collection_factory', DoctrineOrmParameterResourceMetadataCollectionFactory::class)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 998)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 788)
->args([
service('doctrine'),
service('api_platform.doctrine.orm.metadata.resource.parameter_metadata_collection_factory.inner'),
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Bundle/Resources/config/metadata/resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 200)
->args([service('api_platform.metadata.resource.metadata_collection_factory.alternate_uri.inner')]);

// Parameter factories decorate below the YAML, XML and PHP file factories (800) so they also see parameters declared in resource files
$services->set('api_platform.metadata.resource.metadata_collection_factory.parameter', ParameterResourceMetadataCollectionFactory::class)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 1000)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 790)
->args([
service('api_platform.metadata.property.name_collection_factory'),
service('api_platform.metadata.property.metadata_factory'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
->tag('api_platform.state_provider', ['key' => 'api_platform.validator.state.error_provider']);

$services->set('api_platform.validator.metadata.resource.metadata_collection_factory.parameter', ParameterValidationResourceMetadataCollectionFactory::class)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 1000)
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 790)
->args([
service('api_platform.validator.metadata.resource.metadata_collection_factory.parameter.inner'),
service('api_platform.filter_locator'),
Expand Down
51 changes: 51 additions & 0 deletions tests/Fixtures/TestBundle/Entity/Issue7655/Author.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?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\Issue7655;

use Doctrine\ORM\Mapping as ORM;

/**
* Author entity for issue #7655, related to the Book resource declared in YAML.
*
* @see https://github.com/api-platform/core/issues/7655
*/
#[ORM\Entity]
#[ORM\Table(name: 'issue_7655_author')]
class Author
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;

#[ORM\Column(length: 50)]
private string $name = '';

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

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

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

return $this;
}
}
69 changes: 69 additions & 0 deletions tests/Fixtures/TestBundle/Entity/Issue7655/Book.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?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\Issue7655;

use Doctrine\ORM\Mapping as ORM;

/**
* Book entity for issue #7655.
*
* Its resource and query parameters are declared in YAML (see api_resources_orm/resources.yaml), not with attributes.
*
* @see https://github.com/api-platform/core/issues/7655
*/
#[ORM\Entity]
#[ORM\Table(name: 'issue_7655_book')]
class Book
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;

#[ORM\Column(length: 50)]
private string $title = '';

#[ORM\ManyToOne(targetEntity: Author::class)]
#[ORM\JoinColumn(nullable: false)]
private ?Author $author = null;

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

public function getTitle(): string
{
return $this->title;
}

public function setTitle(string $title): self
{
$this->title = $title;

return $this;
}

public function getAuthor(): ?Author
{
return $this->author;
}

public function setAuthor(?Author $author): self
{
$this->author = $author;

return $this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ resources:
toProperty: author
id: [ApiPlatform\Tests\Fixtures\TestBundle\Entity\Program, id]

ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue7655\Book:
shortName: Issue7655Book
operations:
ApiPlatform\Metadata\GetCollection:
uriTemplate: /issue7655_books
parameters:
title:
filter: app_issue7655_exact_filter
authorName:
property: author.name
filter: app_issue7655_exact_filter

ApiPlatform\Tests\Fixtures\TestBundle\Entity\SingleFileConfigDummy:
shortName: single_file_config
description: File configured resource
Expand Down
4 changes: 4 additions & 0 deletions tests/Fixtures/app/config/config_doctrine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,7 @@ services:

ApiPlatform\Tests\Fixtures\TestBundle\Filter\QueryParameterFilter:
tags: [ 'api_platform.filter' ]

app_issue7655_exact_filter:
class: 'ApiPlatform\Doctrine\Orm\Filter\ExactFilter'
tags: [ 'api_platform.filter' ]
99 changes: 99 additions & 0 deletions tests/Functional/Parameters/Issue7655FileDeclaredParameterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?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\Functional\Parameters;

use ApiPlatform\Test\ApiTestCase;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue7655\Author;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue7655\Book;
use ApiPlatform\Tests\RecreateSchemaTrait;
use ApiPlatform\Tests\SetupClassResourcesTrait;

/**
* Parameters declared in resource configuration files (YAML here) must get the same metadata as
* parameters declared with attributes: property defaults, filter schema and OpenAPI parameters,
* and Doctrine nested property information.
*
* @see https://github.com/api-platform/core/issues/7655
*
* @group issue-7655
*/
final class Issue7655FileDeclaredParameterTest extends ApiTestCase
{
use RecreateSchemaTrait;
use SetupClassResourcesTrait;

protected static ?bool $alwaysBootKernel = false;

/**
* @return class-string[]
*/
public static function getResources(): array
{
return [Book::class];
}

protected function setUp(): void
{
if ($this->isMongoDB()) {
$this->markTestSkipped('The Book resource is declared in the ORM resource configuration only.');
}

$this->recreateSchema([Book::class, Author::class]);
$this->loadFixtures();
}

public function testParameterPropertyDefaultsToTheParameterKey(): void
{
$response = self::createClient()->request('GET', '/issue7655_books?title=Dune');
$this->assertResponseIsSuccessful();

$titles = array_map(static fn (array $book): string => $book['title'], $response->toArray()['hydra:member']);
$this->assertSame(['Dune'], $titles);
}

public function testFilterOnNestedProperty(): void
{
$response = self::createClient()->request('GET', '/issue7655_books?authorName=Ursula');
$this->assertResponseIsSuccessful();

$titles = array_map(static fn (array $book): string => $book['title'], $response->toArray()['hydra:member']);
$this->assertSame(['The Dispossessed'], $titles);
}

public function testOpenApiDocumentsTheFilterParameters(): void
{
$response = self::createClient()->request('GET', '/docs', [
'headers' => ['Accept' => 'application/vnd.openapi+json'],
]);
$this->assertResponseIsSuccessful();

$parameterNames = array_column($response->toArray()['paths']['/issue7655_books']['get']['parameters'], 'name');
$this->assertContains('authorName', $parameterNames);
$this->assertContains('authorName[]', $parameterNames);
}

private function loadFixtures(): void
{
$manager = $this->getManager();

$frank = (new Author())->setName('Frank');
$ursula = (new Author())->setName('Ursula');
$manager->persist($frank);
$manager->persist($ursula);

$manager->persist((new Book())->setTitle('Dune')->setAuthor($frank));
$manager->persist((new Book())->setTitle('The Dispossessed')->setAuthor($ursula));
$manager->flush();
}
}
Loading