Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: api-platform/core
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v4.0.20
Choose a base ref
...
head repository: api-platform/core
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v4.0.21
Choose a head ref
  • 5 commits
  • 6 files changed
  • 3 contributors

Commits on Mar 18, 2025

  1. fix: allow parameter provider as object (#7032)

    * fix: allow parameter provider as object
    
    * remove useless phpdoc
    
    ---------
    
    Co-authored-by: soyuka <soyuka@users.noreply.github.com>
    deguif and soyuka authored Mar 18, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    7cb5a6d View commit details
  2. fix: header parameter should be case insensitive (#7031)

    fixes #7022
    soyuka authored Mar 18, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    da2e868 View commit details

Commits on Mar 19, 2025

  1. Merge 3.4

    soyuka committed Mar 19, 2025

    Verified

    This commit was signed with the committer’s verified signature.
    soyuka Antoine Bluchet
    Copy the full SHA
    8744814 View commit details

Commits on Mar 21, 2025

  1. fix(symfony): allow to merge array with string in global defaults (#7037

    )
    
    * fix: merge an array and not a string
    
    * fix: merge an array only if upperkey is 'Formats'
    
    * fix: cs
    
    * fix: transform string to array globally
    
    Co-authored-by: Antoine Bluchet <soyuka@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Antoine Bluchet <soyuka@users.noreply.github.com>
    Crovitche-1623 and soyuka authored Mar 21, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    bb83e9a View commit details
  2. docs: changelog 4.0.21

    soyuka committed Mar 21, 2025

    Verified

    This commit was signed with the committer’s verified signature.
    soyuka Antoine Bluchet
    Copy the full SHA
    4acec63 View commit details
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## v4.0.21

### Bug fixes

* [7cb5a6db8](https://github.com/api-platform/core/commit/7cb5a6db87241d95e6c324318fe861bd4f1820cf) fix: allow parameter provider as object (#7032)
* [bb83e9a03](https://github.com/api-platform/core/commit/bb83e9a034c511156aa20a8555bf367374ef5458) fix(symfony): allow to merge array with string in global defaults (#7037)
* [da2e86809](https://github.com/api-platform/core/commit/da2e86809d4a8dec294dc2fc148d92406f1f7fd1) fix: header parameter should be case insensitive (#7031)


### Features

## v4.0.20

### Bug fixes
4 changes: 4 additions & 0 deletions src/Metadata/Resource/Factory/OperationDefaultsTrait.php
Original file line number Diff line number Diff line change
@@ -63,6 +63,10 @@ private function addGlobalDefaults(ApiResource|Operation $operation): ApiResourc
$currentValue = $operation->{$getter}();

if (\is_array($currentValue) && $currentValue) {
if (\is_string($value)) {
$value = [$value];
}

$operation = $operation->{'with'.$upperKey}(array_merge($value, $currentValue));
}

13 changes: 7 additions & 6 deletions src/State/Provider/ParameterProvider.php
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\Exception\ProviderNotFoundException;
use ApiPlatform\State\ParameterNotFound;
use ApiPlatform\State\ParameterProviderInterface;
use ApiPlatform\State\ProviderInterface;
use ApiPlatform\State\Util\ParameterParserTrait;
use ApiPlatform\State\Util\RequestParser;
@@ -83,13 +82,15 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
continue;
}

if (!\is_string($provider) || !$this->locator->has($provider)) {
throw new ProviderNotFoundException(\sprintf('Provider "%s" not found on operation "%s"', $provider, $operation->getName()));
if (\is_string($provider)) {
if (!$this->locator->has($provider)) {
throw new ProviderNotFoundException(\sprintf('Provider "%s" not found on operation "%s"', $provider, $operation->getName()));
}

$provider = $this->locator->get($provider);
}

/** @var ParameterProviderInterface $providerInstance */
$providerInstance = $this->locator->get($provider);
if (($op = $providerInstance->provide($parameter, $values, $context)) instanceof Operation) {
if (($op = $provider->provide($parameter, $values, $context)) instanceof Operation) {
$operation = $op;
}
}
4 changes: 4 additions & 0 deletions src/State/Util/ParameterParserTrait.php
Original file line number Diff line number Diff line change
@@ -50,6 +50,10 @@ private function extractParameterValues(Parameter $parameter, array $values): st
throw new \RuntimeException('A Parameter should have a key.');
}

if ($parameter instanceof HeaderParameterInterface) {
$key = strtolower($key);
}

$parsedKey = explode('[:property]', $key);
if (isset($parsedKey[0]) && isset($values[$parsedKey[0]])) {
$key = $parsedKey[0];
18 changes: 17 additions & 1 deletion tests/Fixtures/TestBundle/ApiResource/WithParameter.php
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@
'group' => new QueryParameter(provider: [self::class, 'provideGroup']),
'properties' => new QueryParameter(filter: 'my_dummy.property'),
'service' => new QueryParameter(provider: CustomGroupParameterProvider::class),
'object' => new QueryParameter(provider: new CustomGroupParameterProvider()),
'auth' => new HeaderParameter(provider: [self::class, 'restrictAccess']),
'priority' => new QueryParameter(provider: [self::class, 'assertSecond'], priority: 10),
'priorityb' => new QueryParameter(provider: [self::class, 'assertFirst'], priority: 20),
@@ -79,6 +80,13 @@
parameters: new Parameters([new QueryParameter(key: 'q'), new HeaderParameter(key: 'q')]),
provider: [self::class, 'headerAndQueryProvider']
)]
#[GetCollection(
uriTemplate: 'header_required',
parameters: [
'Req' => new HeaderParameter(required: true, schema: ['type' => 'string']),
],
provider: [self::class, 'headerProvider']
)]
#[QueryParameter(key: 'everywhere')]
class WithParameter
{
@@ -127,7 +135,7 @@ public static function restrictAccess(): void
throw new AccessDeniedHttpException();
}

public static function headerAndQueryProvider(Operation $operation, array $uriVariables = [], array $context = [])
public static function headerAndQueryProvider(Operation $operation, array $uriVariables = [], array $context = []): JsonResponse
{
$parameters = $operation->getParameters();
$values = [$parameters->get('q', HeaderParameter::class)->getValue(), $parameters->get('q', QueryParameter::class)->getValue()];
@@ -154,4 +162,12 @@ public static function toInt(Parameter $parameter, array $parameters = [], array

return $operation->withParameters($parameters);
}

public static function headerProvider(Operation $operation, array $uriVariables = [], array $context = []): JsonResponse
{
$parameters = $operation->getParameters();
$values = [$parameters->get('Req', HeaderParameter::class)->getValue()];

return new JsonResponse($values);
}
}
15 changes: 15 additions & 0 deletions tests/Functional/Parameters/ParameterTest.php
Original file line number Diff line number Diff line change
@@ -55,6 +55,12 @@ public function testWithServiceProvider(): void
$this->assertArrayNotHasKey('a', $response->toArray());
}

public function testWithObjectProvider(): void
{
$response = self::createClient()->request('GET', 'with_parameters/1?service=blabla');
$this->assertArrayNotHasKey('a', $response->toArray());
}

public function testWithHeader(): void
{
self::createClient()->request('GET', 'with_parameters/1?service=blabla', ['headers' => ['auth' => 'foo']]);
@@ -91,4 +97,13 @@ public function testHeaderAndQuery(): void
'blabla',
]);
}

public function testHeaderParameterRequired(): void
{
self::createClient()->request('GET', 'header_required', ['headers' => ['req' => 'blabla']]);
$this->assertResponseStatusCodeSame(200);

self::createClient()->request('GET', 'header_required', ['headers' => []]);
$this->assertResponseStatusCodeSame(422);
}
}