Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1bcca09
fix(symfony): provider can throw validation exception (#5586)
soyuka May 11, 2023
547078c
fix: allowed composite identifiers with differents types
Sarahshr May 22, 2023
a0f12b6
fix(serializer): disable_type_enforcement with null values (#5593)
soyuka May 23, 2023
354d84d
ci: php8 is allowed
soyuka May 23, 2023
57bfefb
fix(metadata): convert composite uri variables w/ proper type
soyuka May 23, 2023
fec529d
ci: phpstan
soyuka May 23, 2023
d5a299a
style: symfony rules has use_nullable_type_declaration to false
soyuka May 23, 2023
f5bc28f
cs: remove print
soyuka May 23, 2023
ee8d267
chore: bump javascript dependencies
soyuka May 24, 2023
1fe505a
chore: v3.1.12 changelog
soyuka May 24, 2023
a09e258
fix: allows changing getters and setters without breaks (#5601)
Sarahshr May 28, 2023
14969aa
fix(serializer): put replaces embed collection (#5604)
soyuka May 30, 2023
0c1c1c3
fix: enable API Platform integration in LexikJWTAuthenticationBundle …
alanpoulain Jun 2, 2023
a879623
fix: filters don't have to implement the "legacy" FilterInterface (#…
mrossard Jun 8, 2023
5f8e4a8
test: interface as output (#5621)
Sarahshr Jun 9, 2023
b6acbce
style: maker bundle now applies php-cs-fixer (#5628)
soyuka Jun 13, 2023
c9b279f
fix: improve Processor and Provider PHPDoc (#5627)
dunglas Jun 13, 2023
f794201
Add description on an internal class
soyuka Jul 1, 2023
b8cbdb1
fix: search on nested sub-entity that doesn't use "id" as its ORM ide…
mrossard Jul 5, 2023
0fe4f4d
ci: behat context + cs (#5651)
soyuka Jul 5, 2023
d971c2e
cs: various fixes
soyuka Jul 6, 2023
31a3e87
Merge branch 3.1 into main
soyuka Jul 6, 2023
bdbab30
cs
soyuka Jul 7, 2023
2df34d8
tests
soyuka Jul 7, 2023
c9d729e
tests
soyuka Jul 7, 2023
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
1 change: 0 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
->exclude([
'src/Core/Bridge/Symfony/Maker/Resources/skeleton',
'tests/Fixtures/app/var',
'tests/Fixtures/Symfony/Maker',
])
->notPath('src/Symfony/Bundle/DependencyInjection/Configuration.php')
->notPath('src/Annotation/ApiFilter.php') // temporary
Expand Down
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## v3.1.12

### Bug fixes

* [1bcca0930](https://github.com/api-platform/core/commit/1bcca093074a85da071a8b16c250e084a7c3b68a) fix(symfony): provider can throw validation exception (#5586)
* [57bfefbfa](https://github.com/api-platform/core/commit/57bfefbfa42dd893b6ec3cb66c0402597927efc6) [547078cf7](https://github.com/api-platform/core/commit/547078cf7ce89d6dbfcccf4fa6dbe7031b04b94c) fix(metadata): convert composite uri variables w/ proper type
* [a0f12b667](https://github.com/api-platform/core/commit/a0f12b667a076c6647d7d8281c7a6e3a6bd68692) fix(serializer): disable_type_enforcement with null values (#5593)

Also updates: graphiql, opensans

## v3.1.11

### Bug fixes
Expand Down Expand Up @@ -1605,4 +1615,4 @@ Please read #2825 if you have issues with the behavior of Readable/Writable Link
## 1.0.0 beta 2

* Preserve indexes when normalizing and denormalizing associative arrays
* Allow setting default order for property when registering a `Doctrine\Orm\Filter\OrderFilter` instance
* Allow setting default order for property when registering a `Doctrine\Orm\Filter\OrderFilter` instance
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"psr/log": "^1.0 || ^2.0 || ^3.0",
"ramsey/uuid": "^3.7 || ^4.0",
"ramsey/uuid-doctrine": "^1.4",
"soyuka/contexts": "^3.3.6",
"soyuka/contexts": "v3.3.9",
"soyuka/stubs-mongodb": "^1.0",
"symfony/asset": "^6.1",
"symfony/browser-kit": "^6.1",
Expand Down
9 changes: 9 additions & 0 deletions features/doctrine/search_filter.feature
Original file line number Diff line number Diff line change
Expand Up @@ -1024,3 +1024,12 @@ Feature: Search filter on collections
Then the response status code should be 200
And the response should be in JSON
And the JSON node "hydra:totalItems" should be equal to 1

@!mongodb
@createSchema
Scenario: Search on nested sub-entity that doesn't use "id" as its ORM identifier
Given there is a dummy entity with a sub entity with id "stringId" and name "someName"
When I send a "GET" request to "/dummy_with_subresource?subEntity=/dummy_subresource/stringId"
Then the response status code should be 200
And the response should be in JSON
And the JSON node "hydra:totalItems" should be equal to 1
25 changes: 25 additions & 0 deletions features/jsonld/getter_setter_renaming.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Feature: Resource should contain one field for each property
In order to use API resource
As a developer
I need to have one field exposed for each property (which take getter/setter name)

@createSchema
Scenario: I should be able to POST a new entity
When I add "Accept" header equal to "application/ld+json"
And I add "Content-Type" header equal to "application/ld+json"
When I send a "POST" request to "/entity_with_renamed_getter_and_setters" with body:
"""
{
"firstnameOnly": "Sarah"
}
"""
Then the response status code should be 201
And the JSON should be equal to:
"""
{
"@context": "/contexts/EntityWithRenamedGetterAndSetter",
"@id": "/entity_with_renamed_getter_and_setters",
"@type": "EntityWithRenamedGetterAndSetter",
"firstnameOnly": "Sarah"
}
"""
11 changes: 11 additions & 0 deletions features/jsonld/interface_dto_output.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Feature: Resource should be able to take interface as output value

@createSchema
Scenario: I should be able to GET a collection of objects
Given I add "Accept" header equal to "application/ld+json"
And I add "Content-Type" header equal to "application/json"
When I send a "GET" request to "/entity_with_dto_outputs"
And the JSON node "hydra:member[0].name" should exist
And the JSON node "hydra:member[0].@type" should exist
And the JSON node "hydra:member[0].@id" should exist
And the JSON node "hydra:member[0].city" should not exist
32 changes: 32 additions & 0 deletions features/main/put_collection.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Feature: Update an embed collection with PUT
As a client software developer
I need to be able to update an embed collection

Background:
Given I add "Content-Type" header equal to "application/ld+json"

@createSchema
@!mongodb
Scenario: Update embed collection
And I send a "POST" request to "/issue5584_employees" with body:
"""
{"name": "One"}
"""
Then I add "Content-Type" header equal to "application/ld+json"
And I send a "POST" request to "/issue5584_employees" with body:
"""
{"name": "Two"}
"""
Then print last JSON response
Then I add "Content-Type" header equal to "application/ld+json"
And I send a "POST" request to "/issue5584_businesses" with body:
"""
{"name": "Business"}
"""
Then I add "Content-Type" header equal to "application/ld+json"
And I send a "PUT" request to "/issue5584_businesses/1" with body:
"""
{"name": "Business", "businessEmployees": [{"@id": "/issue5584_employees/1", "id": 1}, {"@id": "/issue5584_employees/2", "id": 2}]}
"""
And the JSON node "businessEmployees[0].name" should contain 'One'
And the JSON node "businessEmployees[1].name" should contain 'Two'
8 changes: 7 additions & 1 deletion src/Doctrine/Common/Filter/SearchFilterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,13 @@ protected function getIdFromValue(string $value): mixed
$iriConverter = $this->getIriConverter();
$item = $iriConverter->getResourceFromIri($value, ['fetch_data' => false]);

return $this->getPropertyAccessor()->getValue($item, 'id');
if (null === $this->identifiersExtractor) {
return $this->getPropertyAccessor()->getValue($item, 'id');
}

$identifiers = $this->identifiersExtractor->getIdentifiersFromItem($item);

return 1 === \count($identifiers) ? array_pop($identifiers) : $identifiers;
} catch (InvalidArgumentException) {
// Do nothing, return the raw value
}
Expand Down
5 changes: 4 additions & 1 deletion src/Doctrine/Orm/Filter/SearchFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB
if ($metadata->hasField($field)) {
if ('id' === $field) {
$values = array_map($this->getIdFromValue(...), $values);
// todo: handle composite IDs
}

if (!$this->hasValidValues($values, $this->getDoctrineFieldType($property, $resourceClass))) {
Expand All @@ -121,9 +122,11 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB
}

$values = array_map($this->getIdFromValue(...), $values);
// todo: handle composite IDs

$associationResourceClass = $metadata->getAssociationTargetClass($field);
$associationFieldIdentifier = $metadata->getIdentifierFieldNames()[0];
$associationMetadata = $this->getClassMetadata($associationResourceClass);
$associationFieldIdentifier = $associationMetadata->getIdentifierFieldNames()[0];
$doctrineTypeField = $this->getDoctrineFieldType($associationFieldIdentifier, $associationResourceClass);

if (!$this->hasValidValues($values, $doctrineTypeField)) {
Expand Down
2 changes: 1 addition & 1 deletion src/Elasticsearch/Serializer/DocumentNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*
* @author Baptiste Meyer <[email protected]>
*/
final class DocumentNormalizer extends ObjectNormalizer
final class DocumentNormalizer extends ObjectNormalizer // @phpstan-ignore-line
{
public const FORMAT = 'elasticsearch';

Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/ApiFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function __construct(
public array $properties = [],
public array $arguments = [],
) {
if (!is_a($this->filterClass, FilterInterface::class, true) || !is_a($this->filterClass, LegacyFilterInterface::class, true)) {
if (!is_a($this->filterClass, FilterInterface::class, true) && !is_a($this->filterClass, LegacyFilterInterface::class, true)) {
throw new InvalidArgumentException(sprintf('The filter class "%s" does not implement "%s". Did you forget a use statement?', $this->filterClass, FilterInterface::class));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __construct(
array $paginationViaCursor = null,
array $hydraContext = null,
array $openapiContext = null,
bool|OpenApiOperation|null $openapi = null,
bool|OpenApiOperation $openapi = null,
array $exceptionToStatus = null,
bool $queryParameterValidationEnabled = null,

Expand Down
4 changes: 2 additions & 2 deletions src/Metadata/ErrorResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function __construct(
string $uriTemplate = null,
string $shortName = null,
string $description = null,
array|string|null $types = null,
array|string $types = null,
$operations = null,
$formats = null,
$inputFormats = null,
Expand All @@ -50,7 +50,7 @@ public function __construct(
bool $collectDenormalizationErrors = null,
array $hydraContext = null,
array $openapiContext = null,
OpenApiOperation|bool|null $openapi = null,
OpenApiOperation|bool $openapi = null,
array $validationContext = null,
array $filters = null,
bool $elasticsearch = null,
Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Get.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __construct(
array $paginationViaCursor = null,
array $hydraContext = null,
array $openapiContext = null,
bool|OpenApiOperation|null $openapi = null,
bool|OpenApiOperation $openapi = null,
array $exceptionToStatus = null,
bool $queryParameterValidationEnabled = null,

Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/GetCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __construct(
array $paginationViaCursor = null,
array $hydraContext = null,
array $openapiContext = null,
bool|OpenApiOperation|null $openapi = null,
bool|OpenApiOperation $openapi = null,
array $exceptionToStatus = null,
bool $queryParameterValidationEnabled = null,

Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Patch.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __construct(
array $paginationViaCursor = null,
array $hydraContext = null,
array $openapiContext = null,
bool|OpenApiOperation|null $openapi = null,
bool|OpenApiOperation $openapi = null,
array $exceptionToStatus = null,
bool $queryParameterValidationEnabled = null,

Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __construct(
array $paginationViaCursor = null,
array $hydraContext = null,
array $openapiContext = null,
bool|OpenApiOperation|null $openapi = null,
bool|OpenApiOperation $openapi = null,
array $exceptionToStatus = null,
bool $queryParameterValidationEnabled = null,

Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Put.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __construct(
array $paginationViaCursor = null,
array $hydraContext = null,
array $openapiContext = null,
bool|OpenApiOperation|null $openapi = null,
bool|OpenApiOperation $openapi = null,
array $exceptionToStatus = null,
bool $queryParameterValidationEnabled = null,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
use ApiPlatform\Metadata\Put;
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;

/**
* Triggers resource deprecations.
*
* @final
*
* @internal
*/
class DeprecationResourceMetadataCollectionFactory implements ResourceMetadataCollectionFactoryInterface
{
// Hashmap to avoid triggering too many deprecations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function testCreateMethodReturnsProperPropertyNameCollectionForObjectWith
])
);

self::assertObjectHasAttribute('ignored', new DummyIgnoreProperty());
$this->assertTrue((new \ReflectionObject(new DummyIgnoreProperty()))->hasProperty('ignored'));

$collection = $factory->create(DummyIgnoreProperty::class, ['serializer_groups' => ['dummy']]);

Expand Down
1 change: 1 addition & 0 deletions src/Metadata/Util/Inflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public static function pluralize(string $word): string
{
if (!self::$keepLegacyInflector) {
$pluralize = (new EnglishInflector())->pluralize($word);

return end($pluralize);
}

Expand Down
9 changes: 7 additions & 2 deletions src/Serializer/AbstractItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public function denormalize(mixed $data, string $class, string $format = null, a

if ($inputClass = $this->getInputClass($context)) {
if (!$this->serializer instanceof DenormalizerInterface) {
throw new LogicException('Cannot normalize the output because the injected serializer is not a normalizer');
throw new LogicException('Cannot denormalize the input because the injected serializer is not a denormalizer');
}

unset($context['input'], $context['operation'], $context['operation_name']);
Expand Down Expand Up @@ -495,14 +495,19 @@ protected function denormalizeCollection(string $attribute, ApiProperty $propert

$collectionKeyType = $type->getCollectionKeyTypes()[0] ?? null;
$collectionKeyBuiltinType = $collectionKeyType?->getBuiltinType();
$childContext = $this->createChildContext(['resource_class' => $className] + $context, $attribute, $format);
unset($childContext['uri_variables']);
if ($this->resourceMetadataCollectionFactory) {
$childContext['operation'] = $this->resourceMetadataCollectionFactory->create($className)->getOperation();
}

$values = [];
foreach ($value as $index => $obj) {
if (null !== $collectionKeyBuiltinType && !\call_user_func('is_'.$collectionKeyBuiltinType, $index)) {
throw NotNormalizableValueException::createForUnexpectedDataType(sprintf('The type of the key "%s" must be "%s", "%s" given.', $index, $collectionKeyBuiltinType, \gettype($index)), $index, [$collectionKeyBuiltinType], ($context['deserialization_path'] ?? false) ? sprintf('key(%s)', $context['deserialization_path']) : null, true);
}

$values[$index] = $this->denormalizeRelation($attribute, $propertyMetadata, $className, $obj, $format, $this->createChildContext($context, $attribute, $format));
$values[$index] = $this->denormalizeRelation($attribute, $propertyMetadata, $className, $obj, $format, $childContext);
}

return $values;
Expand Down
9 changes: 8 additions & 1 deletion src/State/ProcessorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,19 @@
/**
* Process data: send an email, persist to storage, add to queue etc.
*
* @template T
*
* @author Antoine Bluchet <[email protected]>
*/
interface ProcessorInterface
{
/**
* Handle the state.
* Processes the state.
*
* @param array<string, mixed> $uriVariables
* @param array<string, mixed> $context
*
* @return T
*/
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []);
}
7 changes: 5 additions & 2 deletions src/State/ProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@
/**
* Retrieves data from a persistence layer.
*
* @author Antoine Bluchet <[email protected]>
*
* @template T of object
*
* @author Antoine Bluchet <[email protected]>
*/
interface ProviderInterface
{
/**
* Provides data.
*
* @param array<string, mixed> $uriVariables
* @param array<string, mixed> $context
*
* @return T|Pagination\PartialPaginatorInterface<T>|iterable<T>|null
*/
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ public function prepend(ContainerBuilder $container): void
],
]);
}
if (isset($container->getExtensions()['lexik_jwt_authentication'])) {
$container->prependExtensionConfig('lexik_jwt_authentication', [
'api_platform' => [
'enabled' => true,
],
]);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
<service id="api_platform.doctrine_mongodb.odm.search_filter" class="ApiPlatform\Doctrine\Odm\Filter\SearchFilter" public="false" abstract="true">
<argument type="service" id="doctrine_mongodb" />
<argument type="service" id="api_platform.iri_converter" />
<argument type="service" id="api_platform.identifiers_extractor.cached" on-invalid="ignore" />
<argument type="service" id="api_platform.identifiers_extractor" on-invalid="ignore" />
<argument type="service" id="api_platform.property_accessor" />
<argument type="service" id="logger" on-invalid="ignore" />
<argument key="$nameConverter" type="service" id="api_platform.name_converter" on-invalid="ignore"/>
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/Resources/config/doctrine_orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
<argument type="service" id="api_platform.iri_converter" />
<argument type="service" id="api_platform.property_accessor" />
<argument type="service" id="logger" on-invalid="ignore" />
<argument key="$identifiersExtractor" type="service" id="api_platform.identifiers_extractor.cached" on-invalid="ignore" />
<argument key="$identifiersExtractor" type="service" id="api_platform.identifiers_extractor" on-invalid="ignore" />
<argument key="$nameConverter" type="service" id="api_platform.name_converter" on-invalid="ignore" />
</service>
<service id="ApiPlatform\Doctrine\Orm\Filter\SearchFilter" alias="api_platform.doctrine.orm.search_filter" />
Expand Down
Loading