diff --git a/src/BladeX.php b/src/BladeX.php index fe76a0b..70375a1 100755 --- a/src/BladeX.php +++ b/src/BladeX.php @@ -3,7 +3,6 @@ namespace Spatie\BladeX; use Illuminate\Support\Str; -use Illuminate\Support\Facades\File; use Symfony\Component\Finder\SplFileInfo; use Spatie\BladeX\ComponentDirectory\RegularDirectory; use Spatie\BladeX\Exceptions\CouldNotRegisterComponent; @@ -111,18 +110,21 @@ public function getPrefix(): string * * @return \Spatie\BladeX\ComponentCollection|\Spatie\BladeX\Component[] */ - public function registerComponents(string $viewDirectory): ComponentCollection + public function registerComponents(string $viewDirectory) { if (! Str::endsWith($viewDirectory, '*')) { throw CouldNotRegisterComponent::viewDirectoryWithoutWildcard($viewDirectory); } + $includeSubdirectories = Str::endsWith($viewDirectory, '**.*'); + $componentDirectory = Str::contains($viewDirectory, '::') - ? new NamespacedDirectory($viewDirectory) - : new RegularDirectory($viewDirectory); + ? new NamespacedDirectory($viewDirectory, $includeSubdirectories) + : new RegularDirectory($viewDirectory, $includeSubdirectories); return $this->registerViews( - ComponentCollection::make(File::files($componentDirectory->getAbsoluteDirectory())) + ComponentCollection::make($componentDirectory->getFiles()) + ->filter(function (SplFileInfo $file) { return Str::endsWith($file->getFilename(), '.blade.php'); }) diff --git a/src/ComponentDirectory/ComponentDirectory.php b/src/ComponentDirectory/ComponentDirectory.php index 75d0910..9920d02 100644 --- a/src/ComponentDirectory/ComponentDirectory.php +++ b/src/ComponentDirectory/ComponentDirectory.php @@ -3,6 +3,7 @@ namespace Spatie\BladeX\ComponentDirectory; use Illuminate\Support\Str; +use Illuminate\Support\Facades\File; use Symfony\Component\Finder\SplFileInfo; abstract class ComponentDirectory @@ -10,12 +11,28 @@ abstract class ComponentDirectory /** @var string */ protected $viewDirectory; + /** @var bool */ + protected $includeSubdirectories; + abstract public function getAbsoluteDirectory(): string; public function getViewName(SplFileInfo $viewFile): string { + $subDirectory = $viewFile->getRelativePath(); + $view = Str::replaceLast('.blade.php', '', $viewFile->getFilename()); - return empty($this->viewDirectory) ? $view : "{$this->viewDirectory}.{$view}"; + return implode('.', array_filter([ + $this->viewDirectory, + $subDirectory, + $view, + ])); + } + + public function getFiles(): array + { + return $this->includeSubdirectories + ? File::allFiles($this->getAbsoluteDirectory()) + : File::files($this->getAbsoluteDirectory()); } } diff --git a/src/ComponentDirectory/NamespacedDirectory.php b/src/ComponentDirectory/NamespacedDirectory.php index c600623..de1cc07 100644 --- a/src/ComponentDirectory/NamespacedDirectory.php +++ b/src/ComponentDirectory/NamespacedDirectory.php @@ -12,10 +12,11 @@ class NamespacedDirectory extends ComponentDirectory /** @var string */ protected $namespace; - public function __construct(string $viewDirectory) + public function __construct(string $viewDirectory, bool $includeSubdirectories) { [$this->namespace, $viewDirectory] = explode('::', $viewDirectory); $this->viewDirectory = trim(Str::before($viewDirectory, '*'), '.'); + $this->includeSubdirectories = $includeSubdirectories; } public function getAbsoluteDirectory(): string diff --git a/src/ComponentDirectory/RegularDirectory.php b/src/ComponentDirectory/RegularDirectory.php index 0c562aa..517e3ff 100644 --- a/src/ComponentDirectory/RegularDirectory.php +++ b/src/ComponentDirectory/RegularDirectory.php @@ -8,9 +8,10 @@ class RegularDirectory extends ComponentDirectory { - public function __construct(string $viewDirectory) + public function __construct(string $viewDirectory, bool $includeSubdirectories) { $this->viewDirectory = Str::before($viewDirectory, '.*'); + $this->includeSubdirectories = $includeSubdirectories; } public function getAbsoluteDirectory(): string diff --git a/tests/Features/Registration/RegistrationTest.php b/tests/Features/Registration/RegistrationTest.php index 2b36340..293bf8d 100644 --- a/tests/Features/Registration/RegistrationTest.php +++ b/tests/Features/Registration/RegistrationTest.php @@ -197,7 +197,7 @@ public function it_can_register_a_subdirectory_containing_namespaced_view_compon $this->assertEquals([ 'context' => 'bladex::context', - 'subdirectory-namespaced-test::namespaced-view1' => 'subdirectory-namespaced-test::components.namespacedView1', + 'subdirectory-namespaced-test::namespaced-view4' => 'subdirectory-namespaced-test::components.namespacedView4', ], $registeredComponents); } @@ -313,7 +313,7 @@ public function it_can_register_a_directory_containing_namespaced_view_component 'namespaced-view1' => 'namespaced-test::namespacedView1', 'namespaced-view2' => 'namespaced-test::namespacedView2', 'namespaced-view3' => 'namespaced-test::namespacedView3', - 'namespaced-test::namespaced-view1' => 'namespaced-test::components.namespacedView1', + 'namespaced-test::namespaced-view4' => 'namespaced-test::components.namespacedView4', ], $registeredComponents); } @@ -339,7 +339,7 @@ public function it_can_register_a_directory_containing_namespaced_view_component 'x-namespaced-view1' => 'namespaced-test::namespacedView1', 'x-namespaced-view2' => 'namespaced-test::namespacedView2', 'x-namespaced-view3' => 'namespaced-test::namespacedView3', - 'x-namespaced-test::namespaced-view1' => 'namespaced-test::components.namespacedView1', + 'x-namespaced-test::namespaced-view4' => 'namespaced-test::components.namespacedView4', ], $registeredComponents); } @@ -363,7 +363,7 @@ public function it_can_register_a_directory_containing_namespaced_view_component 'ns-namespaced-view1' => 'namespaced-test::namespacedView1', 'ns-namespaced-view2' => 'namespaced-test::namespacedView2', 'ns-namespaced-view3' => 'namespaced-test::namespacedView3', - 'namespaced-test::namespaced-view1' => 'namespaced-test::components.namespacedView1', + 'namespaced-test::namespaced-view4' => 'namespaced-test::components.namespacedView4', ], $registeredComponents); } @@ -389,7 +389,7 @@ public function it_can_register_a_directory_containing_namespaced_view_component 'ns-namespaced-view1' => 'namespaced-test::namespacedView1', 'ns-namespaced-view2' => 'namespaced-test::namespacedView2', 'ns-namespaced-view3' => 'namespaced-test::namespacedView3', - 'nsc-namespaced-view1' => 'namespaced-test::components.namespacedView1', + 'nsc-namespaced-view4' => 'namespaced-test::components.namespacedView4', ], $registeredComponents); } @@ -449,4 +449,26 @@ public function it_can_register_multiple_views_with_prefix() 'context' => 'bladex::context', ], $registeredComponents); } + + /** @test */ + public function it_can_register_a_directory_and_subdirectories_containing_namespaced_view_components() + { + View::addNamespace('namespaced-test', __DIR__.'/stubs/components/namespacedComponents'); + + BladeX::component('namespaced-test::**.*'); + + $registeredComponents = collect(BladeX::registeredComponents()) + ->mapWithKeys(function (Component $bladeXComponent) { + return [$bladeXComponent->getTag() => $bladeXComponent->view]; + }) + ->toArray(); + + $this->assertEquals([ + 'context' => 'bladex::context', + 'namespaced-test::namespaced-view1' => 'namespaced-test::namespacedView1', + 'namespaced-test::namespaced-view2' => 'namespaced-test::namespacedView2', + 'namespaced-test::namespaced-view3' => 'namespaced-test::namespacedView3', + 'namespaced-test::namespaced-view4' => 'namespaced-test::components.namespacedView4', + ], $registeredComponents); + } } diff --git a/tests/Features/Registration/stubs/components/namespacedComponents/components/namespacedView1.blade.php b/tests/Features/Registration/stubs/components/namespacedComponents/components/namespacedView4.blade.php similarity index 100% rename from tests/Features/Registration/stubs/components/namespacedComponents/components/namespacedView1.blade.php rename to tests/Features/Registration/stubs/components/namespacedComponents/components/namespacedView4.blade.php