Skip to content

Commit 6fa2172

Browse files
committed
generate setter for simple arrays
1 parent c50ccf5 commit 6fa2172

File tree

11 files changed

+93
-57
lines changed

11 files changed

+93
-57
lines changed

phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ parameters:
6161
author: false|string,
6262
fieldVisibility: 'private'|'protected'|'public'|null,
6363
accessorMethods: boolean,
64+
useSimpleArraySetter: boolean,
6465
fluentMutatorMethods: boolean,
6566
rangeMapping: array<string, string>,
6667
allTypes: boolean,

src/Model/Class_.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFi
218218
{
219219
$useDoctrineCollections = $config['doctrine']['useCollection'];
220220
$useAccessors = $config['accessorMethods'];
221+
$useSimpleArraySetter = $config['useSimpleArraySetter'];
221222
$useFluentMutators = $config['fluentMutatorMethods'];
222223
$fileHeader = $config['header'] ?? null;
223224
$fieldVisibility = $config['fieldVisibility'];
@@ -333,7 +334,7 @@ public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFi
333334
foreach ($sortedProperties as $property) {
334335
foreach ($property->generateNetteMethods(static function ($string) use ($inflector) {
335336
return $inflector->singularize($string)[0];
336-
}, $namespace, $useDoctrineCollections, $useFluentMutators) as $method) {
337+
}, $namespace, $useDoctrineCollections, $useFluentMutators, $useSimpleArraySetter) as $method) {
337338
$methods[] = $method;
338339
}
339340
}

src/Model/Property.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ public function isArray(): bool
8181
return $this->type instanceof ArrayType;
8282
}
8383

84+
public function isSimpleArray(): bool
85+
{
86+
return 'array' === $this->typeHint;
87+
}
88+
8489
public function addAnnotation(string $annotation): self
8590
{
8691
if ('' === $annotation || !\in_array($annotation, $this->annotations, true)) {
@@ -154,7 +159,7 @@ public function toNetteProperty(PhpNamespace $namespace, ?string $visibility = n
154159
$property->setType($this->resolveName($namespace, $this->typeHint));
155160
}
156161

157-
if (!$this->isArray() || $this->isTypeHintedAsCollection()) {
162+
if (!$this->isArray() || $this->isSimpleArray() || $this->isTypeHintedAsCollection()) {
158163
$property->setNullable($this->isNullable);
159164
}
160165

@@ -195,9 +200,10 @@ public function generateNetteMethods(
195200
PhpNamespace $namespace,
196201
bool $useDoctrineCollections = true,
197202
bool $useFluentMutators = false,
203+
bool $useSimpleArraySetter = false,
198204
): array {
199205
return array_merge(
200-
$this->generateMutators($singularize, $namespace, $useDoctrineCollections, $useFluentMutators),
206+
$this->generateMutators($singularize, $namespace, $useDoctrineCollections, $useFluentMutators, $useSimpleArraySetter),
201207
$this->isReadable ? [$this->generateGetter($namespace)] : []
202208
);
203209
}
@@ -214,7 +220,7 @@ private function generateGetter(PhpNamespace $namespace): Method
214220
}
215221
if ($this->typeHint) {
216222
$getter->setReturnType($this->resolveName($namespace, $this->typeHint));
217-
if ($this->isNullable && !$this->isArray()) {
223+
if ($this->isNullable && (!$this->isArray() || $this->isSimpleArray())) {
218224
$getter->setReturnNullable();
219225
}
220226
}
@@ -231,13 +237,14 @@ private function generateMutators(
231237
PhpNamespace $namespace,
232238
bool $useDoctrineCollections = true,
233239
bool $useFluentMutators = false,
240+
bool $useSimpleArraySetter = false,
234241
): array {
235242
if (!$this->isWritable) {
236243
return [];
237244
}
238245

239246
$mutators = [];
240-
if ($this->isArray()) {
247+
if ($this->isArray() && (!$this->isSimpleArray() || !$useSimpleArraySetter)) {
241248
$singularProperty = $singularize($this->name());
242249

243250
$adder = (new Method('add'.ucfirst($singularProperty)))->setVisibility(ClassType::VISIBILITY_PUBLIC);

src/SchemaGeneratorConfiguration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ public function getConfigTreeBuilder(): TreeBuilder
167167
->scalarNode('author')->defaultFalse()->info('The value of the phpDoc\'s @author annotation')->example('Kévin Dunglas <dunglas@gmail.com>')->end()
168168
->enumNode('fieldVisibility')->values(['private', 'protected', 'public'])->defaultValue('private')->cannotBeEmpty()->info('Visibility of entities fields')->end()
169169
->booleanNode('accessorMethods')->defaultTrue()->info('Set this flag to false to not generate getter, setter, adder and remover methods')->end()
170+
->booleanNode('useSimpleArraySetter')->defaultFalse()->info('Set this flag to true to generate setter method for simple arrays instead of adder and remover methods')->end()
170171
->booleanNode('fluentMutatorMethods')->defaultFalse()->info('Set this flag to true to generate fluent setter, adder and remover methods')->end()
171172
->arrayNode('rangeMapping')
172173
->useAttributeAsKey('name')

tests/Command/DumpConfigurationTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ interface: App\Model # Example: App\Model
154154
# Set this flag to false to not generate getter, setter, adder and remover methods
155155
accessorMethods: true
156156
157+
# Set this flag to true to generate setter method for simple arrays instead of adder and remover methods
158+
useSimpleArraySetter: false
159+
157160
# Set this flag to true to generate fluent setter, adder and remover methods
158161
fluentMutatorMethods: false
159162
rangeMapping:
@@ -275,8 +278,7 @@ interface: null
275278
generatorTemplates: []
276279

277280

278-
YAML
279-
,
281+
YAML,
280282
$commandTester->getDisplay()
281283
);
282284
}

tests/Command/ExtractCardinalitiesCommandTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,6 @@ public function testExtractCardinalities(): void
14751475
"https:\/\/schema.org\/mainEntityOfPage": "unknown"
14761476
}
14771477

1478-
JSON
1479-
, $commandTester->getDisplay());
1478+
JSON, $commandTester->getDisplay());
14801479
}
14811480
}

tests/Command/GenerateCommandTest.php

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ public function getFriends(): Collection
7070
{
7171
return $this->friends;
7272
}
73-
PHP
74-
, $person);
73+
PHP, $person);
7574
}
7675

7776
public function testCustomAttributes(): void
@@ -106,29 +105,24 @@ public function testCustomAttributes(): void
106105
#[MyAttribute]
107106
class Book
108107
{
109-
PHP
110-
, $book);
108+
PHP, $book);
111109

112110
// Attributes given as unordered map.
113111
$this->assertStringContainsString(<<<'PHP'
114112
#[ORM\OneToMany(targetEntity: 'App\Entity\Review', mappedBy: 'book', cascade: ['persist', 'remove'])]
115-
PHP
116-
, $book);
113+
PHP, $book);
117114
$this->assertStringContainsString(<<<'PHP'
118115
#[ORM\OrderBy(name: 'ASC')]
119-
PHP
120-
, $book);
116+
PHP, $book);
121117
// Generated attribute could be merged with next one that is a configured one.
122118
$this->assertStringContainsString(<<<'PHP'
123119
#[ORM\InverseJoinColumn(nullable: false, unique: true, name: 'first_join_column')]
124-
PHP
125-
, $book);
120+
PHP, $book);
126121
// Configured attribute could not be merged with next one and it is treated
127122
// as repeated.
128123
$this->assertStringContainsString(<<<'PHP'
129124
#[ORM\InverseJoinColumn(name: 'second_join_column')]
130-
PHP
131-
, $book);
125+
PHP, $book);
132126
}
133127

134128
public function testFluentMutators(): void
@@ -147,8 +141,7 @@ public function setUrl(?string $url): self
147141
148142
return $this;
149143
}
150-
PHP
151-
, $person);
144+
PHP, $person);
152145

153146
$this->assertStringContainsString(<<<'PHP'
154147
public function addFriend(Person $friend): self
@@ -164,8 +157,7 @@ public function removeFriend(Person $friend): self
164157
165158
return $this;
166159
}
167-
PHP
168-
, $person);
160+
PHP, $person);
169161
}
170162

171163
public function testDoNotGenerateAccessorMethods(): void
@@ -230,8 +222,7 @@ public function testPropertyDefault(): void
230222

231223
$this->assertStringContainsString(<<<'PHP'
232224
private string $availability = 'https://schema.org/InStock';
233-
PHP
234-
, $book);
225+
PHP, $book);
235226
}
236227

237228
public function testReadableWritable(): void
@@ -274,16 +265,14 @@ public function testGeneratedId(): void
274265
#[ORM\GeneratedValue(strategy: 'AUTO')]
275266
#[ORM\Column(type: 'integer')]
276267
private ?int $id = null;
277-
PHP
278-
, $person);
268+
PHP, $person);
279269

280270
$this->assertStringContainsString(<<<'PHP'
281271
public function getId(): ?int
282272
{
283273
return $this->id;
284274
}
285-
PHP
286-
, $person);
275+
PHP, $person);
287276

288277
$this->assertStringNotContainsString('setId(', $person);
289278
}
@@ -304,24 +293,21 @@ public function testNonGeneratedId(): void
304293
#[ORM\Id]
305294
#[ORM\Column(type: 'string')]
306295
private string $id;
307-
PHP
308-
, $person);
296+
PHP, $person);
309297

310298
$this->assertStringContainsString(<<<'PHP'
311299
public function getId(): string
312300
{
313301
return $this->id;
314302
}
315-
PHP
316-
, $person);
303+
PHP, $person);
317304

318305
$this->assertStringContainsString(<<<'PHP'
319306
public function setId(string $id): void
320307
{
321308
$this->id = $id;
322309
}
323-
PHP
324-
, $person);
310+
PHP, $person);
325311
}
326312

327313
public function testGeneratedUuid(): void
@@ -342,16 +328,14 @@ public function testGeneratedUuid(): void
342328
#[ORM\Column(type: 'guid')]
343329
#[Assert\Uuid]
344330
private ?string $id = null;
345-
PHP
346-
, $person);
331+
PHP, $person);
347332

348333
$this->assertStringContainsString(<<<'PHP'
349334
public function getId(): ?string
350335
{
351336
return $this->id;
352337
}
353-
PHP
354-
, $person);
338+
PHP, $person);
355339

356340
$this->assertStringNotContainsString('setId(', $person);
357341
}
@@ -373,25 +357,22 @@ public function testNonGeneratedUuid(): void
373357
#[ORM\Column(type: 'guid')]
374358
#[Assert\Uuid]
375359
private string $id;
376-
PHP
377-
, $person);
360+
PHP, $person);
378361

379362
$this->assertStringContainsString(<<<'PHP'
380363
public function getId(): string
381364
{
382365
return $this->id;
383366
}
384-
PHP
385-
, $person);
367+
PHP, $person);
386368

387369
$this->assertStringContainsString(<<<'PHP'
388370
public function setId(string $id): void
389371
{
390372
$this->id = $id;
391373
}
392374

393-
PHP
394-
, $person);
375+
PHP, $person);
395376
}
396377

397378
public function testDoNotGenerateId(): void
@@ -463,8 +444,7 @@ public function testGeneratedEnum(): void
463444
$this->assertStringContainsString(<<<'PHP'
464445
/** @var string The female gender. */
465446
public const FEMALE = 'https://schema.org/Female';
466-
PHP
467-
, $gender);
447+
PHP, $gender);
468448

469449
$this->assertStringNotContainsString('function setId(', $gender);
470450
}
@@ -490,8 +470,7 @@ public function testSupersededProperties(): void
490470
#[ORM\Column(type: 'text', nullable: true)]
491471
#[ApiProperty(types: ['https://schema.org/award'])]
492472
private ?string $award = null;
493-
PHP
494-
, $creativeWork);
473+
PHP, $creativeWork);
495474

496475
$this->assertStringNotContainsString('protected', $creativeWork);
497476
}
@@ -517,8 +496,7 @@ public function testActivityStreams(): void
517496
#[ORM\Column(type: 'text', nullable: true, name: '`content`')]
518497
#[ApiProperty(types: ['http://www.w3.org/ns/activitystreams#content'])]
519498
private ?string $content = null;
520-
PHP
521-
, $object);
499+
PHP, $object);
522500

523501
$page = file_get_contents("$outputDir/App/Entity/Page.php");
524502

@@ -531,13 +509,47 @@ public function testActivityStreams(): void
531509
#[ORM\Entity]
532510
#[ApiResource(types: ['http://www.w3.org/ns/activitystreams#Page'], routePrefix: 'as')]
533511
class Page extends Object_
534-
PHP
535-
, $page);
512+
PHP, $page);
536513

537514
self::assertFalse($this->fs->exists("$outputDir/App/Entity/Delete.php"));
538515
self::assertFalse($this->fs->exists("$outputDir/App/Entity/Travel.php"));
539516
}
540517

518+
public function testGeneratedSimpleArray(): void
519+
{
520+
$outputDir = __DIR__.'/../../build/simple-array';
521+
$config = __DIR__.'/../config/simple-array.yaml';
522+
523+
$this->fs->mkdir($outputDir);
524+
525+
$commandTester = new CommandTester(new GenerateCommand());
526+
$this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config]));
527+
$source = file_get_contents("$outputDir/App/Entity/Project.php");
528+
529+
$this->assertStringContainsString(<<<'PHP'
530+
/**
531+
* @see _:shareWith
532+
*/
533+
#[ORM\Column(type: 'simple_array', nullable: true)]
534+
#[Assert\Unique]
535+
private ?array $shareWith = [];
536+
PHP, $source);
537+
538+
$this->assertStringContainsString(<<<'PHP'
539+
public function setShareWith(?array $shareWith): void
540+
{
541+
$this->shareWith = $shareWith;
542+
}
543+
544+
public function getShareWith(): ?array
545+
{
546+
return $this->shareWith;
547+
}
548+
PHP, $source);
549+
$this->assertStringNotContainsString('function addShareWith', $source);
550+
$this->assertStringNotContainsString('function removeShareWith', $source);
551+
}
552+
541553
public function testGenerationWithoutConfigFileQuestion(): void
542554
{
543555
// No config file is given.

tests/TypesGeneratorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function testGenerate(): void
105105
$article = file_get_contents("$this->outputDir/App/Entity/Article.php");
106106
$this->assertStringContainsString('abstract class Article extends CreativeWork', $article);
107107
$this->assertStringContainsString('private ?string $articleBody = null;', $article);
108-
$this->assertStringContainsString('private array $articleSection = [];', $article);
108+
$this->assertStringContainsString('private ?array $articleSection = [];', $article);
109109
$this->assertStringContainsString('public function setArticleBody(?string $articleBody): void', $article);
110110
$this->assertStringContainsString('public function getArticleBody(): ?string', $article);
111111
$this->assertStringContainsString('public function addArticleSection(string $articleSection): void', $article);

tests/config/simple-array.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
useSimpleArraySetter: true
2+
types:
3+
Project:
4+
properties:
5+
name:
6+
range: "https://schema.org/Text"
7+
shareWith:
8+
range: "https://schema.org/email"
9+
cardinality: "(0..*)"
10+
attributes:
11+
Assert\Unique: ~
12+
ORM\Column: { type: "simple_array" }

0 commit comments

Comments
 (0)