Skip to content

Commit ad54075

Browse files
committed
Merge 4.1
2 parents 31c8afc + 1e50381 commit ad54075

File tree

83 files changed

+1220
-348
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1220
-348
lines changed

.github/workflows/ci.yml

+53
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,59 @@ jobs:
773773
- name: Run Behat tests
774774
run: vendor/bin/behat --out=std --format=progress --profile=elasticsearch --no-interaction
775775

776+
elasticsearch-v7:
777+
name: Behat (PHP ${{ matrix.php }}) (Elasticsearch v7)
778+
runs-on: ubuntu-latest
779+
timeout-minutes: 20
780+
strategy:
781+
matrix:
782+
php:
783+
- '8.3'
784+
fail-fast: false
785+
env:
786+
APP_ENV: elasticsearch
787+
steps:
788+
- name: Checkout
789+
uses: actions/checkout@v4
790+
- name: Configure sysctl limits
791+
run: |
792+
sudo swapoff -a
793+
sudo sysctl -w vm.swappiness=1
794+
sudo sysctl -w fs.file-max=262144
795+
sudo sysctl -w vm.max_map_count=262144
796+
- name: Runs Elasticsearch
797+
uses: elastic/elastic-github-actions/elasticsearch@master
798+
with:
799+
stack-version: '7.17.0'
800+
security-enabled: false
801+
- name: Setup PHP
802+
uses: shivammathur/setup-php@v2
803+
with:
804+
php-version: ${{ matrix.php }}
805+
tools: pecl, composer
806+
extensions: intl, bcmath, curl, openssl, mbstring, mongodb
807+
coverage: none
808+
ini-values: memory_limit=-1
809+
- name: Get composer cache directory
810+
id: composercache
811+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
812+
- name: Cache dependencies
813+
uses: actions/cache@v4
814+
with:
815+
path: ${{ steps.composercache.outputs.dir }}
816+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
817+
restore-keys: ${{ runner.os }}-composer-
818+
- name: Update project dependencies
819+
run: |
820+
composer global require soyuka/pmu
821+
composer global config allow-plugins.soyuka/pmu true --no-interaction
822+
composer global link .
823+
composer update elasticsearch/elasticsearch --prefer-lowest
824+
- name: Clear test app cache
825+
run: tests/Fixtures/app/console cache:clear --ansi
826+
- name: Run Behat tests
827+
run: vendor/bin/behat --out=std --format=progress --profile=elasticsearch --no-interaction
828+
776829
phpunit-no-deprecations:
777830
name: PHPUnit (PHP ${{ matrix.php }}) (no deprecations)
778831
runs-on: ubuntu-latest

.github/workflows/guides.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
push:
55
pull_request:
66

7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
9+
cancel-in-progress: true
10+
711
env:
812
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
913
COVERAGE: '0'

.php-cs-fixer.dist.php

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
]);
3030

3131
return (new PhpCsFixer\Config())
32-
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
3332
->setRiskyAllowed(true)
3433
->setRules([
3534
'@DoctrineAnnotation' => true,

CHANGELOG.md

+37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## v4.1.0-beta.2
4+
5+
### Bug fixes
6+
7+
* [da37ca91c](https://github.com/api-platform/core/commit/da37ca91c83e4f715c5acbbe3dc0296e8055bebc) fix(laravel): default to file cache instead of cache.default (#6955)
8+
* [e041d721e](https://github.com/api-platform/core/commit/e041d721ea6fe24026eb021905740b25102d7966) fix: errors retrieval and documentation (#6952)
9+
* [e6130cbcc](https://github.com/api-platform/core/commit/e6130cbccc1a8963b731769ef34f39e09f5d2cde) fix: missing filters on swagger ui entrypoint (#6950)
10+
11+
### Features
12+
13+
* [771d9401c](https://github.com/api-platform/core/commit/771d9401cffa0463928bb35ab52a56b269d57e1b) feat(elasticsearch): re-introduce v7 support (#6827)
14+
* [b5372ddee](https://github.com/api-platform/core/commit/b5372ddeef2067333761104f3c17ed1b86001bf4) feat(openapi): filter x-apiplatform-tags to produce different openapi specifications (#6945)
15+
16+
## v4.1.0-beta.1
17+
18+
### Features
19+
20+
* [2e2debb94](https://github.com/api-platform/core/commit/2e2debb94b06752262b0d18b736edc22b501266b) feat(mongodb): Replace usage of deprecated method `AggregationBuilder::execute()` (#6933)
21+
* [4bdf042e5](https://github.com/api-platform/core/commit/4bdf042e5cab1ddb931562cf98a97686d8c415ae) feat(mongodb): Add pagination metadata to the aggregation results (#6912)
22+
* [b968ccd50](https://github.com/api-platform/core/commit/b968ccd5026afb5562c4c4588929885b86ecb3cb) feat(openapi): document error outputs using json-schemas (#6923)
23+
324
## v4.1.0-alpha.2
425

526
### Bug fixes
@@ -39,6 +60,22 @@ On write operations, we added the [expectsHeader](https://www.hydra-cg.com/spec/
3960
* [d0a442786](https://github.com/api-platform/core/commit/d0a44278630d201b91cbba0774a09f4eeaac88f7) feat(doctrine): enhance getLinksHandler with method validation and typo suggestions (#6874)
4061
* [f67f6f1ac](https://github.com/api-platform/core/commit/f67f6f1acb6476182c18a3503f2a8bc80ae89a0b) feat(doctrine): doctrine filters like laravel eloquent filters (#6775)
4162

63+
## v4.0.17
64+
65+
### Bug fixes
66+
67+
* [5124d8c57](https://github.com/api-platform/core/commit/5124d8c571bc4324aa060e4ff808d48f0ffa8d73) fix(laravel): Prevent overwriting existing routes on the router (#6941)
68+
* [5c7e0d2c0](https://github.com/api-platform/core/commit/5c7e0d2c015b5264b2f857abc7e6cb944582de21) fix(symfony): error wrongly inherit normalization context (#6939)
69+
* [af35d34d0](https://github.com/api-platform/core/commit/af35d34d01e62e96dd81dadde6a056ce67d47703) fix(laravel): mitigate property metadata read for Error (#6951)
70+
* [d5b48b1cd](https://github.com/api-platform/core/commit/d5b48b1cd6163ee755211476fdd3d4dd0bf6f7ae) fix(laravel): SwaggerUI custom CSS (#6937)
71+
* [da796b979](https://github.com/api-platform/core/commit/da796b979384663c3eaf4e4fe4d215b447800844) fix(metadata): allow serializer attribute object in ApiProperty::$serialize (#6946)
72+
* [de2d298e3](https://github.com/api-platform/core/commit/de2d298e306b196bce834af290aec242807ea39b) fix: ensure template files have a tpl file extension (#6826) (#6829)
73+
* [b6a67a197](https://github.com/api-platform/core/commit/b6a67a197a668ce15f216cffbcddc637f19c69c2) perf: various optimizations for Laravel/Symfony (#6954)
74+
75+
To save some time during cache warmup we recommend to define uri variables such as: `uriVariables: ['id']`. More details at #6954.
76+
77+
### Features
78+
4279
## v4.0.16
4380

4481
### Bug fixes

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
"doctrine/mongodb-odm": "^2.10",
128128
"doctrine/mongodb-odm-bundle": "^4.0 || ^5.0",
129129
"doctrine/orm": "^2.17 || ^3.0",
130-
"elasticsearch/elasticsearch": "^8.4",
130+
"elasticsearch/elasticsearch": "^7.17 || ^8.4",
131131
"friends-of-behat/mink-browserkit-driver": "^1.3.1",
132132
"friends-of-behat/mink-extension": "^2.2",
133133
"friends-of-behat/symfony-extension": "^2.1",

docs/pdg.config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pdg:
55
src: './guides'
66
references:
77
base_url: '/docs/reference'
8-
exclude: ['*Factory.php', '*.tpl.php', 'deprecation.php']
8+
exclude: ['*Factory.php', '*.php.tpl', 'deprecation.php']
99
exclude_path: ['OpenApi/Tests', 'JsonSchema/Tests', 'RamseyUuid/Tests', 'Metadata/Tests', 'HttpCache/Tests', 'Elasticsearch/Tests', 'Doctrine/Common/Tests', 'GraphQl/Tests', 'Serializer/Tests']
1010
namespace: 'ApiPlatform'
1111
output: 'dist/reference'

features/main/exception_to_status.feature

-5
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,3 @@ Feature: Using exception_to_status config
4545
And I send a "GET" request to "/issue5924"
4646
Then the response status code should be 429
4747
Then the header "retry-after" should be equal to 32
48-
49-
Scenario: Show error page
50-
When I add "Accept" header equal to "text/html"
51-
And I send a "GET" request to "/errors/404"
52-
Then the response status code should be 200

src/Doctrine/Odm/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
],
2626
"require": {
2727
"php": ">=8.2",
28-
"api-platform/doctrine-common": "^3.4 || ^4.0",
28+
"api-platform/doctrine-common": "^4.1",
2929
"api-platform/metadata": "^3.4 || ^4.0",
3030
"api-platform/state": "^3.4 || ^4.0",
3131
"doctrine/mongodb-odm": "^2.2",

src/Doctrine/Orm/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
],
2525
"require": {
2626
"php": ">=8.2",
27-
"api-platform/doctrine-common": "^3.4 || ^4.0",
27+
"api-platform/doctrine-common": "^4.1",
2828
"api-platform/metadata": "^3.4 || ^4.0",
2929
"api-platform/state": "^3.4 || ^4.0",
3030
"doctrine/orm": "^2.17 || ^3.0",

src/Elasticsearch/State/CollectionProvider.php

+13-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
use Elastic\Elasticsearch\Client;
2525
use Elastic\Elasticsearch\Exception\ClientResponseException;
2626
use Elastic\Elasticsearch\Response\Elasticsearch;
27+
use Elasticsearch\Client as V7Client;
28+
use Elasticsearch\Common\Exceptions\Missing404Exception as V7Missing404Exception;
2729
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
2830

2931
/**
@@ -37,8 +39,13 @@ final class CollectionProvider implements ProviderInterface
3739
/**
3840
* @param RequestBodySearchCollectionExtensionInterface[] $collectionExtensions
3941
*/
40-
public function __construct(private readonly Client $client, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?Pagination $pagination = null, private readonly iterable $collectionExtensions = [], private readonly ?InflectorInterface $inflector = new Inflector())
41-
{
42+
public function __construct(
43+
private readonly V7Client|Client $client, // @phpstan-ignore-line
44+
private readonly ?DenormalizerInterface $denormalizer = null,
45+
private readonly ?Pagination $pagination = null,
46+
private readonly iterable $collectionExtensions = [],
47+
private readonly ?InflectorInterface $inflector = new Inflector(),
48+
) {
4249
}
4350

4451
/**
@@ -68,13 +75,15 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
6875
];
6976

7077
try {
71-
$documents = $this->client->search($params);
78+
$documents = $this->client->search($params); // @phpstan-ignore-line
79+
} catch (V7Missing404Exception $e) { // @phpstan-ignore-line
80+
throw new Error(status: $e->getCode(), detail: $e->getMessage(), title: $e->getMessage(), originalTrace: $e->getTrace()); // @phpstan-ignore-line
7281
} catch (ClientResponseException $e) {
7382
$response = $e->getResponse();
7483
throw new Error(status: $response->getStatusCode(), detail: (string) $response->getBody(), title: $response->getReasonPhrase(), originalTrace: $e->getTrace());
7584
}
7685

77-
if ($documents instanceof Elasticsearch) {
86+
if (class_exists(Elasticsearch::class) && $documents instanceof Elasticsearch) {
7887
$documents = $documents->asArray();
7988
}
8089

src/Elasticsearch/State/ItemProvider.php

+11-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
use Elastic\Elasticsearch\Client;
2424
use Elastic\Elasticsearch\Exception\ClientResponseException;
2525
use Elastic\Elasticsearch\Response\Elasticsearch;
26+
use Elasticsearch\Client as V7Client;
27+
use Elasticsearch\Common\Exceptions\Missing404Exception as V7Missing404Exception;
2628
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
2729
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
2830

@@ -34,8 +36,11 @@
3436
*/
3537
final class ItemProvider implements ProviderInterface
3638
{
37-
public function __construct(private readonly Client $client, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?InflectorInterface $inflector = new Inflector())
38-
{
39+
public function __construct(
40+
private readonly V7Client|Client $client, // @phpstan-ignore-line
41+
private readonly ?DenormalizerInterface $denormalizer = null,
42+
private readonly ?InflectorInterface $inflector = new Inflector(),
43+
) {
3944
}
4045

4146
/**
@@ -55,7 +60,9 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
5560
];
5661

5762
try {
58-
$document = $this->client->get($params);
63+
$document = $this->client->get($params); // @phpstan-ignore-line
64+
} catch (V7Missing404Exception) { // @phpstan-ignore-line
65+
return null;
5966
} catch (ClientResponseException $e) {
6067
$response = $e->getResponse();
6168
if (404 === $response->getStatusCode()) {
@@ -65,7 +72,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
6572
throw new Error(status: $response->getStatusCode(), detail: (string) $response->getBody(), title: $response->getReasonPhrase(), originalTrace: $e->getTrace());
6673
}
6774

68-
if ($document instanceof Elasticsearch) {
75+
if (class_exists(Elasticsearch::class) && $document instanceof Elasticsearch) {
6976
$document = $document->asArray();
7077
}
7178

src/Elasticsearch/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"api-platform/metadata": "^3.4 || ^4.0",
2828
"api-platform/serializer": "^3.4 || ^4.0",
2929
"api-platform/state": "^3.4 || ^4.0",
30-
"elasticsearch/elasticsearch": "^8.4",
30+
"elasticsearch/elasticsearch": "^7.17 || ^8.4",
3131
"symfony/cache": "^6.4 || ^7.0",
3232
"symfony/console": "^6.4 || ^7.0",
3333
"symfony/property-access": "^6.4 || ^7.0",

src/JsonSchema/DefinitionNameFactory.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public function create(string $className, string $format = 'json', ?string $inpu
5050
}
5151

5252
$definitionName = $serializerContext[SchemaFactory::OPENAPI_DEFINITION_NAME] ?? null;
53-
if ($definitionName) {
54-
$name = \sprintf('%s-%s', $prefix, $definitionName);
53+
if (null !== $definitionName) {
54+
$name = \sprintf('%s%s', $prefix, $definitionName ? '-'.$definitionName : $definitionName);
5555
} else {
5656
$groups = (array) ($serializerContext[AbstractNormalizer::GROUPS] ?? []);
5757
$name = $groups ? \sprintf('%s-%s', $prefix, implode('_', $groups)) : $prefix;

src/JsonSchema/ResourceMetadataTrait.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ private function findOperation(string $className, string $type, ?Operation $oper
5454
$operation = new HttpOperation();
5555
}
5656

57-
return $this->findOperationForType($resourceMetadataCollection, $type, $operation, $format);
57+
return $this->findOperationForType($resourceMetadataCollection, $type, $operation, $forceSubschema ? null : $format);
5858
}
5959

6060
// The best here is to use an Operation when calling `buildSchema`, we try to do a smart guess otherwise

src/JsonSchema/SchemaFactory.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function buildSchema(string $className, string $format = 'json', string $
6161
$inputOrOutputClass = $className;
6262
$serializerContext ??= [];
6363
} else {
64-
$operation = $this->findOperation($className, $type, $operation, $serializerContext);
64+
$operation = $this->findOperation($className, $type, $operation, $serializerContext, $format);
6565
$inputOrOutputClass = $this->findOutputClass($className, $type, $operation, $serializerContext);
6666
$serializerContext ??= $this->getSerializerContext($operation, $type);
6767
}
@@ -74,7 +74,6 @@ public function buildSchema(string $className, string $format = 'json', string $
7474
$validationGroups = $operation ? $this->getValidationGroups($operation) : [];
7575
$version = $schema->getVersion();
7676
$definitionName = $this->definitionNameFactory->create($className, $format, $inputOrOutputClass, $operation, $serializerContext);
77-
7877
$method = $operation instanceof HttpOperation ? $operation->getMethod() : 'GET';
7978
if (!$operation) {
8079
$method = Schema::TYPE_INPUT === $type ? 'POST' : 'GET';
@@ -291,6 +290,10 @@ private function getFactoryOptions(array $serializerContext, array $validationGr
291290
$options['validation_groups'] = $validationGroups;
292291
}
293292

293+
if ($operation && ($ignoredAttributes = $operation->getNormalizationContext()['ignored_attributes'] ?? null)) {
294+
$options['ignored_attributes'] = $ignoredAttributes;
295+
}
296+
294297
return $options;
295298
}
296299

0 commit comments

Comments
 (0)