Skip to content

Commit 0cb9df3

Browse files
committedDec 16, 2024·
fix: relationships names and add phpdocs for relationships
1 parent 5d11be5 commit 0cb9df3

File tree

8 files changed

+106
-52
lines changed

8 files changed

+106
-52
lines changed
 

‎src/Commands/LaravelModelsGeneratorCommand.php

+10-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Doctrine\DBAL\Types\StringType;
1515
use Doctrine\DBAL\Types\Type;
1616
use GiacomoMasseroni\LaravelModelsGenerator\Drivers\DriverFacade;
17+
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Property;
1718
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Relationships\BelongsTo;
1819
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Relationships\BelongsToMany;
1920
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Relationships\HasMany;
@@ -123,7 +124,7 @@ public function handle(): int
123124
if (($laravelColumnType = $this->laravelColumnType($column->getType(), $dbTable)) !== null) {
124125
$dbTable->casts[$column->getName()] = $laravelColumnType;
125126

126-
$properties[] = $laravelColumnType.($column->getNotnull() ? '' : '|null').' $'.$column->getName();
127+
$properties[] = new Property('$'.$column->getName(), $laravelColumnType.($column->getNotnull() ? '' : '|null')); //$laravelColumnType.($column->getNotnull() ? '' : '|null').' $'.$column->getName();
127128
}
128129

129130
// Get morph
@@ -136,7 +137,8 @@ public function handle(): int
136137
$dbTable->properties = $properties;
137138

138139
foreach ($fks as $fk) {
139-
$dbTable->belongsTo[$fk->getName()] = new BelongsTo($fk);
140+
$dbTable->addBelongsTo(new BelongsTo($fk));
141+
//$dbTable->belongsTo[$fk->getName()] = new BelongsTo($fk);
140142
}
141143

142144
$dbTables[$table->getName()] = $dbTable;
@@ -297,6 +299,8 @@ private function modelContent(string $className, Table $dbTable): string
297299

298300
$dbTable->imports = array_merge($dbTable->imports, $arImports);
299301

302+
$dbTable->fixRelationshipsName();
303+
300304
$writer = new Writer($className, $dbTable, $content);
301305

302306
return $writer->writeModelFile();
@@ -339,14 +343,14 @@ private function laravelColumnType(Type $type, Table $dbTable): ?string
339343
return 'int';
340344
}
341345
if ($type instanceof DateType) {
342-
$dbTable->imports[] = 'Datetime';
346+
$dbTable->imports[] = 'Carbon\Carbon';
343347

344-
return 'Datetime';
348+
return 'Carbon';
345349
}
346350
if ($type instanceof DateTimeType) {
347-
$dbTable->imports[] = 'Datetime';
351+
$dbTable->imports[] = 'Carbon\Carbon';
348352

349-
return 'Datetime';
353+
return 'Carbon';
350354
}
351355
if ($type instanceof StringType) {
352356
return 'string';

‎src/Entities/Property.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace GiacomoMasseroni\LaravelModelsGenerator\Entities;
6+
7+
class Property
8+
{
9+
public function __construct(
10+
public string $field,
11+
public string $return,
12+
public bool $readOnly = false
13+
) {}
14+
}

‎src/Entities/Relationships/BelongsTo.php

+8
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,13 @@
99

1010
class BelongsTo implements RelationshipInterface
1111
{
12+
public string $name;
13+
14+
public string $foreignClassName;
15+
16+
public string $foreignColumnName;
17+
18+
public string $localColumnName;
19+
1220
public function __construct(public ForeignKeyConstraint $foreignKey) {}
1321
}

‎src/Entities/Relationships/BelongsToMany.php

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
class BelongsToMany implements RelationshipInterface
1010
{
11+
public string $name;
12+
13+
public string $foreignClassName;
14+
1115
public bool $timestamps = false;
1216

1317
/**

‎src/Entities/Table.php

+53-5
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Relationships\HasMany;
1010
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Relationships\MorphMany;
1111
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Relationships\MorphTo;
12+
use Illuminate\Support\Str;
1213

1314
class Table
1415
{
1516
/** @var array<string> */
1617
public array $imports = [];
1718

18-
/** @var array<string> */
19+
/** @var array<Property> */
1920
public array $properties = [];
2021

2122
/** @var array<HasMany> */
@@ -66,8 +67,26 @@ public function addBelongsToMany(BelongsToMany $belongsToMany): self
6667
}
6768
}
6869

69-
if ($alreadyInserted !== false) {
70+
if ($alreadyInserted === false) {
71+
if ($belongsToMany->pivot == $this->name.'_'.$belongsToMany->related ||
72+
$belongsToMany->pivot == $belongsToMany->related.'_'.$this->name) {
73+
$relationName = Str::camel(Str::plural($belongsToMany->related));
74+
} else {
75+
if (Str::start($belongsToMany->related, $belongsToMany->pivot)) {
76+
$related = str_replace($belongsToMany->pivot.'_', '', $belongsToMany->related);
77+
} else {
78+
$related = $belongsToMany->related;
79+
}
80+
$relationName = Str::camel(str_replace("{$this->name}_", '', $belongsToMany->pivot).'_'.Str::plural($related));
81+
}
82+
$foreignClassName = ucfirst(Str::camel(Str::singular($belongsToMany->related)));
83+
$belongsToMany->name = $relationName;
84+
$belongsToMany->foreignClassName = $foreignClassName;
85+
7086
$this->belongsToMany[] = $belongsToMany;
87+
88+
$this->properties[] = new Property('$'.$belongsToMany->name, 'Collection|'.$belongsToMany->foreignClassName.'[]', false);
89+
$this->imports[] = 'Illuminate\Database\Eloquent\Collection';
7190
}
7291

7392
return $this;
@@ -82,8 +101,24 @@ public function addBelongsTo(BelongsTo $belongsTo): self
82101
}
83102
}
84103

85-
if ($alreadyInserted !== false) {
86-
$this->belongsTo[] = $belongsTo;
104+
if ($alreadyInserted === false) {
105+
$foreignClassName = ucfirst(Str::camel(Str::singular($belongsTo->foreignKey->getForeignTableName())));
106+
$foreignColumnName = $belongsTo->foreignKey->getForeignColumns()[0];
107+
$localColumnName = $belongsTo->foreignKey->getLocalColumns()[0];
108+
if (str_contains($localColumnName, $foreignColumnName) && $localColumnName != $foreignColumnName) {
109+
$relationName = Str::camel(str_replace($foreignColumnName, '', $localColumnName));
110+
} else {
111+
$relationName = Str::camel(Str::singular($belongsTo->foreignKey->getForeignTableName()));
112+
}
113+
$belongsTo->name = $relationName;
114+
$belongsTo->foreignClassName = $foreignClassName;
115+
$belongsTo->foreignColumnName = $foreignColumnName;
116+
$belongsTo->localColumnName = $localColumnName;
117+
118+
$this->belongsTo[$belongsTo->foreignKey->getName()] = $belongsTo;
119+
120+
$this->properties[] = new Property('$'.$belongsTo->name, 'Collection|'.$belongsTo->foreignClassName.'[]', false);
121+
$this->imports[] = 'Illuminate\Database\Eloquent\Collection';
87122
}
88123

89124
return $this;
@@ -92,11 +127,24 @@ public function addBelongsTo(BelongsTo $belongsTo): self
92127
public function thereIsAnotherHasMany(HasMany $hasMany): bool
93128
{
94129
foreach ($this->hasMany as $rel) {
95-
if ($rel !== $hasMany && $rel->name === $hasMany->name) {
130+
if ($rel !== $hasMany && $rel->related === $hasMany->related) {
96131
return true;
97132
}
98133
}
99134

100135
return false;
101136
}
137+
138+
public function fixRelationshipsName(): void
139+
{
140+
foreach ($this->hasMany as $key => $hasMany) {
141+
if ($this->thereIsAnotherHasMany($hasMany)) {
142+
$this->hasMany[$key]->name = Str::camel(Str::plural($hasMany->name)).'As'.ucfirst(Str::camel(str_replace($this->primaryKey, '', $hasMany->foreignKeyName)));
143+
} else {
144+
$this->hasMany[$key]->name = Str::camel(Str::plural($hasMany->name));
145+
}
146+
$this->properties[] = new Property('$'.$hasMany->name, 'Collection|'.$hasMany->related.'[]', false);
147+
$this->imports[] = 'Illuminate\Database\Eloquent\Collection';
148+
}
149+
}
102150
}

‎src/Entities/stubs/model.stub

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
<?php{{strict}}
2-
1+
<?php
2+
{{strict}}
33
namespace {{namespace}};
44

55
{{imports}}

‎src/Writers/Laravel11/Writer.php

+14-38
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace GiacomoMasseroni\LaravelModelsGenerator\Writers\Laravel11;
66

7+
use GiacomoMasseroni\LaravelModelsGenerator\Entities\Property;
78
use GiacomoMasseroni\LaravelModelsGenerator\Writers\WriterInterface;
89
use Illuminate\Support\Str;
910

@@ -20,8 +21,8 @@ public function imports(): string
2021

2122
public function properties(): string
2223
{
23-
return implode("\n", array_map(function (string $property) {
24-
return " * @property $property";
24+
return implode("\n", array_map(function (Property $property) {
25+
return ' * @property'.($property->readOnly ? '-read' : '').' '.$property->return.' '.$property->field;
2526
}, $this->table->properties));
2627
}
2728

@@ -171,19 +172,14 @@ private function hasMany(): string
171172
{
172173
$content = '';
173174
foreach ($this->table->hasMany as $hasMany) {
174-
if ($this->table->thereIsAnotherHasMany($hasMany)) {
175-
$relationName = Str::camel(Str::plural($hasMany->name)).'As'.ucfirst(Str::camel(str_replace($this->table->primaryKey, '', $hasMany->foreignKeyName)));
176-
} else {
177-
$relationName = Str::camel(Str::plural($hasMany->name));
178-
}
179175
$relatedClassName = ucfirst(Str::camel($hasMany->related));
180176

181177
$content .= "\n"."\n";
182178

183179
$content .= $this->spacer.'/**'."\n";
184180
$content .= $this->spacer.' * @return HasMany<'.$relatedClassName.', $this>'."\n";
185181
$content .= $this->spacer.' */'."\n";
186-
$content .= $this->spacer.'public function '.$relationName.'(): HasMany'."\n";
182+
$content .= $this->spacer.'public function '.$hasMany->name.'(): HasMany'."\n";
187183
$content .= $this->spacer.'{'."\n";
188184
$content .= str_repeat($this->spacer, 2).'return $this->hasMany('.$relatedClassName.'::class, \''.$hasMany->foreignKeyName.'\''.(! empty($hasMany->localKeyName) ? ', \''.$hasMany->localKeyName.'\'' : '').');'."\n";
189185
$content .= $this->spacer.'}';
@@ -196,21 +192,13 @@ private function belongTo(): string
196192
{
197193
$content = '';
198194
foreach ($this->table->belongsTo as $belongsTo) {
199-
$foreignClassName = ucfirst(Str::camel(Str::singular($belongsTo->foreignKey->getForeignTableName())));
200-
$foreignColumnName = $belongsTo->foreignKey->getForeignColumns()[0];
201-
$localColumnName = $belongsTo->foreignKey->getLocalColumns()[0];
202-
if (str_contains($localColumnName, $foreignColumnName) && $localColumnName != $foreignColumnName) {
203-
$relationName = Str::camel(str_replace($foreignColumnName, '', $localColumnName));
204-
} else {
205-
$relationName = Str::camel(Str::singular($belongsTo->foreignKey->getForeignTableName()));
206-
}
207195
$content .= "\n"."\n";
208196
$content .= $this->spacer.'/**'."\n";
209-
$content .= $this->spacer.' * @return BelongsTo<'.$foreignClassName.', $this>'."\n";
197+
$content .= $this->spacer.' * @return BelongsTo<'.$belongsTo->foreignClassName.', $this>'."\n";
210198
$content .= $this->spacer.' */'."\n";
211-
$content .= $this->spacer.'public function '.$relationName.'(): BelongsTo'."\n";
199+
$content .= $this->spacer.'public function '.$belongsTo->name.'(): BelongsTo'."\n";
212200
$content .= $this->spacer.'{'."\n";
213-
$content .= str_repeat($this->spacer, 2).'return $this->belongsTo('.$foreignClassName.'::class, \''.$foreignColumnName.'\''.($localColumnName != $this->table->primaryKey ? ', \''.$localColumnName.'\'' : '').');'."\n";
201+
$content .= str_repeat($this->spacer, 2).'return $this->belongsTo('.$belongsTo->foreignClassName.'::class, \''.$belongsTo->foreignColumnName.'\''.($belongsTo->localColumnName != $this->table->primaryKey ? ', \''.$belongsTo->localColumnName.'\'' : '').');'."\n";
214202
$content .= $this->spacer.'}';
215203
}
216204

@@ -222,30 +210,18 @@ private function belongsToMany(): string
222210
$content = '';
223211

224212
foreach ($this->table->belongsToMany as $belongsToMany) {
225-
if ($belongsToMany->pivot == $this->table->name.'_'.$belongsToMany->related ||
226-
$belongsToMany->pivot == $belongsToMany->related.'_'.$this->table->name) {
227-
$relationName = Str::camel(Str::plural($belongsToMany->related));
228-
} else {
229-
if (Str::start($belongsToMany->related, $belongsToMany->pivot)) {
230-
$related = str_replace($belongsToMany->pivot.'_', '', $belongsToMany->related);
231-
} else {
232-
$related = $belongsToMany->related;
233-
}
234-
$relationName = Str::camel(str_replace("{$this->table->name}_", '', $belongsToMany->pivot).'_'.Str::plural($related));
235-
}
213+
$withPivot = count($belongsToMany->pivotAttributes);
236214

237-
$foreignClassName = ucfirst(Str::camel(Str::singular($belongsToMany->related)));
238-
//$foreignColumnName = $belongsTo->foreignKey->getForeignColumns()[0];
239215
$content .= "\n"."\n";
240216
$content .= $this->spacer.'/**'."\n";
241-
$content .= $this->spacer.' * @return BelongsToMany<'.$foreignClassName.', $this>'."\n";
217+
$content .= $this->spacer.' * @return BelongsToMany<'.$belongsToMany->foreignClassName.', $this>'."\n";
242218
$content .= $this->spacer.' */'."\n";
243-
$content .= $this->spacer.'public function '.$relationName.'(): BelongsToMany'."\n";
219+
$content .= $this->spacer.'public function '.$belongsToMany->name.'(): BelongsToMany'."\n";
244220
$content .= $this->spacer.'{'."\n";
245-
$content .= str_repeat($this->spacer, 2).'return $this->belongsToMany('.$foreignClassName.'::class, \''.$belongsToMany->pivot.'\', \''.$belongsToMany->foreignPivotKey.'\', \''.$belongsToMany->relatedPivotKey.'\')'."\n";
246-
$content .= str_repeat($this->spacer, 3).(count($belongsToMany->pivotAttributes) > 0 ? '->withPivot(\''.implode('\', \'', $belongsToMany->pivotAttributes).'\')' : '')."\n";
247-
$content .= str_repeat($this->spacer, 3).($belongsToMany->timestamps ? '->withTimestamps()' : '').';'."\n";
248-
$content .= '}';
221+
$content .= str_repeat($this->spacer, 2).'return $this->belongsToMany('.$belongsToMany->foreignClassName.'::class, \''.$belongsToMany->pivot.'\', \''.$belongsToMany->foreignPivotKey.'\', \''.$belongsToMany->relatedPivotKey.'\')'.(! $withPivot ? ';' : '')."\n";
222+
$content .= $withPivot ? str_repeat($this->spacer, 3).(count($belongsToMany->pivotAttributes) > 0 ? '->withPivot(\''.implode('\', \'', $belongsToMany->pivotAttributes).'\')' : '').(! $belongsToMany->timestamps ? ';' : '')."\n" : '';
223+
$content .= $belongsToMany->timestamps ? str_repeat($this->spacer, 3).'->withTimestamps();'."\n" : '';
224+
$content .= $this->spacer.'}';
249225
}
250226

251227
return $content;

‎src/Writers/Writer.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ public function namespace(): string
6767

6868
public function strict(): string
6969
{
70-
return (bool) config('models-generator.strict_types', true) ? ' declare(strict_types=1);' : '';
70+
return config('models-generator.strict_types', true) ? "\n".'declare(strict_types=1);'."\n" : '';
7171
}
7272
}

0 commit comments

Comments
 (0)
Please sign in to comment.