Add settings with spatie package

WIP: Create settings page to manage settings. For now, we just need a
way to get default settings
This commit is contained in:
philipp lang 2021-11-19 00:15:20 +01:00
parent e0a72c4f0f
commit 25b970770f
13 changed files with 498 additions and 107 deletions

View File

@ -3,6 +3,7 @@ APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_MODE=
LOG_CHANNEL=stack

View File

@ -0,0 +1,29 @@
<?php
namespace App\Setting\Controllers;
use App\Http\Controllers\Controller;
use App\Setting\GeneralSettings;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class SettingController extends Controller
{
/**
* @wip
*/
public function index(GeneralSettings $generalSettings): Response
{
return Inertia::render('setting/Index', [
'options' => [
'modes' => $generalSettings->modeOptions()
],
'general' => [
'modes' => $generalSettings->modes
]
]);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Setting;
use Spatie\LaravelSettings\Settings;
class GeneralSettings extends Settings
{
/** @var array<int, string> */
public array $modes;
/**
* @return array<int, string>
*/
public function modeOptions(): array
{
return [
'bill',
];
}
public static function group(): string
{
return 'general';
}
}

View File

@ -28,6 +28,7 @@
"nunomaduro/larastan": "^0.7.12",
"predis/predis": "^1.1",
"spatie/laravel-medialibrary": "^7.19",
"spatie/laravel-settings": "^2.2",
"zoomyboy/laravel-nami": "dev-master"
},
"require-dev": {

346
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "cff6a20ccb92b5672db30ea521f74318",
"content-hash": "41058785137f0b880343dab892655c32",
"packages": [
{
"name": "asm89/stack-cors",
@ -4016,6 +4016,109 @@
},
"time": "2021-04-09T13:42:10+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jaap van Otterdijk",
"email": "opensource@ijaap.nl"
}
],
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
"homepage": "http://www.phpdoc.org",
"keywords": [
"FQSEN",
"phpDocumentor",
"phpdoc",
"reflection",
"static analysis"
],
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
},
"time": "2020-06-27T09:03:43+00:00"
},
{
"name": "phpdocumentor/type-resolver",
"version": "1.5.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae",
"reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.0"
},
"require-dev": {
"ext-tokenizer": "*",
"psalm/phar": "^4.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1"
},
"time": "2021-10-02T14:08:47+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.8.0",
@ -5031,6 +5134,65 @@
},
"time": "2021-08-19T21:01:38+00:00"
},
{
"name": "spatie/data-transfer-object",
"version": "2.8.3",
"source": {
"type": "git",
"url": "https://github.com/spatie/data-transfer-object.git",
"reference": "2625a59566804ec63f01947d85947336237cbda6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/2625a59566804ec63f01947d85947336237cbda6",
"reference": "2625a59566804ec63f01947d85947336237cbda6",
"shasum": ""
},
"require": {
"php": "^7.4|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
},
"suggest": {
"phpstan/phpstan": "Take advantage of checkUninitializedProperties with \\Spatie\\DataTransferObject\\PHPstan\\PropertiesAreAlwaysInitializedExtension"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\DataTransferObject\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Brent Roose",
"email": "brent@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Data transfer objects with batteries included",
"homepage": "https://github.com/spatie/data-transfer-object",
"keywords": [
"data-transfer-object",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/data-transfer-object/issues",
"source": "https://github.com/spatie/data-transfer-object/tree/2.8.3"
},
"funding": [
{
"url": "https://www.patreon.com/spatie",
"type": "patreon"
}
],
"time": "2021-02-12T08:46:52+00:00"
},
{
"name": "spatie/image",
"version": "1.10.5",
@ -5254,6 +5416,85 @@
],
"time": "2021-05-26T16:48:02+00:00"
},
{
"name": "spatie/laravel-settings",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-settings.git",
"reference": "212ae74e67c0b9cc0907ffa15c73bc7a6efaa75e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-settings/zipball/212ae74e67c0b9cc0907ffa15c73bc7a6efaa75e",
"reference": "212ae74e67c0b9cc0907ffa15c73bc7a6efaa75e",
"shasum": ""
},
"require": {
"doctrine/dbal": "^2.6|^3",
"ext-json": "*",
"illuminate/database": "^7.0|^8.24.0",
"php": "^7.4|^8.0",
"phpdocumentor/type-resolver": "^1.4",
"spatie/data-transfer-object": "^2.0|^3.0",
"spatie/temporary-directory": "^1.2|^2.0"
},
"require-dev": {
"ext-redis": "*",
"mockery/mockery": "^1.4",
"orchestra/testbench": "^5.0|^6.0",
"phpunit/phpunit": "^9.1",
"psalm/plugin-laravel": "^1.4",
"spatie/phpunit-snapshot-assertions": "^4.2",
"vimeo/psalm": "^4.2"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Spatie\\LaravelSettings\\LaravelSettingsServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Spatie\\LaravelSettings\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ruben Van Assche",
"email": "ruben@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Store your application settings",
"homepage": "https://github.com/spatie/laravel-settings",
"keywords": [
"laravel-settings",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-settings/issues",
"source": "https://github.com/spatie/laravel-settings/tree/2.2.0"
},
"funding": [
{
"url": "https://spatie.be/open-source/support-us",
"type": "custom"
},
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2021-10-22T11:55:01+00:00"
},
{
"name": "spatie/pdf-to-image",
"version": "2.1.0",
@ -8861,59 +9102,6 @@
},
"time": "2021-02-23T14:00:09+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jaap van Otterdijk",
"email": "opensource@ijaap.nl"
}
],
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
"homepage": "http://www.phpdoc.org",
"keywords": [
"FQSEN",
"phpDocumentor",
"phpdoc",
"reflection",
"static analysis"
],
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
},
"time": "2020-06-27T09:03:43+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "5.3.0",
@ -8971,56 +9159,6 @@
},
"time": "2021-10-19T17:43:47+00:00"
},
{
"name": "phpdocumentor/type-resolver",
"version": "1.5.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae",
"reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.0"
},
"require-dev": {
"ext-tokenizer": "*",
"psalm/phar": "^4.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1"
},
"time": "2021-10-02T14:08:47+00:00"
},
{
"name": "phpspec/prophecy",
"version": "1.14.0",

View File

@ -95,6 +95,18 @@ return [
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| App Mode
|--------------------------------------------------------------------------
|
| The mode of the app will set some default settings for you on initial
| database setup. You can change these Settings anytime later, but it
| usually defines a good starting point for you to set up the world.
|
*/
'mode' => env('APP_MODE', 'stamm'),
/*
|--------------------------------------------------------------------------
| Faker Locale
@ -105,7 +117,6 @@ return [
| localized telephone numbers, street address information and more.
|
*/
'faker_locale' => 'de_DE',
/*

79
config/settings.php Normal file
View File

@ -0,0 +1,79 @@
<?php
return [
/*
* Each settings class used in your application must be registered, you can
* put them (manually) here.
*/
'settings' => [
],
/*
* In these directories settings migrations will be stored and ran when migrating. A settings
* migration created via the make:settings-migration command will be stored in the first path or
* a custom defined path when running the command.
*/
'migrations_paths' => [
database_path('settings'),
],
/*
* When no repository was set for a settings class the following repository
* will be used for loading and saving settings.
*/
'default_repository' => 'database',
/*
* Settings will be stored and loaded from these repositories.
*/
'repositories' => [
'database' => [
'type' => Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class,
'model' => null,
'table' => null,
'connection' => null,
],
'redis' => [
'type' => Spatie\LaravelSettings\SettingsRepositories\RedisSettingsRepository::class,
'connection' => null,
'prefix' => null,
],
],
/*
* The contents of settings classes can be cached through your application,
* settings will be stored within a provided Laravel store and can have an
* additional prefix.
*/
'cache' => [
'enabled' => env('SETTINGS_CACHE_ENABLED', false),
'store' => null,
'prefix' => null,
],
/*
* These global casts will be automatically used whenever a property within
* your settings class isn't a default PHP type.
*/
'global_casts' => [
DateTimeInterface::class => Spatie\LaravelSettings\SettingsCasts\DateTimeInterfaceCast::class,
DateTimeZone::class => Spatie\LaravelSettings\SettingsCasts\DateTimeZoneCast::class,
Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class,
],
/*
* The package will look for settings in these paths and automatically
* register them.
*/
'auto_discover_settings' => [
app()->path(),
],
/*
* Automatically discovered settings classes can be cached so they don't
* need to be searched each time the application boots up.
*/
'discovered_settings_cache_path' => storage_path('app/laravel-settings'),
];

View File

@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSettingsTable extends Migration
{
public function up()
{
Schema::create('settings', function (Blueprint $table): void {
$table->id();
$table->string('group')->index();
$table->string('name');
$table->boolean('locked');
$table->json('payload');
$table->timestamps();
});
}
}

View File

@ -0,0 +1,31 @@
<?php
use Spatie\LaravelSettings\Migrations\SettingsMigration;
class CreateGeneralSettings extends SettingsMigration
{
/**
* @param string $mode
* @return array<string, string|array>
*/
public function defaults(string $mode): array
{
$defaults = [
'diözese' => [
'modes' => []
],
'stamm' => [
'modes' => ['bill']
]
];
return $defaults[$mode];
}
public function up(): void
{
$defaults = $this->defaults(config('app.mode'));
$this->migrator->add('general.modes', $defaults['modes']);
}
}

@ -1 +1 @@
Subproject commit 2b7aca9b0dc30c8e0fb0dd9ca9df7b74358b8803
Subproject commit 61d98f69502e10ad726b5c079738ac62ba258136

View File

@ -10,6 +10,7 @@ use App\Payment\PaymentController;
use App\Payment\SendpaymentController;
use App\Payment\SubscriptionController;
use App\Pdf\MemberPdfController;
use App\Setting\Controllers\SettingController;
Route::group(['namespace' => 'App\\Http\\Controllers'], function(): void {
Auth::routes(['register' => false]);
@ -28,4 +29,5 @@ Route::group(['middleware' => 'auth:web'], function (): void {
Route::get('/sendpayment', [SendpaymentController::class, 'create'])->name('sendpayment.create');
Route::get('/sendpayment/pdf', [SendpaymentController::class, 'send'])->name('sendpayment.pdf');
Route::apiResource('member.membership', MembershipController::class);
Route::resource('setting', SettingController::class);
});

View File

@ -0,0 +1,39 @@
<?php
namespace Tests\Feature\Settings;
use App\Setting\GeneralSettings;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class GlobalSettingTest extends TestCase
{
use RefreshDatabase;
public function testItLoadsGeneralSettings(): void
{
GeneralSettings::fake([
'mode' => ['bill']
]);
$this->withoutExceptionHandling();
$this->login()->init();
$response = $this->get('/setting');
$response->assertInertiaComponent('setting/Index');
$this->assertEquals(['bill'], $response->inertia('general.modes'));
}
public function testItGetsOptionsForModels(): void
{
$this->withoutExceptionHandling();
$this->login()->init();
$response = $this->get('/setting');
$this->assertContains('bill', $response->inertia('options.modes'));
}
}

View File

@ -2,6 +2,7 @@
namespace Tests;
use App\Member\Member;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Testing\TestResponse;
use Tests\Lib\InertiaMixin;
@ -19,7 +20,7 @@ abstract class TestCase extends BaseTestCase
TestResponse::mixin(new InertiaMixin());
}
public function login(): void
public function login(): self
{
app(FakeBackend::class)
->fakeLogin('123')
@ -28,6 +29,15 @@ abstract class TestCase extends BaseTestCase
'mglnr' => 123,
'password' => 'secret',
]);
return $this;
}
public function init(): self
{
Member::factory()->defaults()->create();
return $this;
}
}