|
2 | 2 |
|
3 | 3 | namespace RedberryProducts\PageBuilderPlugin\Commands; |
4 | 4 |
|
| 5 | +use Filament\Facades\Filament; |
| 6 | +use Filament\Panel; |
5 | 7 | use Illuminate\Console\Command; |
| 8 | +use Illuminate\Filesystem\Filesystem; |
| 9 | +use Illuminate\Support\Arr; |
| 10 | +use Illuminate\Support\Str; |
| 11 | + |
| 12 | +use function Laravel\Prompts\confirm; |
| 13 | +use function Laravel\Prompts\select; |
| 14 | +use function Laravel\Prompts\text; |
6 | 15 |
|
7 | 16 | class PageBuilderPluginCommand extends Command |
8 | 17 | { |
9 | | - // TODO: Implement scaffolding block class |
10 | | - public $signature = 'page-builder-plugin'; |
| 18 | + public $signature = 'page-builder-plugin:make-block {name?} {--T|type=} {--panel=}'; |
11 | 19 |
|
12 | | - public $description = 'My command'; |
| 20 | + public $description = 'create a new block'; |
13 | 21 |
|
14 | 22 | public function handle(): int |
15 | 23 | { |
16 | | - $this->comment('All done'); |
| 24 | + $block = (string) str( |
| 25 | + $this->argument('name') ?? |
| 26 | + text( |
| 27 | + label: 'What is the block name?', |
| 28 | + placeholder: 'Header', |
| 29 | + required: true, |
| 30 | + ), |
| 31 | + ) |
| 32 | + ->trim('/') |
| 33 | + ->trim('\\') |
| 34 | + ->trim(' ') |
| 35 | + ->replace('/', '\\'); |
| 36 | + |
| 37 | + $panel = $this->option('panel'); |
| 38 | + |
| 39 | + if ($panel) { |
| 40 | + $panel = Filament::getPanel($panel, isStrict: false); |
| 41 | + } |
| 42 | + |
| 43 | + if (! $panel) { |
| 44 | + $panels = Filament::getPanels(); |
| 45 | + |
| 46 | + /** @var Panel $panel */ |
| 47 | + $panel = (count($panels) > 1) ? $panels[select( |
| 48 | + label: 'Which panel would you like to create this in?', |
| 49 | + options: array_map( |
| 50 | + fn (Panel $panel): string => $panel->getId(), |
| 51 | + $panels, |
| 52 | + ), |
| 53 | + default: Filament::getDefaultPanel()->getId() |
| 54 | + )] : Arr::first($panels); |
| 55 | + } |
| 56 | + |
| 57 | + $blocksNamespace = array_map( |
| 58 | + fn (string $namespace): string => str_replace('Resources', 'Blocks', $namespace), |
| 59 | + $panel->getResourceNamespaces(), |
| 60 | + ); |
| 61 | + |
| 62 | + $blocksNamespace = (count($blocksNamespace) > 1) ? |
| 63 | + select( |
| 64 | + label: 'Which namespace would you like to create this in?', |
| 65 | + options: $blocksNamespace |
| 66 | + ) : (Arr::first($blocksNamespace)); |
| 67 | + |
| 68 | + $blockClass = $blocksNamespace . '\\' . $block; |
| 69 | + |
| 70 | + if (class_exists($blockClass)) { |
| 71 | + if (! confirm( |
| 72 | + label: 'This block already exists. Do you want to overwrite it?', |
| 73 | + default: false, |
| 74 | + )) { |
| 75 | + return self::FAILURE; |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + $blockType = $this->option('type') ?? select( |
| 80 | + label: 'What type of block is this?', |
| 81 | + options: ['iframe', 'view'], |
| 82 | + default: 'iframe', |
| 83 | + ); |
| 84 | + |
| 85 | + if ($blockType === 'iframe') { |
| 86 | + $this->createFileFromStub( |
| 87 | + 'block', |
| 88 | + $this->appClassToPath($blockClass), |
| 89 | + [ |
| 90 | + "{{ class }}" => str($blockClass)->afterLast('\\')->replace('\\', ''), |
| 91 | + "{{ namespace }}" => str($blockClass)->beforeLast('\\'), |
| 92 | + ] |
| 93 | + ); |
| 94 | + } |
| 95 | + |
| 96 | + if ($blockType === 'view') { |
| 97 | + $viewName = str($block)->replace("\\", ".")->kebab()->replace(".-", "."); |
| 98 | + $this->createFileFromStub( |
| 99 | + 'block.view', |
| 100 | + $this->appClassToPath($blockClass), |
| 101 | + [ |
| 102 | + "{{ class }}" => str($block)->afterLast('\\')->replace('\\', ''), |
| 103 | + "{{ namespace }}" => str($blockClass)->beforeLast('\\'), |
| 104 | + '{{ viewName }}' => $viewName, |
| 105 | + ] |
| 106 | + ); |
| 107 | + |
| 108 | + $this->createFileFromStub( |
| 109 | + 'block.blade', |
| 110 | + resource_path( |
| 111 | + $viewName |
| 112 | + ->replace('.', '/') |
| 113 | + ->prepend("views/blocks/") |
| 114 | + ->append('.blade.php') |
| 115 | + ), |
| 116 | + ); |
| 117 | + } |
17 | 118 |
|
18 | 119 | return self::SUCCESS; |
19 | 120 | } |
| 121 | + |
| 122 | + public function createFileFromStub(string $stub, string $path, array $replacements = []): void |
| 123 | + { |
| 124 | + /** @var Filesystem */ |
| 125 | + $filesystem = app(Filesystem::class); |
| 126 | + |
| 127 | + if (! file_exists($stubPath = base_path("stubs/page-builder-plugin/{$stub}.stub"))) { |
| 128 | + $stubPath = __DIR__ . "/../../stubs/{$stub}.stub"; |
| 129 | + } |
| 130 | + |
| 131 | + $contents = strtr(file_get_contents($stubPath), $replacements); |
| 132 | + |
| 133 | + $filesystem->ensureDirectoryExists( |
| 134 | + pathinfo($path, PATHINFO_DIRNAME) |
| 135 | + ); |
| 136 | + |
| 137 | + ray($path, $contents); |
| 138 | + |
| 139 | + $filesystem->put($path, $contents); |
| 140 | + } |
| 141 | + |
| 142 | + private function appClassToPath(string $class): string |
| 143 | + { |
| 144 | + $appNamespace = app()->getNamespace(); |
| 145 | + $relativePath = Str::replaceFirst($appNamespace, '', $class); |
| 146 | + |
| 147 | + return app_path( |
| 148 | + str_replace('\\', '/', $relativePath) . '.php' |
| 149 | + ); |
| 150 | + } |
20 | 151 | } |
0 commit comments