Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a1a85f1
fix(json-schema): use collectionKeyType for building JSON Schema (#4385)
yoshz Sep 27, 2021
2f2b1c8
fix(doctrine): handle inverse side of OneToOne association in Doctrin…
carlobeltrame Sep 27, 2021
85763b7
chore: update JS deps (#4477)
dunglas Sep 29, 2021
25c71b2
docs: add changelog for version 2.6.6 (#4478)
dunglas Sep 29, 2021
9cf864e
fix: add missing dev dependency
dunglas Oct 7, 2021
5f09071
fix: type in Required filter
dunglas Oct 7, 2021
7bc8fe7
chore: add return types and PHPDoc
dunglas Oct 7, 2021
23e5b92
chore: fix typehint in test
dunglas Oct 7, 2021
c67d7d0
chore: fix CS
dunglas Oct 7, 2021
5110448
fix: remove useless PHPDocs
dunglas Oct 7, 2021
2106d60
ci: run PHP CS Fixer and PHPStan on PHP 8
dunglas Oct 7, 2021
ba89b59
chore: fix some behat tests
dunglas Oct 7, 2021
da8b941
chore: fix types in fixtures
dunglas Oct 8, 2021
f417e08
chore: fix PHPStan
dunglas Oct 8, 2021
cf2b361
chore: fix MongoDB documents' types
dunglas Oct 9, 2021
8a60e00
chore: add more PHPDoc annotations
dunglas Oct 10, 2021
736fe29
chore: fix PHP CS Fixer config
dunglas Oct 11, 2021
87ad91f
chore: remove useless Behat steps
dunglas Oct 11, 2021
0d37caa
Merge pull request #4503 from dunglas/feat/symfony-5.4
dunglas Oct 11, 2021
3063220
fix: improve compatibility with Symfony 5.4 (#4514)
PierreRebeilleau Oct 22, 2021
5272238
fix: Pass the child context when normalizing nested non-resource obje…
norkunas Oct 22, 2021
1eaacf2
fix(doctrine): do not apply order extension if sorting already define…
natepage Oct 22, 2021
e05b62a
Merge remote-tracking branch 'upstream/2.6' into merge-26
soyuka Oct 22, 2021
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
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ jobs:
strategy:
matrix:
php:
- '8'
- '8.0'
fail-fast: false
env:
PHP_CS_FIXER_FUTURE_MODE: '1'
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -42,7 +40,7 @@ jobs:
strategy:
matrix:
php:
- '8'
- '8.0'
fail-fast: false
env:
APP_DEBUG: '1' # https://github.com/phpstan/phpstan-symfony/issues/37
Expand Down
9 changes: 4 additions & 5 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
'@PHPUnit60Migration:risky' => true,
'@Symfony' => true,
'@Symfony:risky' => true,
'single_line_comment_style' => false, // Temporary fix for compatibility with PHP 8 attributes, see https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/5284
'comment_to_phpdoc' => true, // Temporary fix for compatibility with PHP 8 attributes, see https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/5284
'align_multiline_comment' => [
'comment_type' => 'phpdocs_like',
],
Expand Down Expand Up @@ -76,9 +74,10 @@
],
],
'no_superfluous_elseif' => true,
'no_superfluous_phpdoc_tags' => [
'allow_mixed' => false,
],
// To re-enable in API Platform 3: https://github.com/symfony/symfony/issues/43021
//'no_superfluous_phpdoc_tags' => [
// 'allow_mixed' => false,
//],
'no_unset_cast' => true,
'no_unset_on_property' => true,
'no_useless_else' => true,
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@
* Add support for `security_post_validation` attribute
* Mark the GraphQL subsystem as stable (#4500)

## 2.6.6

* fix(json-schema): consider `SplFileInfo` class as a binary type (#4332)
* fix(json-schema): use `collectionKeyType` for building JSON Schema (#4385)
* fix(openapi): failing recursion on api resources with "paths" key (#4325)
* fix(graphql): make sure form content type is recognized as a multipart request (#4461)
* fix(doctrine): handle inverse side of OneToOne association in Doctrine search filter (#4366)
* fix(doctrine): usage of deprecated DBAL type constants (#4399)
* fix(test): fix `REMOTE_ADDR` support in `ApiTestCase` (#4446)
* fix(docs): use `asset_package` for all assets (#4470)
* fix(docs): upgrade Swagger UI to version 3.52.3 (#4477)
* fix(docs): upgrade ReDoc to version 2.0.0-rc.56 (#4477)
* fix(docs): upgrade Swagger UI to version 2.0.0-rc.56 (#4477)

## 2.6.5

* Fix various usage of various deprecated methods
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"symfony/framework-bundle": "^4.4 || ^5.1",
"symfony/http-client": "^4.4 || ^5.1",
"symfony/maker-bundle": "^1.24",
"symfony/intl": "^4.4 || ^5.3",
"symfony/mercure-bundle": "*",
"symfony/messenger": "^4.4 || ^5.1",
"symfony/phpunit-bridge": "^5.1.7",
Expand Down
28 changes: 28 additions & 0 deletions features/jsonld/non_resource.feature
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,34 @@ Feature: JSON-LD non-resource handling
}
"""

Scenario: Get a resource containing a raw object with selected properties
Given there are 1 dummy objects with relatedDummy and its thirdLevel
When I send a "GET" request to "/contain_non_resources/1?properties[]=id&properties[nested][notAResource][]=foo&properties[notAResource][]=bar"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
And the JSON should be a superset of:
"""
{
"@context": "/contexts/ContainNonResource",
"@id": "/contain_non_resources/1",
"@type": "ContainNonResource",
"id": 1,
"nested": {
"@id": "/contain_non_resources/1-nested",
"@type": "ContainNonResource",
"notAResource": {
"@type": "NotAResource",
"foo": "f2"
}
},
"notAResource": {
"@type": "NotAResource",
"bar": "b1"
}
}
"""

@!mongodb
@createSchema
Scenario: Create a resource that has a non-resource relation.
Expand Down
2 changes: 2 additions & 0 deletions src/Api/IdentifiersExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public function getIdentifiersFromItem($item, string $operationName = null, arra

/**
* Gets the value of the given class property.
*
* @param mixed $item
*/
private function getIdentifierValue($item, string $class, string $property, string $parameterName)
{
Expand Down
1 change: 1 addition & 0 deletions src/Core/Api/ResourceClassResolverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface ResourceClassResolverInterface
*
* @param string $resourceClass The expected resource class
* @param bool $strict If true, value must match the expected resource class
* @param mixed $value
*
* @throws InvalidArgumentException
*/
Expand Down
4 changes: 4 additions & 0 deletions src/Core/Bridge/Doctrine/Common/DataPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public function remove($data, array $context = [])

/**
* Gets the Doctrine object manager associated with given data.
*
* @param mixed $data
*/
private function getManager($data): ?DoctrineObjectManager
{
Expand All @@ -88,6 +90,8 @@ private function getManager($data): ?DoctrineObjectManager

/**
* Checks if doctrine does not manage data automatically.
*
* @param mixed $data
*/
private function isDeferredExplicit(DoctrineObjectManager $manager, $data): bool
{
Expand Down
2 changes: 2 additions & 0 deletions src/Core/Bridge/Doctrine/EventListener/WriteListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public function onKernelView(ViewEvent $event): void

/**
* Gets the manager if applicable.
*
* @param mixed $data
*/
private function getManager(string $resourceClass, $data): ?ObjectManager
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ final class CollectionDataProvider implements CollectionDataProviderInterface, R

/**
* @param AggregationCollectionExtensionInterface[] $collectionExtensions
* @param mixed $resourceMetadataFactory
*/
public function __construct(ManagerRegistry $managerRegistry, $resourceMetadataFactory, iterable $collectionExtensions = [])
{
Expand All @@ -56,7 +57,7 @@ public function supports(string $resourceClass, string $operationName = null, ar
*
* @throws RuntimeException
*/
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
public function getCollection(string $resourceClass, string $operationName = null, array $context = []): iterable
{
/** @var DocumentManager $manager */
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ final class FilterExtension implements AggregationCollectionExtensionInterface
private $resourceMetadataFactory;

/**
* @param ContainerInterface|FilterCollection $filterLocator The new filter locator or the deprecated filter collection
* @param ContainerInterface|FilterCollection $filterLocator The new filter locator or the deprecated filter collection
* @param mixed $resourceMetadataFactory
*/
public function __construct($resourceMetadataFactory, $filterLocator)
{
Expand Down
30 changes: 30 additions & 0 deletions src/Core/Bridge/Doctrine/MongoDbOdm/Extension/OrderExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
use ApiPlatform\Exception\OperationNotFoundException;
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
use Doctrine\ODM\MongoDB\Aggregation\Builder;
use Doctrine\ODM\MongoDB\Aggregation\Stage\Sort;
use Doctrine\Persistence\ManagerRegistry;
use OutOfRangeException;

/**
* Applies selected ordering while querying resource collection.
Expand Down Expand Up @@ -56,6 +58,11 @@ public function __construct(string $order = null, $resourceMetadataFactory = nul
*/
public function applyToCollection(Builder $aggregationBuilder, string $resourceClass, string $operationName = null, array &$context = [])
{
// Do not apply order if already defined on $aggregationBuilder
if ($this->hasSortStage($aggregationBuilder)) {
return;
}

$classMetaData = $this->getClassMetadata($resourceClass);
$identifiers = $classMetaData->getIdentifier();
if (null !== $this->resourceMetadataFactory) {
Expand Down Expand Up @@ -107,4 +114,27 @@ protected function getManagerRegistry(): ManagerRegistry
{
return $this->managerRegistry;
}

private function hasSortStage(Builder $aggregationBuilder): bool
{
$shouldStop = false;
$index = 0;

do {
try {
if ($aggregationBuilder->getStage($index) instanceof Sort) {
// If at least one stage is sort, then it has sorting
return true;
}
} catch (OutOfRangeException $outOfRangeException) {
// There is no more stages on the aggregation builder
$shouldStop = true;
}

++$index;
} while (!$shouldStop);

// No stage was sort, and we iterated through all stages
return false;
}
}
2 changes: 2 additions & 0 deletions src/Core/Bridge/Doctrine/MongoDbOdm/Filter/AbstractFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public function apply(Builder $aggregationBuilder, string $resourceClass, string

/**
* Passes a property through the filter.
*
* @param mixed $value
*/
abstract protected function filterProperty(string $property, $value, Builder $aggregationBuilder, string $resourceClass, string $operationName = null, array &$context = []);

Expand Down
2 changes: 2 additions & 0 deletions src/Core/Bridge/Doctrine/MongoDbOdm/Filter/DateFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ protected function filterProperty(string $property, $values, Builder $aggregatio

/**
* Adds the match stage according to the chosen null management.
*
* @param mixed $value
*/
private function addMatch(Builder $aggregationBuilder, string $field, string $operator, $value, string $nullManagement = null): void
{
Expand Down
4 changes: 4 additions & 0 deletions src/Core/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ protected function filterProperty(string $property, $value, Builder $aggregation

/**
* Add equality match stage according to the strategy.
*
* @param mixed $values
*/
private function addEqualityMatchStrategy(string $strategy, Builder $aggregationBuilder, string $field, string $matchField, $values, bool $caseSensitive, ClassMetadata $metadata): void
{
Expand All @@ -166,6 +168,8 @@ private function addEqualityMatchStrategy(string $strategy, Builder $aggregation
/**
* Get equality match value according to the strategy.
*
* @param mixed $value
*
* @throws InvalidArgumentException If strategy does not exist
*
* @return Regex|string
Expand Down
1 change: 1 addition & 0 deletions src/Core/Bridge/Doctrine/MongoDbOdm/ItemDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ final class ItemDataProvider implements DenormalizedIdentifiersAwareItemDataProv

/**
* @param AggregationItemExtensionInterface[] $itemExtensions
* @param mixed $resourceMetadataFactory
*/
public function __construct(ManagerRegistry $managerRegistry, $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $itemExtensions = [])
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ public function __construct(ObjectManager $objectManager)

/**
* {@inheritdoc}
*
* @return string[]|null
*/
public function getProperties($class, array $context = [])
public function getProperties($class, array $context = []): ?array
{
if (null === $metadata = $this->getMetadata($class)) {
return null;
Expand All @@ -55,8 +57,10 @@ public function getProperties($class, array $context = [])

/**
* {@inheritdoc}
*
* @return Type[]|null
*/
public function getTypes($class, $property, array $context = [])
public function getTypes($class, $property, array $context = []): ?array
{
if (null === $metadata = $this->getMetadata($class)) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ final class SubresourceDataProvider implements SubresourceDataProviderInterface
/**
* @param AggregationCollectionExtensionInterface[] $collectionExtensions
* @param AggregationItemExtensionInterface[] $itemExtensions
* @param mixed $resourceMetadataFactory
*/
public function __construct(ManagerRegistry $managerRegistry, $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $collectionExtensions = [], iterable $itemExtensions = [])
{
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Bridge/Doctrine/Orm/CollectionDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function supports(string $resourceClass, string $operationName = null, ar
*
* @throws RuntimeException
*/
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
public function getCollection(string $resourceClass, string $operationName = null, array $context = []): iterable
{
/** @var EntityManagerInterface $manager */
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ final class EagerLoadingExtension implements ContextAwareQueryCollectionExtensio

/**
* @TODO move $fetchPartial after $forceEager (@soyuka) in 3.0
*
* @param mixed $resourceMetadataFactory
*/
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, $resourceMetadataFactory, int $maxJoins = 30, bool $forceEager = true, RequestStack $requestStack = null, SerializerContextBuilderInterface $serializerContextBuilder = null, bool $fetchPartial = false, ClassMetadataFactoryInterface $classMetadataFactory = null)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Core/Bridge/Doctrine/Orm/Extension/FilterExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ final class FilterExtension implements ContextAwareQueryCollectionExtensionInter
private $resourceMetadataFactory;

/**
* @param ContainerInterface|FilterCollection $filterLocator The new filter locator or the deprecated filter collection
* @param ContainerInterface|FilterCollection $filterLocator The new filter locator or the deprecated filter collection
* @param mixed $resourceMetadataFactory
*/
public function __construct($resourceMetadataFactory, $filterLocator)
{
Expand Down
6 changes: 6 additions & 0 deletions src/Core/Bridge/Doctrine/Orm/Extension/OrderExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGenerator
throw new InvalidArgumentException('The "$resourceClass" parameter must not be null');
}

// Do not apply order if already defined on queryBuilder
$orderByDqlPart = $queryBuilder->getDQLPart('orderBy');
if (\is_array($orderByDqlPart) && \count($orderByDqlPart) > 0) {
return;
}

$rootAlias = $queryBuilder->getRootAliases()[0];

$classMetaData = $queryBuilder->getEntityManager()->getClassMetadata($resourceClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public function supportsResult(string $resourceClass, string $operationName = nu
/**
* {@inheritdoc}
*/
public function getResult(QueryBuilder $queryBuilder, string $resourceClass = null, string $operationName = null, array $context = [])
public function getResult(QueryBuilder $queryBuilder, string $resourceClass = null, string $operationName = null, array $context = []): iterable
{
$query = $queryBuilder->getQuery();

Expand Down
2 changes: 2 additions & 0 deletions src/Core/Bridge/Doctrine/Orm/Filter/AbstractFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $q

/**
* Passes a property through the filter.
*
* @param mixed $value
*/
abstract protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null/*, array $context = []*/);

Expand Down
1 change: 1 addition & 0 deletions src/Core/Bridge/Doctrine/Orm/Filter/DateFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
* Adds the where clause according to the chosen null management.
*
* @param string|DBALType $type
* @param mixed $value
*/
protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $alias, string $field, string $operator, $value, string $nullManagement = null, $type = null)
{
Expand Down
4 changes: 3 additions & 1 deletion src/Core/Bridge/Doctrine/Orm/Filter/SearchFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB

$associationAlias = $alias;
$associationField = $field;
if ($metadata->isCollectionValuedAssociation($associationField)) {
if ($metadata->isCollectionValuedAssociation($associationField) || $metadata->isAssociationInverseSide($field)) {
$associationAlias = QueryBuilderHelper::addJoinOnce($queryBuilder, $queryNameGenerator, $alias, $associationField);
$associationField = $associationFieldIdentifier;
}
Expand All @@ -161,6 +161,8 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB
/**
* Adds where clause according to the strategy.
*
* @param mixed $values
*
* @throws InvalidArgumentException If strategy does not exist
*/
protected function addWhereByStrategy(string $strategy, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $alias, string $field, $values, bool $caseSensitive)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public function supports(string $resourceClass, ?string $operationName = null, a
/**
* {@inheritdoc}
*/
public function getCollection(string $resourceClass, ?string $operationName = null, array $context = [])
public function getCollection(string $resourceClass, ?string $operationName = null, array $context = []): iterable
{
$documentMetadata = $this->documentMetadataFactory->create($resourceClass);
$body = [];
Expand Down
Loading