Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Forced Features: Implement it
Browse files Browse the repository at this point in the history
This exists in the JS SDK, but not in the PHP sdk.

It's useful for cases like QA overrides during testing of features
jarstelfox committed Jul 15, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 589111a commit 4dffc2a
Showing 2 changed files with 48 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/Growthbook.php
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@ class Growthbook implements LoggerAwareInterface
private $attributes = [];
/** @var Feature<mixed>[] */
private $features = [];
/** @var array<string, FeatureResult<mixed>> */
private $forcedFeatures = [];
/** @var array<string,int> */
private $forcedVariations = [];
/** @var bool */
@@ -63,7 +65,7 @@ public static function create(): Growthbook
}

/**
* @param array{enabled?:bool,logger?:\Psr\Log\LoggerInterface,url?:string,attributes?:array<string,mixed>,features?:array<string,mixed>,forcedVariations?:array<string,int>,qaMode?:bool,trackingCallback?:callable,cache?:\Psr\SimpleCache\CacheInterface,httpClient?:\Psr\Http\Client\ClientInterface,requestFactory?:\Psr\Http\Message\RequestFactoryInterface,decryptionKey?:string} $options
* @param array{enabled?:bool,logger?:\Psr\Log\LoggerInterface,url?:string,attributes?:array<string,mixed>,features?:array<string,mixed>,forcedVariations?:array<string,int>,qaMode?:bool,trackingCallback?:callable,cache?:\Psr\SimpleCache\CacheInterface,httpClient?:\Psr\Http\Client\ClientInterface,requestFactory?:\Psr\Http\Message\RequestFactoryInterface,decryptionKey?:string,forcedFeatures?:array<string, FeatureResult<mixed>>} $options
*/
public function __construct(array $options = [])
{
@@ -75,6 +77,7 @@ public function __construct(array $options = [])
"attributes",
"features",
"forcedVariations",
"forcedFeatures",
"qaMode",
"trackingCallback",
"cache",
@@ -104,6 +107,10 @@ public function __construct(array $options = [])
// Ignore errors from discovery
}

if(array_key_exists("forcedFeatures", $options)) {
$this->withForcedFeatures($options['forcedFeatures']);
}

if (array_key_exists("features", $options)) {
$this->withFeatures(($options["features"]));
}
@@ -155,6 +162,15 @@ public function withForcedVariations(array $forcedVariations): Growthbook
$this->forcedVariations = $forcedVariations;
return $this;
}

/**
* @param array<string, FeatureResult<mixed>> $forcedFeatures
* @return Growthbook
*/
public function withForcedFeatures(array $forcedFeatures) {
$this->forcedFeatures = $forcedFeatures;
return $this;
}
/**
* @param string $url
* @return Growthbook
@@ -211,6 +227,12 @@ public function getForcedVariations(): array
{
return $this->forcedVariations;
}
/**
* @return array<string, FeatureResult<mixed>>
*/
public function getForcedFeatured() {
return $this->forcedFeatures;
}
/**
* @return string
*/
@@ -267,6 +289,17 @@ public function getFeature(string $key): FeatureResult
}
$this->log(LogLevel::DEBUG, "Evaluating feature - $key");
$feature = $this->features[$key];

// Check if the feature is forced
if (array_key_exists($key, $this->forcedFeatures)) {
$this->log(LogLevel::DEBUG, "Feature Forced - $key", [
"feature" => $key,
"result" => $this->forcedFeatures[$key],
]);

return $this->forcedFeatures[$key];
}

if ($feature->rules) {
foreach ($feature->rules as $rule) {
if ($rule->condition) {
14 changes: 14 additions & 0 deletions tests/GrowthbookTest.php
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
require_once __DIR__ . '/../vendor/autoload.php';

use Growthbook\Condition;
use Growthbook\FeatureResult;
use Growthbook\Growthbook;
use Growthbook\InlineExperiment;
use PHPUnit\Framework\TestCase;
@@ -330,6 +331,19 @@ public function testFluentInterface(): void
);
}

public function testForcedFeatures(): void
{
$gb = Growthbook::create()
->withFeatures([
'feature-1'=>['defaultValue' => false, 'rules' => []]
])
->withForcedFeatures([
'feature-1' => new FeatureResult(true, 'forcedFeature')
]);

$this->assertSame(true, $gb->getFeature('feature-1')->value);
}

public function testInlineExperiment(): void
{
$condition = ['country'=>'US'];

0 comments on commit 4dffc2a

Please sign in to comment.