Skip to content

Commit

Permalink
settings
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgergo committed Oct 13, 2024
1 parent ed35734 commit 21ac462
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 20 deletions.
3 changes: 2 additions & 1 deletion database/factories/SettingFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class SettingFactory extends Factory
public function definition(): array
{
return [
//
'key' => $this->faker->slug(1),
'value' => mt_rand(10, 1000),
];
}
}
5 changes: 0 additions & 5 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use Cone\Root\Http\Controllers\DashboardController;
use Cone\Root\Http\Controllers\DownloadController;
use Cone\Root\Http\Controllers\ResourceController;
use Cone\Root\Http\Controllers\SettingController;
use Illuminate\Support\Facades\Route;

// Dashboard
Expand All @@ -12,10 +11,6 @@
// Download
Route::get('/download/{medium:uuid}', DownloadController::class)->name('download');

// Settings
Route::get('/settings/{group}', [SettingController::class, 'show'])->name('settings.show');
Route::patch('/settings/{group}', [SettingController::class, 'update'])->name('settings.update');

// Resource
Route::get('/{resource}', [ResourceController::class, 'index'])->name('resource.index');
Route::get('/{resource}/create', [ResourceController::class, 'create'])->name('resource.create');
Expand Down
5 changes: 4 additions & 1 deletion src/Interfaces/Settings/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@

interface Registry
{
//
/**
* Get the repository instance.
*/
public function getRepository(): Repository;
}
57 changes: 56 additions & 1 deletion src/Interfaces/Settings/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,62 @@

namespace Cone\Root\Interfaces\Settings;

use Cone\Root\Models\Setting;

interface Repository
{
//
/**
* Get the setting model.
*/
public function model(): Setting;

/**
* Set the value cast.
*/
public function cast(string $key, string $type): void;

/**
* Merge the casts.
*/
public function mergeCasts(array $casts): void;

/**
* Remove the given casts.
*/
public function removeCasts(string|array $keys): void;

/**
* Remove the given casts.
*/
public function clearCasts(): void;

/**
* Get the value casts.
*/
public function getCasts(): array;

/**
* Get the value for the given key.
*/
public function get(string $key, mixed $default = null, bool $fresh = false): mixed;

/**
* Set the value for the given key.
*/
public function set(string $key, mixed $value): mixed;

/**
* Delete the given keys.
*/
public function delete(string|array $keys): void;

/**
* Flush the cache.
*/
public function flush(): void;

/**
* Get all the settings.
*/
public function all(): array;
}
10 changes: 6 additions & 4 deletions src/Models/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ protected static function newFactory(): SettingFactory
/**
* Cast the value attribute to the given type.
*/
public function castValue(?string $type = null): void
public function castValue(?string $type = null): static
{
if (is_null($type)) {
unset($this->casts['value']);
} else {
if (! is_null($type)) {
$this->casts['value'] = $type;
} else {
unset($this->casts['value']);
}

return $this;
}
}
8 changes: 8 additions & 0 deletions src/Settings/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ public function __construct(Repository $repository)
$this->repository = $repository;
}

/**
* Get the repository instance.
*/
public function getRepository(): Repository
{
return $this->repository;
}

/**
* Dynamically call the given method.
*/
Expand Down
33 changes: 25 additions & 8 deletions src/Settings/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Cone\Root\Interfaces\Settings\Repository as Contract;
use Cone\Root\Models\Setting;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\Eloquent\Builder;

class Repository implements Arrayable, ArrayAccess, Contract
{
Expand All @@ -27,6 +28,14 @@ public function model(): Setting
return Setting::proxy();
}

/**
* Get the base query for the repository.
*/
public function query(): Builder
{
return $this->model()->newQuery();
}

/**
* Set the value cast.
*/
Expand Down Expand Up @@ -78,23 +87,31 @@ public function get(string $key, mixed $default = null, bool $fresh = false): mi
return $this->offsetGet($key);
}

$model = $this->model()->newQuery()->firstWhere('key', '=', $key);
return $this->refresh($key, $default);
}

if (! is_null($model)) {
$model->castValue($this->casts[$key] ?? null);
/**
* Refresh the given key.
*/
public function refresh(string $key, mixed $default = null): mixed
{
$model = $this->query()->firstWhere('key', '=', $key);

$this->offsetSet($key, $model->value);
}
$value = is_null($model)
? $default
: $model->castValue($this->casts[$key] ?? null)->value;

$this->offsetSet($key, $value);

return $this->cache[$key] ?? $default;
return $value;
}

/**
* Set the value for the given key.
*/
public function set(string $key, mixed $value): mixed
{
$model = $this->model()->newQuery()->firstOrNew(['key' => $key]);
$model = $this->query()->firstOrNew(['key' => $key]);

$model->castValue($this->casts[$key] ?? null);

Expand All @@ -116,7 +133,7 @@ public function delete(string|array $keys): void
$this->offsetUnset($key);
}

$this->model()->newQuery()->whereIn('key', (array) $keys)->delete();
$this->query()->whereIn('key', (array) $keys)->delete();
}

/**
Expand Down
70 changes: 70 additions & 0 deletions tests/Settings/SettingsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Cone\Root\Tests\Settings;

use Cone\Root\Settings\Registry;
use Cone\Root\Settings\Repository;
use Cone\Root\Tests\TestCase;
use Illuminate\Support\Facades\Date;

class SettingsTest extends TestCase
{
protected Registry $registry;

public function setUp(): void
{
parent::setUp();

$this->registry = new Registry(new Repository);
}

public function test_setting_can_be_set(): void
{
$value = $this->registry->set('foo', 'bar');
$this->assertSame('bar', $value);

$this->assertDatabaseHas('root_settings', ['key' => 'foo', 'value' => 'bar']);
}

public function test_setting_value_with_cast(): void
{
$this->registry->cast('ran_at', 'datetime');

$value = $this->registry->get('ran_at');
$this->assertNull($value);

$value = $this->registry->set('ran_at', $now = Date::now());
$this->assertSame(
$now->__toString(),
$this->registry->query()->firstWhere('key', 'ran_at')->value
);

$this->assertSame(
$now->__toString(),
$this->registry->get('ran_at')->__toString()
);
}

public function test_setting_can_be_get(): void
{
$value = $this->registry->get('foo');
$this->assertNull($value);

$value = $this->registry->get('foo', 'bar');
$this->assertSame('bar', $value);
}

public function test_setting_can_be_deleted(): void
{
$value = $this->registry->set('foo', 'bar');
$this->assertSame('bar', $value);

$value = $this->registry->get('foo');
$this->assertSame('bar', $value);

$this->registry->delete('foo');
$this->assertNull($this->registry->get('foo'));

$this->assertDatabaseMissing('root_settings', ['key' => 'foo']);
}
}

0 comments on commit 21ac462

Please sign in to comment.