diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd12a8b..c94eb28 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,5 @@ on: push: - pull_request: - schedule: - - cron: '0 0 */3 * *' name: CI jobs: diff --git a/src/Context/Context.php b/src/Context/Context.php index d70888a..fc48fe1 100644 --- a/src/Context/Context.php +++ b/src/Context/Context.php @@ -4,6 +4,7 @@ use ABSmartly\SDK\Assignment; use ABSmartly\SDK\AudienceMatcher; +use ABSmartly\SDK\ContextCustomFieldValue; use ABSmartly\SDK\Exception\InvalidArgumentException; use ABSmartly\SDK\Exception\LogicException; use ABSmartly\SDK\Experiment; @@ -44,6 +45,7 @@ class Context { private array $index; private array $indexVariables; + private array $contextCustomFields; private array $hashedUnits; @@ -124,6 +126,8 @@ private function setData(ContextData $data): void { $this->data = $data; $this->index = []; $this->indexVariables = []; + $this->contextCustomFields = []; + $experimentCustomFields = []; foreach ($data->experiments as $experiment) { $experimentVariables = new ExperimentVariables(); @@ -148,7 +152,35 @@ private function setData(ContextData $data): void { $experimentVariables->variables[] = $parsed; } + if ( + property_exists($experiment, 'customFieldValues') && + $experiment->customFieldValues !== null) { + $experimentCustomFields = []; + foreach ($experiment->customFieldValues as $customFieldValue) { + $type = $customFieldValue->type; + $value = new ContextCustomFieldValue(); + $value->type = $type; + + if ($customFieldValue->value !== null) { + $customValue = $customFieldValue->value; + + if (strpos($type, 'json') > -1) { + $value->value = $this->variableParser->parse($experiment->name, $customValue); + } else if (strpos($type, 'boolean') > -1) { + $value->value = settype($customValue, 'boolean'); + } else if (strpos($type, 'number') > -1) { + $value->value = settype($customValue, 'int'); + } else { + $value->value = $customValue; + } + } + $experimentCustomFields[$customFieldValue->name] = $value; + } + } + + $this->index[$experiment->name] = $experimentVariables; + $this->contextCustomFields[$experiment->name] = $experimentCustomFields; } } @@ -318,6 +350,52 @@ public function getVariableValue(string $key, $defaultValue = null) { return $assignment->variables->{$key} ?? $defaultValue; } + public function getCustomFieldKeys(): array{ + $return = []; + foreach ($this->data->experiments as $experiment) { + if (property_exists($experiment, 'customFieldValues')) { + $customFieldValues = $experiment->customFieldValues; + if ($customFieldValues != null) { + foreach ($experiment->customFieldValues as $customFieldValue) { + $return[] = $customFieldValue->name; + } + } + } + } + $return = array_unique($return); + sort($return); + return $return; + } + + public function getCustomFieldValue(string $environmentName, string $key){ + if (array_key_exists($environmentName, $this->contextCustomFields)) { + $customFieldValues = $this->contextCustomFields[$environmentName]; + if (array_key_exists($key, $customFieldValues)) { + $field = $customFieldValues[$key]; + if ($field != null) { + return $field->value; + } + } + } + + return null; + } + + public function getCustomFieldValueType(string $environmentName, string $key) + { + if (array_key_exists($environmentName, $this->contextCustomFields)) { + $customFieldValues = $this->contextCustomFields[$environmentName]; + if (array_key_exists($key, $customFieldValues)) { + $field = $customFieldValues[$key]; + if ($field != null) { + return $field->type; + } + } + } + + return null; + } + public function getVariableKeys(): array { $return = []; foreach ($this->indexVariables as $variable => $experimentVars) { diff --git a/src/ContextCustomFieldValue.php b/src/ContextCustomFieldValue.php new file mode 100644 index 0000000..7e6fd1d --- /dev/null +++ b/src/ContextCustomFieldValue.php @@ -0,0 +1,8 @@ +audience)) { @@ -34,6 +35,7 @@ public function __construct(object $data) { $this->audience = null; } + $this->customFieldValues = null; $data = get_object_varsAlias($data); foreach ($data as $field => $value) { diff --git a/tests/Context/ContextTest.php b/tests/Context/ContextTest.php index 78bbe92..bc425bf 100644 --- a/tests/Context/ContextTest.php +++ b/tests/Context/ContextTest.php @@ -505,6 +505,38 @@ public function testGetVariableKeys(): void { self::assertEquals($this->variableExperiments, $context->getVariableKeys()); } + public function testGetFieldValueKeys(): void{ + $context = $this->createReadyContext(); + self::assertEquals(['country', 'languages', 'overrides'], $context->getCustomFieldKeys()); + } + + public function testGetFieldValueValues(): void { + $context = $this->createReadyContext(); + self::assertEquals(null, $context->getCustomFieldValue('not_found', 'not_found')); + self::assertEquals(null, $context->getCustomFieldValue('exp_test_ab', 'not_found')); + self::assertEquals("US,PT,ES,DE,FR", $context->getCustomFieldValue('exp_test_ab', 'country')); + self::assertEquals((object)array('123' => 1, '456' => 0), $context->getCustomFieldValue('exp_test_ab', 'overrides')); + self::assertEquals("json", $context->getCustomFieldValueType('exp_test_ab', 'overrides')); + + self::assertEquals(null, $context->getCustomFieldValue('exp_test_ab', 'languages')); + self::assertEquals(null, $context->getCustomFieldValueType('exp_test_ab', 'languages')); + + self::assertEquals(null, $context->getCustomFieldValue('exp_test_abc', 'overrides')); + self::assertEquals(null, $context->getCustomFieldValueType('exp_test_abc', 'overrides')); + + self::assertEquals("en-US,en-GB,pt-PT,pt-BR,es-ES,es-MX", $context->getCustomFieldValue('exp_test_abc', 'languages')); + self::assertEquals("string", $context->getCustomFieldValueType('exp_test_abc', 'languages')); + + self::assertEquals(null, $context->getCustomFieldValue('exp_test_no_custom_fields', 'country')); + self::assertEquals(null, $context->getCustomFieldValueType('exp_test_no_custom_fields', 'country')); + + self::assertEquals(null, $context->getCustomFieldValue('exp_test_no_custom_fields', 'overrides')); + self::assertEquals(null, $context->getCustomFieldValueType('exp_test_no_custom_fields', 'overrides')); + + self::assertEquals(null, $context->getCustomFieldValue('exp_test_no_custom_fields', 'languages')); + self::assertEquals(null, $context->getCustomFieldValueType('exp_test_no_custom_fields', 'languages')); + } + public function testPeekTreatmentReturnsOverrideVariant(): void { $context = $this->createReadyContext(); diff --git a/tests/Fixtures/json/context.json b/tests/Fixtures/json/context.json index 493313b..7cc1b14 100644 --- a/tests/Fixtures/json/context.json +++ b/tests/Fixtures/json/context.json @@ -25,7 +25,7 @@ ], "variants":[ { - "name":"A", + "name":"J", "config":null }, { @@ -33,7 +33,19 @@ "config":"{\"banner.border\":1,\"banner.size\":\"large\"}" } ], - "audience": null + "audience": null, + "customFieldValues": [ + { + "name": "country", + "value": "US,PT,ES,DE,FR", + "type": "string" + }, + { + "name": "overrides", + "value": "{\"123\":1,\"456\":0}", + "type": "json" + } + ] }, { "id":2, @@ -73,7 +85,19 @@ "config":"{\"button.color\":\"red\"}" } ], - "audience": "" + "audience": "", + "customFieldValues": [ + { + "name": "country", + "value": "US,PT,ES,DE,FR", + "type": "string" + }, + { + "name": "languages", + "value": "en-US,en-GB,pt-PT,pt-BR,es-ES,es-MX", + "type": "string" + } + ] }, { "id":3, @@ -113,7 +137,8 @@ "config":"{\"card.width\":\"75%\"}" } ], - "audience": "{}" + "audience": "{}", + "customFieldValues": null }, { "id":4,