diff --git a/src/Console/Commands/BuildBackpackCommand.php b/src/Console/Commands/BuildBackpackCommand.php index 1432ae6..3d624ef 100644 --- a/src/Console/Commands/BuildBackpackCommand.php +++ b/src/Console/Commands/BuildBackpackCommand.php @@ -3,7 +3,7 @@ namespace Backpack\Generators\Console\Commands; use Illuminate\Console\Command; -use Illuminate\Support\Arr; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class BuildBackpackCommand extends Command @@ -41,7 +41,7 @@ public function handle() return; } - foreach ($models as $key => $model) { + foreach ($models as $model) { $this->call('backpack:crud', ['name' => $model, '--validation' => $this->option('validation')]); $this->line(' ----------'); } @@ -49,28 +49,65 @@ public function handle() $this->deleteLines(); } - private function getModels($path) + private function getModels(string $path): array { $out = []; $results = scandir($path); foreach ($results as $result) { - if ($result === '.' or $result === '..') { + $filepath = "$path/$result"; + + // ignore `.` (dot) prefixed files + if ($result[0] === '.') { continue; } - $filename = $path.'/'.$result; - - if (is_dir($filename)) { - $out = array_merge($out, $this->getModels($filename)); - } else { - $file_content = file_get_contents($filename); - if (Str::contains($file_content, 'Illuminate\Database\Eloquent\Model') && - Str::contains($file_content, 'extends Model')) { - $out[] = Arr::last(explode('/', substr($filename, 0, -4))); - } + + if (is_dir($filepath)) { + $out = array_merge($out, $this->getModels($filepath)); + continue; + } + + // Try to load it by path as namespace + $class = Str::of($filepath) + ->after(base_path()) + ->trim('\\/') + ->replace('/', '\\') + ->before('.php') + ->ucfirst() + ->value(); + + $result = $this->validateModelClass($class); + if ($result) { + $out[] = $result; + continue; + } + + // Try to load it from file content + $fileContent = Str::of(file_get_contents($filepath)); + $namespace = $fileContent->match('/namespace (.*);/')->value(); + $classname = $fileContent->match('/class (\w+)/')->value(); + + $result = $this->validateModelClass("$namespace\\$classname"); + if ($result) { + $out[] = $result; + continue; } } return $out; } + + private function validateModelClass(string $class): ?string + { + try { + $reflection = new \ReflectionClass($class); + + if ($reflection->isSubclassOf(Model::class) && ! $reflection->isAbstract()) { + return Str::of($class)->afterLast('\\'); + } + } catch (\Throwable$e) { + } + + return null; + } }