Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* Generated classes include scalar typehints and return type
* Nullable typehints are generated instead of a default `null` value
* Add new `readable` and `writable` options to fields to skip getter or mutator generation.
* A fluent interface isn't generated anymore by default unless you set the `fluentMutatorMethods` config flag to `true`
* Useless PHPDoc (`@param` and `@return` annotations when a typehint exist and mutator description) isn't generated anymore
* `DateTimeInterface` is used instead of `DateTime` when possible
Expand Down
44 changes: 24 additions & 20 deletions src/TypesGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,24 +295,28 @@ public function generate(array $config): void
// Generate ID
if ($config['generateId']) {
foreach ($classes as &$class) {
if (!$class['hasChild'] && !$class['isEnum'] && !$class['embeddable']) {
$class['fields'] = [
'id' => [
'name' => 'id',
'resource' => null,
'range' => 'Integer',
'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1,
'ormColumn' => null,
'isArray' => false,
'isNullable' => false,
'isUnique' => false,
'isCustom' => true,
'isEnum' => false,
'isId' => true,
'typeHint' => 'int',
],
] + $class['fields'];
if ($class['hasChild'] || $class['isEnum'] || $class['embeddable']) {
continue;
}

$class['fields'] = [
'id' => [
'name' => 'id',
'resource' => null,
'range' => 'Integer',
'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1,
'ormColumn' => null,
'isArray' => false,
'isReadable' => true,
'isWritable' => false,
'isNullable' => false,
'isUnique' => false,
'isCustom' => true,
'isEnum' => false,
'isId' => true,
'typeHint' => 'int',
],
] + $class['fields'];
}
}

Expand Down Expand Up @@ -593,8 +597,6 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t
$cardinality = $property ? $this->cardinalities[$propertyName] : CardinalitiesExtractor::CARDINALITY_1_1;
}

$ormColumn = $propertyConfig['ormColumn'] ?? null;

$isArray = in_array($cardinality, [
CardinalitiesExtractor::CARDINALITY_0_N,
CardinalitiesExtractor::CARDINALITY_1_N,
Expand Down Expand Up @@ -622,8 +624,10 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t
'resource' => $property,
'range' => $ranges[0],
'cardinality' => $cardinality,
'ormColumn' => $ormColumn,
'ormColumn' => $propertyConfig['ormColumn'] ?? null,
'isArray' => $isArray,
'isReadable' => $propertyConfig['readable'] ?? true,
'isWritable' => $propertyConfig['writable'] ?? true,
'isNullable' => $isNullable,
'isUnique' => isset($propertyConfig['unique']) && $propertyConfig['unique'],
'isCustom' => empty($property),
Expand Down
6 changes: 4 additions & 2 deletions src/TypesGeneratorConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,10 @@ function ($rdfa) {
->info('Symfony Serialization Groups')
->prototype('scalar')->end()
->end()
->scalarNode('nullable')->defaultTrue()->info('The property nullable')->end()
->scalarNode('unique')->defaultFalse()->info('The property unique')->end()
->booleanNode('readable')->defaultTrue()->info('Is the property readable?')->end()
->booleanNode('writable')->defaultTrue()->info('Is the property writable?')->end()
->booleanNode('nullable')->defaultTrue()->info('Is the property nullable?')->end()
->booleanNode('unique')->defaultFalse()->info('The property unique')->end()
->booleanNode('embedded')->defaultFalse()->info('Is the property embedded?')->end()
->booleanNode('columnPrefix')->defaultFalse()->info('The property columnPrefix')->end()
->end()
Expand Down
4 changes: 4 additions & 0 deletions templates/class.php.twig
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ use {{ use }};

{% if config.accessorMethods %}
{% for field in class.fields %}
{% if field.isWritable %}
{% if field.isArray %}
/**
{% for annotation in field.adderAnnotations %}
Expand Down Expand Up @@ -112,7 +113,9 @@ use {{ use }};
{% endif %}
}
{% endif %}
{% endif %}

{% if field.isReadable %}
/**
{% for annotation in field.getterAnnotations %}
* {{ annotation }}
Expand All @@ -123,6 +126,7 @@ use {{ use }};
return $this->{{ field.name }};
}

{% endif %}
{% endfor %}
{% endif %}
}
8 changes: 7 additions & 1 deletion tests/Command/DumpConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,13 @@ interface: null
# Symfony Serialization Groups
groups: []

# The property nullable
# Is the property readable?
readable: true

# Is the property writable?
writable: true

# Is the property nullable?
nullable: true

# The property unique
Expand Down
33 changes: 26 additions & 7 deletions tests/Command/GenerateTypesCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ public function testDoctrineCollection()
$this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config]));

$person = file_get_contents($outputDir.'/AddressBook/Entity/Person.php');

$this->assertContains('use Doctrine\Common\Collections\ArrayCollection;', $person);
$this->assertContains('use Doctrine\Common\Collections\Collection;', $person);

Expand All @@ -86,8 +85,8 @@ public function testFluentMutators()
$this->fs->mkdir($outputDir);
$commandTester = new CommandTester(new GenerateTypesCommand());
$this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config]));
$person = file_get_contents($outputDir.'/AppBundle/Entity/Person.php');

$person = file_get_contents($outputDir.'/AppBundle/Entity/Person.php');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question : Why concatenation here instead of sprintf method ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it's already easy to read and it's faster (even if it doesn't matter much in a test). The fastest solution in PHP 7 would be file_get_contents("$outputDir/AppBundle/Entity/Person.php");

$this->assertContains(<<<'PHP'
public function setUrl(?string $url): self
{
Expand Down Expand Up @@ -126,10 +125,30 @@ public function testDoNotGenerateAccessorMethods()
$commandTester = new CommandTester(new GenerateTypesCommand());
$this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config]));

$organization = file_get_contents($outputDir.'/AppBundle/Entity/Person.php');
$this->assertNotContains('function get', $organization);
$this->assertNotContains('function set', $organization);
$this->assertNotContains('function add', $organization);
$this->assertNotContains('function remove', $organization);
$person = file_get_contents($outputDir.'/AppBundle/Entity/Person.php');
$this->assertNotContains('function get', $person);
$this->assertNotContains('function set', $person);
$this->assertNotContains('function add', $person);
$this->assertNotContains('function remove', $person);
}

public function testReadableWritable()
{
$outputDir = __DIR__.'/../../build/readable-writable';
$config = __DIR__.'/../config/readable-writable.yaml';

$this->fs->mkdir($outputDir);

$commandTester = new CommandTester(new GenerateTypesCommand());
$this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config]));

$person = file_get_contents($outputDir.'/AppBundle/Entity/Person.php');
$this->assertContains('function getId(', $person);
$this->assertNotContains('function setId(', $person);
$this->assertContains('function getName(', $person);
$this->assertNotContains('function setName(', $person);
$this->assertContains('function getFriends(', $person);
$this->assertNotContains('function addFriends(', $person);
$this->assertNotContains('function removeFriends(', $person);
}
}
27 changes: 24 additions & 3 deletions tests/TypesGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace ApiPlatform\SchemaGenerator\Tests;

use ApiPlatform\SchemaGenerator\CardinalitiesExtractor;
use ApiPlatform\SchemaGenerator\GoodRelationsBridge;
use ApiPlatform\SchemaGenerator\TypesGenerator;
use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration;
use PHPUnit\Framework\TestCase;
Expand All @@ -27,19 +28,19 @@ class TypesGeneratorTest extends TestCase
{
public function testGenerate(): void
{
$twigProphecy = $this->prophesize('Twig_Environment');
$twigProphecy = $this->prophesize(\Twig_Environment::class);
foreach ($this->getClasses() as $class) {
$twigProphecy->render('class.php.twig', Argument::that($this->getContextMatcher($class)))->willReturn()->shouldBeCalled();
}
$twigProphecy->render('class.php.twig', Argument::type('array'))->willReturn();
$twig = $twigProphecy->reveal();

$cardinalitiesExtractorProphecy = $this->prophesize('ApiPlatform\SchemaGenerator\CardinalitiesExtractor');
$cardinalitiesExtractorProphecy = $this->prophesize(CardinalitiesExtractor::class);
$cardinalities = $this->getCardinalities();
$cardinalitiesExtractorProphecy->extract()->willReturn($cardinalities)->shouldBeCalled();
$cardinalitiesExtractor = $cardinalitiesExtractorProphecy->reveal();

$goodRelationsBridgeProphecy = $this->prophesize('ApiPlatform\SchemaGenerator\GoodRelationsBridge');
$goodRelationsBridgeProphecy = $this->prophesize(GoodRelationsBridge::class);
$goodRelationsBridge = $goodRelationsBridgeProphecy->reveal();

$typesGenerator = new TypesGenerator($twig, new NullLogger(), $this->getGraphs(), $cardinalitiesExtractor, $goodRelationsBridge);
Expand Down Expand Up @@ -190,6 +191,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'articleBody',
Expand All @@ -201,6 +204,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'articleSection',
Expand All @@ -223,6 +228,8 @@ private function getClasses(): array
'isCustom' => true,
'isEnum' => false,
'isId' => true,
'isReadable' => true,
'isWritable' => true,
'isNullable' => false,
'isUnique' => false,
'name' => 'id',
Expand All @@ -245,6 +252,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'author',
Expand All @@ -256,6 +265,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'datePublished',
Expand All @@ -267,6 +278,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'headline',
Expand All @@ -278,6 +291,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'isFamilyFriendly',
Expand All @@ -300,6 +315,8 @@ private function getClasses(): array
'isCustom' => true,
'isEnum' => false,
'isId' => true,
'isReadable' => true,
'isWritable' => true,
'isNullable' => false,
'isUnique' => false,
'name' => 'id',
Expand All @@ -322,6 +339,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'sharedContent',
Expand All @@ -344,6 +363,8 @@ private function getClasses(): array
'isCustom' => false,
'isEnum' => false,
'isId' => false,
'isReadable' => true,
'isWritable' => true,
'isNullable' => true,
'isUnique' => false,
'name' => 'name',
Expand Down
9 changes: 9 additions & 0 deletions tests/config/readable-writable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
rdfa: [{ uri: tests/data/schema.rdfa, format: rdfa }]
relations: [tests/data/v1.owl]

types:
Person:
properties:
name: { writable: false }
familyName: { readable: false }
friends: { range: "Person", cardinality: (0..*), writable: false }