Skip to content

Commit 1ca53d1

Browse files
rashidspaliabbasrizvi
authored andcommitted
feat(decision-listener): Incorporated new decision notification listener changes. (#173)
1 parent a116a3b commit 1ca53d1

File tree

9 files changed

+264
-121
lines changed

9 files changed

+264
-121
lines changed

src/Optimizely/DecisionService/DecisionService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public function getVariationForFeatureExperiment(FeatureFlag $featureFlag, $user
238238
"The user '{$userId}' is bucketed into experiment '{$experiment->getKey()}' of feature '{$featureFlagKey}'."
239239
);
240240

241-
return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_EXPERIMENT);
241+
return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_FEATURE_TEST);
242242
}
243243
}
244244

src/Optimizely/DecisionService/FeatureDecision.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
class FeatureDecision
2020
{
21-
const DECISION_SOURCE_EXPERIMENT = 'EXPERIMENT';
22-
const DECISION_SOURCE_ROLLOUT = 'ROLLOUT';
21+
const DECISION_SOURCE_FEATURE_TEST = 'feature-test';
22+
const DECISION_SOURCE_ROLLOUT = 'rollout';
2323

2424
/**
2525
* The experiment in this decision.
@@ -36,7 +36,7 @@ class FeatureDecision
3636
private $_variation;
3737

3838
/**
39-
* The source of the decision. Either DECISION_SOURCE_EXPERIMENT or DECISION_SOURCE_ROLLOUT
39+
* The source of the decision. Either DECISION_SOURCE_FEATURE_TEST or DECISION_SOURCE_ROLLOUT
4040
*
4141
* @var string
4242
*/

src/Optimizely/Enums/DecisionInfoTypes.php renamed to src/Optimizely/Enums/DecisionNotificationTypes.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717

1818
namespace Optimizely\Enums;
1919

20-
class DecisionInfoTypes
20+
class DecisionNotificationTypes
2121
{
22-
const EXPERIMENT = "experiment";
22+
const AB_TEST = "ab-test";
2323
const FEATURE = "feature";
24-
const FEATURE_VARIABLE = "feature_variable";
24+
const FEATURE_TEST = "feature-test";
25+
const FEATURE_VARIABLE = "feature-variable";
2526
}

src/Optimizely/Optimizely.php

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
use Optimizely\DecisionService\FeatureDecision;
2828
use Optimizely\Entity\Experiment;
2929
use Optimizely\Entity\FeatureVariable;
30-
use Optimizely\Enums\DecisionInfoTypes;
30+
use Optimizely\Enums\DecisionNotificationTypes;
3131
use Optimizely\ErrorHandler\ErrorHandlerInterface;
3232
use Optimizely\ErrorHandler\NoOpErrorHandler;
3333
use Optimizely\Event\Builder\EventBuilder;
@@ -408,11 +408,17 @@ public function getVariation($experimentKey, $userId, $attributes = null)
408408
$variation = $this->_decisionService->getVariation($experiment, $userId, $attributes);
409409
$variationKey = ($variation === null) ? null : $variation->getKey();
410410

411+
if ($this->_config->isFeatureExperiment($experiment->getId())) {
412+
$decisionNotificationType = DecisionNotificationTypes::FEATURE_TEST;
413+
} else {
414+
$decisionNotificationType = DecisionNotificationTypes::AB_TEST;
415+
}
416+
411417
$attributes = $attributes ?: [];
412418
$this->notificationCenter->sendNotifications(
413419
NotificationType::DECISION,
414420
array(
415-
DecisionInfoTypes::EXPERIMENT,
421+
$decisionNotificationType,
416422
$userId,
417423
$attributes,
418424
(object) array(
@@ -519,9 +525,14 @@ public function isFeatureEnabled($featureFlagKey, $userId, $attributes = null)
519525
if ($variation) {
520526
$experiment = $decision->getExperiment();
521527
$featureEnabled = $variation->getFeatureEnabled();
522-
if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_EXPERIMENT) {
528+
if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_FEATURE_TEST) {
523529
$experimentKey = $experiment->getKey();
524530
$variationKey = $variation->getKey();
531+
$sourceInfo = (object) array(
532+
'experimentKey'=> $experimentKey,
533+
'variationKey'=> $variationKey
534+
);
535+
525536
$this->sendImpressionEvent($experimentKey, $variationKey, $userId, $attributes);
526537
} else {
527538
$this->_logger->log(Logger::INFO, "The user '{$userId}' is not being experimented on Feature Flag '{$featureFlagKey}'.");
@@ -532,15 +543,14 @@ public function isFeatureEnabled($featureFlagKey, $userId, $attributes = null)
532543
$this->notificationCenter->sendNotifications(
533544
NotificationType::DECISION,
534545
array(
535-
DecisionInfoTypes::FEATURE,
546+
DecisionNotificationTypes::FEATURE,
536547
$userId,
537548
$attributes,
538549
(object) array(
539550
'featureKey'=>$featureFlagKey,
540551
'featureEnabled'=> $featureEnabled,
541552
'source'=> $decision->getSource(),
542-
'sourceExperimentKey'=> isset($experimentKey) ? $experimentKey : null,
543-
'sourceVariationKey'=> isset($variationKey) ? $variationKey : null
553+
'sourceInfo'=> isset($sourceInfo) ? $sourceInfo : (object) array()
544554
)
545555
)
546556
);
@@ -654,9 +664,11 @@ public function getFeatureVariableValueForType(
654664
$variation = $decision->getVariation();
655665
$featureEnabled = $variation->getFeatureEnabled();
656666

657-
if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_EXPERIMENT) {
658-
$experimentKey = $experiment->getKey();
659-
$variationKey = $variation->getKey();
667+
if ($decision->getSource() == FeatureDecision::DECISION_SOURCE_FEATURE_TEST) {
668+
$sourceInfo = (object) array(
669+
'experimentKey'=> $experiment->getKey(),
670+
'variationKey'=> $variation->getKey()
671+
);
660672
}
661673

662674
if ($featureEnabled) {
@@ -692,7 +704,7 @@ public function getFeatureVariableValueForType(
692704
$this->notificationCenter->sendNotifications(
693705
NotificationType::DECISION,
694706
array(
695-
DecisionInfoTypes::FEATURE_VARIABLE,
707+
DecisionNotificationTypes::FEATURE_VARIABLE,
696708
$userId,
697709
$attributes,
698710
(object) array(
@@ -702,8 +714,7 @@ public function getFeatureVariableValueForType(
702714
'variableType'=> $variableType,
703715
'variableValue'=> $variableValue,
704716
'source'=> $decision->getSource(),
705-
'sourceExperimentKey'=> isset($experimentKey) ? $experimentKey : null,
706-
'sourceVariationKey'=> isset($variationKey) ? $variationKey : null
717+
'sourceInfo'=> isset($sourceInfo) ? $sourceInfo : (object) array()
707718
)
708719
)
709720
);

src/Optimizely/ProjectConfig.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ class ProjectConfig
182182
*/
183183
private $_featureFlagVariableMap;
184184

185+
/**
186+
* Associative array of experiment ID to Feature ID(s) in the datafile.
187+
*
188+
* @var <String, Array>
189+
*/
190+
private $_experimentFeatureMap;
191+
185192
/**
186193
* ProjectConfig constructor to load and set project configuration data.
187194
*
@@ -289,13 +296,19 @@ public function __construct($datafile, $logger, $errorHandler)
289296
$this->_featureKeyMap[$featureFlag->getKey()] = $featureFlag;
290297
}
291298

299+
$this->_experimentFeatureMap = [];
292300
if ($this->_featureKeyMap) {
293301
foreach ($this->_featureKeyMap as $featureKey => $featureFlag) {
294302
$this->_featureFlagVariableMap[$featureKey] = ConfigParser::generateMap(
295303
$featureFlag->getVariables(),
296304
'key',
297305
FeatureVariable::class
298306
);
307+
308+
$featureFlagId = $featureFlag->getId();
309+
foreach ($featureFlag->getExperimentIds() as $experimentId) {
310+
$this->_experimentFeatureMap[$experimentId] = [$featureFlagId];
311+
}
299312
}
300313
}
301314
}
@@ -680,4 +693,16 @@ public function setForcedVariation($experimentKey, $userId, $variationKey)
680693

681694
return true;
682695
}
696+
697+
/**
698+
* Determines if given experiment is a feature test.
699+
*
700+
* @param string Experiment ID.
701+
*
702+
* @return boolean A boolean value that indicates if the experiment is a feature test.
703+
*/
704+
public function isFeatureExperiment($experimentId)
705+
{
706+
return array_key_exists($experimentId, $this->_experimentFeatureMap);
707+
}
683708
}

tests/DecisionServiceTests/DecisionServiceTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ public function testGetVariationForFeatureExperimentGivenNonMutexGroupAndUserIsB
753753
->will($this->returnValue($variation));
754754

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

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

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

784-
$featureFlag = $this->config->getFeatureFlagFromKey('boolean_feature');
784+
$featureFlag = $this->config->getFeatureFlagFromKey('mutex_group_feature');
785785
$this->loggerMock->expects($this->at(0))
786786
->method('log')
787787
->with(
788788
Logger::INFO,
789-
"The user 'user_1' is bucketed into experiment 'group_experiment_1' of feature 'boolean_feature'."
789+
"The user 'user_1' is bucketed into experiment 'group_experiment_1' of feature 'mutex_group_feature'."
790790
);
791791
$this->assertEquals(
792792
$expected_decision,
@@ -830,7 +830,7 @@ public function testGetVariationForFeatureWhenTheUserIsBucketedIntoFeatureExperi
830830
$expected_decision = new FeatureDecision(
831831
$expected_experiment,
832832
$expected_variation,
833-
FeatureDecision::DECISION_SOURCE_EXPERIMENT
833+
FeatureDecision::DECISION_SOURCE_FEATURE_TEST
834834
);
835835

836836
$decisionServiceMock->expects($this->at(0))

0 commit comments

Comments
 (0)