diff --git a/src/Console/AdminLteInstallCommand.php b/src/Console/AdminLteInstallCommand.php index 062285f2..ddec433b 100644 --- a/src/Console/AdminLteInstallCommand.php +++ b/src/Console/AdminLteInstallCommand.php @@ -6,6 +6,7 @@ use JeroenNoten\LaravelAdminLte\Console\PackageResources\AdminlteAssetsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\AuthRoutesResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\AuthViewsResource; +use JeroenNoten\LaravelAdminLte\Console\PackageResources\BladeComponentsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\ConfigResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\LayoutViewsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\TranslationsResource; @@ -19,8 +20,8 @@ class AdminLteInstallCommand extends Command */ protected $signature = 'adminlte:install {--type=basic : The installation type: basic, basic_with_auth, basic_with_views or full} - {--only=* : To install only specific resources: assets, config, translations, auth_views, auth_routes or main_views. Can\'t be mixed with option --with} - {--with=* : To install with additional resources: auth_views, auth_routes or main_views} + {--only=* : To install only specific resources: assets, config, translations, auth_views, auth_routes, main_views or components. Can\'t be mixed with option --with} + {--with=* : To install with additional resources: auth_views, auth_routes, main_views or components} {--force : To force the overwrite of existing files during the installation process} {--interactive : To allow the installation process guide you through it}'; @@ -84,6 +85,7 @@ public function __construct() 'main_views' => new LayoutViewsResource(), 'auth_views' => new AuthViewsResource(), 'auth_routes' => new AuthRoutesResource(), + 'components' => new BladeComponentsResource(), ]; // Add the resources related to each available --type option. @@ -91,7 +93,7 @@ public function __construct() $basic = ['assets', 'config', 'translations']; $basicWithAuth = array_merge($basic, ['auth_views', 'auth_routes']); $basicWithViews = array_merge($basic, ['main_views']); - $full = array_merge($basicWithAuth, ['main_views']); + $full = array_merge($basicWithAuth, ['main_views', 'components']); $this->optTypeResources = [ 'basic' => $basic, @@ -109,6 +111,7 @@ public function __construct() 'main_views' => ['main_views'], 'auth_views' => ['auth_views'], 'auth_routes' => ['auth_routes'], + 'components' => ['components'], ]; // Add the resources related to each available --with option. @@ -117,6 +120,7 @@ public function __construct() 'main_views' => ['main_views'], 'auth_views' => ['auth_views'], 'auth_routes' => ['auth_routes'], + 'components' => ['components'], ]; } diff --git a/src/Console/AdminLteStatusCommand.php b/src/Console/AdminLteStatusCommand.php index 57c6fc30..797f627a 100644 --- a/src/Console/AdminLteStatusCommand.php +++ b/src/Console/AdminLteStatusCommand.php @@ -6,6 +6,7 @@ use JeroenNoten\LaravelAdminLte\Console\PackageResources\AdminlteAssetsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\AuthRoutesResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\AuthViewsResource; +use JeroenNoten\LaravelAdminLte\Console\PackageResources\BladeComponentsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\ConfigResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\LayoutViewsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\TranslationsResource; @@ -74,6 +75,7 @@ public function __construct() 'main_views' => new LayoutViewsResource(), 'auth_views' => new AuthViewsResource(), 'auth_routes' => new AuthRoutesResource(), + 'components' => new BladeComponentsResource(), ]; } @@ -161,10 +163,14 @@ protected function showResourcesStatus($resStatus) ? $this->styleOutput('yes', 'green') : 'no'; + $publishingTarget = is_array($resource->target) + ? implode(PHP_EOL, $resource->target) + : $resource->target; + $tblContent[] = [ $name, $resource->description, - str_replace(base_path('/'), '', $resource->target), + str_replace(base_path().'/', '', $publishingTarget), $requiredLabel, $resStatus[$name] ?? 'Unknown', ]; diff --git a/src/Console/PackageResources/BladeComponentsResource.php b/src/Console/PackageResources/BladeComponentsResource.php new file mode 100644 index 00000000..cb61364e --- /dev/null +++ b/src/Console/PackageResources/BladeComponentsResource.php @@ -0,0 +1,163 @@ +description = 'The set of blade components provided by this package'; + + $this->source = [ + 'classes' => CommandHelper::getPackagePath('src/View/Components'), + 'views' => CommandHelper::getPackagePath('resources/views/components'), + ]; + + $this->target = [ + 'classes' => app_path('View/Components/Adminlte'), + 'views' => CommandHelper::getViewPath('vendor/adminlte/components'), + ]; + + $this->required = false; + + // Fill the set of installation messages. + + $this->messages = [ + 'install' => 'Do you want to publish the blade component files?', + 'overwrite' => 'Blade components were already published. Want to replace?', + 'success' => 'Blade components files published successfully', + ]; + } + + /** + * Installs or publishes the resource. + * + * @return void + */ + public function install() + { + // Copy the component classes to the publishing destination. + + CommandHelper::CopyDirectory( + $this->source['classes'], + $this->target['classes'], + true, + true + ); + + // Copy the component views to the publishing destination. + + CommandHelper::CopyDirectory( + $this->source['views'], + $this->target['views'], + true, + true + ); + + // Adapt published components classes to the Laravel framework, this + // will mainly change the component classes namespace. + + $this->adaptPublishedComponentClasses(); + } + + /** + * Uninstalls the resource. + * + * @return void + */ + public function uninstall() + { + // Remove the component classes from the target folder. When + // component classes does not exists, we consider they as uninstalled. + + if (File::isDirectory($this->target['classes'])) { + File::deleteDirectory($this->target['classes']); + } + + // Remove the component views from the target folder. When + // component views does not exists, we consider they as uninstalled. + + if (File::isDirectory($this->target['views'])) { + File::deleteDirectory($this->target['views']); + } + } + + /** + * Checks whether the resource already exists in the target location. + * + * @return bool + */ + public function exists() + { + return File::isDirectory($this->target['classes']) + || File::isDirectory($this->target['views']); + } + + /** + * Checks whether the resource is correctly installed, i.e. if the source + * items matches with the items available at the target location. + * + * @return bool + */ + public function installed() + { + // Note we can't expect the published component classes to match + // exactly with the default package ones, since the namespace of the + // classes are changed during the installation process. So, we'll just + // control that the number of published component classes matches with + // the packages default ones. + + $srcClassesNum = count(File::allFiles($this->source['classes'])); + + $tgtClassesNum = File::isDirectory($this->target['classes']) + ? count(File::allFiles($this->target['classes'])) + : 0; + + return $srcClassesNum === $tgtClassesNum + && CommandHelper::compareDirectories( + $this->source['views'], + $this->target['views'], + true + ); + } + + /** + * Adapt the published blade component classes by changing their namespace. + * + * @return void + */ + protected function adaptPublishedComponentClasses() + { + // Get an array of all published component classes files. + + $files = File::allFiles($this->target['classes']); + + // Make replacements on each of the collected files. + + foreach ($files as $file) { + $content = File::get($file->getPathname()); + + // Replace the namespace. + + $content = str_replace( + 'namespace JeroenNoten\LaravelAdminLte\View\Components', + 'namespace App\View\Components\Adminlte', + $content + ); + + // Put the new content in the file. + + File::put($file->getPathname(), $content); + } + } +} diff --git a/tests/Console/CommandTestCase.php b/tests/Console/CommandTestCase.php index 8086e418..8a657d5b 100644 --- a/tests/Console/CommandTestCase.php +++ b/tests/Console/CommandTestCase.php @@ -4,6 +4,7 @@ use JeroenNoten\LaravelAdminLte\Console\PackageResources\AdminlteAssetsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\AuthRoutesResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\AuthViewsResource; +use JeroenNoten\LaravelAdminLte\Console\PackageResources\BladeComponentsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\ConfigResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\LayoutViewsResource; use JeroenNoten\LaravelAdminLte\Console\PackageResources\PackageResource; @@ -35,6 +36,7 @@ public function setUp(): void 'main_views' => new LayoutViewsResource(), 'auth_views' => new AuthViewsResource(), 'auth_routes' => new AuthRoutesResource(), + 'components' => new BladeComponentsResource(), ]; } @@ -87,6 +89,11 @@ protected function createDummyResource($name, $resource) $stubFile = CommandHelper::getStubPath('routes.stub'); $content = File::get($stubFile); $this->createDummyFile($target, $content); + } elseif ($name === 'components') { + $view = $target['views'].DIRECTORY_SEPARATOR.'form/input.blade.php'; + $this->createDummyFile($view); + $class = $target['classes'].DIRECTORY_SEPARATOR.'Form/Input.php'; + $this->createDummyFile($class); } } diff --git a/tests/Console/InstallTest.php b/tests/Console/InstallTest.php index 7d932aa0..011b01ae 100644 --- a/tests/Console/InstallTest.php +++ b/tests/Console/InstallTest.php @@ -314,6 +314,7 @@ public function testInstallWithTypeFull() $this->getResources('auth_views'), $this->getResources('auth_routes'), $this->getResources('main_views'), + $this->getResources('components'), ]; // Ensure the required vendor assets exists.