Skip to content

Commit

Permalink
[1.x] Extract serialization to shared helper (#27)
Browse files Browse the repository at this point in the history
* Extract serialization to helper method

* Fix code styling

---------

Co-authored-by: timacdonald <timacdonald@users.noreply.github.com>
  • Loading branch information
timacdonald and timacdonald authored Feb 14, 2023
1 parent 7a3bea4 commit d3d458d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 48 deletions.
26 changes: 4 additions & 22 deletions src/Drivers/ArrayDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
namespace Laravel\Pennant\Drivers;

use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Laravel\Pennant\Contracts\Driver;
use Laravel\Pennant\Events\UnknownFeatureResolved;
use RuntimeException;
use Laravel\Pennant\Feature;
use stdClass;

class ArrayDriver implements Driver
Expand Down Expand Up @@ -99,7 +98,7 @@ public function getAll($features): array
*/
public function get($feature, $scope): mixed
{
$scopeKey = $this->serializeScope($scope);
$scopeKey = Feature::serializeScope($scope);

if (isset($this->resolvedFeatureStates[$feature][$scopeKey])) {
return $this->resolvedFeatureStates[$feature][$scopeKey];
Expand Down Expand Up @@ -145,7 +144,7 @@ public function set($feature, $scope, $value): void
{
$this->resolvedFeatureStates[$feature] ??= [];

$this->resolvedFeatureStates[$feature][$this->serializeScope($scope)] = $value;
$this->resolvedFeatureStates[$feature][Feature::serializeScope($scope)] = $value;
}

/**
Expand All @@ -171,7 +170,7 @@ public function setForAllScopes($feature, $value): void
*/
public function delete($feature, $scope): void
{
unset($this->resolvedFeatureStates[$feature][$this->serializeScope($scope)]);
unset($this->resolvedFeatureStates[$feature][Feature::serializeScope($scope)]);
}

/**
Expand Down Expand Up @@ -210,21 +209,4 @@ public function flushCache()
{
$this->resolvedFeatureStates = [];
}

/**
* Serialize the given scope for storage.
*
* @param mixed $scope
* @return string
*/
protected function serializeScope($scope)
{
return match (true) {
$scope === null => '__laravel_null',
is_string($scope) => $scope,
is_numeric($scope) => (string) $scope,
$scope instanceof Model => $scope::class.'|'.$scope->getKey(),
default => throw new RuntimeException('Unable to serialize the feature scope to a string. You should implement the FeatureScopeable contract.')
};
}
}
34 changes: 8 additions & 26 deletions src/Drivers/DatabaseDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\Connection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Laravel\Pennant\Contracts\Driver;
use Laravel\Pennant\Events\UnknownFeatureResolved;
use RuntimeException;
use Laravel\Pennant\Feature;
use stdClass;

class DatabaseDriver implements Driver
Expand Down Expand Up @@ -102,15 +101,15 @@ public function getAll($features): array
$features = Collection::make($features)
->map(fn ($scopes, $feature) => Collection::make($scopes)
->each(fn ($scope) => $query->orWhere(
fn ($q) => $q->where('name', $feature)->where('scope', $this->serializeScope($scope))
fn ($q) => $q->where('name', $feature)->where('scope', Feature::serializeScope($scope))
)));

$records = $query->get();

$inserts = new Collection;

$results = $features->map(fn ($scopes, $feature) => $scopes->map(function ($scope) use ($feature, $records, $inserts) {
$filtered = $records->where('name', $feature)->where('scope', $this->serializeScope($scope));
$filtered = $records->where('name', $feature)->where('scope', Feature::serializeScope($scope));

if ($filtered->isNotEmpty()) {
return json_decode($filtered->value('value'), flags: JSON_OBJECT_AS_ARRAY | JSON_THROW_ON_ERROR);
Expand All @@ -123,7 +122,7 @@ public function getAll($features): array

$inserts[] = [
'name' => $feature,
'scope' => $this->serializeScope($scope),
'scope' => Feature::serializeScope($scope),
'value' => json_encode($value, flags: JSON_THROW_ON_ERROR),
];

Expand Down Expand Up @@ -172,7 +171,7 @@ protected function retrieve($feature, $scope)
{
return $this->newQuery()
->where('name', $feature)
->where('scope', $this->serializeScope($scope))
->where('scope', Feature::serializeScope($scope))
->first();
}

Expand Down Expand Up @@ -236,7 +235,7 @@ protected function update($feature, $scope, $value)
{
$exists = $this->newQuery()
->where('name', $feature)
->where('scope', $serialized = $this->serializeScope($scope))
->where('scope', $serialized = Feature::serializeScope($scope))
->exists();

if (! $exists) {
Expand Down Expand Up @@ -266,7 +265,7 @@ protected function insert($feature, $scope, $value)
{
return $this->newQuery()->insert([
'name' => $feature,
'scope' => $this->serializeScope($scope),
'scope' => Feature::serializeScope($scope),
'value' => json_encode($value, flags: JSON_THROW_ON_ERROR),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
Expand All @@ -283,7 +282,7 @@ public function delete($feature, $scope): void
{
$this->newQuery()
->where('name', $feature)
->where('scope', $this->serializeScope($scope))
->where('scope', Feature::serializeScope($scope))
->delete();
}

Expand All @@ -303,23 +302,6 @@ public function purge($features): void
}
}

/**
* Serialize the given scope for storage.
*
* @param mixed $scope
* @return string|null
*/
protected function serializeScope($scope)
{
return match (true) {
$scope === null => '__laravel_null',
is_string($scope) => $scope,
is_numeric($scope) => (string) $scope,
$scope instanceof Model => $scope::class.'|'.$scope->getKey(),
default => throw new RuntimeException('Unable to serialize the feature scope to a string. You should implement the FeatureScopeable contract.')
};
}

/**
* Create a new table query.
*
Expand Down
19 changes: 19 additions & 0 deletions src/Feature.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Laravel\Pennant;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Facade;
use RuntimeException;

/**
* @method static mixed store(string|null $store = null)
Expand Down Expand Up @@ -60,4 +62,21 @@ protected static function getFacadeAccessor()
{
return FeatureManager::class;
}

/**
* Serialize the given scope for storage.
*
* @param mixed $scope
* @return string|null
*/
public static function serializeScope($scope)
{
return match (true) {
$scope === null => '__laravel_null',
is_string($scope) => $scope,
is_numeric($scope) => (string) $scope,
$scope instanceof Model => $scope::class.'|'.$scope->getKey(),
default => throw new RuntimeException('Unable to serialize the feature scope to a string. You should implement the FeatureScopeable contract.')
};
}
}

0 comments on commit d3d458d

Please sign in to comment.