Skip to content

Commit d6d0391

Browse files
committed
feature #104 make:entity improved: interactive field created & entity update support (weaverryan)
This PR was squashed before being merged into the 1.0-dev branch (closes #104). Discussion ---------- make:entity improved: interactive field created & entity update support Hi guys! The PR we (or at least me) have been waiting for :). This makes `make:entity` behave similar to `doctrine:generate:entity` from SensioGeneratorBundle: it interactively asks you for the field names and generates the getters/setters... but with some improved UX. ## Features: * Ability to create new entities & fields * Ability to update *existing* entities 🎆 * Support for adding *relations* (double 🎆) * A `--regenerate` flag to add getters/setters for existing properties (replaces `doctrine:generate:entities`) * Generates code that passes phpcs Please help test! It's easy: [composer require details to for testing](https://gist.github.com/weaverryan/a20fc281ccd1faea2ea04a5da7fdaa55) ## Blocker 😢 We're using the newest version of `nikic/php-parser` heavily... but it only has a *beta* release so far :(. We need to wait until this is stable. OR, we need to remove it as a dependency temporarily, then throw an error to tell people to install it manually (at the beta version). :/ nikic/PHP-Parser#474 ## Important notes: * I bumped the min php version to 7.1 (from 7.0). This was so that we could consistently generated code using nullable types. * Some of the code generated for relationships is opinionated. For example, I automatically synchronize (i.e. by calling the setter) the *owning* side if you set data on the inverse side of the relation. I also make all relation return types nullable (even if the relation is required in the db), to be friendly in case they're not set yet. * The setters are not fluent. We *could* make them fluent, or make that an option on the bundle (i.e. one in a config file, not asked interactively) ![make:entity](https://i.imgur.com/Sflti0y.gif) If you want to see the available type list (relations are now in this list, but not shown): <img width="535" alt="screen shot 2018-01-08 at 3 09 32 pm" src="https://user-images.githubusercontent.com/121003/34690183-21f7498e-f486-11e7-9fcf-a5fe56d2a321.png"> I would love feedback! I added many little "features" to make the user experience as excellent as possible. But, I need users to help validate that! Cheers! Commits ------- 16596b1 updating tests for removed comment 01f6a3c Fixing a bug where a repository would not be generated under certain conditions 2f0e0f3 adding support for associative arrays in annotations 7d3042c Fixing bug where the name was always interactive 2a72ee3 Fixing cs 3b65fb6 Merge branch 'master' into make-entity-improved e54988c Fixing issue where sometimes nullable is not defined on a join column 259141d removing comment - it does not add much value & is hard to keep in the right place b0fed52 updating to stable nickic/php-parser 4.0 release! 7bcc966 Disabling replaceNodes to avoid possible AST accidental changes 613abef Adding an option (true by default) for fluent setter methods 8634a91 cs 9261cd1 Adding the "length" question for the string type 9c5a786 phpcs 328e486 fixing windows bug 92aeff5 playing with appveyor b3647d7 attempting to split tests to combat windows testing issue f022f5f Fixed window path bug while looking for the vendor/ dir 89d5708 trying to fix windows tests with long paths that cause errors :/ fd088ac temporarily debugging Windows errors 35ef3ae removing duplicate sqlite extension for appveyor 8c37893 Making appveyor use sqlite for simplicity abbe8d9 Fixing windows bug where C:/ slash may already be normalized 20df636 Fixing a few Windows bugs f9fa0db adding missing success message 38e6a0e Fixing missing return on --regenerate 1650301 Fixing missing method fb74302 Fixing typo for class name 9c40654 added missing service 866e534 Extracting logic into AutoloaderUtil 05480da Fixing bug where new classes were never actually written in regenerator e535f0d Adding an error if you try to generate a class that does not use annotation metadata 656c199 Fixing 2 merge bugs: entities could not be updated & mix up of entity vs repo class name 8d400e7 Fixing bug with getting property of classes just created e8e5689 fix arg name b8856c0 Code changes to sync with upstream updates 4afbc0e removing dup functions after merge a34a1a2 Fixing "composer require orm orm" bug 5bc34bd removing unused use d34ff45 also run phpcs on updated files f370b52 fixing tests 5395788 Not setting the owning side (from inverse) on OneToOne 922563a clarifying note ab03675 fixing missing return type cf9e08a making decimal/scale more clear 0f2d52d Removing unnecessary service locator: just let the registry be null 1f57317 minor tweaks d65d772 Fixing some tests a822400 adding missing headers dc7973d Fixing tests + one missing return c3ccf5f Ask the user if they want the inverse side of a relation 2fd2e0c Making the user message a little nicer 663afee test needs database c79b73c Fixes thanks to Stof! 6c914fa Removing debugging code, committing missing file to fix tests 4bde1dc With --overwrite, put updated methods in same location as original ed15a2b temp debugging code for failing test on CI dbe11a5 hack to fix tests temporarily cd4f517 Fixing possible non-existent directory in tests e52e33e Adding an enhanced make:entity command
2 parents 4f6d30c + 16596b1 commit d6d0391

File tree

128 files changed

+7502
-214
lines changed

Some content is hidden

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

128 files changed

+7502
-214
lines changed

.gitignore

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
composer.lock
2-
phpunit.xml
3-
vendor/
4-
tests/tmp/*
5-
.php_cs.cache
1+
/composer.lock
2+
/phpunit.xml
3+
/vendor/
4+
/tests/tmp/*
5+
/.php_cs.cache

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ git:
77
depth: 1
88

99
php:
10-
- 7.0
1110
- 7.1
1211
- 7.2
1312

appveyor.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ cache:
88
init:
99
- SET PATH=c:\php;%PATH%
1010

11+
environment:
12+
TEST_DATABASE_DSN: sqlite:///c:\projects\maker-bundle\tests\tmp\app.db
13+
1114
install:
1215
- mkdir c:\php && cd c:\php
1316
- appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-Win32-VC14-x86.zip
@@ -47,4 +50,6 @@ install:
4750
- ./vendor/bin/simple-phpunit install
4851

4952
test_script:
50-
- ./vendor/bin/simple-phpunit
53+
- ./vendor/bin/simple-phpunit --group=functional_group1
54+
- ./vendor/bin/simple-phpunit --group=functional_group2
55+
- ./vendor/bin/simple-phpunit --exclude-group=functional_group1,functional_group2

composer.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@
1212
}
1313
],
1414
"require": {
15-
"php": "^7.0.8",
15+
"php": "^7.1.3",
16+
"doctrine/inflector": "^1.2",
17+
"nikic/php-parser": "^4.0",
1618
"symfony/config": "^3.4|^4.0",
1719
"symfony/console": "^3.4|^4.0",
1820
"symfony/dependency-injection": "^3.4|^4.0",
1921
"symfony/filesystem": "^3.4|^4.0",
22+
"symfony/finder": "^3.4|^4.0",
2023
"symfony/framework-bundle": "^3.4|^4.0",
2124
"symfony/http-kernel": "^3.4|^4.0"
2225
},
2326
"require-dev": {
2427
"allocine/twigcs": "^3.0",
28+
"doctrine/doctrine-bundle": "^1.8",
29+
"doctrine/orm": "^2.6",
2530
"friendsofphp/php-cs-fixer": "^2.8",
2631
"symfony/phpunit-bridge": "^3.4|^4.0",
2732
"symfony/process": "^3.4|^4.0"

phpunit.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
>
1010
<php>
1111
<ini name="error_reporting" value="-1" />
12+
<env name="TEST_DATABASE_DSN" value="mysql://root:@127.0.0.1:3306/test_maker" />
1213
</php>
1314

1415
<testsuites>

src/DependencyBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ private function getRequiredDependencyNames(array $dependencies)
113113
$packages[] = $package['name'];
114114
}
115115

116-
return $packages;
116+
return array_unique($packages);
117117
}
118118

119119
private function calculateMissingDependencies(array $dependencies)
@@ -134,6 +134,6 @@ private function calculateMissingDependencies(array $dependencies)
134134
return [];
135135
}
136136

137-
return array_merge($missingPackages, $missingOptionalPackages);
137+
return array_unique(array_merge($missingPackages, $missingOptionalPackages));
138138
}
139139
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Doctrine;
13+
14+
use Symfony\Bundle\MakerBundle\Str;
15+
16+
/**
17+
* @internal
18+
*/
19+
abstract class BaseCollectionRelation extends BaseRelation
20+
{
21+
abstract public function getOrphanRemoval(): bool;
22+
23+
abstract public function getTargetSetterMethodName(): string;
24+
25+
public function getAdderMethodName(): string
26+
{
27+
return 'add'.Str::asCamelCase(Str::pluralCamelCaseToSingular($this->getPropertyName()));
28+
}
29+
30+
public function getRemoverMethodName(): string
31+
{
32+
return 'remove'.Str::asCamelCase(Str::pluralCamelCaseToSingular($this->getPropertyName()));
33+
}
34+
}

src/Doctrine/BaseRelation.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Doctrine;
13+
14+
/**
15+
* @internal
16+
*/
17+
abstract class BaseRelation
18+
{
19+
private $propertyName;
20+
private $targetClassName;
21+
private $targetPropertyName;
22+
private $mapInverseRelation = true;
23+
24+
abstract public function isOwning(): bool;
25+
26+
public function getPropertyName()
27+
{
28+
return $this->propertyName;
29+
}
30+
31+
public function setPropertyName($propertyName)
32+
{
33+
$this->propertyName = $propertyName;
34+
35+
return $this;
36+
}
37+
38+
public function getTargetClassName()
39+
{
40+
return $this->targetClassName;
41+
}
42+
43+
public function setTargetClassName($targetClassName)
44+
{
45+
$this->targetClassName = $targetClassName;
46+
47+
return $this;
48+
}
49+
50+
public function getTargetPropertyName()
51+
{
52+
return $this->targetPropertyName;
53+
}
54+
55+
public function setTargetPropertyName(?string $targetPropertyName)
56+
{
57+
$this->targetPropertyName = $targetPropertyName;
58+
59+
return $this;
60+
}
61+
62+
public function getMapInverseRelation(): bool
63+
{
64+
return $this->mapInverseRelation;
65+
}
66+
67+
public function setMapInverseRelation(bool $mapInverseRelation)
68+
{
69+
$this->mapInverseRelation = $mapInverseRelation;
70+
71+
return $this;
72+
}
73+
}

src/Doctrine/BaseSingleRelation.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Doctrine;
13+
14+
/**
15+
* @internal
16+
*/
17+
abstract class BaseSingleRelation extends BaseRelation
18+
{
19+
private $isNullable;
20+
21+
public function isNullable(): bool
22+
{
23+
return $this->isNullable;
24+
}
25+
26+
public function setIsNullable($isNullable)
27+
{
28+
$this->isNullable = $isNullable;
29+
30+
return $this;
31+
}
32+
}

src/Doctrine/DoctrineMetadataFactory.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
namespace Symfony\Bundle\MakerBundle\Doctrine;
1313

1414
use Doctrine\Common\Persistence\ManagerRegistry;
15+
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
16+
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
17+
use Doctrine\ORM\EntityManagerInterface;
1518
use Doctrine\ORM\Mapping\ClassMetadata;
1619
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
1720

@@ -55,12 +58,7 @@ public function getMetadataForNamespace($namespace)
5558
return $metadata;
5659
}
5760

58-
/**
59-
* @param string $entity
60-
*
61-
* @return ClassMetadata|null
62-
*/
63-
public function getMetadataForClass(string $entity)
61+
public function getMetadataForClass(string $entity): ?ClassMetadata
6462
{
6563
foreach ($this->registry->getManagers() as $em) {
6664
$cmf = new DisconnectedClassMetadataFactory();
@@ -74,6 +72,30 @@ public function getMetadataForClass(string $entity)
7472
return null;
7573
}
7674

75+
public function getMappingDriverForClass(string $className): ?MappingDriver
76+
{
77+
/** @var EntityManagerInterface $em */
78+
$em = $this->registry->getManagerForClass($className);
79+
80+
if (null === $em) {
81+
throw new \InvalidArgumentException(sprintf('Cannot find the entity manager for class "%s"', $className));
82+
}
83+
84+
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
85+
86+
if (!$metadataDriver instanceof MappingDriverChain) {
87+
return $metadataDriver;
88+
}
89+
90+
foreach ($metadataDriver->getDrivers() as $namespace => $driver) {
91+
if (0 === strpos($className, $namespace)) {
92+
return $driver;
93+
}
94+
}
95+
96+
return $metadataDriver->getDefaultDriver();
97+
}
98+
7799
/**
78100
* @return array
79101
*/

0 commit comments

Comments
 (0)