Skip to content
46 changes: 42 additions & 4 deletions src/Generators/ModelGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,18 @@ protected function hasRelations(): bool

protected function getNewModelContent(): string
{
$relations = $this->prepareRelations();

return $this->getStub('model', [
'entity' => $this->model,
'fields' => Arr::collapse($this->fields),
'relations' => $this->prepareRelations(),
'relations' => $relations,
'casts' => $this->getCasts($this->fields),
'namespace' => $this->getNamespace('models', $this->modelSubFolder),
'importRelations' => $this->getImportedRelations(),
'anotationProperties' => $this->generateAnnotationProperties($this->fields),
'annotationProperties' => $this->generateAnnotationProperties($this->fields, $relations),
'hasCarbonField' => !empty($this->fields['timestamp']) || !empty($this->fields['timestamp-required']),
'hasCollectionType' => !empty($this->relations->hasMany) || !empty($this->relations->belongsToMany),
]);
}

Expand Down Expand Up @@ -81,14 +84,19 @@ public function prepareRelatedModels(): void
$this->insertImport($content, $namespace);
}

$relationName = $this->getRelationName($this->model, $types[$type]);

$newRelation = $this->getStub('relation', [
'name' => $this->getRelationName($this->model, $types[$type]),
'name' => $relationName,
'type' => $types[$type],
'entity' => $this->model,
]);

// TODO: use ronasit/larabuilder instead regexp
$fixedContent = preg_replace('/\}$/', "\n {$newRelation}\n}", $content);

$this->insertPropertyAnnotation($fixedContent, $this->getRelationType($this->model, $types[$type]), $relationName);

$this->saveClass('models', $relation, $fixedContent);
}
}
Expand All @@ -106,6 +114,7 @@ protected function insertImport(string &$classContent, string $import): void
$import = "use {$import};";

if (!Str::contains($classContent, $import)) {
// TODO: use ronasit/larabuilder instead regexp
$classContent = preg_replace('/(namespace\s+[^;]+;\s*)/', "$1{$import}\n", $classContent, 1);
}
}
Expand Down Expand Up @@ -195,7 +204,7 @@ protected function generateClassNamespace(string $className, ?string $folder = n
return "{$path}\\{$psrPath}";
}

protected function generateAnnotationProperties(array $fields): array
protected function generateAnnotationProperties(array $fields, array $relations): array
{
$result = [];

Expand All @@ -205,6 +214,10 @@ protected function generateAnnotationProperties(array $fields): array
}
}

foreach ($relations as $relation) {
$result[$relation['name']] = $this->getRelationType($relation['entity'], $relation['type']);
}

return $result;
}

Expand Down Expand Up @@ -244,4 +257,29 @@ protected function isRequired(string $typeName): bool
{
return Str::endsWith($typeName, 'required');
}

protected function getRelationType(string $model, string $relation): string
{
if (in_array($relation, self::PLURAL_NUMBER_REQUIRED)) {
return "Collection<{$model}>";
}

return "{$model}|null";
}

protected function insertPropertyAnnotation(string &$content, string $propertyDataType, string $propertyName): void
{
$annotation = "* @property {$propertyDataType} \${$propertyName}";

// TODO: use ronasit/larabuilder instead regexp
if (!Str::contains($content, '/**')) {
$content = preg_replace('/^\s*class.*\n/m', "\n/**\n {$annotation}\n */$0", $content);
} else {
$content = preg_replace('/\*\/\n/', "{$annotation}\n $0", $content);
}

if (Str::contains($propertyDataType, 'Collection')) {
$this->insertImport($content, 'Illuminate\Database\Eloquent\Collection');
}
}
}
9 changes: 6 additions & 3 deletions stubs/model.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
@if($hasCarbonField)
use Carbon\Carbon;
@endif
@if($hasCollectionType)
use Illuminate\Database\Eloquent\Collection;
@endif

@if(!empty($anotationProperties))
@if(!empty($annotationProperties))
/**
@foreach($anotationProperties as $key => $value)
* @property {{ $value }} ${{ $key }}
@foreach($annotationProperties as $key => $value)
* @property {!! $value !!} ${{ $key }}
@endforeach
*/
@else
Expand Down
24 changes: 22 additions & 2 deletions tests/ModelGeneratorTest.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function setUp(): void
{
parent::setUp();

$this->mockFilesystem();
$this->mockDefaultFilesystem();
}

public function testModelAlreadyExists()
Expand All @@ -41,7 +41,9 @@ className: ResourceAlreadyExistsException::class,

public function testRelationModelMissing()
{
$this->mockFileSystemWithoutCommentModel();
$this->mockFilesystem([
'User.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'),
]);

$this->assertExceptionThrew(
className: ClassNotExistsException::class,
Expand Down Expand Up @@ -244,4 +246,22 @@ className: WarningEvent::class,
message: 'Generation of model has been skipped cause the view incorrect_stub from the config entity-generator.stubs.relation is not exists. Please check that config has the correct view name value.',
);
}

public function testAddPropertyAnnotationToRelatedModel()
{
app(ModelGenerator::class)
->setModel('Category')
->setFields([])
->setRelations(new RelationsDTO(
belongsToMany: ['User'],
))
->generate();

$this->assertGeneratedFileEquals('related_model_with_property.php', 'app/Models/User.php');

$this->assertEventPushed(
className: SuccessCreateMessage::class,
message: 'Created a new Model: Category',
);
}
}
15 changes: 6 additions & 9 deletions tests/Support/Model/ModelMockTrait.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,24 @@ trait ModelMockTrait
{
use GeneratorMockTrait;


public function mockFileSystemWithoutCommentModel(): void
public function mockDefaultFilesystem(): void
{
$fileSystemMock = new FileSystemMock();

$fileSystemMock->models = [
'Comment.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'),
'User.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'),
'Forum/Author.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'),
];

$fileSystemMock->setStructure();
}

public function mockFilesystem(): void
public function mockFilesystem(array $models): void
{
$fileSystemMock = new FileSystemMock;
$fileSystemMock = new FileSystemMock();

$fileSystemMock->models = [
'Comment.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'),
'User.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'),
'Forum/Author.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'),
];
$fileSystemMock->models = $models;

$fileSystemMock->setStructure();
}
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/ModelGeneratorTest/comment_relation_model.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use Illuminate\Database\Eloquent\Model;
use RonasIT\Support\Traits\ModelTrait;

/**
* @property Post|null $post
*/
class WelcomeBonus extends Model
{
use ModelTrait;
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/ModelGeneratorTest/new_model.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Database\Eloquent\Model;
use RonasIT\Support\Traits\ModelTrait;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;

/**
* @property int|null $priority
Expand All @@ -20,6 +21,8 @@
* @property Carbon|null $updated_at
* @property Carbon $published_at
* @property array $meta
* @property Comment|null $comment
* @property Collection<User> $users
*/
class Post extends Model
{
Expand Down
3 changes: 2 additions & 1 deletion tests/fixtures/ModelGeneratorTest/new_model_with_many_relations.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
use Illuminate\Database\Eloquent\Model;
use RonasIT\Support\Traits\ModelTrait;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;

//TODO: add @property annotation for each model's field
/**
* @property Collection<User> $users
*/
class Post extends Model
{
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/ModelGeneratorTest/new_model_with_subfolers_relations.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
use Illuminate\Database\Eloquent\Model;
use RonasIT\Support\Traits\ModelTrait;
use App\Models\Forum\Author;
use Illuminate\Database\Eloquent\Collection;

/**
* @property string $title
* @property Collection<Author> $authors
*/
class Post extends Model
{
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/ModelGeneratorTest/new_subfolders_model.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Models\Comment;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;

/**
* @property int|null $priority
Expand All @@ -22,6 +23,8 @@
* @property Carbon|null $updated_at
* @property Carbon $published_at
* @property array $meta
* @property Comment|null $comment
* @property Collection<User> $users
*/
class Post extends Model
{
Expand Down
34 changes: 34 additions & 0 deletions tests/fixtures/ModelGeneratorTest/related_model_with_property.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace RonasIT\Support\Tests\Support\Models;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use RonasIT\Support\Traits\ModelTrait;

/**
* @property Collection<Category> $categories
*/
class WelcomeBonus extends Model
{
use ModelTrait;

public function getConnectionName(): string
{
return 'pgsql';
}

protected $fillable = [
'title',
'name',
];

public function some_relation()
{
}

public function categories()
{
return $this->belongsToMany(Category::class);
}
}