rewrite modular logic :D

This commit is contained in:
2024-11-05 21:04:56 +05:00
parent db69904f38
commit eb43d4ad86
5 changed files with 230 additions and 90 deletions

View File

@@ -1,16 +1,14 @@
<?php <?php
use App\Modules\BaseModule; use App\Modules\BaseModule;
use App\Modules\EmptyModule;
use App\Modules\Module; use App\Modules\Module;
use App\Modules\ModuleContract; use App\Modules\ModuleContract;
use App\Modules\ModuleRepository;
use App\Modules\TurkmenNumberFormatter\Repositories\TurkmenNumberFormatter; use App\Modules\TurkmenNumberFormatter\Repositories\TurkmenNumberFormatter;
use Illuminate\Contracts\Cache\Repository as CacheRepository; use Illuminate\Contracts\Cache\Repository as CacheRepository;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
/** /**
* Application locales * Application locales
@@ -23,28 +21,11 @@ function appLocales(): array
} }
/** /**
* Get module * Return modular repo
*/ */
function module(string $moduleName): ModuleContract function modular(): ModuleRepository
{ {
$moduleClass = 'App\\Modules\\'.$moduleName.'\\'.$moduleName.'Module'; return app(ModuleRepository::class);
if (class_exists($moduleClass)) {
/** @var ModuleContract $module */
$module = new $moduleClass;
return $module;
}
return emptyModule();
}
/**
* Empty module
*/
function emptyModule(): ModuleContract
{
return new EmptyModule;
} }
/** /**
@@ -52,7 +33,15 @@ function emptyModule(): ModuleContract
*/ */
function modules_path(string $path = ''): string function modules_path(string $path = ''): string
{ {
return app_path('Modules/'.$path); return modular()->path().'/'.$path;
}
/**
* Get module
*/
function module(string $moduleName): ModuleContract
{
return modular()->module($moduleName);
} }
/** /**
@@ -62,41 +51,15 @@ function modules_path(string $path = ''): string
*/ */
function modules(bool $withDisabled = false): Collection function modules(bool $withDisabled = false): Collection
{ {
if (temp_cache()->has('modules')) { return $withDisabled ? modular()->allModules() : modular()->modules();
/** @var Collection<array-key, BaseModule> $modules */ }
$modules = temp_cache('modules');
return $modules; /**
} * Empty module
*/
/** @var array<int, string> */ function emptyModule(): ModuleContract
$modulesDir = File::directories(modules_path()); {
$modules = collect(); return modular()->emptyModule();
foreach ($modulesDir as $modulePath) {
$moduleName = Str::afterLast($modulePath, '/');
$module = new BaseModule(
path: $modulePath,
name: $moduleName,
enabled: module($moduleName)->isEnabled()
);
// Include all
if ($withDisabled) {
$modules->push($module);
continue;
}
if ($module->enabled) {
$modules->push($module);
}
}
temp_cache()->put('modules', $modules);
return $modules;
} }
/** /**

View File

@@ -7,6 +7,9 @@ class BaseModule
public function __construct( public function __construct(
public string $path, public string $path,
public string $name, public string $name,
public bool $enabled, public ModuleContract $app,
) {} public bool $enabled = false,
) {
$this->enabled = $this->app->isEnabled();
}
} }

View File

@@ -0,0 +1,197 @@
<?php
namespace App\Modules;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class ModuleRepository
{
public function __construct(
/** @var string */
protected string $modules_path = '',
/** @var Collection<array-key, BaseModule> */
protected Collection $modules = new Collection([]),
/** @var Collection<array-key, BaseModule> */
protected Collection $allModules = new Collection([]),
/** @var array<int, string> */
protected array $migrationsPaths = [],
/** @var array<int, class-string> */
protected array $databaseSeederClasses = [],
) {
$this->prepareModules();
}
/**
* Prepare modules
*/
public function prepareModules(): void
{
$this->setPath();
$this->setModules();
$this->setConfigurations();
}
/**
* Set path
*/
public function setPath(): void
{
$this->modules_path = __DIR__;
}
/**
* Set modules
*
* @param bool|bool $withDisabled
*/
public function setModules(bool $withDisabled = false): void
{
/** @var array<int, string> */
$modulesDir = File::directories($this->path());
foreach ($modulesDir as $modulePath) {
$moduleName = Str::afterLast($modulePath, '/');
$module = new BaseModule(
path: $modulePath,
name: $moduleName,
app: $this->module($moduleName),
);
$this->allModules->push($module);
// Include all
if ($withDisabled) {
$this->modules->push($module);
continue;
}
if ($module->app->isEnabled()) {
$this->modules->push($module);
}
}
}
/**
* Set configs
*/
public function setConfigurations(): void
{
$this->modules()->each(function (BaseModule $module) {
$this->setMigrations($module);
$this->setSeeders($module);
});
}
/**
* Gather module migrations and set it
*/
public function setMigrations(BaseModule $module): void
{
$migrationDirectory = $module->path.'/Database/Migrations';
if (is_dir($migrationDirectory)) {
$this->migrationsPaths[] = $migrationDirectory;
}
}
/**
* Set seeders
*/
public function setSeeders(BaseModule $module): void
{
$seedersPath = $module->path.'/Database/Seeders';
if (is_dir($seedersPath)) {
$files = File::files($seedersPath);
foreach ($files as $file) {
$seederClassPath = 'App\\Modules\\'.$module->name.'\\Database\\Seeders\\'.$file->getFilenameWithoutExtension();
if (class_exists($seederClassPath)) {
$this->databaseSeederClasses[] = $seederClassPath;
}
}
}
}
/**
* Modules path
*/
public function path(): string
{
return $this->modules_path;
}
/**
* Instantiate new module class if exists
*/
public function module(string $moduleName): ModuleContract
{
$moduleClass = 'App\\Modules\\'.$moduleName.'\\'.$moduleName.'Module';
if (class_exists($moduleClass)) {
/** @var ModuleContract $module */
$module = new $moduleClass;
return $module;
}
return $this->emptyModule();
}
/**
* Modules
*
* @return Collection<array-key, BaseModule>
*/
public function modules(): Collection
{
return $this->modules;
}
/**
* Empty module
*/
public function emptyModule(): ModuleContract
{
return new EmptyModule;
}
/**
* Get all modules regardless if disabled
*
* @return Collection<array-key, BaseModule>
*/
public function allModules(): Collection
{
return $this->allModules;
}
/**
* Migration paths
*
* @return array<int, string>
*/
public function migrationsPaths(): array
{
return $this->migrationsPaths;
}
/**
* Database seeders classes
*
* @return array<int, class-string>
*/
public function databaseSeederClasses(): array
{
return $this->databaseSeederClasses;
}
}

View File

@@ -2,7 +2,8 @@
namespace App\Providers; namespace App\Providers;
use App\Modules\BaseModule; use App\Modules\ModuleRepository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@@ -13,7 +14,9 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function register(): void public function register(): void
{ {
// $this->app->singleton(ModuleRepository::class, function (Application $app) {
return new ModuleRepository;
});
} }
/** /**
@@ -34,13 +37,6 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function registerModules(): void public function registerModules(): void
{ {
$migrationDirectories = []; $this->loadMigrationsFrom(modular()->migrationsPaths());
modules()->each(function (BaseModule $module) use (&$migrationDirectories) {
is_dir($module->path.'/Database/Migrations')
? array_push($migrationDirectories, $module->path.'/Database/Migrations')
: '';
});
$this->loadMigrationsFrom($migrationDirectories);
} }
} }

View File

@@ -4,9 +4,7 @@ namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents; // use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Modules\BaseModule;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\File;
class DatabaseSeeder extends Seeder class DatabaseSeeder extends Seeder
{ {
@@ -16,24 +14,7 @@ class DatabaseSeeder extends Seeder
public function run(): void public function run(): void
{ {
$seeders = []; $seeders = [];
// $seeders = modular()->databaseSeederClasses();
modules()->each(function (BaseModule $module) use (&$seeders) {
$seedersPath = $module->path.'/Database/Seeders';
if (is_dir($seedersPath)) {
$files = File::files($seedersPath);
foreach ($files as $file) {
$file->getFilenameWithoutExtension();
$moduleClass = 'App\\Modules\\'.$module->name.'\\Database\\Seeders\\'.$file->getFilenameWithoutExtension();
if (class_exists($moduleClass)) {
$seeders[] = $moduleClass;
}
}
}
});
$this->call($seeders); $this->call($seeders);
} }