Skip to content

Commit 57f53e3

Browse files
committed
feat: enhance ModelMakeCommand to support builder generation and add model stub
1 parent ca2b076 commit 57f53e3

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

src/Commands/ModelMakeCommand.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,36 @@ public function handle()
2020
}
2121
}
2222

23+
/**
24+
* @inheritdoc
25+
*/
26+
protected function getStub()
27+
{
28+
return $this->resolveStubPath('/../../stubs/model.stub');
29+
}
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
protected function resolveStubPath($stub)
35+
{
36+
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
37+
? $customPath
38+
: __DIR__.$stub;
39+
}
40+
41+
/**
42+
* @inheritdoc
43+
*/
44+
protected function buildClass($name)
45+
{
46+
$replace = $this->buildBuilderReplacements();
47+
48+
return str_replace(
49+
array_keys($replace), array_values($replace), parent::buildClass($name)
50+
);
51+
}
52+
2353
/**
2454
* Create a builder file for the model.
2555
*
@@ -35,6 +65,51 @@ protected function createBuilder()
3565
]);
3666
}
3767

68+
/**
69+
* Build the replacements for a builder.
70+
*
71+
* @return array<string, string>
72+
*/
73+
protected function buildBuilderReplacements()
74+
{
75+
$replacements = [];
76+
77+
if ($this->option('builder') || $this->option('all')) {
78+
$modelPath = Str::of($this->argument('name'))->studly()->replace('/', '\\')->toString();
79+
80+
$builderNamespace = 'App\\Models\\Builders\\'.$modelPath.'Builder';
81+
$builderClass = Str::of($builderNamespace)->afterLast('\\')->toString();
82+
83+
$builderCode = <<<EOT
84+
/**
85+
* Create a new Eloquent query builder for the model.
86+
*
87+
* @param \Illuminate\Database\Query\Builder \$query
88+
* @return $builderClass<$modelPath>
89+
*/
90+
public function newEloquentBuilder(\$query): $builderClass
91+
{
92+
return new $builderClass(\$query);
93+
}
94+
EOT;
95+
96+
$replacements['{{ newBuilderFunction }}'] = $builderCode;
97+
$replacements['{{ builderImport }}'] = "use $builderNamespace;";
98+
99+
if(! $this->option('factory')){
100+
$replacements["//\n"] = '';
101+
$replacements["//\r\n"] = '';
102+
}
103+
} else {
104+
$replacements["{{ newBuilderFunction }}\n"] = '';
105+
$replacements["{{ newBuilderFunction }}\r\n"] = '';
106+
$replacements["{{ builderImport }}\n"] = '';
107+
$replacements["{{ builderImport }}\r\n"] = '';
108+
}
109+
110+
return $replacements;
111+
}
112+
38113
/**
39114
* @inheritDoc
40115
*/

stubs/model.stub

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace {{ namespace }};
4+
5+
{{ factoryImport }}
6+
{{ builderImport }}
7+
use Illuminate\Database\Eloquent\Model;
8+
9+
class {{ class }} extends Model
10+
{
11+
{{ factory }}
12+
13+
{{ newBuilderFunction }}
14+
}

tests/Unit/Commands/ModelMakeCommandTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
$this->assertFileContains([
3131
'namespace App\Models;',
3232
'class Foo extends Model',
33+
'use App\Models\Builders\FooBuilder;',
34+
'@return FooBuilder<Foo>',
35+
'public function newEloquentBuilder($query): FooBuilder',
36+
'return new FooBuilder($query);',
3337
], 'app/Models/Foo.php');
3438

3539
$this->assertFileContains([

0 commit comments

Comments
 (0)