Skip to content

Commit 1b6c576

Browse files
authored
Enums as setting keys (#37)
1 parent 90181dd commit 1b6c576

File tree

8 files changed

+121
-27
lines changed

8 files changed

+121
-27
lines changed

docs/api/settings.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ public function context(Context $context = null): self
2222
/**
2323
* Remove a persisted setting from storage.
2424
*
25-
* @param string $key
25+
* @param string|\BackedEnum $key
2626
* @return void
2727
*/
28-
public function forget($key)
28+
public function forget(string|BackedEnum $key)
2929
```
3030

3131
### get
@@ -34,11 +34,11 @@ public function forget($key)
3434
/**
3535
* Retrieve a setting from storage.
3636
*
37-
* @param string $key
37+
* @param string|\BackedEnum $key
3838
* @param mixed $default
3939
* @return mixed
4040
*/
41-
public function get(string $key, $default = null)
41+
public function get(string|BackedEnum $key, $default = null)
4242
```
4343

4444
### all
@@ -59,10 +59,10 @@ public function all($keys = null): \Illuminate\Support\Collection
5959
/**
6060
* Determine if a setting has been persisted to storage.
6161
*
62-
* @param string $key
62+
* @param string|\BackedEnum $key
6363
* @return bool
6464
*/
65-
public function has($key): bool
65+
public function has(string|BackedEnum $key): bool
6666
```
6767

6868
### set
@@ -86,11 +86,11 @@ public function set(string $key, $value = null)
8686
* Determine if a setting is set to a false value.
8787
* Returns true if the value is false, '0', or 0.
8888
*
89-
* @param string $key
89+
* @param string|\BackedEnum $key
9090
* @param bool|int|string $default
9191
* @return bool
9292
*/
93-
public function isFalse(string $key, $default = false): bool
93+
public function isFalse(string|BackedEnum $key, $default = false): bool
9494
```
9595

9696
### isTrue
@@ -100,11 +100,11 @@ public function isFalse(string $key, $default = false): bool
100100
* Determine if a setting is set to a truthy value.
101101
* Returns true if the value is true, '1', or 1.
102102
*
103-
* @param string $key
103+
* @param string|\BackedEnum $key
104104
* @param bool|int|string $default
105105
* @return bool
106106
*/
107-
public function isTrue(string $key, $default = true): bool
107+
public function isTrue(string|BackedEnum $key, $default = true): bool
108108
```
109109

110110
### flush
@@ -125,8 +125,8 @@ public function flush($keys = null): void
125125
/**
126126
* Get the correct cache key for a given setting.
127127
*
128-
* @param string $key
128+
* @param string|\BackedEnum $key
129129
* @return string
130130
*/
131-
public function cacheKeyForSetting(string $key): string
131+
public function cacheKeyForSetting(string|BackedEnum $key): string
132132
```

docs/best-practices/enums.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
title: Enums
3+
sort: 4
4+
---
5+
6+
## Introduction
7+
8+
PHP 8.1 introduced native enums, which can be a great way to define setting keys to use with this package.
9+
Using an enum instead of hard-coding your setting keys can be helpful for both keeping track of which
10+
settings are available to the application and for consistency.
11+
As of version `3.1.0` of the package, the settings service will support enums as setting keys in the `get()`,
12+
`set()`, `forget()`, and `has()` methods, as well as `isTrue()`, `isFalse()`, and `cacheKeyForSetting()`.
13+
14+
To use an enum as a setting key, you must use a string backed enum, like the example below:
15+
16+
```php
17+
namespace App\Enums;
18+
19+
enum SettingKey: string
20+
{
21+
case Timezone = 'app.timezone';
22+
case DefaultRole = 'default-role';
23+
}
24+
```
25+
26+
Now, you can use that enum when interacting with settings:
27+
28+
```php
29+
settings()->get(SettingKey::Timezone);
30+
```

src/Exceptions/InvalidEnumType.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rawilk\Settings\Exceptions;
6+
7+
use InvalidArgumentException;
8+
9+
final class InvalidEnumType extends InvalidArgumentException
10+
{
11+
public static function make(string $enumClass): self
12+
{
13+
return new self("Only string backed enums are supported. `{$enumClass}` is not a string backed enum.");
14+
}
15+
}

src/Facades/Settings.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
* @see \Rawilk\Settings\Settings
1111
*
1212
* @method static \Rawilk\Settings\Settings context(null|\Rawilk\Settings\Support\Context $context = null)
13-
* @method static null|mixed forget($key)
14-
* @method static mixed get(string $key, null|mixed $default = null)
13+
* @method static null|mixed forget(string|\BackedEnum $key)
14+
* @method static mixed get(string|\BackedEnum $key, null|mixed $default = null)
1515
* @method static \Illuminate\Support\Collection all($keys)
16-
* @method static bool isFalse(string $key, bool|int|string $default = false)
17-
* @method static bool isTrue(string $key, bool|int|string $default = true)
18-
* @method static bool has($key)
19-
* @method static null|mixed set(string $key, null|mixed $value = null)
16+
* @method static bool isFalse(string|\BackedEnum $key, bool|int|string $default = false)
17+
* @method static bool isTrue(string|\BackedEnum $key, bool|int|string $default = true)
18+
* @method static bool has(string|\BackedEnum $key)
19+
* @method static null|mixed set(string|\BackedEnum $key, null|mixed $value = null)
2020
* @method static void flush($keys)
2121
* @method static self disableCache()
2222
* @method static self enableCache()

src/Settings.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Rawilk\Settings;
66

7+
use BackedEnum;
78
use Illuminate\Contracts\Cache\Repository as Cache;
89
use Illuminate\Contracts\Encryption\Encrypter;
910
use Illuminate\Database\Eloquent\Model;
@@ -17,6 +18,7 @@
1718
use Rawilk\Settings\Events\SettingWasDeleted;
1819
use Rawilk\Settings\Events\SettingWasStored;
1920
use Rawilk\Settings\Exceptions\InvalidBulkValueResult;
21+
use Rawilk\Settings\Exceptions\InvalidEnumType;
2022
use Rawilk\Settings\Exceptions\InvalidKeyGenerator;
2123
use Rawilk\Settings\Support\Context;
2224
use Rawilk\Settings\Support\KeyGenerators\Md5KeyGenerator;
@@ -108,7 +110,7 @@ public function setTeamForeignKey(?string $foreignKey): self
108110
return $this;
109111
}
110112

111-
public function forget($key)
113+
public function forget(string|BackedEnum $key)
112114
{
113115
$key = $this->normalizeKey($key);
114116

@@ -141,7 +143,7 @@ public function forget($key)
141143
return $driverResult;
142144
}
143145

144-
public function get(string $key, $default = null)
146+
public function get(string|BackedEnum $key, $default = null)
145147
{
146148
$key = $this->normalizeKey($key);
147149

@@ -210,7 +212,7 @@ public function all($keys = null): Collection
210212
return $values;
211213
}
212214

213-
public function has($key): bool
215+
public function has(string|BackedEnum $key): bool
214216
{
215217
$key = $this->normalizeKey($key);
216218

@@ -229,7 +231,7 @@ public function has($key): bool
229231
return $has;
230232
}
231233

232-
public function set(string $key, $value = null): mixed
234+
public function set(string|BackedEnum $key, $value = null): mixed
233235
{
234236
$key = $this->normalizeKey($key);
235237

@@ -269,14 +271,14 @@ public function set(string $key, $value = null): mixed
269271
return $driverResult;
270272
}
271273

272-
public function isFalse(string $key, $default = false): bool
274+
public function isFalse(string|BackedEnum $key, $default = false): bool
273275
{
274276
$value = $this->get(key: $key, default: $default);
275277

276278
return $value === false || $value === '0' || $value === 0;
277279
}
278280

279-
public function isTrue(string $key, $default = true): bool
281+
public function isTrue(string|BackedEnum $key, $default = true): bool
280282
{
281283
$value = $this->get(key: $key, default: $default);
282284

@@ -400,7 +402,7 @@ public function getKeyGenerator(): KeyGenerator
400402
* Generate the key to use for caching a specific setting.
401403
* This is meant for external usage.
402404
*/
403-
public function cacheKeyForSetting(string $key): string
405+
public function cacheKeyForSetting(string|BackedEnum $key): string
404406
{
405407
$storageKey = $this->getKeyForStorage(
406408
$this->normalizeKey($key),
@@ -417,8 +419,17 @@ public function cacheKeyForSetting(string $key): string
417419
return $cacheKey;
418420
}
419421

420-
protected function normalizeKey(string $key): string
422+
protected function normalizeKey(string|BackedEnum $key): string
421423
{
424+
if ($key instanceof BackedEnum) {
425+
throw_unless(
426+
is_string($key->value),
427+
InvalidEnumType::make($key::class)
428+
);
429+
430+
$key = $key->value;
431+
}
432+
422433
if (Str::startsWith(haystack: $key, needles: 'file_')) {
423434
return str_replace(search: 'file_', replace: 'file.', subject: $key);
424435
}
@@ -542,6 +553,6 @@ protected function normalizeBulkLookupKey($key): string|Collection|bool
542553
return collect($key)
543554
->flatten()
544555
->filter()
545-
->map(fn (string $key): string => $this->getKeyForStorage($this->normalizeKey($key)));
556+
->map(fn (string|BackedEnum $key): string => $this->getKeyForStorage($this->normalizeKey($key)));
546557
}
547558
}

tests/Feature/SettingsTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Rawilk\Settings\Events\SettingsFlushed;
1010
use Rawilk\Settings\Events\SettingWasDeleted;
1111
use Rawilk\Settings\Events\SettingWasStored;
12+
use Rawilk\Settings\Exceptions\InvalidEnumType;
1213
use Rawilk\Settings\Exceptions\InvalidKeyGenerator;
1314
use Rawilk\Settings\Facades\Settings as SettingsFacade;
1415
use Rawilk\Settings\Support\Context;
@@ -17,6 +18,8 @@
1718
use Rawilk\Settings\Support\KeyGenerators\Md5KeyGenerator;
1819
use Rawilk\Settings\Support\KeyGenerators\ReadableKeyGenerator;
1920
use Rawilk\Settings\Support\ValueSerializers\JsonValueSerializer;
21+
use Rawilk\Settings\Tests\Support\Enums\IntBackedEnum as InvalidEnumTypeEnum;
22+
use Rawilk\Settings\Tests\Support\Enums\SettingKey;
2023

2124
beforeEach(function () {
2225
config([
@@ -499,6 +502,21 @@
499502
expect(SettingsFacade::cacheKeyForSetting('foo'))->toBe('settings.foo::team:1');
500503
});
501504

505+
it('accepts a backed enum for a key instead of a string', function () {
506+
SettingsFacade::set(SettingKey::Timezone, 'foo');
507+
508+
expect(SettingsFacade::get(SettingKey::Timezone))->toBe('foo')
509+
->and(SettingsFacade::has(SettingKey::Timezone))->toBeTrue();
510+
511+
SettingsFacade::forget(SettingKey::Timezone);
512+
513+
expect(SettingsFacade::has(SettingKey::Timezone))->toBeFalse();
514+
});
515+
516+
it('throws an exception when an int backed enum is used', function () {
517+
SettingsFacade::get(InvalidEnumTypeEnum::Foo);
518+
})->throws(InvalidEnumType::class);
519+
502520
// Helpers...
503521

504522
function assertQueryCount(int $expected): void

tests/Support/Enums/IntBackedEnum.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rawilk\Settings\Tests\Support\Enums;
6+
7+
enum IntBackedEnum: int
8+
{
9+
case Foo = 1;
10+
}

tests/Support/Enums/SettingKey.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rawilk\Settings\Tests\Support\Enums;
6+
7+
enum SettingKey: string
8+
{
9+
case Timezone = 'app.timezone';
10+
}

0 commit comments

Comments
 (0)