Skip to content

Commit 319b69f

Browse files
committed
Added an workaround for issue #862
1 parent c4ba28e commit 319b69f

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
/*
3+
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4+
*
5+
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Affero General Public License as published
9+
* by the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
24+
namespace App\ApiPlatform;
25+
26+
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
27+
use ApiPlatform\Metadata\Property\PropertyNameCollection;
28+
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
29+
use function Symfony\Component\String\u;
30+
31+
/**
32+
* This decorator removes all camelCase property names from the property name collection, if a snake_case version exists.
33+
* This is a fix for https://github.com/Part-DB/Part-DB-server/issues/862, as the openapi schema generator wrongly collects
34+
* both camelCase and snake_case property names, which leads to duplicate properties in the schema.
35+
* This seems to come from the fact that the openapi schema generator uses no serializerContext, which seems then to collect
36+
* the getters too...
37+
*/
38+
#[AsDecorator('api_platform.metadata.property.name_collection_factory')]
39+
class NormalizePropertyNameCollectionFactory implements PropertyNameCollectionFactoryInterface
40+
{
41+
public function __construct(private readonly PropertyNameCollectionFactoryInterface $decorated)
42+
{
43+
}
44+
45+
public function create(string $resourceClass, array $options = []): PropertyNameCollection
46+
{
47+
// Get the default properties from the decorated service
48+
$propertyNames = $this->decorated->create($resourceClass, $options);
49+
50+
//Only become active in the context of the openapi schema generation
51+
if (!isset($options['schema_type'])) {
52+
return $propertyNames;
53+
}
54+
55+
//If we are not in the jsonapi generator (which sets no serializer groups), return the property names as is
56+
if (isset($options['serializer_groups'])) {
57+
return $propertyNames;
58+
}
59+
60+
//Remove all camelCase property names from the collection, if a snake_case version exists
61+
$properties = iterator_to_array($propertyNames);
62+
63+
foreach ($properties as $property) {
64+
if (str_contains($property, '_')) {
65+
$camelized = u($property)->camel()->toString();
66+
67+
//If the camelized version exists, remove it from the collection
68+
$index = array_search($camelized, $properties);
69+
if ($index !== false) {
70+
unset($properties[$index]);
71+
}
72+
}
73+
}
74+
75+
return new PropertyNameCollection($properties);
76+
}
77+
}

0 commit comments

Comments
 (0)