diff --git a/src/Illuminate/Foundation/Console/ViewMakeCommand.php b/src/Illuminate/Foundation/Console/ViewMakeCommand.php new file mode 100644 index 000000000000..49899312c65d --- /dev/null +++ b/src/Illuminate/Foundation/Console/ViewMakeCommand.php @@ -0,0 +1,236 @@ +random(), + $contents, + ); + } + + /** + * Get the destination view path. + * + * @param string $name + * @return string + */ + protected function getPath($name) + { + return $this->viewPath( + $this->getNameInput().'.'.$this->option('extension'), + ); + } + + /** + * Get the desired view name from the input. + * + * @return string + */ + protected function getNameInput() + { + $name = trim($this->argument('name')); + + $name = str_replace(['\\', '.'], '/', $this->argument('name')); + + return $name; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getStub() + { + return $this->resolveStubPath( + '/stubs/view.stub', + ); + } + + /** + * Resolve the fully-qualified path to the stub. + * + * @param string $stub + * @return string + */ + protected function resolveStubPath($stub) + { + return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) + ? $customPath + : __DIR__.$stub; + } + + /** + * Get the destination test case path. + * + * @return string + */ + protected function getTestPath() + { + return base_path( + Str::of($this->testClassFullyQualifiedName()) + ->replace('\\', '/') + ->replaceFirst('Tests/Feature', 'tests/Feature') + ->append('Test.php') + ->value() + ); + } + + /** + * Create the matching test case if requested. + * + * @param string $path + */ + protected function handleTestCreation($path): bool + { + if (! $this->option('test') && ! $this->option('pest')) { + return false; + } + + $contents = preg_replace( + ['/\{{ namespace \}}/', '/\{{ class \}}/', '/\{{ name \}}/'], + [$this->testNamespace(), $this->testClassName(), $this->testViewName()], + File::get($this->getTestStub()), + ); + + File::ensureDirectoryExists(dirname($this->getTestPath()), 0755, true); + + return File::put($this->getTestPath(), $contents); + } + + /** + * Get the namespace for the test. + * + * @return string + */ + protected function testNamespace() + { + return Str::of($this->testClassFullyQualifiedName()) + ->beforeLast('\\') + ->value(); + } + + /** + * Get the class name for the test. + * + * @return string + */ + protected function testClassName() + { + return Str::of($this->testClassFullyQualifiedName()) + ->afterLast('\\') + ->append('Test') + ->value(); + } + + /** + * Get the class fully qualified name for the test. + * + * @return string + */ + protected function testClassFullyQualifiedName() + { + $name = Str::of(Str::lower($this->getNameInput()))->replace('.'.$this->option('extension'), ''); + + $namespacedName = Str::of( + Str::of($name) + ->replace('/', ' ') + ->explode(' ') + ->map(fn ($part) => Str::of($part)->ucfirst()) + ->implode('\\') + ) + ->replace(['-', '_'], ' ') + ->explode(' ') + ->map(fn ($part) => Str::of($part)->ucfirst()) + ->implode(''); + + return 'Tests\\Feature\\View\\'.$namespacedName; + } + + /** + * Get the test stub file for the generator. + * + * @return string + */ + protected function getTestStub() + { + $stubName = 'view.'.($this->option('pest') ? 'pest' : 'test').'.stub'; + + return file_exists($customPath = $this->laravel->basePath("stubs/$stubName")) + ? $customPath + : __DIR__.'/stubs/'.$stubName; + } + + /** + * Get the view name for the test. + * + * @return string + */ + protected function testViewName() + { + return Str::of($this->getNameInput()) + ->replace('/', '.') + ->lower() + ->value(); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getOptions() + { + return [ + ['extension', null, InputOption::VALUE_OPTIONAL, 'The extension of the generated view', 'blade.php'], + ['force', 'f', InputOption::VALUE_NONE, 'Create the view even if the view already exists'], + ]; + } +} diff --git a/src/Illuminate/Foundation/Console/stubs/view.pest.stub b/src/Illuminate/Foundation/Console/stubs/view.pest.stub new file mode 100644 index 000000000000..93d07907caa4 --- /dev/null +++ b/src/Illuminate/Foundation/Console/stubs/view.pest.stub @@ -0,0 +1,9 @@ +view('{{ name }}', [ + // + ]); + + $contents->assertSee(''); +}); diff --git a/src/Illuminate/Foundation/Console/stubs/view.stub b/src/Illuminate/Foundation/Console/stubs/view.stub new file mode 100644 index 000000000000..6ecd80c26413 --- /dev/null +++ b/src/Illuminate/Foundation/Console/stubs/view.stub @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/Illuminate/Foundation/Console/stubs/view.test.stub b/src/Illuminate/Foundation/Console/stubs/view.test.stub new file mode 100644 index 000000000000..8b9a9bf0f833 --- /dev/null +++ b/src/Illuminate/Foundation/Console/stubs/view.test.stub @@ -0,0 +1,20 @@ +view('{{ name }}', [ + // + ]); + + $contents->assertSee(''); + } +} diff --git a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php index f78472a98b32..b92bd4ac91cb 100755 --- a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php +++ b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php @@ -76,6 +76,7 @@ use Illuminate\Foundation\Console\VendorPublishCommand; use Illuminate\Foundation\Console\ViewCacheCommand; use Illuminate\Foundation\Console\ViewClearCommand; +use Illuminate\Foundation\Console\ViewMakeCommand; use Illuminate\Notifications\Console\NotificationTableCommand; use Illuminate\Queue\Console\BatchesTableCommand; use Illuminate\Queue\Console\ClearCommand as QueueClearCommand; @@ -204,6 +205,7 @@ class ArtisanServiceProvider extends ServiceProvider implements DeferrableProvid 'StubPublish' => StubPublishCommand::class, 'TestMake' => TestMakeCommand::class, 'VendorPublish' => VendorPublishCommand::class, + 'ViewMake' => ViewMakeCommand::class, ]; /**