Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Optimizely/DecisionService/DecisionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ public function getVariationForFeatureExperiment(FeatureFlag $featureFlag, $user
"The user '{$userId}' is bucketed into experiment '{$experiment->getKey()}' of feature '{$featureFlagKey}'."
);

return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_EXPERIMENT);
return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_FEATURE_TEST);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Optimizely/DecisionService/FeatureDecision.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

class FeatureDecision
{
const DECISION_SOURCE_EXPERIMENT = 'EXPERIMENT';
const DECISION_SOURCE_ROLLOUT = 'ROLLOUT';
const DECISION_SOURCE_FEATURE_TEST = 'feature-test';
const DECISION_SOURCE_ROLLOUT = 'rollout';

/**
* The experiment in this decision.
Expand All @@ -36,7 +36,7 @@ class FeatureDecision
private $_variation;

/**
* The source of the decision. Either DECISION_SOURCE_EXPERIMENT or DECISION_SOURCE_ROLLOUT
* The source of the decision. Either DECISION_SOURCE_FEATURE_TEST or DECISION_SOURCE_ROLLOUT
*
* @var string
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@

namespace Optimizely\Enums;

class DecisionInfoTypes
class DecisionNotificationTypes
{
const EXPERIMENT = "experiment";
const AB_TEST = "ab-test";
const FEATURE = "feature";
const FEATURE_VARIABLE = "feature_variable";
const FEATURE_TEST = "feature-test";
const FEATURE_VARIABLE = "feature-variable";
}
35 changes: 23 additions & 12 deletions src/Optimizely/Optimizely.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
use Optimizely\DecisionService\FeatureDecision;
use Optimizely\Entity\Experiment;
use Optimizely\Entity\FeatureVariable;
use Optimizely\Enums\DecisionInfoTypes;
use Optimizely\Enums\DecisionNotificationTypes;
use Optimizely\ErrorHandler\ErrorHandlerInterface;
use Optimizely\ErrorHandler\NoOpErrorHandler;
use Optimizely\Event\Builder\EventBuilder;
Expand Down Expand Up @@ -408,11 +408,17 @@ public function getVariation($experimentKey, $userId, $attributes = null)
$variation = $this->_decisionService->getVariation($experiment, $userId, $attributes);
$variationKey = ($variation === null) ? null : $variation->getKey();

if ($this->_config->isFeatureExperiment($experiment->getId())) {
$decisionNotificationType = DecisionNotificationTypes::FEATURE_TEST;
} else {
$decisionNotificationType = DecisionNotificationTypes::AB_TEST;
}

$attributes = $attributes ?: [];
$this->notificationCenter->sendNotifications(
NotificationType::DECISION,
array(
DecisionInfoTypes::EXPERIMENT,
$decisionNotificationType,
$userId,
$attributes,
(object) array(
Expand Down Expand Up @@ -519,9 +525,14 @@ public function isFeatureEnabled($featureFlagKey, $userId, $attributes = null)
if ($variation) {
$experiment = $decision->getExperiment();
$featureEnabled = $variation->getFeatureEnabled();
if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_EXPERIMENT) {
if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_FEATURE_TEST) {
$experimentKey = $experiment->getKey();
$variationKey = $variation->getKey();
$sourceInfo = (object) array(
'experimentKey'=> $experimentKey,
'variationKey'=> $variationKey
);

$this->sendImpressionEvent($experimentKey, $variationKey, $userId, $attributes);
} else {
$this->_logger->log(Logger::INFO, "The user '{$userId}' is not being experimented on Feature Flag '{$featureFlagKey}'.");
Expand All @@ -532,15 +543,14 @@ public function isFeatureEnabled($featureFlagKey, $userId, $attributes = null)
$this->notificationCenter->sendNotifications(
NotificationType::DECISION,
array(
DecisionInfoTypes::FEATURE,
DecisionNotificationTypes::FEATURE,
$userId,
$attributes,
(object) array(
'featureKey'=>$featureFlagKey,
'featureEnabled'=> $featureEnabled,
'source'=> $decision->getSource(),
'sourceExperimentKey'=> isset($experimentKey) ? $experimentKey : null,
'sourceVariationKey'=> isset($variationKey) ? $variationKey : null
'sourceInfo'=> isset($sourceInfo) ? $sourceInfo : (object) array()
)
)
);
Expand Down Expand Up @@ -654,9 +664,11 @@ public function getFeatureVariableValueForType(
$variation = $decision->getVariation();
$featureEnabled = $variation->getFeatureEnabled();

if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_EXPERIMENT) {
$experimentKey = $experiment->getKey();
$variationKey = $variation->getKey();
if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_FEATURE_TEST) {
$sourceInfo = (object) array(
'experimentKey'=> $experiment->getKey(),
'variationKey'=> $variation->getKey()
);
}

if ($featureEnabled) {
Expand Down Expand Up @@ -692,7 +704,7 @@ public function getFeatureVariableValueForType(
$this->notificationCenter->sendNotifications(
NotificationType::DECISION,
array(
DecisionInfoTypes::FEATURE_VARIABLE,
DecisionNotificationTypes::FEATURE_VARIABLE,
$userId,
$attributes,
(object) array(
Expand All @@ -702,8 +714,7 @@ public function getFeatureVariableValueForType(
'variableType'=> $variableType,
'variableValue'=> $variableValue,
'source'=> $decision->getSource(),
'sourceExperimentKey'=> isset($experimentKey) ? $experimentKey : null,
'sourceVariationKey'=> isset($variationKey) ? $variationKey : null
'sourceInfo'=> isset($sourceInfo) ? $sourceInfo : (object) array()
)
)
);
Expand Down
25 changes: 25 additions & 0 deletions src/Optimizely/ProjectConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ class ProjectConfig
*/
private $_featureFlagVariableMap;

/**
* Associative array of experiment ID to Feature ID(s) in the datafile.
*
* @var <String, Array>
*/
private $_experimentFeatureMap;

/**
* ProjectConfig constructor to load and set project configuration data.
*
Expand Down Expand Up @@ -289,13 +296,19 @@ public function __construct($datafile, $logger, $errorHandler)
$this->_featureKeyMap[$featureFlag->getKey()] = $featureFlag;
}

$this->_experimentFeatureMap = [];
if ($this->_featureKeyMap) {
foreach ($this->_featureKeyMap as $featureKey => $featureFlag) {
$this->_featureFlagVariableMap[$featureKey] = ConfigParser::generateMap(
$featureFlag->getVariables(),
'key',
FeatureVariable::class
);

$featureFlagId = $featureFlag->getId();
foreach ($featureFlag->getExperimentIds() as $experimentId) {
$this->_experimentFeatureMap[$experimentId] = [$featureFlagId];
}
}
}
}
Expand Down Expand Up @@ -680,4 +693,16 @@ public function setForcedVariation($experimentKey, $userId, $variationKey)

return true;
}

/**
* Determines if given experiment is a feature test.
*
* @param string Experiment ID.
*
* @return boolean A boolean value that indicates if the experiment is a feature test.
*/
public function isFeatureExperiment($experimentId)
{
return array_key_exists($experimentId, $this->_experimentFeatureMap);
}
}
10 changes: 5 additions & 5 deletions tests/DecisionServiceTests/DecisionServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ public function testGetVariationForFeatureExperimentGivenNonMutexGroupAndUserIsB
->will($this->returnValue($variation));

$featureFlag = $this->config->getFeatureFlagFromKey('multi_variate_feature');
$expected_decision = new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_EXPERIMENT);
$expected_decision = new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_FEATURE_TEST);

$this->loggerMock->expects($this->at(0))
->method('log')
Expand All @@ -779,14 +779,14 @@ public function testGetVariationForFeatureExperimentGivenMutexGroupAndUserIsBuck

$mutex_exp = $this->config->getExperimentFromKey('group_experiment_1');
$variation = $mutex_exp->getVariations()[0];
$expected_decision = new FeatureDecision($mutex_exp, $variation, FeatureDecision::DECISION_SOURCE_EXPERIMENT);
$expected_decision = new FeatureDecision($mutex_exp, $variation, FeatureDecision::DECISION_SOURCE_FEATURE_TEST);

$featureFlag = $this->config->getFeatureFlagFromKey('boolean_feature');
$featureFlag = $this->config->getFeatureFlagFromKey('mutex_group_feature');
$this->loggerMock->expects($this->at(0))
->method('log')
->with(
Logger::INFO,
"The user 'user_1' is bucketed into experiment 'group_experiment_1' of feature 'boolean_feature'."
"The user 'user_1' is bucketed into experiment 'group_experiment_1' of feature 'mutex_group_feature'."
);
$this->assertEquals(
$expected_decision,
Expand Down Expand Up @@ -830,7 +830,7 @@ public function testGetVariationForFeatureWhenTheUserIsBucketedIntoFeatureExperi
$expected_decision = new FeatureDecision(
$expected_experiment,
$expected_variation,
FeatureDecision::DECISION_SOURCE_EXPERIMENT
FeatureDecision::DECISION_SOURCE_FEATURE_TEST
);

$decisionServiceMock->expects($this->at(0))
Expand Down
Loading