Skip to content

Commit 7e8c466

Browse files
authored
Merge pull request #98 from dunglas/plural
Use singular for adders and removers (Symfony PropertyAccess compat)
2 parents 861eced + 64a065f commit 7e8c466

File tree

9 files changed

+38
-27
lines changed

9 files changed

+38
-27
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 2.0
44

55
* Generated classes include scalar typehints and return type
6+
* New options to generate autoincremented IDs, UUIDs, custom IDs or to not generate IDs at all (DTO)
67
* Nullable typehints are generated instead of a default `null` value
78
* Add new `readable` and `writable` options to fields to skip getter or mutator generation.
89
* A fluent interface isn't generated anymore by default unless you set the `fluentMutatorMethods` config flag to `true`
@@ -13,6 +14,8 @@
1314
* The annotation generator for API Platform v1 has been dropped. Only API Platform v2 is now supported.
1415
* Parent class is not generated by default anymore (using inheritance for entity is discouraged)
1516
* `SerializerGroupsAnnotationGenerator` is enabled by default
17+
* The property name is pluralized for `to-many` relations and singularized for `to-one` relations
18+
* Adder and remover methods are always singularized to be compatible with the Symfony Property Accessor
1619
* The code has been modernized to use PHP 7 and 7.1's new features (typehints, strict types), PHP 7.1 is now a requirement
1720
* PHP CS Fixer has ben upgraded to its version 2
1821

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
},
2020
"require": {
2121
"php": ">=7.1",
22+
"doctrine/inflector": "^1.0",
2223
"easyrdf/easyrdf": "^0.9",
2324
"ext-json": "*",
2425
"friendsofphp/php-cs-fixer": "^2.4",

src/AnnotationGenerator/PhpDocAnnotationGenerator.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\SchemaGenerator\AnnotationGenerator;
1515

16+
use Doctrine\Common\Util\Inflector;
1617
use League\HTMLToMarkdown\HtmlConverter;
1718
use Psr\Log\LoggerInterface;
1819

@@ -106,7 +107,9 @@ public function generateSetterAnnotations(string $className, string $fieldName):
106107
return [];
107108
}
108109

109-
return [sprintf('@param %s $%s', $this->toPhpDocType($this->classes[$className]['fields'][$fieldName]), $fieldName)];
110+
$field = $this->classes[$className]['fields'][$fieldName];
111+
112+
return [sprintf('@param %s $%s', $this->toPhpDocType($this->classes[$className]['fields'][$fieldName]), $field['name'])];
110113
}
111114

112115
/**
@@ -118,7 +121,7 @@ public function generateAdderAnnotations(string $className, string $fieldName):
118121
return [];
119122
}
120123

121-
return [sprintf('@param %s $%s', $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), $fieldName)];
124+
return [sprintf('@param %s $%s', $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), Inflector::singularize($fieldName))];
122125
}
123126

124127
/**
@@ -130,7 +133,7 @@ public function generateRemoverAnnotations(string $className, string $fieldName)
130133
return [];
131134
}
132135

133-
return [sprintf('@param %s $%s', $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), $fieldName)];
136+
return [sprintf('@param %s $%s', $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), Inflector::singularize($fieldName))];
134137
}
135138

136139
private function isDocUseful(string $className, string $fieldName, $adderOrRemover = false): bool

src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* Symfony Serializer Groups annotation generator.
2020
*
2121
* @author Youssef El Montaser <[email protected]>
22+
* @author Kévin Dunglas <[email protected]>
2223
*
2324
* @see https://symfony.com/doc/master/components/serializer.html
2425
*/
@@ -29,15 +30,15 @@ final class SerializerGroupsAnnotationGenerator extends AbstractAnnotationGenera
2930
*/
3031
public function generateFieldAnnotations(string $className, string $fieldName): array
3132
{
32-
$annotations = [];
33-
34-
$properties = $this->config['types'][$className]['properties'];
33+
if (null === $field = $this->config['types'][$className]['properties'] ?? null) {
34+
return [];
35+
}
3536

36-
if (false === $this->classes[$className]['fields'][$fieldName]['isId'] && $groups = $properties[$fieldName]['groups'] ?? false) {
37-
$annotations[] = sprintf('@Groups({"%s"})', implode('","', $groups));
37+
if (false === $this->classes[$className]['fields'][$fieldName]['isId'] && $groups = $field[$fieldName]['groups'] ?? false) {
38+
return [sprintf('@Groups({"%s"})', implode('", "', $groups))];
3839
}
3940

40-
return $annotations;
41+
return [];
4142
}
4243

4344
/**

src/Command/GenerateTypesCommand.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\SchemaGenerator\GoodRelationsBridge;
1818
use ApiPlatform\SchemaGenerator\TypesGenerator;
1919
use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration;
20+
use Doctrine\Common\Util\Inflector;
2021
use Symfony\Component\Config\Definition\Processor;
2122
use Symfony\Component\Console\Command\Command;
2223
use Symfony\Component\Console\Input\InputArgument;
@@ -86,10 +87,11 @@ protected function execute(InputInterface $input, OutputInterface $output): void
8687
$goodRelationsBridge = new GoodRelationsBridge($relations);
8788
$cardinalitiesExtractor = new CardinalitiesExtractor($graphs, $goodRelationsBridge);
8889

89-
$ucfirstFilter = new \Twig_SimpleFilter('ucfirst', 'ucfirst');
9090
$loader = new \Twig_Loader_Filesystem(__DIR__.'/../../templates/');
9191
$twig = new \Twig_Environment($loader, ['autoescape' => false, 'debug' => $processedConfiguration['debug']]);
92-
$twig->addFilter($ucfirstFilter);
92+
$twig->addFilter(new \Twig_SimpleFilter('ucfirst', 'ucfirst'));
93+
$twig->addFilter(new \Twig_SimpleFilter('pluralize', [Inflector::class, 'pluralize']));
94+
$twig->addFilter(new \Twig_SimpleFilter('singularize', [Inflector::class, 'singularize']));
9395

9496
if ($processedConfiguration['debug']) {
9597
$twig->addExtension(new \Twig_Extension_Debug());

src/TypesGenerator.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\SchemaGenerator\AnnotationGenerator\AnnotationGeneratorInterface;
1717
use Doctrine\Common\Collections\ArrayCollection;
1818
use Doctrine\Common\Collections\Collection;
19+
use Doctrine\Common\Util\Inflector;
1920
use MyCLabs\Enum\Enum;
2021
use PhpCsFixer\Cache\NullCacheManager;
2122
use PhpCsFixer\Differ\NullDiffer;
@@ -647,7 +648,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t
647648
}
648649

649650
$class['fields'][$propertyName] = [
650-
'name' => $propertyName,
651+
'name' => $isArray ? Inflector::pluralize($propertyName) : Inflector::singularize($propertyName),
651652
'resource' => $property,
652653
'range' => $ranges[0],
653654
'cardinality' => $cardinality,

templates/class.php.twig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
#}
77
<?php
88
9-
{% if config.header %}{{ config.header }}{% endif %}
10-
9+
{% if config.header %}{{ config.header }}
10+
{% endif %}
1111
declare(strict_types=1);
1212
1313
namespace {{ class.namespace }};
@@ -68,9 +68,9 @@ use {{ use }};
6868
* {{ annotation }}
6969
{% endfor %}
7070
*/
71-
public function add{{ field.name|ucfirst }}({% if field.typeHint and not field.isEnum %}{{ field.adderRemoverTypeHint }} {% endif %}${{ field.name }}): {% if config.fluentMutatorMethods %}self{% else %}void{% endif %}
71+
public function add{{ field.name|singularize|ucfirst }}({% if field.typeHint and not field.isEnum %}{{ field.adderRemoverTypeHint }} {% endif %}${{ field.name|singularize }}): {% if config.fluentMutatorMethods %}self{% else %}void{% endif %}
7272
{
73-
$this->{{ field.name }}[] = {% if field.isEnum %}(string) {% endif %}${{ field.name }};
73+
$this->{{ field.name }}[] = {% if field.isEnum %}(string) {% endif %}${{ field.name|singularize }};
7474
{% if config.fluentMutatorMethods %}
7575
7676
return $this;
@@ -82,12 +82,12 @@ use {{ use }};
8282
* {{ annotation }}
8383
{% endfor %}
8484
*/
85-
public function remove{{ field.name|ucfirst }}({% if field.typeHint %}{{ field.adderRemoverTypeHint }} {% endif %}${{ field.name }}): {% if config.fluentMutatorMethods %}self{% else %}void{% endif %}
85+
public function remove{{ field.name|singularize|ucfirst }}({% if field.typeHint %}{{ field.adderRemoverTypeHint }} {% endif %}${{ field.name|singularize }}): {% if config.fluentMutatorMethods %}self{% else %}void{% endif %}
8686
{
8787
{% if config.doctrine.useCollection and field.isArray and field.typeHint and not field.isEnum %}
88-
$this->{{ field.name }}->removeElement({% if field.isEnum %}(string) {% endif %}${{ field.name }});
88+
$this->{{ field.name }}->removeElement({% if field.isEnum %}(string) {% endif %}${{ field.name|singularize }});
8989
{% else %}
90-
$key = array_search({% if field.isEnum %}(string) {% endif %}${{ field.name }}, $this->{{ field.name }}, true);
90+
$key = array_search({% if field.isEnum %}(string) {% endif %}${{ field.name|singularize }}, $this->{{ field.name }}, true);
9191
if (false !== $key) {
9292
unset($this->{{ field.name }}[$key]);
9393
}

templates/interface.php.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
#}
77
<?php
88
9-
{% if config.header %}{{ config.header }}{% endif %}
10-
9+
{% if config.header %}{{ config.header }}
10+
{% endif %}
1111
declare(strict_types=1);
1212
1313
namespace {{ class.interfaceNamespace }};

tests/Command/GenerateTypesCommandTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,16 @@ public function setUrl(?string $url): self
9898
, $person);
9999

100100
$this->assertContains(<<<'PHP'
101-
public function addFriends(Person $friends): self
101+
public function addFriend(Person $friend): self
102102
{
103-
$this->friends[] = $friends;
103+
$this->friends[] = $friend;
104104
105105
return $this;
106106
}
107107
108-
public function removeFriends(Person $friends): self
108+
public function removeFriend(Person $friend): self
109109
{
110-
$this->friends->removeElement($friends);
110+
$this->friends->removeElement($friend);
111111
112112
return $this;
113113
}
@@ -148,8 +148,8 @@ public function testReadableWritable()
148148
$this->assertContains('public function getName(', $person);
149149
$this->assertNotContains('function setName(', $person);
150150
$this->assertContains('public function getFriends(', $person);
151-
$this->assertNotContains('function addFriends(', $person);
152-
$this->assertNotContains('function removeFriends(', $person);
151+
$this->assertNotContains('function addFriend(', $person);
152+
$this->assertNotContains('function removeFriend(', $person);
153153
}
154154

155155
public function testGeneratedId()

0 commit comments

Comments
 (0)