Skip to content

Commit be24be4

Browse files
authored
feature #1511 [make:entity] helper message with two classes having the same name under different namespaces
1 parent 481d6c6 commit be24be4

File tree

5 files changed

+140
-0
lines changed

5 files changed

+140
-0
lines changed

src/Maker/MakeEntity.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,12 @@ private function askRelationType(ConsoleStyle $io, string $entityClass, string $
779779

780780
$originalEntityShort = Str::getShortClassName($entityClass);
781781
$targetEntityShort = Str::getShortClassName($targetEntityClass);
782+
if ($originalEntityShort === $targetEntityShort) {
783+
[$originalDiscriminator, $targetDiscriminator] = Str::getHumanDiscriminatorBetweenTwoClasses($entityClass, $targetEntityClass);
784+
$originalEntityShort = trim($originalDiscriminator.'\\'.$originalEntityShort, '\\');
785+
$targetEntityShort = trim($targetDiscriminator.'\\'.$targetEntityShort, '\\');
786+
}
787+
782788
$rows = [];
783789
$rows[] = [
784790
EntityRelation::MANY_TO_ONE,

src/Str.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,38 @@ public static function getShortClassName(string $fullClassName): string
129129
return substr($fullClassName, strrpos($fullClassName, '\\') + 1);
130130
}
131131

132+
/**
133+
* @return array{0: string, 1: string}
134+
*/
135+
public static function getHumanDiscriminatorBetweenTwoClasses(string $className, string $classNameOther): array
136+
{
137+
$namespace = self::getNamespace($className);
138+
$namespaceOther = self::getNamespace($classNameOther);
139+
if (empty($namespace) || empty($namespaceOther)) {
140+
return [$namespace, $namespaceOther];
141+
}
142+
143+
$namespaceParts = explode('\\', $namespace);
144+
$namespacePartsOther = explode('\\', $namespaceOther);
145+
146+
$min = min(\count($namespaceParts), \count($namespacePartsOther));
147+
for ($i = 0; $i < $min; ++$i) {
148+
$part = $namespaceParts[$i];
149+
$partOther = $namespacePartsOther[$i];
150+
if ($part !== $partOther) {
151+
break;
152+
}
153+
154+
$namespaceParts[$i] = null;
155+
$namespacePartsOther[$i] = null;
156+
}
157+
158+
return [
159+
implode('\\', array_filter($namespaceParts)),
160+
implode('\\', array_filter($namespacePartsOther)),
161+
];
162+
}
163+
132164
public static function getNamespace(string $fullClassName): string
133165
{
134166
return substr($fullClassName, 0, strrpos($fullClassName, '\\'));

tests/Maker/MakeEntityTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,45 @@ public function getTestDetails(): \Generator
376376
}),
377377
];
378378

379+
yield 'it_adds_many_to_many_between_same_entity_name_different_namespace' => [$this->createMakeEntityTest()
380+
->run(function (MakerTestRunner $runner) {
381+
$this->copyEntity($runner, 'User-basic.php');
382+
$this->copyEntity($runner, 'Friend/User-sub-namespace.php');
383+
384+
$output = $runner->runMaker([
385+
// entity class name
386+
'User',
387+
// field name
388+
'friends',
389+
// add a relationship field
390+
'relation',
391+
// the target entity
392+
'Friend\\User',
393+
// relation type
394+
'ManyToMany',
395+
// inverse side?
396+
'y',
397+
// field name on opposite side - use default 'courses'
398+
'',
399+
// finish adding fields
400+
'',
401+
]);
402+
403+
$this->assertStringContainsString('src/Entity/User.php', $output);
404+
$this->assertStringContainsString('src/Entity/Friend/User.php', $output);
405+
$this->assertStringContainsString('ManyToOne Each User relates to (has) one Friend\User.', $output);
406+
$this->assertStringContainsString('Each Friend\User can relate to (can have) many User objects.', $output);
407+
$this->assertStringContainsString('OneToMany Each User can relate to (can have) many Friend\User objects.', $output);
408+
$this->assertStringContainsString('Each Friend\User relates to (has) one User.', $output);
409+
$this->assertStringContainsString('ManyToMany Each User can relate to (can have) many Friend\User objects.', $output);
410+
$this->assertStringContainsString('Each Friend\User can also relate to (can also have) many User objects.', $output);
411+
$this->assertStringContainsString('OneToOne Each User relates to (has) exactly one Friend\User.', $output);
412+
$this->assertStringContainsString('Each Friend\User also relates to (has) exactly one User.', $output);
413+
414+
// $this->runCustomTest($runner, 'it_adds_many_to_many_between_same_entity_name_different_namespace.php');
415+
}),
416+
];
417+
379418
yield 'it_adds_one_to_one_simple' => [$this->createMakeEntityTest()
380419
->run(function (MakerTestRunner $runner) {
381420
$this->copyEntity($runner, 'User-basic.php');

tests/StrTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,24 @@ public function getShortClassNameCaseTests()
185185
yield ['Foo', 'Foo'];
186186
}
187187

188+
/**
189+
* @dataProvider getHumanDiscriminatorBetweenTwoClassesTests
190+
*/
191+
public function testHumanDiscriminatorBetweenTwoClasses(string $className, string $classNameOther, array $expected)
192+
{
193+
$this->assertSame($expected, Str::getHumanDiscriminatorBetweenTwoClasses($className, $classNameOther));
194+
}
195+
196+
public function getHumanDiscriminatorBetweenTwoClassesTests()
197+
{
198+
yield ['\\User', 'App\\Entity\\User', ['', 'App\\Entity']];
199+
yield ['App\\Entity\\User', 'App\\Entity\\Friend\\User', ['', 'Friend']];
200+
yield ['App\\Entity\\User', 'Custom\\Entity\\User', ['App\\Entity', 'Custom\\Entity']];
201+
yield ['App\\Entity\\User', 'App\\Bundle\\Entity\\User', ['Entity', 'Bundle\\Entity']];
202+
yield ['App\\Entity\\User', 'App\\Bundle\\User', ['Entity', 'Bundle']];
203+
yield ['App\\Entity\\User', 'Custom\\Bundle\\Friend\\Entity\\User', ['App\\Entity', 'Custom\\Bundle\\Friend\\Entity']];
204+
}
205+
188206
/**
189207
* @dataProvider asHumanWordsTests
190208
*/
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace App\Entity\Friend;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
#[ORM\Entity]
8+
class User
9+
{
10+
#[ORM\Id]
11+
#[ORM\GeneratedValue]
12+
#[ORM\Column]
13+
private ?int $id = null;
14+
15+
#[ORM\Column(length: 255, nullable: true)]
16+
private ?string $firstName = null;
17+
18+
#[ORM\Column(nullable: true)]
19+
private ?\DateTimeInterface $createdAt = null;
20+
21+
public function getId()
22+
{
23+
return $this->id;
24+
}
25+
26+
public function getFirstName()
27+
{
28+
return $this->firstName;
29+
}
30+
31+
public function setFirstName(?string $firstName)
32+
{
33+
$this->firstName = $firstName;
34+
}
35+
36+
public function getCreatedAt(): ?\DateTimeInterface
37+
{
38+
return $this->createdAt;
39+
}
40+
41+
public function setCreatedAt(?\DateTimeInterface $createdAt)
42+
{
43+
$this->createdAt = $createdAt;
44+
}
45+
}

0 commit comments

Comments
 (0)