Skip to content

Commit 6383103

Browse files
authored
Merge pull request #146 from Laravel-Backpack/load-models-by-namespace
[BugFix] avoid backpack:build to generate interfaces for abstract models and others
2 parents 5f1f960 + a7b4306 commit 6383103

File tree

1 file changed

+51
-14
lines changed

1 file changed

+51
-14
lines changed

src/Console/Commands/BuildBackpackCommand.php

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Backpack\Generators\Console\Commands;
44

55
use Illuminate\Console\Command;
6-
use Illuminate\Support\Arr;
6+
use Illuminate\Database\Eloquent\Model;
77
use Illuminate\Support\Str;
88

99
class BuildBackpackCommand extends Command
@@ -41,36 +41,73 @@ public function handle()
4141
return false;
4242
}
4343

44-
foreach ($models as $key => $model) {
44+
foreach ($models as $model) {
4545
$this->call('backpack:crud', ['name' => $model, '--validation' => $this->option('validation')]);
4646
$this->line(' <fg=gray>----------</>');
4747
}
4848

4949
$this->deleteLines();
5050
}
5151

52-
private function getModels($path)
52+
private function getModels(string $path): array
5353
{
5454
$out = [];
5555
$results = scandir($path);
5656

5757
foreach ($results as $result) {
58-
if ($result === '.' or $result === '..') {
58+
$filepath = "$path/$result";
59+
60+
// ignore `.` (dot) prefixed files
61+
if ($result[0] === '.') {
5962
continue;
6063
}
61-
$filename = $path.'/'.$result;
62-
63-
if (is_dir($filename)) {
64-
$out = array_merge($out, $this->getModels($filename));
65-
} else {
66-
$file_content = file_get_contents($filename);
67-
if (Str::contains($file_content, 'Illuminate\Database\Eloquent\Model') &&
68-
Str::contains($file_content, 'extends Model')) {
69-
$out[] = Arr::last(explode('/', substr($filename, 0, -4)));
70-
}
64+
65+
if (is_dir($filepath)) {
66+
$out = array_merge($out, $this->getModels($filepath));
67+
continue;
68+
}
69+
70+
// Try to load it by path as namespace
71+
$class = Str::of($filepath)
72+
->after(base_path())
73+
->trim('\\/')
74+
->replace('/', '\\')
75+
->before('.php')
76+
->ucfirst()
77+
->value();
78+
79+
$result = $this->validateModelClass($class);
80+
if ($result) {
81+
$out[] = $result;
82+
continue;
83+
}
84+
85+
// Try to load it from file content
86+
$fileContent = Str::of(file_get_contents($filepath));
87+
$namespace = $fileContent->match('/namespace (.*);/')->value();
88+
$classname = $fileContent->match('/class (\w+)/')->value();
89+
90+
$result = $this->validateModelClass("$namespace\\$classname");
91+
if ($result) {
92+
$out[] = $result;
93+
continue;
7194
}
7295
}
7396

7497
return $out;
7598
}
99+
100+
private function validateModelClass(string $class): ?string
101+
{
102+
try {
103+
$reflection = new \ReflectionClass($class);
104+
105+
if ($reflection->isSubclassOf(Model::class) && ! $reflection->isAbstract()) {
106+
return Str::of($class)->afterLast('\\');
107+
}
108+
} catch (\Throwable$e) {
109+
}
110+
111+
return null;
112+
}
76113
}

0 commit comments

Comments
 (0)