Skip to content

Commit

Permalink
Add ability to fetch all settings
Browse files Browse the repository at this point in the history
  • Loading branch information
rawilk committed Sep 28, 2023
1 parent 84989d4 commit b32c6b3
Show file tree
Hide file tree
Showing 18 changed files with 494 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/Contracts/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@

namespace Rawilk\Settings\Contracts;

use Illuminate\Contracts\Support\Arrayable;

interface Driver
{
public function forget($key, $teamId = null);

public function get(string $key, $default = null, $teamId = null);

public function all($teamId = null, $keys = null): array|Arrayable;

public function has($key, $teamId = null): bool;

public function set(string $key, $value = null, $teamId = null);
Expand Down
4 changes: 4 additions & 0 deletions src/Contracts/KeyGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ interface KeyGenerator
{
public function generate(string $key, Context $context = null): string;

public function removeContextFromKey(string $key): string;

public function setContextSerializer(ContextSerializer $serializer): self;

public function contextPrefix(): string;
}
4 changes: 4 additions & 0 deletions src/Contracts/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@

namespace Rawilk\Settings\Contracts;

use Illuminate\Contracts\Support\Arrayable;

interface Setting
{
public static function getValue(string $key, $default = null, $teamId = null);

public static function getAll($teamId = null, $keys = null): array|Arrayable;

public static function has($key, $teamId = null): bool;

public static function removeSetting($key, $teamId = null);
Expand Down
42 changes: 42 additions & 0 deletions src/Drivers/DatabaseDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

namespace Rawilk\Settings\Drivers;

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\Connection;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Rawilk\Settings\Contracts\Driver;
use Rawilk\Settings\Facades\Settings;

class DatabaseDriver implements Driver
{
Expand Down Expand Up @@ -41,6 +44,32 @@ public function get(string $key, $default = null, $teamId = null)
return $value ?? $default;
}

public function all($teamId = null, $keys = null): array|Arrayable
{
$keys = $this->normalizeKeys($keys);

return $this->db()
->when(
// False means we want settings without a context set.
$keys === false,
fn (Builder $query) => $query->where('key', 'NOT LIKE', '%' . Settings::getKeyGenerator()->contextPrefix() . '%'),
)
->when(
// When keys is a string, we're trying to do a partial lookup for context
is_string($keys),
fn (Builder $query) => $query->where('key', 'LIKE', "%{$keys}"),
)
->when(
$keys instanceof Collection && $keys->isNotEmpty(),
fn (Builder $query) => $query->whereIn('key', $keys),
)
->when(
$teamId !== false,
fn (Builder $query) => $query->where("{$this->table}.{$this->teamForeignKey}", $teamId)
)
->get();
}

public function has($key, $teamId = null): bool
{
return $this->db()
Expand Down Expand Up @@ -69,4 +98,17 @@ protected function db(): Builder
{
return $this->connection->table($this->table);
}

protected function normalizeKeys($keys): string|Collection|bool
{
if (is_bool($keys)) {
return $keys;
}

if (is_string($keys)) {
return $keys;
}

return collect($keys)->flatten()->filter();
}
}
6 changes: 6 additions & 0 deletions src/Drivers/EloquentDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Rawilk\Settings\Drivers;

use Illuminate\Contracts\Support\Arrayable;
use Rawilk\Settings\Contracts\Driver;
use Rawilk\Settings\Contracts\Setting;

Expand All @@ -23,6 +24,11 @@ public function get(string $key, $default = null, $teamId = null)
return $this->model::getValue($key, $default, $teamId);
}

public function all($teamId = null, $keys = null): array|Arrayable
{
return $this->model::getAll($teamId, $keys);
}

public function has($key, $teamId = null): bool
{
return $this->model::has($key, $teamId);
Expand Down
21 changes: 21 additions & 0 deletions src/Exceptions/InvalidBulkValueResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Rawilk\Settings\Exceptions;

use Exception;
use Illuminate\Database\Eloquent\Model;

final class InvalidBulkValueResult extends Exception
{
public static function notObject(): self
{
return new self('A record returned from `all()` must be an array, object, or inherit from ' . Model::class);
}

public static function missingValueOrKey(): self
{
return new self('A record returned from `all()` must have a `value` and `key` property.');
}
}
18 changes: 18 additions & 0 deletions src/Exceptions/InvalidKeyGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Rawilk\Settings\Exceptions;

use Exception;
use Rawilk\Settings\Support\KeyGenerators\ReadableKeyGenerator;

final class InvalidKeyGenerator extends Exception
{
public static function forPartialLookup(string $class): self
{
return new self(
"The `{$class}` key generator cannot be used for partial context setting lookups. We recommend using the " . ReadableKeyGenerator::class . ' key generator instead. You can change the `key_generator` configuration key to this value in your `config/settings.php` file.',
);
}
}
2 changes: 2 additions & 0 deletions src/Facades/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* @method static \Rawilk\Settings\Settings context(null|\Rawilk\Settings\Support\Context $context = null)
* @method static null|mixed forget($key)
* @method static mixed get(string $key, null|mixed $default = null)
* @method static \Illuminate\Support\Collection all($keys)
* @method static bool isFalse(string $key, bool|int|string $default = false)
* @method static bool isTrue(string $key, bool|int|string $default = true)
* @method static bool has($key)
Expand All @@ -26,6 +27,7 @@
* @method static self enableTeams()
* @method static self disableTeams()
* @method static bool teamsAreEnabled()
* @method static \Rawilk\Settings\Contracts\KeyGenerator getKeyGenerator()
*/
class Settings extends Facade
{
Expand Down
45 changes: 45 additions & 0 deletions src/Models/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

namespace Rawilk\Settings\Models;

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Rawilk\Settings\Contracts\Setting as SettingContract;
use Rawilk\Settings\Facades\Settings;

class Setting extends Model implements SettingContract
{
Expand Down Expand Up @@ -40,6 +43,35 @@ public static function getValue(string $key, $default = null, $teamId = null)
return $value ?? $default;
}

public static function getAll($teamId = null, $keys = null): array|Arrayable
{
$keys = static::normalizeKeys($keys);

return static::query()
->when(
// False means we want settings without a context set.
$keys === false,
fn (Builder $query) => $query->where('key', 'NOT LIKE', '%' . Settings::getKeyGenerator()->contextPrefix() . '%'),
)
->when(
// When keys is a string, we're trying to do a partial lookup for context
is_string($keys),
fn (Builder $query) => $query->where('key', 'LIKE', "%{$keys}"),
)
->when(
$keys instanceof Collection && $keys->isNotEmpty(),
fn (Builder $query) => $query->whereIn('key', $keys),
)
->when(
$teamId !== false,
fn (Builder $query) => $query->where(
static::make()->getTable() . '.' . config('settings.team_foreign_key'),
$teamId,
),
)
->get();
}

public static function has($key, $teamId = null): bool
{
return static::query()
Expand Down Expand Up @@ -78,4 +110,17 @@ public static function set(string $key, $value = null, $teamId = null)

return static::updateOrCreate($data, compact('value'));
}

protected static function normalizeKeys($keys): string|Collection|bool
{
if (is_bool($keys)) {
return $keys;
}

if (is_string($keys)) {
return $keys;
}

return collect($keys)->flatten()->filter();
}
}
Loading

0 comments on commit b32c6b3

Please sign in to comment.