allow vendord
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s

This commit is contained in:
2026-03-30 14:54:57 +07:00
parent 66aed7c4e8
commit b5e3a778ce
21316 changed files with 2777892 additions and 13 deletions

View File

@@ -0,0 +1,210 @@
<?php
namespace Nwidart\Modules\Activators;
use Illuminate\Cache\CacheManager;
use Illuminate\Config\Repository as Config;
use Illuminate\Container\Container;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Filesystem\Filesystem;
use Nwidart\Modules\Contracts\ActivatorInterface;
use Nwidart\Modules\Module;
class FileActivator implements ActivatorInterface
{
/**
* Laravel cache instance
*
* @var CacheManager
*/
private $cache;
/**
* Laravel Filesystem instance
*
* @var Filesystem
*/
private $files;
/**
* Laravel config instance
*
* @var Config
*/
private $config;
/**
* @var string
*/
private $cacheKey;
/**
* @var string
*/
private $cacheLifetime;
/**
* Array of modules activation statuses
*
* @var array
*/
private $modulesStatuses;
/**
* File used to store activation statuses
*
* @var string
*/
private $statusesFile;
public function __construct(Container $app)
{
$this->cache = $app['cache'];
$this->files = $app['files'];
$this->config = $app['config'];
$this->statusesFile = $this->config('statuses-file');
$this->cacheKey = $this->config('cache-key');
$this->cacheLifetime = $this->config('cache-lifetime');
$this->modulesStatuses = $this->getModulesStatuses();
}
/**
* Get the path of the file where statuses are stored
*
* @return string
*/
public function getStatusesFilePath(): string
{
return $this->statusesFile;
}
/**
* @inheritDoc
*/
public function reset(): void
{
if ($this->files->exists($this->statusesFile)) {
$this->files->delete($this->statusesFile);
}
$this->modulesStatuses = [];
$this->flushCache();
}
/**
* @inheritDoc
*/
public function enable(Module $module): void
{
$this->setActiveByName($module->getName(), true);
}
/**
* @inheritDoc
*/
public function disable(Module $module): void
{
$this->setActiveByName($module->getName(), false);
}
/**
* @inheritDoc
*/
public function hasStatus(Module $module, bool $status): bool
{
if (!isset($this->modulesStatuses[$module->getName()])) {
return $status === false;
}
return $this->modulesStatuses[$module->getName()] === $status;
}
/**
* @inheritDoc
*/
public function setActive(Module $module, bool $active): void
{
$this->setActiveByName($module->getName(), $active);
}
/**
* @inheritDoc
*/
public function setActiveByName(string $name, bool $status): void
{
$this->modulesStatuses[$name] = $status;
$this->writeJson();
$this->flushCache();
}
/**
* @inheritDoc
*/
public function delete(Module $module): void
{
if (!isset($this->modulesStatuses[$module->getName()])) {
return;
}
unset($this->modulesStatuses[$module->getName()]);
$this->writeJson();
$this->flushCache();
}
/**
* Writes the activation statuses in a file, as json
*/
private function writeJson(): void
{
$this->files->put($this->statusesFile, json_encode($this->modulesStatuses, JSON_PRETTY_PRINT));
}
/**
* Reads the json file that contains the activation statuses.
* @return array
* @throws FileNotFoundException
*/
private function readJson(): array
{
if (!$this->files->exists($this->statusesFile)) {
return [];
}
return json_decode($this->files->get($this->statusesFile), true);
}
/**
* Get modules statuses, either from the cache or from
* the json statuses file if the cache is disabled.
* @return array
* @throws FileNotFoundException
*/
private function getModulesStatuses(): array
{
if (!$this->config->get('modules.cache.enabled')) {
return $this->readJson();
}
return $this->cache->store($this->config->get('modules.cache.driver'))->remember($this->cacheKey, $this->cacheLifetime, function () {
return $this->readJson();
});
}
/**
* Reads a config parameter under the 'activators.file' key
*
* @param string $key
* @param $default
* @return mixed
*/
private function config(string $key, $default = null)
{
return $this->config->get('modules.activators.file.' . $key, $default);
}
/**
* Flushes the modules activation statuses cache
*/
private function flushCache(): void
{
$this->cache->store($this->config->get('modules.cache.driver'))->forget($this->cacheKey);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Nwidart\Modules;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Collection as BaseCollection;
class Collection extends BaseCollection
{
/**
* Get items collections.
*
* @return array
*/
public function getItems()
{
return $this->items;
}
/**
* Get the collection of items as a plain array.
*
* @return array
*/
public function toArray()
{
return array_map(function ($value) {
if ($value instanceof Module) {
$attributes = $value->json()->getAttributes();
$attributes["path"] = $value->getPath();
return $attributes;
}
return $value instanceof Arrayable ? $value->toArray() : $value;
}, $this->items);
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
final class ChannelMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-channel';
protected $argumentName = 'name';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new channel class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.channels.namespace') ?: $module->config('paths.generator.channels.path', 'Broadcasting');
}
/**
* Get template contents.
*
* @return string
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/channel.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* Get the destination file path.
*
* @return string
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$channelPath = GenerateConfigReader::read('channels');
return $path . $channelPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the channel class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
}

View File

@@ -0,0 +1,251 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Symfony\Component\Console\Input\InputArgument;
class CheckLangCommand extends Command
{
private $langPath;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:lang';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check missing language keys in the specified module.';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->langPath = DIRECTORY_SEPARATOR . config('modules.paths.generator.lang.path', 'Resources/lang');
$this->components->alert('Checking languages ...');
$this->newLine();
if ($name = $this->argument('module')) {
$this->check($name);
return 0;
}
$this->checkAll();
return 0;
}
/**
* enableAll
*
* @return void
*/
public function checkAll()
{
$modules = $this->laravel['modules']->all();
foreach ($modules as $module) {
$this->check($module);
}
}
/**
* enable
*
* @param string $name
* @return void
*/
public function check($name)
{
if ($name instanceof Module) {
$module = $name;
} else {
$module = $this->laravel['modules']->findOrFail($name);
}
$directories = $this->getDirectories($module);
if (! $directories) {
return;
}
$this->checkMissingFiles($directories);
$this->checkMissingKeys($directories);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'Module name.'],
];
}
private function getLangFiles($module)
{
$files = [];
$path = $module->getPath() . $this->langPath;
if (is_dir($path)) {
$files = array_merge($files, $this->laravel['files']->all($path));
}
return $files;
}
private function getDirectories($module)
{
$moduleName = $module->getStudlyName();
$path = $module->getPath() . '/Resources/lang';
if (is_dir($path)) {
$directories = $this->laravel['files']->directories($path);
$directories = array_map(function ($directory) use ($moduleName) {
return [
'name' => basename($directory),
'module' => $moduleName,
'path' => $directory,
'files' => array_map(function ($file) {
return basename($file);
}, \File::glob($directory . DIRECTORY_SEPARATOR . "*")),
];
}, $directories);
}
if (count($directories) == 0) {
$this->components->info("No language files found in module $moduleName");
return false;
}
if (count($directories) == 1) {
$this->components->warn("Only one language file found in module $moduleName");
return false;
}
return collect($directories);
}
private function checkMissingFiles(Collection $directories)
{
//show missing files
$missingFilesMessage = [];
$uniqeLangFiles = $directories->pluck('files')->flatten()->unique()->values();
$directories->each(function ($directory) use ($uniqeLangFiles, &$missingFilesMessage) {
$missingFiles = $uniqeLangFiles->diff($directory['files']);
if ($missingFiles->count() > 0) {
$missingFiles->each(function ($missingFile) use ($directory, &$missingFilesMessage) {
$missingFilesMessage[$directory['name']][] = " {$directory['module']} - Missing language file: {$directory['name']}/{$missingFile}";
});
}
});
if (count($missingFilesMessage) > 0) {
collect($missingFilesMessage)->each(function ($messages, $langDirectory) {
$this->components->error("Missing language files in $langDirectory directory");
$this->components->bulletList(
collect($messages)->unique()->values()->toArray()
);
$this->newLine();
});
}
}
private function checkMissingKeys(Collection $directories)
{
//show missing keys
$uniqeLangFiles = $directories->pluck('files')->flatten()->unique();
$langDirectories = $directories->pluck('name');
$missingKeysMessage = [];
$directories->each(function ($directory) use ($uniqeLangFiles, $langDirectories, &$missingKeysMessage) {
$uniqeLangFiles->each(function ($file) use ($directory, $langDirectories, &$missingKeysMessage) {
$langKeys = $this->getLangKeys($directory['path'] . DIRECTORY_SEPARATOR . $file);
if ($langKeys == false) {
return;
}
$langDirectories->each(function ($langDirectory) use ($directory, $file, $langKeys, &$missingKeysMessage) {
if ($directory['name'] != $langDirectory) {
$basePath = str_replace($directory['name'], $langDirectory, $directory['path']);
$otherLangKeys = $this->getLangKeys($basePath . DIRECTORY_SEPARATOR . $file);
if ($otherLangKeys == false) {
return;
}
$missingKeys = $langKeys->diff($otherLangKeys);
if ($missingKeys->count() > 0) {
$missingKeys->each(function ($missingKey) use ($directory, $langDirectory, $file, &$missingKeysMessage) {
$missingKeysMessage[$langDirectory][] = " {$directory['module']} - Missing language key: {$langDirectory}/{$file} | key: $missingKey";
});
}
}
});
});
});
if (count($missingKeysMessage) > 0) {
collect($missingKeysMessage)->each(function ($messages, $langDirectory) {
$this->components->error("Missing language keys for directory $langDirectory:");
$this->components->bulletList(
collect($messages)->unique()->values()->toArray()
);
$this->newLine();
});
}
}
private function getLangKeys($file)
{
if (\File::exists($file)) {
$lang = \File::getRequire($file);
return collect(\Arr::dot($lang))->keys();
} else {
return false;
}
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class CommandMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-command';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate new Artisan command for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.command.namespace') ?: $module->config('paths.generator.command.path', 'Console');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the command.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['command', null, InputOption::VALUE_OPTIONAL, 'The terminal command that should be assigned.', null],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/command.stub', [
'COMMAND_NAME' => $this->getCommandName(),
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* @return string
*/
private function getCommandName()
{
return $this->option('command') ?: 'command:name';
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$commandPath = GenerateConfigReader::read('command');
return $path . $commandPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class ComponentClassMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-component';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new component-class for the specified module.';
public function handle(): int
{
if (parent::handle() === E_ERROR) {
return E_ERROR;
}
$this->writeComponentViewTemplate();
return 0;
}
/**
* Write the view template for the component.
*
* @return void
*/
protected function writeComponentViewTemplate()
{
$this->call('module:make-component-view', ['name' => $this->argument('name') , 'module' => $this->argument('module')]);
}
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.component-class.namespace') ?: $module->config('paths.generator.component-class.path', 'View/Component');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the component.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/component-class.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
'LOWER_NAME' => $module->getLowerName(),
'COMPONENT_NAME' => 'components.' . Str::lower($this->argument('name')),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$factoryPath = GenerateConfigReader::read('component-class');
return $path . $factoryPath->getPath() . '/' . $this->getFileName();
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name')) . '.php';
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class ComponentViewMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-component-view';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new component-view for the specified module.';
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the component.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
return (new Stub('/component-view.stub', ['QUOTE'=> Inspiring::quote()]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$factoryPath = GenerateConfigReader::read('component-view');
return $path . $factoryPath->getPath() . '/' . $this->getFileName();
}
/**
* @return string
*/
private function getFileName()
{
return Str::lower($this->argument('name')) . '.blade.php';
}
}

View File

@@ -0,0 +1,141 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ControllerMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument being used.
*
* @var string
*/
protected $argumentName = 'controller';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-controller';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate new restful controller for the specified module.';
/**
* Get controller name.
*
* @return string
*/
public function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$controllerPath = GenerateConfigReader::read('controller');
return $path . $controllerPath->getPath() . '/' . $this->getControllerName() . '.php';
}
/**
* @return string
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub($this->getStubName(), [
'MODULENAME' => $module->getStudlyName(),
'CONTROLLERNAME' => $this->getControllerName(),
'NAMESPACE' => $module->getStudlyName(),
'CLASS_NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getControllerNameWithoutNamespace(),
'LOWER_NAME' => $module->getLowerName(),
'MODULE' => $this->getModuleName(),
'NAME' => $this->getModuleName(),
'STUDLY_NAME' => $module->getStudlyName(),
'MODULE_NAMESPACE' => $this->laravel['modules']->config('namespace'),
]))->render();
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['controller', InputArgument::REQUIRED, 'The name of the controller class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* @return array
*/
protected function getOptions()
{
return [
['plain', 'p', InputOption::VALUE_NONE, 'Generate a plain controller', null],
['api', null, InputOption::VALUE_NONE, 'Exclude the create and edit methods from the controller.'],
];
}
/**
* @return array|string
*/
protected function getControllerName()
{
$controller = Str::studly($this->argument('controller'));
if (Str::contains(strtolower($controller), 'controller') === false) {
$controller .= 'Controller';
}
return $controller;
}
/**
* @return array|string
*/
private function getControllerNameWithoutNamespace()
{
return class_basename($this->getControllerName());
}
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.controller.namespace') ?: $module->config('paths.generator.controller.path', 'Http/Controllers');
}
/**
* Get the stub file name based on the options
* @return string
*/
protected function getStubName()
{
if ($this->option('plain') === true) {
$stub = '/controller-plain.stub';
} elseif ($this->option('api') === true) {
$stub = '/controller-api.stub';
} else {
$stub = '/controller.stub';
}
return $stub;
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Module;
use Symfony\Component\Console\Input\InputArgument;
class DisableCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:disable';
/**
* The console command signature.
*
* @var string
*/
protected $signature = 'module:disable {module?*}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Disable an array of modules.';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('Disabling module ...');
if (count($this->argument('module'))) {
foreach($this->argument('module') as $name) {
$this->disable($name);
}
return 0;
}
$this->disableAll();
return 0;
}
/**
* disableAll
*
* @return void
*/
public function disableAll()
{
/** @var Modules $modules */
$modules = $this->laravel['modules']->all();
foreach ($modules as $module) {
$this->disable($module);
}
}
/**
* disable
*
* @param string $name
* @return void
*/
public function disable($name)
{
if ($name instanceof Module) {
$module = $name;
}else {
$module = $this->laravel['modules']->findOrFail($name);
}
if ($module->isEnabled()) {
$module->disable();
$this->components->info("Module [{$module}] disabled successful.");
} else {
$this->components->warn("Module [{$module}] has already disabled.");
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'Module name.'],
];
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Module;
use Symfony\Component\Console\Input\InputArgument;
class DumpCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:dump';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Dump-autoload the specified module or for all module.';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('Generating optimized autoload modules.');
if ($name = $this->argument('module') ) {
$this->dump($name);
return 0;
}
$this->dumpAll();
return 0;
}
/**
* dumpAll
*
* @return void
*/
public function dumpAll()
{
/** @var Modules $modules */
$modules = $this->laravel['modules']->all();
foreach ($modules as $module) {
$this->dump($module);
}
}
public function dump($name)
{
if ($name instanceof Module) {
$module = $name;
} else {
$module = $this->laravel['modules']->findOrFail($name);
}
$this->components->task("$module", function () use ($module) {
chdir($module->getPath());
passthru('composer dump -o -n -q');
});
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'Module name.'],
];
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Module;
use Symfony\Component\Console\Input\InputArgument;
class EnableCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:enable';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Enable the specified module.';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('Enabling module ...');
if ($name = $this->argument('module') ) {
$this->enable($name);
return 0;
}
$this->enableAll();
return 0;
}
/**
* enableAll
*
* @return void
*/
public function enableAll()
{
/** @var Modules $modules */
$modules = $this->laravel['modules']->all();
foreach ($modules as $module) {
$this->enable($module);
}
}
/**
* enable
*
* @param string $name
* @return void
*/
public function enable($name)
{
if ($name instanceof Module) {
$module = $name;
}else {
$module = $this->laravel['modules']->findOrFail($name);
}
if ($module->isDisabled()) {
$module->enable();
$this->components->info("Module [{$module}] enabled successful.");
}else {
$this->components->warn("Module [{$module}] has already enabled.");
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'Module name.'],
];
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class EventMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-event';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new event class for the specified module';
public function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/event.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
public function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$eventPath = GenerateConfigReader::read('event');
return $path . $eventPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
protected function getFileName()
{
return Str::studly($this->argument('name'));
}
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.event.namespace') ?: $module->config('paths.generator.event.path', 'Events');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the event.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class FactoryMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-factory';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new model factory for the specified module.';
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the model.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/factory.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'NAME' => $this->getModelName(),
'MODEL_NAMESPACE' => $this->getModelNamespace(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$factoryPath = GenerateConfigReader::read('factory');
return $path . $factoryPath->getPath() . '/' . $this->getFileName();
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name')) . 'Factory.php';
}
/**
* @return mixed|string
*/
private function getModelName()
{
return Str::studly($this->argument('name'));
}
/**
* Get default namespace.
*
* @return string
*/
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.factory.namespace') ?: $module->config('paths.generator.factory.path');
}
/**
* Get model namespace.
*
* @return string
*/
public function getModelNamespace(): string
{
$path = $this->laravel['modules']->config('paths.generator.model.path', 'Entities');
$path = str_replace('/', '\\', $path);
return $this->laravel['modules']->config('namespace') . '\\' . $this->laravel['modules']->findOrFail($this->getModuleName()) . '\\' . $path;
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Exceptions\FileAlreadyExistException;
use Nwidart\Modules\Generators\FileGenerator;
abstract class GeneratorCommand extends Command
{
/**
* The name of 'name' argument.
*
* @var string
*/
protected $argumentName = '';
/**
* Get template contents.
*
* @return string
*/
abstract protected function getTemplateContents();
/**
* Get the destination file path.
*
* @return string
*/
abstract protected function getDestinationFilePath();
/**
* Execute the console command.
*/
public function handle(): int
{
$path = str_replace('\\', '/', $this->getDestinationFilePath());
if (!$this->laravel['files']->isDirectory($dir = dirname($path))) {
$this->laravel['files']->makeDirectory($dir, 0777, true);
}
$contents = $this->getTemplateContents();
try {
$this->components->task("Generating file {$path}",function () use ($path,$contents) {
$overwriteFile = $this->hasOption('force') ? $this->option('force') : false;
(new FileGenerator($path, $contents))->withFileOverwrite($overwriteFile)->generate();
});
} catch (FileAlreadyExistException $e) {
$this->components->error("File : {$path} already exists.");
return E_ERROR;
}
return 0;
}
/**
* Get class name.
*
* @return string
*/
public function getClass()
{
return class_basename($this->argument($this->argumentName));
}
/**
* Get default namespace.
*
* @return string
*/
public function getDefaultNamespace(): string
{
return '';
}
/**
* Get class namespace.
*
* @param \Nwidart\Modules\Module $module
*
* @return string
*/
public function getClassNamespace($module)
{
$extra = str_replace($this->getClass(), '', $this->argument($this->argumentName));
$extra = str_replace('/', '\\', $extra);
$namespace = $this->laravel['modules']->config('namespace');
$namespace .= '\\' . $module->getStudlyName();
$namespace .= '\\' . $this->getDefaultNamespace();
$namespace .= '\\' . $extra;
$namespace = str_replace('/', '\\', $namespace);
return trim($namespace, '\\');
}
}

View File

@@ -0,0 +1,148 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Json;
use Nwidart\Modules\Process\Installer;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class InstallCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:install';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Install the specified module by given package name (vendor/name).';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle(): int
{
if (is_null($this->argument('name'))) {
return $this->installFromFile();
}
$this->install(
$this->argument('name'),
$this->argument('version'),
$this->option('type'),
$this->option('tree')
);
return 0;
}
/**
* Install modules from modules.json file.
*/
protected function installFromFile(): int
{
if (!file_exists($path = base_path('modules.json'))) {
$this->error("File 'modules.json' does not exist in your project root.");
return E_ERROR;
}
$modules = Json::make($path);
$dependencies = $modules->get('require', []);
foreach ($dependencies as $module) {
$module = collect($module);
$this->install(
$module->get('name'),
$module->get('version'),
$module->get('type')
);
}
return 0;
}
/**
* Install the specified module.
*
* @param string $name
* @param string $version
* @param string $type
* @param bool $tree
*/
protected function install($name, $version = 'dev-master', $type = 'composer', $tree = false)
{
$installer = new Installer(
$name,
$version,
$type ?: $this->option('type'),
$tree ?: $this->option('tree')
);
$installer->setRepository($this->laravel['modules']);
$installer->setConsole($this);
if ($timeout = $this->option('timeout')) {
$installer->setTimeout($timeout);
}
if ($path = $this->option('path')) {
$installer->setPath($path);
}
$installer->run();
if (!$this->option('no-update')) {
$this->call('module:update', [
'module' => $installer->getModuleName(),
]);
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::OPTIONAL, 'The name of module will be installed.'],
['version', InputArgument::OPTIONAL, 'The version of module will be installed.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['timeout', null, InputOption::VALUE_OPTIONAL, 'The process timeout.', null],
['path', null, InputOption::VALUE_OPTIONAL, 'The installation path.', null],
['type', null, InputOption::VALUE_OPTIONAL, 'The type of installation.', null],
['tree', null, InputOption::VALUE_NONE, 'Install the module as a git subtree', null],
['no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.', null],
];
}
}

View File

@@ -0,0 +1,112 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class JobMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-job';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new job class for the specified module';
protected $argumentName = 'name';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.jobs.namespace') ?: $module->config('paths.generator.jobs.path', 'Jobs');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the job.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['sync', null, InputOption::VALUE_NONE, 'Indicates that job should be synchronous.'],
];
}
/**
* Get template contents.
*
* @return string
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub($this->getStubName(), [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* Get the destination file path.
*
* @return string
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$jobPath = GenerateConfigReader::read('jobs');
return $path . $jobPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
/**
* @return string
*/
protected function getStubName(): string
{
if ($this->option('sync')) {
return '/job.stub';
}
return '/job-queued.stub';
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Contracts\RepositoryInterface;
use Nwidart\Modules\Module;
class LaravelModulesV6Migrator extends Command
{
protected $name = 'module:v6:migrate';
protected $description = 'Migrate laravel-modules v5 modules statuses to v6.';
public function handle(): int
{
$moduleStatuses = [];
/** @var RepositoryInterface $modules */
$modules = $this->laravel['modules'];
$modules = $modules->all();
/** @var Module $module */
foreach ($modules as $module) {
if ($module->json()->get('active') === 1) {
$module->enable();
$moduleStatuses[] = [$module->getName(), 'Enabled'];
}
if ($module->json()->get('active') === 0) {
$module->disable();
$moduleStatuses[] = [$module->getName(), 'Disabled'];
}
}
$this->info('All modules have been migrated.');
$this->table(['Module name', 'Status'], $moduleStatuses);
return 0;
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Module;
use Symfony\Component\Console\Input\InputOption;
class ListCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:list';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Show list of all modules.';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->twoColumnDetail('<fg=gray>Status / Name</>', '<fg=gray>Path / priority</>');
collect($this->getRows())->each(function ($row) {
$this->components->twoColumnDetail("[{$row[1]}] {$row[0]}", "{$row[3]} [{$row[2]}]");
});
return 0;
}
/**
* Get table rows.
*
* @return array
*/
public function getRows()
{
$rows = [];
/** @var Module $module */
foreach ($this->getModules() as $module) {
$rows[] = [
$module->getName(),
$module->isEnabled() ? '<fg=green>Enabled</>' : '<fg=red>Disabled</>',
$module->get('priority'),
$module->getPath(),
];
}
return $rows;
}
public function getModules()
{
switch ($this->option('only')) {
case 'enabled':
return $this->laravel['modules']->getByStatus(1);
break;
case 'disabled':
return $this->laravel['modules']->getByStatus(0);
break;
case 'priority':
return $this->laravel['modules']->getPriority($this->option('direction'));
break;
default:
return $this->laravel['modules']->all();
break;
}
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['only', 'o', InputOption::VALUE_OPTIONAL, 'Types of modules will be displayed.', null],
['direction', 'd', InputOption::VALUE_OPTIONAL, 'The direction of ordering.', 'asc'],
];
}
}

View File

@@ -0,0 +1,129 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Module;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ListenerMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-listener';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new event listener class for the specified module';
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the command.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['event', 'e', InputOption::VALUE_OPTIONAL, 'The event class being listened for.'],
['queued', null, InputOption::VALUE_NONE, 'Indicates the event listener should be queued.'],
];
}
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub($this->getStubName(), [
'NAMESPACE' => $this->getClassNamespace($module),
'EVENTNAME' => $this->getEventName($module),
'SHORTEVENTNAME' => $this->getShortEventName(),
'CLASS' => $this->getClass(),
]))->render();
}
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.listener.namespace') ?: $module->config('paths.generator.listener.path', 'Listeners');
}
protected function getEventName(Module $module)
{
$namespace = $this->laravel['modules']->config('namespace') . "\\" . $module->getStudlyName();
$eventPath = GenerateConfigReader::read('event');
$eventName = $namespace . "\\" . $eventPath->getPath() . "\\" . $this->option('event');
return str_replace('/', '\\', $eventName);
}
protected function getShortEventName()
{
return class_basename($this->option('event'));
}
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$listenerPath = GenerateConfigReader::read('listener');
return $path . $listenerPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
protected function getFileName()
{
return Str::studly($this->argument('name'));
}
/**
* @return string
*/
protected function getStubName(): string
{
if ($this->option('queued')) {
if ($this->option('event')) {
return '/listener-queued.stub';
}
return '/listener-queued-duck.stub';
}
if ($this->option('event')) {
return '/listener.stub';
}
return '/listener-duck.stub';
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class MailMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-mail';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new email class for the specified module';
protected $argumentName = 'name';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.emails.namespace') ?: $module->config('paths.generator.emails.path', 'Emails');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the mailable.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get template contents.
*
* @return string
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/mail.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* Get the destination file path.
*
* @return string
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$mailPath = GenerateConfigReader::read('emails');
return $path . $mailPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class MiddlewareMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-middleware';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new middleware class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.filter.namespace') ?: $module->config('paths.generator.filter.path', 'Http/Middleware');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the command.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/middleware.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$middlewarePath = GenerateConfigReader::read('filter');
return $path . $middlewarePath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
/**
* Run the command.
*/
public function handle(): int
{
$this->components->info('Creating middleware...');
parent::handle();
return 0;
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Migrations\Migrator;
use Nwidart\Modules\Module;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MigrateCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:migrate';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Migrate the migrations from the specified module or from all modules.';
/**
* @var \Nwidart\Modules\Contracts\RepositoryInterface
*/
protected $module;
/**
* Execute the console command.
*
* @return mixed
*/
public function handle(): int
{
$this->module = $this->laravel['modules'];
$name = $this->argument('module');
if ($name) {
$module = $this->module->findOrFail($name);
$this->migrate($module);
return 0;
}
foreach ($this->module->getOrdered($this->option('direction')) as $module) {
$this->line('Running for module: <info>' . $module->getName() . '</info>');
$this->migrate($module);
}
return 0;
}
/**
* Run the migration from the specified module.
*
* @param Module $module
*/
protected function migrate(Module $module)
{
$path = str_replace(base_path(), '', (new Migrator($module, $this->getLaravel()))->getPath());
if ($this->option('subpath')) {
$path = $path . "/" . $this->option("subpath");
}
$this->call('migrate', [
'--path' => $path,
'--database' => $this->option('database'),
'--pretend' => $this->option('pretend'),
'--force' => $this->option('force'),
]);
if ($this->option('seed')) {
$this->call('module:seed', ['module' => $module->getName(), '--force' => $this->option('force')]);
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['direction', 'd', InputOption::VALUE_OPTIONAL, 'The direction of ordering.', 'asc'],
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
['subpath', null, InputOption::VALUE_OPTIONAL, 'Indicate a subpath to run your migrations from'],
];
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MigrateFreshCommand extends Command
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:migrate-fresh';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Drop all database tables and re-run all migrations';
/**
* Execute the console command.
*/
public function handle(): int
{
$module = $this->argument('module');
if ($module && !$this->getModuleName()) {
$this->error("Module [$module] does not exists.");
return E_ERROR;
}
$this->call('migrate:fresh');
$this->call('module:migrate', [
'module' => $this->getModuleName(),
'--database' => $this->option('database'),
'--force' => $this->option('force'),
'--seed' => $this->option('seed'),
]);
return 0;
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
];
}
public function getModuleName()
{
$module = $this->argument('module');
if (!$module) {
return null;
}
$module = app('modules')->find($module);
return $module ? $module->getStudlyName() : null;
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MigrateRefreshCommand extends Command
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:migrate-refresh';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Rollback & re-migrate the modules migrations.';
/**
* Execute the console command.
*/
public function handle(): int
{
$module = $this->argument('module');
if ($module && !$this->getModuleName()) {
$this->error("Module [$module] does not exists.");
return E_ERROR;
}
$this->call('module:migrate-reset', [
'module' => $this->getModuleName(),
'--database' => $this->option('database'),
'--force' => $this->option('force'),
]);
$this->call('module:migrate', [
'module' => $this->getModuleName(),
'--database' => $this->option('database'),
'--force' => $this->option('force'),
]);
if ($this->option('seed')) {
$this->call('module:seed', [
'module' => $this->getModuleName(),
]);
}
return 0;
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],
];
}
public function getModuleName()
{
$module = $this->argument('module');
if (!$module) {
return null;
}
$module = app('modules')->find($module);
return $module ? $module->getStudlyName() : null;
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Migrations\Migrator;
use Nwidart\Modules\Traits\MigrationLoaderTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MigrateResetCommand extends Command
{
use MigrationLoaderTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:migrate-reset';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Reset the modules migrations.';
/**
* @var \Nwidart\Modules\Contracts\RepositoryInterface
*/
protected $module;
/**
* Execute the console command.
*/
public function handle(): int
{
$this->module = $this->laravel['modules'];
$name = $this->argument('module');
if (!empty($name)) {
$this->reset($name);
return 0;
}
foreach ($this->module->getOrdered($this->option('direction')) as $module) {
$this->line('Running for module: <info>' . $module->getName() . '</info>');
$this->reset($module);
}
return 0;
}
/**
* Rollback migration from the specified module.
*
* @param $module
*/
public function reset($module)
{
if (is_string($module)) {
$module = $this->module->findOrFail($module);
}
$migrator = new Migrator($module, $this->getLaravel());
$database = $this->option('database');
if (!empty($database)) {
$migrator->setDatabase($database);
}
$migrated = $migrator->reset();
if (count($migrated)) {
foreach ($migrated as $migration) {
$this->line("Rollback: <info>{$migration}</info>");
}
return;
}
$this->comment('Nothing to rollback.');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['direction', 'd', InputOption::VALUE_OPTIONAL, 'The direction of ordering.', 'desc'],
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
];
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Migrations\Migrator;
use Nwidart\Modules\Traits\MigrationLoaderTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MigrateRollbackCommand extends Command
{
use MigrationLoaderTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:migrate-rollback';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Rollback the modules migrations.';
/**
* @var \Nwidart\Modules\Contracts\RepositoryInterface
*/
protected $module;
/**
* Execute the console command.
*/
public function handle(): int
{
$this->module = $this->laravel['modules'];
$name = $this->argument('module');
if (!empty($name)) {
$this->rollback($name);
return 0;
}
foreach ($this->module->getOrdered($this->option('direction')) as $module) {
$this->line('Running for module: <info>' . $module->getName() . '</info>');
$this->rollback($module);
}
return 0;
}
/**
* Rollback migration from the specified module.
*
* @param $module
*/
public function rollback($module)
{
if (is_string($module)) {
$module = $this->module->findOrFail($module);
}
$migrator = new Migrator($module, $this->getLaravel(), $this->option('subpath'));
$database = $this->option('database');
if (!empty($database)) {
$migrator->setDatabase($database);
}
$migrated = $migrator->rollback();
if (count($migrated)) {
foreach ($migrated as $migration) {
$this->line("Rollback: <info>{$migration}</info>");
}
return;
}
$this->comment('Nothing to rollback.');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['direction', 'd', InputOption::VALUE_OPTIONAL, 'The direction of ordering.', 'desc'],
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
['subpath', null, InputOption::VALUE_OPTIONAL, 'Indicate a subpath for modules specific migration file']
];
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Migrations\Migrator;
use Nwidart\Modules\Module;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MigrateStatusCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:migrate-status';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Status for all module migrations';
/**
* @var \Nwidart\Modules\Contracts\RepositoryInterface
*/
protected $module;
/**
* Execute the console command.
*
* @return mixed
*/
public function handle(): int
{
$this->module = $this->laravel['modules'];
$name = $this->argument('module');
if ($name) {
$module = $this->module->findOrFail($name);
$this->migrateStatus($module);
return 0;
}
foreach ($this->module->getOrdered($this->option('direction')) as $module) {
$this->line('Running for module: <info>' . $module->getName() . '</info>');
$this->migrateStatus($module);
}
return 0;
}
/**
* Run the migration from the specified module.
*
* @param Module $module
*/
protected function migrateStatus(Module $module)
{
$path = str_replace(base_path(), '', (new Migrator($module, $this->getLaravel()))->getPath());
$this->call('migrate:status', [
'--path' => $path,
'--database' => $this->option('database'),
]);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['direction', 'd', InputOption::VALUE_OPTIONAL, 'The direction of ordering.', 'asc'],
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
];
}
}

View File

@@ -0,0 +1,169 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Migrations\NameParser;
use Nwidart\Modules\Support\Migrations\SchemaParser;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MigrationMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-migration';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new migration for the specified module.';
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The migration name will be created.'],
['module', InputArgument::OPTIONAL, 'The name of module will be created.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['fields', null, InputOption::VALUE_OPTIONAL, 'The specified fields table.', null],
['plain', null, InputOption::VALUE_NONE, 'Create plain migration.'],
];
}
/**
* Get schema parser.
*
* @return SchemaParser
*/
public function getSchemaParser()
{
return new SchemaParser($this->option('fields'));
}
/**
* @throws \InvalidArgumentException
*
* @return mixed
*/
protected function getTemplateContents()
{
$parser = new NameParser($this->argument('name'));
if ($parser->isCreate()) {
return Stub::create('/migration/create.stub', [
'class' => $this->getClass(),
'table' => $parser->getTableName(),
'fields' => $this->getSchemaParser()->render(),
]);
} elseif ($parser->isAdd()) {
return Stub::create('/migration/add.stub', [
'class' => $this->getClass(),
'table' => $parser->getTableName(),
'fields_up' => $this->getSchemaParser()->up(),
'fields_down' => $this->getSchemaParser()->down(),
]);
} elseif ($parser->isDelete()) {
return Stub::create('/migration/delete.stub', [
'class' => $this->getClass(),
'table' => $parser->getTableName(),
'fields_down' => $this->getSchemaParser()->up(),
'fields_up' => $this->getSchemaParser()->down(),
]);
} elseif ($parser->isDrop()) {
return Stub::create('/migration/drop.stub', [
'class' => $this->getClass(),
'table' => $parser->getTableName(),
'fields' => $this->getSchemaParser()->render(),
]);
}
return Stub::create('/migration/plain.stub', [
'class' => $this->getClass(),
]);
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$generatorPath = GenerateConfigReader::read('migration');
return $path . $generatorPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return date('Y_m_d_His_') . $this->getSchemaName();
}
/**
* @return array|string
*/
private function getSchemaName()
{
return $this->argument('name');
}
/**
* @return string
*/
private function getClassName()
{
return Str::studly($this->argument('name'));
}
public function getClass()
{
return $this->getClassName();
}
/**
* Run the command.
*/
public function handle(): int
{
$this->components->info('Creating migration...');
if (parent::handle() === E_ERROR) {
return E_ERROR;
}
if (app()->environment() === 'testing') {
return 0;
}
return 0;
}
}

View File

@@ -0,0 +1,245 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ModelMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'model';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-model';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new model for the specified module.';
public function handle(): int
{
if (parent::handle() === E_ERROR) {
return E_ERROR;
}
$this->handleOptionalMigrationOption();
$this->handleOptionalControllerOption();
$this->handleOptionalSeedOption();
$this->handleOptionalFactoryOption();
$this->handleOptionalRequestOption();
return 0;
}
/**
* Create a proper migration name:
* ProductDetail: product_details
* Product: products
* @return string
*/
private function createMigrationName()
{
$pieces = preg_split('/(?=[A-Z])/', $this->argument('model'), -1, PREG_SPLIT_NO_EMPTY);
$string = '';
foreach ($pieces as $i => $piece) {
if ($i+1 < count($pieces)) {
$string .= strtolower($piece) . '_';
} else {
$string .= Str::plural(strtolower($piece));
}
}
return $string;
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['model', InputArgument::REQUIRED, 'The name of model will be created.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['fillable', null, InputOption::VALUE_OPTIONAL, 'The fillable attributes.', null],
['migration', 'm', InputOption::VALUE_NONE, 'Flag to create associated migrations', null],
['controller', 'c', InputOption::VALUE_NONE, 'Flag to create associated controllers', null],
['seed', 's', InputOption::VALUE_NONE, 'Create a new seeder for the model', null],
['factory', 'f', InputOption::VALUE_NONE, 'Create a new factory for the model', null],
['request', 'r', InputOption::VALUE_NONE, 'Create a new request for the model', null],
];
}
/**
* Create the migration file with the given model if migration flag was used
*/
private function handleOptionalMigrationOption()
{
if ($this->option('migration') === true) {
$migrationName = 'create_' . $this->createMigrationName() . '_table';
$this->call('module:make-migration', ['name' => $migrationName, 'module' => $this->argument('module')]);
}
}
/**
* Create the controller file for the given model if controller flag was used
*/
private function handleOptionalControllerOption()
{
if ($this->option('controller') === true) {
$controllerName = "{$this->getModelName()}Controller";
$this->call('module:make-controller', array_filter([
'controller' => $controllerName,
'module' => $this->argument('module'),
]));
}
}
/**
* Create a seeder file for the model.
*
* @return void
*/
protected function handleOptionalSeedOption()
{
if ($this->option('seed') === true) {
$seedName = "{$this->getModelName()}Seeder";
$this->call('module:make-seed', array_filter([
'name' => $seedName,
'module' => $this->argument('module')
]));
}
}
/**
* Create a seeder file for the model.
*
* @return void
*/
protected function handleOptionalFactoryOption()
{
if ($this->option('factory') === true) {
$this->call('module:make-factory', array_filter([
'name' => $this->getModelName(),
'module' => $this->argument('module')
]));
}
}
/**
* Create a request file for the model.
*
* @return void
*/
protected function handleOptionalRequestOption()
{
if ($this->option('request') === true) {
$requestName = "{$this->getModelName()}Request";
$this->call('module:make-request', array_filter([
'name' => $requestName,
'module' => $this->argument('module')
]));
}
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/model.stub', [
'NAME' => $this->getModelName(),
'FILLABLE' => $this->getFillable(),
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
'LOWER_NAME' => $module->getLowerName(),
'MODULE' => $this->getModuleName(),
'STUDLY_NAME' => $module->getStudlyName(),
'MODULE_NAMESPACE' => $this->laravel['modules']->config('namespace'),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$modelPath = GenerateConfigReader::read('model');
return $path . $modelPath->getPath() . '/' . $this->getModelName() . '.php';
}
/**
* @return mixed|string
*/
private function getModelName()
{
return Str::studly($this->argument('model'));
}
/**
* @return string
*/
private function getFillable()
{
$fillable = $this->option('fillable');
if (!is_null($fillable)) {
$arrays = explode(',', $fillable);
return json_encode($arrays);
}
return '[]';
}
/**
* Get default namespace.
*
* @return string
*/
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.model.namespace') ?: $module->config('paths.generator.model.path', 'Entities');
}
}

View File

@@ -0,0 +1,119 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Contracts\Console\PromptsForMissingInput;
use Illuminate\Database\Console\PruneCommand;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Nwidart\Modules\Facades\Module;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Finder\Finder;
use function Laravel\Prompts\multiselect;
class ModelPruneCommand extends PruneCommand implements PromptsForMissingInput
{
const ALL = 'All';
protected $name = 'module:prune';
/**
* The console command name.
*
* @var string
*/
protected $signature = 'module:prune {module*}
{--all : Check all Modules}
{--model=* : Class names of the models to be pruned}
{--except=* : Class names of the models to be excluded from pruning}
{--path=* : Absolute path(s) to directories where models are located}
{--chunk=1000 : The number of models to retrieve per chunk of models to be deleted}
{--pretend : Display the number of prunable records found instead of deleting them}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Prune models by module that are no longer needed';
protected function promptForMissingArguments(InputInterface $input, OutputInterface $output): void
{
if ($this->option('all')) {
$input->setArgument('module', [self::ALL]);
return;
}
$selected_item = multiselect(
label : 'What Module want to check?',
options : [
self::ALL,
...array_keys(Module::all()),
],
required: 'You must select at least one module',
);
$input->setArgument('module',
value: in_array(self::ALL, $selected_item)
? [self::ALL]
: $selected_item
);
}
/**
* Determine the models that should be pruned.
*
* @return Collection
*/
protected function models(): Collection
{
if (! empty($models = $this->option('model'))) {
return collect($models)->filter(function ($model) {
return class_exists($model);
})->values();
}
$except = $this->option('except');
if (! empty($models) && ! empty($except)) {
throw new InvalidArgumentException('The --models and --except options cannot be combined.');
}
if ($this->argument('module') == [self::ALL]) {
$path = sprintf('%s/*/%s',
config('modules.paths.modules'),
config('modules.paths.generator.model.path')
);
}
else {
$path = sprintf('%s/{%s}/%s',
config('modules.paths.modules'),
collect($this->argument('module'))->implode(','),
config('modules.paths.generator.model.path'));
}
return collect(Finder::create()->in($path)->files()->name('*.php'))
->map(function ($model) {
$namespace = config('modules.namespace');
return $namespace . str_replace(
['/', '.php'],
['\\', ''],
Str::after($model->getRealPath(), realpath(config('modules.paths.modules')))
);
})->values()
->when(! empty($except), function ($models) use ($except) {
return $models->reject(function ($model) use ($except) {
return in_array($model, $except);
});
})->filter(function ($model) {
return class_exists($model);
})->filter(function ($model) {
return $this->isPrunable($model);
})->values();
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Database\Console\ShowModelCommand;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand('module:model-show', 'Show information about an Eloquent model in modules')]
class ModelShowCommand extends ShowModelCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:model-show';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Show information about an Eloquent model in modules';
/**
* The console command signature.
*
* @var string
*/
protected $signature = 'module:model-show {model : The model to show}
{--database= : The database connection to use}
{--json : Output the model as JSON}';
/**
* Qualify the given model class base name.
*
* @param string $model
* @return string
*
* @see \Illuminate\Console\GeneratorCommand
*/
protected function qualifyModel(string $model): string
{
if (str_contains($model, '\\') && class_exists($model)) {
return $model;
}
$rootNamespace = config('modules.namespace');
$modelPath = glob($rootNamespace . DIRECTORY_SEPARATOR .
'*' . DIRECTORY_SEPARATOR .
config('modules.paths.generator.model.path') . DIRECTORY_SEPARATOR .
"$model.php");
if (!count($modelPath)) {
return $model;
}
return str_replace(['/', '.php'], ['\\', ''], $modelPath[0]);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
class ModuleDeleteCommand extends Command
{
protected $name = 'module:delete';
protected $description = 'Delete a module from the application';
public function handle(): int
{
$this->laravel['modules']->delete($this->argument('module'));
$this->components->info("Module {$this->argument('module')} has been deleted.");
return 0;
}
protected function getArguments()
{
return [
['module', InputArgument::REQUIRED, 'The name of module to delete.'],
];
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Contracts\ActivatorInterface;
use Nwidart\Modules\Generators\ModuleGenerator;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ModuleMakeCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new module.';
/**
* Execute the console command.
*/
public function handle(): int
{
$names = $this->argument('name');
$success = true;
foreach ($names as $name) {
$code = with(new ModuleGenerator($name))
->setFilesystem($this->laravel['files'])
->setModule($this->laravel['modules'])
->setConfig($this->laravel['config'])
->setActivator($this->laravel[ActivatorInterface::class])
->setConsole($this)
->setComponent($this->components)
->setForce($this->option('force'))
->setType($this->getModuleType())
->setActive(!$this->option('disabled'))
->generate();
if ($code === E_ERROR) {
$success = false;
}
}
return $success ? 0 : E_ERROR;
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::IS_ARRAY, 'The names of modules will be created.'],
];
}
protected function getOptions()
{
return [
['plain', 'p', InputOption::VALUE_NONE, 'Generate a plain module (without some resources).'],
['api', null, InputOption::VALUE_NONE, 'Generate an api module.'],
['web', null, InputOption::VALUE_NONE, 'Generate a web module.'],
['disabled', 'd', InputOption::VALUE_NONE, 'Do not enable the module at creation.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when the module already exists.'],
];
}
/**
* Get module type .
*
* @return string
*/
private function getModuleType()
{
$isPlain = $this->option('plain');
$isApi = $this->option('api');
if ($isPlain && $isApi) {
return 'web';
}
if ($isPlain) {
return 'plain';
} elseif ($isApi) {
return 'api';
} else {
return 'web';
}
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
final class NotificationMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-notification';
protected $argumentName = 'name';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new notification class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.notifications.namespace') ?: $module->config('paths.generator.notifications.path', 'Notifications');
}
/**
* Get template contents.
*
* @return string
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/notification.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* Get the destination file path.
*
* @return string
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$notificationPath = GenerateConfigReader::read('notifications');
return $path . $notificationPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the notification class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
}

View File

@@ -0,0 +1,135 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class ObserverMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-observer';
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new observer for the specified module.';
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The observer name will be created.'],
['module', InputArgument::OPTIONAL, 'The name of module will be created.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/observer.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'NAME' => $this->getModelName(),
'MODEL_NAMESPACE' => $this->getModelNamespace(),
'NAME_VARIABLE' => $this->getModelVariable(),
]))->render();
}
/**
* Get model namespace.
*
* @return string
*/
public function getModelNamespace(): string
{
$path = $this->laravel['modules']->config('paths.generator.model.path', 'Entities');
$path = str_replace('/', '\\', $path);
return $this->laravel['modules']->config('namespace') . '\\' . $this->laravel['modules']->findOrFail($this->getModuleName()) . '\\' . $path;
}
/**
* @return mixed|string
*/
private function getModelName()
{
return Str::studly($this->argument('name'));
}
/**
* @return mixed|string
*/
private function getModelVariable() : string
{
return '$'.Str::lower($this->argument('name'));
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$observerPath = GenerateConfigReader::read('observer');
return $path . $observerPath->getPath() . '/' . $this->getFileName();
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name')) . 'Observer.php';
}
public function handle(): int
{
$this->components->info('Creating observer...');
parent::handle();
return 0;
}
/**
* Get default namespace.
*
* @return string
*/
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.observer.namespace') ?: $module->config('paths.generator.observer.path', 'Observers');
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class PolicyMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-policy';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new policy class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.policies.namespace') ?: $module->config('paths.generator.policies.path', 'Policies');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the policy class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/policy.plain.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$policyPath = GenerateConfigReader::read('policies');
return $path . $policyPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
}

View File

@@ -0,0 +1,115 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Module;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ProviderMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-provider';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new service provider class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.provider.namespace') ?: $module->config('paths.generator.provider.path', 'Providers');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The service provider name.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['master', null, InputOption::VALUE_NONE, 'Indicates the master service provider', null],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$stub = $this->option('master') ? 'scaffold/provider' : 'provider';
/** @var Module $module */
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/' . $stub . '.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
'LOWER_NAME' => $module->getLowerName(),
'MODULE' => $this->getModuleName(),
'NAME' => $this->getFileName(),
'STUDLY_NAME' => $module->getStudlyName(),
'MODULE_NAMESPACE' => $this->laravel['modules']->config('namespace'),
'PATH_VIEWS' => GenerateConfigReader::read('views')->getPath(),
'PATH_LANG' => GenerateConfigReader::read('lang')->getPath(),
'PATH_CONFIG' => GenerateConfigReader::read('config')->getPath(),
'MIGRATIONS_PATH' => GenerateConfigReader::read('migration')->getPath(),
'FACTORIES_PATH' => GenerateConfigReader::read('factory')->getPath(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$generatorPath = GenerateConfigReader::read('provider');
return $path . $generatorPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Module;
use Nwidart\Modules\Publishing\AssetPublisher;
use Symfony\Component\Console\Input\InputArgument;
class PublishCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:publish';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Publish a module\'s assets to the application';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('Publishing module assets...');
if ($name = $this->argument('module')) {
$this->publish($name);
return 0;
}
$this->publishAll();
return 0;
}
/**
* Publish assets from all modules.
*/
public function publishAll()
{
foreach ($this->laravel['modules']->allEnabled() as $module) {
$this->publish($module);
}
}
/**
* Publish assets from the specified module.
*
* @param string $name
*/
public function publish($name)
{
if ($name instanceof Module) {
$module = $name;
} else {
$module = $this->laravel['modules']->findOrFail($name);
}
with(new AssetPublisher($module))
->setRepository($this->laravel['modules'])
->setConsole($this)
->publish();
$this->components->task($module->getStudlyName(), fn()=>true);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class PublishConfigurationCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:publish-config';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Publish a module\'s config files to the application';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('publishing module config files...');
if ($module = $this->argument('module')) {
$this->publishConfiguration($module);
return 0;
}
foreach ($this->laravel['modules']->allEnabled() as $module) {
$this->publishConfiguration($module->getName());
}
return 0;
}
/**
* @param string $module
* @return string
*/
private function getServiceProviderForModule($module)
{
$namespace = $this->laravel['config']->get('modules.namespace');
$studlyName = Str::studly($module);
$provider = $this->laravel['config']->get('modules.paths.generator.provider.path');
$provider = str_replace('/', '\\', $provider);
return "$namespace\\$studlyName\\$provider\\{$studlyName}ServiceProvider";
}
/**
* @param string $module
*/
private function publishConfiguration($module)
{
$this->call('vendor:publish', [
'--provider' => $this->getServiceProviderForModule($module),
'--force' => $this->option('force'),
'--tag' => ['config'],
]);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module being used.'],
];
}
/**
* @return array
*/
protected function getOptions()
{
return [
['--force', '-f', InputOption::VALUE_NONE, 'Force the publishing of config files'],
];
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Migrations\Migrator;
use Nwidart\Modules\Publishing\MigrationPublisher;
use Symfony\Component\Console\Input\InputArgument;
class PublishMigrationCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:publish-migration';
/**
* The console command description.
*
* @var string
*/
protected $description = "Publish a module's migrations to the application";
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('publishing module migrations...');
if ($name = $this->argument('module')) {
$module = $this->laravel['modules']->findOrFail($name);
$this->publish($module);
return 0;
}
foreach ($this->laravel['modules']->allEnabled() as $module) {
$this->publish($module);
}
return 0;
}
/**
* Publish migration for the specified module.
*
* @param \Nwidart\Modules\Module $module
*/
public function publish($module)
{
with(new MigrationPublisher(new Migrator($module, $this->getLaravel())))
->setRepository($this->laravel['modules'])
->setConsole($this)
->publish();
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module being used.'],
];
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Module;
use Nwidart\Modules\Publishing\LangPublisher;
use Symfony\Component\Console\Input\InputArgument;
class PublishTranslationCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:publish-translation';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Publish a module\'s translations to the application';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('Publishing module translations...');
if ($name = $this->argument('module')) {
$this->publish($name);
return 0;
}
$this->publishAll();
return 0;
}
/**
* Publish assets from all modules.
*/
public function publishAll()
{
foreach ($this->laravel['modules']->allEnabled() as $module) {
$this->publish($module);
}
}
/**
* Publish assets from the specified module.
*
* @param string $name
*/
public function publish($name)
{
if ($name instanceof Module) {
$module = $name;
} else {
$module = $this->laravel['modules']->findOrFail($name);
}
with(new LangPublisher($module))
->setRepository($this->laravel['modules'])
->setConsole($this)
->publish();
$this->line("<info>Published</info>: {$module->getStudlyName()}");
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class RequestMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-request';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new form request class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.request.namespace') ?: $module->config('paths.generator.request.path', 'Http/Requests');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the form request class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/request.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$requestPath = GenerateConfigReader::read('request');
return $path . $requestPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ResourceMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
protected $argumentName = 'name';
protected $name = 'module:make-resource';
protected $description = 'Create a new resource class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.resource.namespace') ?: $module->config('paths.generator.resource.path', 'Transformers');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the resource class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
protected function getOptions()
{
return [
['collection', 'c', InputOption::VALUE_NONE, 'Create a resource collection.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub($this->getStubName(), [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$resourcePath = GenerateConfigReader::read('resource');
return $path . $resourcePath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
/**
* Determine if the command is generating a resource collection.
*
* @return bool
*/
protected function collection(): bool
{
return $this->option('collection') ||
Str::endsWith($this->argument('name'), 'Collection');
}
/**
* @return string
*/
protected function getStubName(): string
{
if ($this->collection()) {
return '/resource-collection.stub';
}
return '/resource.stub';
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace Nwidart\Modules\Commands;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class RouteProviderMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
protected $argumentName = 'module';
/**
* The command name.
*
* @var string
*/
protected $name = 'module:route-provider';
/**
* The command description.
*
* @var string
*/
protected $description = 'Create a new route service provider for the specified module.';
/**
* The command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
protected function getOptions()
{
return [
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when the file already exists.'],
];
}
/**
* Get template contents.
*
* @return string
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/route-provider.stub', [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getFileName(),
'MODULE_NAMESPACE' => $this->laravel['modules']->config('namespace'),
'MODULE' => $this->getModuleName(),
'CONTROLLER_NAMESPACE' => $this->getControllerNameSpace(),
'WEB_ROUTES_PATH' => $this->getWebRoutesPath(),
'API_ROUTES_PATH' => $this->getApiRoutesPath(),
'LOWER_NAME' => $module->getLowerName(),
]))->render();
}
/**
* @return string
*/
private function getFileName()
{
return 'RouteServiceProvider';
}
/**
* Get the destination file path.
*
* @return string
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$generatorPath = GenerateConfigReader::read('provider');
return $path . $generatorPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return mixed
*/
protected function getWebRoutesPath()
{
return '/' . $this->laravel['modules']->config('stubs.files.routes/web', 'Routes/web.php');
}
/**
* @return mixed
*/
protected function getApiRoutesPath()
{
return '/' . $this->laravel['modules']->config('stubs.files.routes/api', 'Routes/api.php');
}
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.provider.namespace') ?: $module->config('paths.generator.provider.path', 'Providers');
}
/**
* @return string
*/
private function getControllerNameSpace(): string
{
$module = $this->laravel['modules'];
return str_replace('/', '\\', $module->config('paths.generator.controller.namespace') ?: $module->config('paths.generator.controller.path', 'Controller'));
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class RuleMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
/**
* The name of argument name.
*
* @var string
*/
protected $argumentName = 'name';
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:make-rule';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new validation rule for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.rules.namespace') ?: $module->config('paths.generator.rules.path', 'Rules');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the rule class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['implicit', 'i', InputOption::VALUE_NONE, 'Generate an implicit rule'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
$stub = $this->option('implicit')
? '/rule.implicit.stub'
: '/rule.stub';
return (new Stub($stub, [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getFileName(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$rulePath = GenerateConfigReader::read('rules');
return $path . $rulePath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
}

View File

@@ -0,0 +1,246 @@
<?php
namespace Nwidart\Modules\Commands;
use ErrorException;
use Illuminate\Console\Command;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Support\Str;
use Nwidart\Modules\Contracts\RepositoryInterface;
use Nwidart\Modules\Module;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use RuntimeException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class SeedCommand extends Command
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:seed';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Run database seeder from the specified module or from all modules.';
/**
* Execute the console command.
*/
public function handle(): int
{
try {
if ($name = $this->argument('module')) {
$name = Str::studly($name);
$this->moduleSeed($this->getModuleByName($name));
} else {
$modules = $this->getModuleRepository()->getOrdered();
array_walk($modules, [$this, 'moduleSeed']);
$this->info('All modules seeded.');
}
} catch (\Error $e) {
$e = new ErrorException($e->getMessage(), $e->getCode(), 1, $e->getFile(), $e->getLine(), $e);
$this->reportException($e);
$this->renderException($this->getOutput(), $e);
return E_ERROR;
} catch (\Exception $e) {
$this->reportException($e);
$this->renderException($this->getOutput(), $e);
return E_ERROR;
}
return 0;
}
/**
* @throws RuntimeException
* @return RepositoryInterface
*/
public function getModuleRepository(): RepositoryInterface
{
$modules = $this->laravel['modules'];
if (!$modules instanceof RepositoryInterface) {
throw new RuntimeException('Module repository not found!');
}
return $modules;
}
/**
* @param $name
*
* @throws RuntimeException
*
* @return Module
*/
public function getModuleByName($name)
{
$modules = $this->getModuleRepository();
if ($modules->has($name) === false) {
throw new RuntimeException("Module [$name] does not exists.");
}
return $modules->find($name);
}
/**
* @param Module $module
*
* @return void
*/
public function moduleSeed(Module $module)
{
$seeders = [];
$name = $module->getName();
$config = $module->get('migration');
if (is_array($config) && array_key_exists('seeds', $config)) {
foreach ((array)$config['seeds'] as $class) {
if (class_exists($class)) {
$seeders[] = $class;
}
}
} else {
$class = $this->getSeederName($name); //legacy support
if (class_exists($class)) {
$seeders[] = $class;
} else {
//look at other namespaces
$classes = $this->getSeederNames($name);
foreach ($classes as $class) {
if (class_exists($class)) {
$seeders[] = $class;
}
}
}
}
if (count($seeders) > 0) {
array_walk($seeders, [$this, 'dbSeed']);
$this->info("Module [$name] seeded.");
}
}
/**
* Seed the specified module.
*
* @param string $className
*/
protected function dbSeed($className)
{
if ($option = $this->option('class')) {
$params['--class'] = Str::finish(substr($className, 0, strrpos($className, '\\')), '\\') . $option;
} else {
$params = ['--class' => $className];
}
if ($option = $this->option('database')) {
$params['--database'] = $option;
}
if ($option = $this->option('force')) {
$params['--force'] = $option;
}
$this->call('db:seed', $params);
}
/**
* Get master database seeder name for the specified module.
*
* @param string $name
*
* @return string
*/
public function getSeederName($name)
{
$name = Str::studly($name);
$namespace = $this->laravel['modules']->config('namespace');
$config = GenerateConfigReader::read('seeder');
$seederPath = str_replace('/', '\\', $config->getPath());
return $namespace . '\\' . $name . '\\' . $seederPath . '\\' . $name . 'DatabaseSeeder';
}
/**
* Get master database seeder name for the specified module under a different namespace than Modules.
*
* @param string $name
*
* @return array $foundModules array containing namespace paths
*/
public function getSeederNames($name)
{
$name = Str::studly($name);
$seederPath = GenerateConfigReader::read('seeder');
$seederPath = str_replace('/', '\\', $seederPath->getPath());
$foundModules = [];
foreach ($this->laravel['modules']->config('scan.paths') as $path) {
$namespace = array_slice(explode('/', $path), -1)[0];
$foundModules[] = $namespace . '\\' . $name . '\\' . $seederPath . '\\' . $name . 'DatabaseSeeder';
}
return $foundModules;
}
/**
* Report the exception to the exception handler.
*
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param \Throwable $e
* @return void
*/
protected function renderException($output, \Exception $e)
{
$this->laravel[ExceptionHandler::class]->renderForConsole($output, $e);
}
/**
* Report the exception to the exception handler.
*
* @param \Throwable $e
* @return void
*/
protected function reportException(\Exception $e)
{
$this->laravel[ExceptionHandler::class]->report($e);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['class', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder.'],
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed.'],
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
];
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\CanClearModulesCache;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class SeedMakeCommand extends GeneratorCommand
{
use CanClearModulesCache;
use ModuleCommandTrait;
protected $argumentName = 'name';
/**
* The console command name.
*/
protected $name = 'module:make-seed';
/**
* The console command description.
*/
protected $description = 'Generate new seeder for the specified module.';
/**
* Get the console command arguments.
*/
protected function getArguments(): array
{
return [
['name', InputArgument::REQUIRED, 'The name of seeder will be created.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*/
protected function getOptions(): array
{
return [
[
'master',
null,
InputOption::VALUE_NONE,
'Indicates the seeder will created is a master database seeder.',
],
];
}
protected function getTemplateContents(): mixed
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
return (new Stub('/seeder.stub', [
'NAME' => $this->getSeederName(),
'MODULE' => $this->getModuleName(),
'NAMESPACE' => $this->getClassNamespace($module),
]))->render();
}
protected function getDestinationFilePath(): mixed
{
$this->clearCache();
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
$seederPath = GenerateConfigReader::read('seeder');
return $path . $seederPath->getPath() . '/' . $this->getSeederName() . '.php';
}
/**
* Get the seeder name.
*/
private function getSeederName(): string
{
$string = $this->argument('name');
$string .= $this->option('master') ? 'Database' : '';
$suffix = 'Seeder';
if (strpos($string, $suffix) === false) {
$string .= $suffix;
}
return Str::studly($string);
}
/**
* Get default namespace.
*/
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
return $module->config('paths.generator.seeder.namespace') ?: $module->config('paths.generator.seeder.path', 'Database/Seeders');
}
}

View File

@@ -0,0 +1,79 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
class SetupCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:setup';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Setting up modules folders for first use.';
/**
* Execute the console command.
*/
public function handle(): int
{
$code = $this->generateModulesFolder();
return $this->generateAssetsFolder() | $code;
}
/**
* Generate the modules folder.
*/
public function generateModulesFolder()
{
return $this->generateDirectory(
$this->laravel['modules']->config('paths.modules'),
'Modules directory created successfully',
'Modules directory already exist'
);
}
/**
* Generate the assets folder.
*/
public function generateAssetsFolder()
{
return $this->generateDirectory(
$this->laravel['modules']->config('paths.assets'),
'Assets directory created successfully',
'Assets directory already exist'
);
}
/**
* Generate the specified directory by given $dir.
*
* @param $dir
* @param $success
* @param $error
* @return int
*/
protected function generateDirectory($dir, $success, $error): int
{
if (!$this->laravel['files']->isDirectory($dir)) {
$this->laravel['files']->makeDirectory($dir, 0755, true, true);
$this->components->info($success);
return 0;
}
$this->components->error($error);
return E_ERROR;
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Support\Str;
use Nwidart\Modules\Support\Config\GenerateConfigReader;
use Nwidart\Modules\Support\Stub;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class TestMakeCommand extends GeneratorCommand
{
use ModuleCommandTrait;
protected $argumentName = 'name';
protected $name = 'module:make-test';
protected $description = 'Create a new test class for the specified module.';
public function getDefaultNamespace(): string
{
$module = $this->laravel['modules'];
if ($this->option('feature')) {
return $module->config('paths.generator.test-feature.namespace') ?: $module->config('paths.generator.test-feature.path', 'Tests/Feature');
}
return $module->config('paths.generator.test.namespace') ?: $module->config('paths.generator.test.path', 'Tests/Unit');
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the form request class.'],
['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['feature', false, InputOption::VALUE_NONE, 'Create a feature test.'],
];
}
/**
* @return mixed
*/
protected function getTemplateContents()
{
$module = $this->laravel['modules']->findOrFail($this->getModuleName());
$stub = '/unit-test.stub';
if ($this->option('feature')) {
$stub = '/feature-test.stub';
}
return (new Stub($stub, [
'NAMESPACE' => $this->getClassNamespace($module),
'CLASS' => $this->getClass(),
]))->render();
}
/**
* @return mixed
*/
protected function getDestinationFilePath()
{
$path = $this->laravel['modules']->getModulePath($this->getModuleName());
if ($this->option('feature')) {
$testPath = GenerateConfigReader::read('test-feature');
} else {
$testPath = GenerateConfigReader::read('test');
}
return $path . $testPath->getPath() . '/' . $this->getFileName() . '.php';
}
/**
* @return string
*/
private function getFileName()
{
return Str::studly($this->argument('name'));
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
class UnUseCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:unuse';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Forget the used module with module:use';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->laravel['modules']->forgetUsed();
$this->components->info('Previous module used successfully forgotten.');
return 0;
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Nwidart\Modules\Module;
use Nwidart\Modules\Traits\ModuleCommandTrait;
use Symfony\Component\Console\Input\InputArgument;
class UpdateCommand extends Command
{
use ModuleCommandTrait;
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:update';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Update dependencies for the specified module or for all modules.';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->components->info('Updating module ...');
if ($name = $this->argument('module')) {
$this->updateModule($name);
return 0;
}
$this->updateAllModule();
return 0;
}
protected function updateAllModule()
{
/** @var \Nwidart\Modules\Module $module */
$modules = $this->laravel['modules']->getOrdered();
foreach ($modules as $module) {
$this->updateModule($module);
}
}
protected function updateModule($name)
{
if ($name instanceof Module) {
$module = $name;
}else {
$module = $this->laravel['modules']->findOrFail($name);
}
$this->components->task("Updating {$module->getName()} module", function () use ($module) {
$this->laravel['modules']->update($module);
});
$this->laravel['modules']->update($name);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::OPTIONAL, 'The name of module will be updated.'],
];
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Nwidart\Modules\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputArgument;
class UseCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'module:use';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Use the specified module.';
/**
* Execute the console command.
*/
public function handle(): int
{
$module = Str::studly($this->argument('module'));
if (!$this->laravel['modules']->has($module)) {
$this->error("Module [{$module}] does not exists.");
return E_ERROR;
}
$this->laravel['modules']->setUsed($module);
$this->info("Module [{$module}] used successfully.");
return 0;
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['module', InputArgument::REQUIRED, 'The name of module will be used.'],
];
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace $NAMESPACE$;
class $CLASS$
{
/**
* Create a new channel instance.
*/
public function __construct()
{
//
}
/**
* Authenticate the user's access to the channel.
*/
public function join(Operator $user): array|bool
{
//
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class $CLASS$ extends Command
{
/**
* The name and signature of the console command.
*/
protected $signature = '$COMMAND_NAME$';
/**
* The console command description.
*/
protected $description = 'Command description.';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
//
}
/**
* Get the console command arguments.
*/
protected function getArguments(): array
{
return [
['example', InputArgument::REQUIRED, 'An example argument.'],
];
}
/**
* Get the console command options.
*/
protected function getOptions(): array
{
return [
['example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null],
];
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace $NAMESPACE$;
use Illuminate\View\Component;
use Illuminate\View\View;
class $CLASS$ extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
//
}
/**
* Get the view/contents that represent the component.
*/
public function render(): View|string
{
return view('$LOWER_NAME$::$COMPONENT_NAME$');
}
}

View File

@@ -0,0 +1,3 @@
<div>
<!-- $QUOTE$ -->
</div>

View File

@@ -0,0 +1,31 @@
{
"name": "$VENDOR$/$LOWER_NAME$",
"description": "",
"authors": [
{
"name": "$AUTHOR_NAME$",
"email": "$AUTHOR_EMAIL$"
}
],
"extra": {
"laravel": {
"providers": [],
"aliases": {
}
}
},
"autoload": {
"psr-4": {
"$MODULE_NAMESPACE$\\$STUDLY_NAME$\\": "",
"$MODULE_NAMESPACE$\\$STUDLY_NAME$\\App\\": "app/",
"$MODULE_NAMESPACE$\\$STUDLY_NAME$\\Database\\Factories\\": "database/factories/",
"$MODULE_NAMESPACE$\\$STUDLY_NAME$\\Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"$MODULE_NAMESPACE$\\$STUDLY_NAME$\\Tests\\": "tests/"
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace $CLASS_NAMESPACE$;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class $CLASS$ extends Controller
{
public array $data = [];
/**
* Display a listing of the resource.
*/
public function index(): JsonResponse
{
//
return response()->json($this->data);
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): JsonResponse
{
//
return response()->json($this->data);
}
/**
* Show the specified resource.
*/
public function show($id): JsonResponse
{
//
return response()->json($this->data);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, $id): JsonResponse
{
//
return response()->json($this->data);
}
/**
* Remove the specified resource from storage.
*/
public function destroy($id): JsonResponse
{
//
return response()->json($this->data);
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace $CLASS_NAMESPACE$;
use Illuminate\Routing\Controller;
class $CLASS$ extends Controller
{
}

View File

@@ -0,0 +1,67 @@
<?php
namespace $CLASS_NAMESPACE$;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class $CLASS$ extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('$LOWER_NAME$::index');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('$LOWER_NAME$::create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): RedirectResponse
{
//
}
/**
* Show the specified resource.
*/
public function show($id)
{
return view('$LOWER_NAME$::show');
}
/**
* Show the form for editing the specified resource.
*/
public function edit($id)
{
return view('$LOWER_NAME$::edit');
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, $id): RedirectResponse
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy($id)
{
//
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Queue\SerializesModels;
class $CLASS$
{
use SerializesModels;
/**
* Create a new event instance.
*/
public function __construct()
{
//
}
/**
* Get the channels the event should be broadcast on.
*/
public function broadcastOn(): array
{
return [];
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Database\Eloquent\Factories\Factory;
class $NAME$Factory extends Factory
{
/**
* The name of the factory's corresponding model.
*/
protected $model = \$MODEL_NAMESPACE$\$NAME$::class;
/**
* Define the model's default state.
*/
public function definition(): array
{
return [];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace $NAMESPACE$;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class $CLASS$ extends TestCase
{
/**
* A basic feature test example.
*/
public function testExample(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class $CLASS$ implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*/
public function __construct()
{
//
}
/**
* Execute the job.
*/
public function handle(): void
{
//
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
class $CLASS$ implements ShouldQueue
{
use Dispatchable, Queueable;
/**
* Create a new job instance.
*/
public function __construct()
{
//
}
/**
* Execute the job.
*/
public function handle(): void
{
//
}
}

View File

@@ -0,0 +1,11 @@
{
"name": "$STUDLY_NAME$",
"alias": "$LOWER_NAME$",
"description": "",
"keywords": [],
"priority": 0,
"providers": [
"$MODULE_NAMESPACE$\\$STUDLY_NAME$\\$PROVIDER_NAMESPACE$\\$STUDLY_NAME$ServiceProvider"
],
"files": []
}

View File

@@ -0,0 +1,25 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class $CLASS$
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle($event): void
{
//
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class $CLASS$ implements ShouldQueue
{
use InteractsWithQueue;
/**
* Create the event listener
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle($event): void
{
//
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace $NAMESPACE$;
use $EVENTNAME$;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class $CLASS$ implements ShouldQueue
{
use InteractsWithQueue;
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle($SHORTEVENTNAME$ $event): void
{
//
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace $NAMESPACE$;
use $EVENTNAME$;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class $CLASS$
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle($SHORTEVENTNAME$ $event): void
{
//
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class $CLASS$ extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct()
{
//
}
/**
* Build the message.
*/
public function build(): self
{
return $this->view('view.name');
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace $NAMESPACE$;
use Closure;
use Illuminate\Http\Request;
class $CLASS$
{
/**
* Handle an incoming request.
*/
public function handle(Request $request, Closure $next)
{
return $next($request);
}
}

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('$TABLE$', function (Blueprint $table) {
$FIELDS_UP$
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('$TABLE$', function (Blueprint $table) {
$FIELDS_DOWN$
});
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('$TABLE$', function (Blueprint $table) {
$table->id();
$FIELDS$
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('$TABLE$');
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('$TABLE$', function (Blueprint $table) {
$FIELDS_UP$
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('$TABLE$', function (Blueprint $table) {
$FIELDS_DOWN$
});
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::dropIfExists('$TABLE$');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::create('$TABLE$', function (Blueprint $table) {
$table->id();
$FIELDS$
$table->timestamps();
});
}
};

View File

@@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
//
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};

View File

@@ -0,0 +1,22 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use $MODULE_NAMESPACE$\$MODULE$\Database\factories\$NAME$Factory;
class $CLASS$ extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*/
protected $fillable = $FILLABLE$;
protected static function newFactory(): $NAME$Factory
{
//return $NAME$Factory::new();
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class $CLASS$ extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*/
public function via($notifiable): array
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*/
public function toMail($notifiable): MailMessage
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', 'https://laravel.com')
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*/
public function toArray($notifiable): array
{
return [];
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace $NAMESPACE$;
use $MODEL_NAMESPACE$\$NAME$;
class $NAME$Observer
{
/**
* Handle the $NAME$ "created" event.
*/
public function created($NAME$ $NAME_VARIABLE$): void
{
//
}
/**
* Handle the $NAME$ "updated" event.
*/
public function updated($NAME$ $NAME_VARIABLE$): void
{
//
}
/**
* Handle the $NAME$ "deleted" event.
*/
public function deleted($NAME$ $NAME_VARIABLE$): void
{
//
}
/**
* Handle the $NAME$ "restored" event.
*/
public function restored($NAME$ $NAME_VARIABLE$): void
{
//
}
/**
* Handle the $NAME$ "force deleted" event.
*/
public function forceDeleted($NAME$ $NAME_VARIABLE$): void
{
//
}
}

View File

@@ -0,0 +1,15 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.5",
"sass": "^1.69.5",
"postcss": "^8.3.7",
"vite": "^4.0.0"
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Auth\Access\HandlesAuthorization;
class $CLASS$
{
use HandlesAuthorization;
/**
* Create a new policy instance.
*/
public function __construct()
{
//
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Support\ServiceProvider;
class $CLASS$ extends ServiceProvider
{
/**
* Register the service provider.
*/
public function register(): void
{
//
}
/**
* Get the services provided by the provider.
*/
public function provides(): array
{
return [];
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Foundation\Http\FormRequest;
class $CLASS$ extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
//
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Http\Resources\Json\ResourceCollection;
class $CLASS$ extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*/
public function toArray($request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Http\Resources\Json\JsonResource;
class $CLASS$ extends JsonResource
{
/**
* Transform the resource into an array.
*/
public function toArray($request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class $CLASS$ extends ServiceProvider
{
/**
* The module namespace to assume when generating URLs to actions.
*/
protected string $moduleNamespace = '$MODULE_NAMESPACE$\$MODULE$\$CONTROLLER_NAMESPACE$';
/**
* Called before routes are registered.
*
* Register any model bindings or pattern based filters.
*/
public function boot(): void
{
parent::boot();
}
/**
* Define the routes for the application.
*/
public function map(): void
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*/
protected function mapWebRoutes(): void
{
Route::middleware('web')
->namespace($this->moduleNamespace)
->group(module_path('$MODULE$', '$WEB_ROUTES_PATH$'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*/
protected function mapApiRoutes(): void
{
Route::prefix('api')
->middleware('api')
->namespace($this->moduleNamespace)
->group(module_path('$MODULE$', '$API_ROUTES_PATH$'));
}
}

View File

@@ -0,0 +1,19 @@
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware(['auth:sanctum'])->prefix('v1')->name('api.')->group(function () {
Route::get('$LOWER_NAME$', fn (Request $request) => $request->user())->name('$LOWER_NAME$');
});

View File

@@ -0,0 +1,19 @@
<?php
use Illuminate\Support\Facades\Route;
use $MODULE_NAMESPACE$\$STUDLY_NAME$\$CONTROLLER_NAMESPACE$\$STUDLY_NAME$Controller;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::group([], function () {
Route::resource('$LOWER_NAME$', $STUDLY_NAME$Controller::class)->names('$LOWER_NAME$');
});

View File

@@ -0,0 +1,22 @@
<?php
namespace $NAMESPACE$;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class $CLASS$ implements ValidationRule
{
/**
* Indicates whether the rule should be implicit.
*/
public bool $implicit = true;
/**
* Run the validation rule.
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
//
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace $NAMESPACE$;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class $CLASS$ implements ValidationRule
{
/**
* Run the validation rule.
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
//
}
}

View File

@@ -0,0 +1,5 @@
<?php
return [
'name' => '$STUDLY_NAME$',
];

View File

@@ -0,0 +1,114 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class $CLASS$ extends ServiceProvider
{
protected string $moduleName = '$MODULE$';
protected string $moduleNameLower = '$LOWER_NAME$';
/**
* Boot the application events.
*/
public function boot(): void
{
$this->registerCommands();
$this->registerCommandSchedules();
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
$this->loadMigrationsFrom(module_path($this->moduleName, '$MIGRATIONS_PATH$'));
}
/**
* Register the service provider.
*/
public function register(): void
{
$this->app->register(RouteServiceProvider::class);
}
/**
* Register commands in the format of Command::class
*/
protected function registerCommands(): void
{
// $this->commands([]);
}
/**
* Register command Schedules.
*/
protected function registerCommandSchedules(): void
{
// $this->app->booted(function () {
// $schedule = $this->app->make(Schedule::class);
// $schedule->command('inspire')->hourly();
// });
}
/**
* Register translations.
*/
public function registerTranslations(): void
{
$langPath = resource_path('lang/modules/'.$this->moduleNameLower);
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
$this->loadJsonTranslationsFrom($langPath);
} else {
$this->loadTranslationsFrom(module_path($this->moduleName, '$PATH_LANG$'), $this->moduleNameLower);
$this->loadJsonTranslationsFrom(module_path($this->moduleName, '$PATH_LANG$'));
}
}
/**
* Register config.
*/
protected function registerConfig(): void
{
$this->publishes([module_path($this->moduleName, '$PATH_CONFIG$/config.php') => config_path($this->moduleNameLower.'.php')], 'config');
$this->mergeConfigFrom(module_path($this->moduleName, '$PATH_CONFIG$/config.php'), $this->moduleNameLower);
}
/**
* Register views.
*/
public function registerViews(): void
{
$viewPath = resource_path('views/modules/'.$this->moduleNameLower);
$sourcePath = module_path($this->moduleName, '$PATH_VIEWS$');
$this->publishes([$sourcePath => $viewPath], ['views', $this->moduleNameLower.'-module-views']);
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
$componentNamespace = str_replace('/', '\\', config('modules.namespace').'\\'.$this->moduleName.'\\'.config('modules.paths.generator.component-class.path'));
Blade::componentNamespace($componentNamespace, $this->moduleNameLower);
}
/**
* Get the services provided by the provider.
*/
public function provides(): array
{
return [];
}
private function getPublishableViewPaths(): array
{
$paths = [];
foreach (config('view.paths') as $path) {
if (is_dir($path.'/modules/'.$this->moduleNameLower)) {
$paths[] = $path.'/modules/'.$this->moduleNameLower;
}
}
return $paths;
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace $NAMESPACE$;
use Illuminate\Database\Seeder;
class $NAME$ extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// $this->call([]);
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace $NAMESPACE$;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class $CLASS$ extends TestCase
{
/**
* A basic unit test example.
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}

View File

@@ -0,0 +1,7 @@
@extends('$LOWER_NAME$::layouts.master')
@section('content')
<h1>Hello World</h1>
<p>Module: {!! config('$LOWER_NAME$.name') !!}</p>
@endsection

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>$STUDLY_NAME$ Module - {{ config('app.name', 'Laravel') }}</title>
<meta name="description" content="{{ $description ?? '' }}">
<meta name="keywords" content="{{ $keywords ?? '' }}">
<meta name="author" content="{{ $author ?? '' }}">
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
{{-- Vite CSS --}}
{{-- {{ module_vite('build-$LOWER_NAME$', 'resources/assets/sass/app.scss') }} --}}
</head>
<body>
@yield('content')
{{-- Vite JS --}}
{{-- {{ module_vite('build-$LOWER_NAME$', 'resources/assets/js/app.js') }} --}}
</body>

View File

@@ -0,0 +1,26 @@
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
build: {
outDir: '../../public/build-$LOWER_NAME$',
emptyOutDir: true,
manifest: true,
},
plugins: [
laravel({
publicDirectory: '../../public',
buildDirectory: 'build-$LOWER_NAME$',
input: [
__dirname + '/resources/assets/sass/app.scss',
__dirname + '/resources/assets/js/app.js'
],
refresh: true,
}),
],
});
//export const paths = [
// 'Modules/$STUDLY_NAME$/resources/assets/sass/app.scss',
// 'Modules/$STUDLY_NAME$/resources/assets/js/app.js',
//];

Some files were not shown because too many files have changed in this diff Show More