Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
inmanturbo committed Feb 26, 2025
1 parent 1169cbb commit 8b312f1
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Laravel\Pennant\Migrations\PennantMigration;

return new class extends PennantMigration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('features', function (Blueprint $table) {
$table->boolean('active')->after('value')->nullable();
$table->text('value')->nullable()->change();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('features', function (Blueprint $table) {
$table->dropColumn('active');
$table->text('value')->change();
});
}
};
29 changes: 18 additions & 11 deletions src/Drivers/DatabaseDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Laravel\Pennant\Contracts\Driver;
use Laravel\Pennant\Events\UnknownFeatureResolved;
use Laravel\Pennant\Feature;
use Laravel\Pennant\FeatureValues;
use RuntimeException;
use stdClass;

Expand Down Expand Up @@ -204,7 +205,13 @@ public function getAll($features): array
public function get($feature, $scope): mixed
{
if (($record = $this->retrieve($feature, $scope)) !== null) {
return json_decode($record->value, flags: JSON_OBJECT_AS_ARRAY | JSON_THROW_ON_ERROR);
$value = json_decode($record->value, flags: JSON_OBJECT_AS_ARRAY | JSON_THROW_ON_ERROR);

if (isset($record->active)) {
return (bool) $record->active ? $value : false;
}

return $value;
}

return with($this->resolveValue($feature, $scope), function ($value) use ($feature, $scope) {
Expand Down Expand Up @@ -272,13 +279,13 @@ protected function resolveValue($feature, $scope)
*/
public function set($feature, $scope, $value): void
{
$this->newQuery()->upsert([
$this->newQuery()->upsert(FeatureValues::make([
'name' => $feature,
'scope' => Feature::serializeScope($scope),
'value' => json_encode($value, flags: JSON_THROW_ON_ERROR),
static::CREATED_AT => $now = Carbon::now(),
static::UPDATED_AT => $now,
], uniqueBy: ['name', 'scope'], update: ['value', static::UPDATED_AT]);
])->toArray(), uniqueBy: ['name', 'scope'], update: ['value', static::UPDATED_AT]);
}

/**
Expand All @@ -291,10 +298,10 @@ public function setForAllScopes($feature, $value): void
{
$this->newQuery()
->where('name', $feature)
->update([
->update(FeatureValues::make([
'value' => json_encode($value, flags: JSON_THROW_ON_ERROR),
static::UPDATED_AT => Carbon::now(),
]);
])->toArray());
}

/**
Expand All @@ -310,10 +317,10 @@ protected function update($feature, $scope, $value)
return (bool) $this->newQuery()
->where('name', $feature)
->where('scope', Feature::serializeScope($scope))
->update([
->update(FeatureValues::make([
'value' => json_encode($value, flags: JSON_THROW_ON_ERROR),
static::UPDATED_AT => Carbon::now(),
]);
])->toArray());
}

/**
Expand All @@ -326,11 +333,11 @@ protected function update($feature, $scope, $value)
*/
protected function insert($feature, $scope, $value)
{
return $this->insertMany([[
return $this->insertMany([FeatureValues::make([
'name' => $feature,
'scope' => $scope,
'value' => $value,
]]);
])->toArray()]);
}

/**
Expand All @@ -343,13 +350,13 @@ protected function insertMany($inserts)
{
$now = Carbon::now();

return $this->newQuery()->insert(array_map(fn ($insert) => [
return $this->newQuery()->insert(array_map(fn ($insert) => FeatureValues::make([
'name' => $insert['name'],
'scope' => Feature::serializeScope($insert['scope']),
'value' => json_encode($insert['value'], flags: JSON_THROW_ON_ERROR),
static::CREATED_AT => $now,
static::UPDATED_AT => $now,
], $inserts));
])->toArray(), $inserts));
}

/**
Expand Down
71 changes: 71 additions & 0 deletions src/FeatureValues.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Laravel\Pennant;

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Arr;

/** @phpstan-consistent-constructor */
class FeatureValues implements Arrayable
{
/**
* Whether the Feature is active
*
* @var bool
*/
protected bool $active;

/**
* The Feature's value
*
* @var mixed
*/
protected $value;

/**
* Create a new Feature Values instance
*
* @param array $values
*/
public function __construct(
protected array $values,
) {

$this->value = $this->values['value'] ?? null;

$this->active = $this->value ? true : false;

$this->values['active'] = $this->active;
}

/**
* Make a FeatureValues instance
*
* @param array $values
* @return static
*/
public static function make(array $values): static
{
return new static($values);
}

/**
* Get the values for the instance.
*
* @return array
*/
public function values(): array
{
return $this->active ? $this->values : Arr::except($this->values, 'value');
}

/**
* Get the instance as an array.
*
* @return array
*/
public function toArray(): array
{
return $this->values();
}
}

0 comments on commit 8b312f1

Please sign in to comment.