new modules

This commit is contained in:
Mark Gregory
2026-07-24 09:25:27 +01:00
parent d7d2a3f610
commit 73f7a918c1
88 changed files with 2342 additions and 1 deletions
+6
View File
@@ -0,0 +1,6 @@
<?php
return [
'name' => 'Settings',
'enabled' => true,
];
@@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
Schema::create('settings', function (Blueprint $table): void {
$table->id(); $table->string('group')->default('general')->index(); $table->string('key');
$table->longText('value')->nullable(); $table->string('type')->default('string'); $table->boolean('is_public')->default(false);
$table->timestamps(); $table->unique(['group','key']);
});
}
public function down(): void { Schema::dropIfExists('settings'); }
};
+11
View File
@@ -0,0 +1,11 @@
<?php
namespace Modules\Settings\Models;
use Illuminate\Database\Eloquent\Model;
final class Setting extends Model
{
protected $fillable = ['group','key','value','type','is_public'];
protected function casts(): array { return ['is_public'=>'boolean']; }
}
@@ -0,0 +1,17 @@
<?php
namespace Modules\Settings\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
final class RouteServiceProvider extends ServiceProvider
{
public function boot(): void
{
parent::boot();
$this->routes(function (): void {
Route::middleware('web')->group(module_path('Settings', 'Routes/web.php'));
});
}
}
@@ -0,0 +1,21 @@
<?php
namespace Modules\Settings\Providers;
use Illuminate\Support\ServiceProvider;
use Modules\Settings\Support\ModuleInfo;
final class SettingsServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->register(RouteServiceProvider::class);
$this->mergeConfigFrom(module_path(ModuleInfo::name(), 'Config/config.php'), ModuleInfo::nameLower());
}
public function boot(): void
{
$this->loadMigrationsFrom(module_path(ModuleInfo::name(), 'Database/Migrations'));
$this->loadViewsFrom(module_path(ModuleInfo::name(), 'Resources/views'), ModuleInfo::nameLower());
}
}
+5
View File
@@ -0,0 +1,5 @@
<?php
use Illuminate\Support\Facades\Route;
// Module routes are intentionally registered by each feature as it is enabled.
@@ -0,0 +1,17 @@
<?php
namespace Modules\Settings\Services;
use Illuminate\Support\Facades\Cache;
use Modules\Settings\Models\Setting;
final class SettingsRepository
{
public function get(string $key, mixed $default = null, string $group = 'general'): mixed
{ return Cache::rememberForever("settings.$group.$key", fn () => Setting::query()->where(compact('group','key'))->value('value') ?? $default); }
public function put(string $key, mixed $value, string $group = 'general', string $type = 'string', bool $public = false): Setting
{
$setting = Setting::query()->updateOrCreate(compact('group','key'), ['value'=>is_scalar($value)||$value===null?(string)$value:json_encode($value, JSON_THROW_ON_ERROR),'type'=>$type,'is_public'=>$public]);
Cache::forget("settings.$group.$key"); return $setting;
}
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace Modules\Settings\Support;
final class ModuleInfo
{
public static function name(): string { return 'Settings'; }
public static function nameLower(): string { return 'settings'; }
}
@@ -0,0 +1,5 @@
<?php
it('boots the Settings module', function (): void {
expect(config('settings.name'))->toBe('Settings');
});
+10
View File
@@ -0,0 +1,10 @@
{
"name": "absdev/settings-module",
"description": "Settings foundation module for the ABSDEV Laravel application platform.",
"type": "laravel-module",
"autoload": {
"psr-4": {
"Modules\\Settings\\": ""
}
}
}
+20
View File
@@ -0,0 +1,20 @@
{
"name": "Settings",
"alias": "settings",
"version": "1.0.0",
"description": "Settings foundation module for the ABSDEV Laravel application platform.",
"keywords": [
"laravel",
"modules",
"settings"
],
"priority": 10,
"providers": [
"Modules\\Settings\\Providers\\SettingsServiceProvider"
],
"aliases": {},
"files": [],
"requires": [
"Core"
]
}