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
23 changes: 20 additions & 3 deletions lib/Api/DevCycleClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
use DevCycle\Model\InlineResponse201;
use DevCycle\Model\Variable;
use DevCycle\Model\EvalHookRunner;
use DevCycle\Model\EvalObject;
use DevCycle\Model\EvalReasons;
use DevCycle\Model\DefaultReasonDetails;
use DevCycle\Model\HookContext;
use DevCycle\Model\BeforeHookError;
use DevCycle\Model\AfterHookError;
Expand Down Expand Up @@ -317,11 +320,15 @@ public function variable(DevCycleUser $user, string $key, mixed $default): Varia
$result = $this->reformatVariable($key, $response, $default);
$context->setVariableDetails($result);
} catch (GuzzleException|ApiException $e) {
$eval = (object) [
'reason' => EvalReasons::DEFAULT,
'details' => DefaultReasonDetails::ERROR
];
$evaluationError = $e;
if ($e->getCode() != 404) {
error_log("Failed to get variable value for key $key, " . $e->getMessage());
}
$result = new Variable(array("key" => $key, "value" => $default, "type" => gettype($default), "isDefaulted" => true));
$result = new Variable(array("key" => $key, "value" => $default, "type" => gettype($default), "isDefaulted" => true, "eval" => $eval));
$context->setVariableDetails($result);
}

Expand Down Expand Up @@ -370,13 +377,18 @@ private function reformatVariable(string $key, Variable $response, mixed $defaul
}

if (!$doTypesMatch) {
return new Variable(array("key" => $key, "value" => $default, "type" => $defaultType, "isDefaulted" => true));
$eval = (object) [
'reason' => EvalReasons::DEFAULT,
'details' => DefaultReasonDetails::TYPE_MISMATCH
];
return new Variable(array("key" => $key, "value" => $default, "type" => $defaultType, "isDefaulted" => true, "eval" => $eval));
} else {
$eval = $response->getEval();
if ($responseType === 'array') {
$jsonValue = json_decode(json_encode($unwrappedValue), true);
$unwrappedValue = $jsonValue;
}
return new Variable(array("key" => $key, "value" => $unwrappedValue, "type" => $responseType, "isDefaulted" => false));
return new Variable(array("key" => $key, "value" => $unwrappedValue, "type" => $responseType, "isDefaulted" => false, "eval" => $eval));
}
}

Expand Down Expand Up @@ -408,6 +420,11 @@ private function variableWithHttpInfo(DevCycleUser $user_data, string $key): arr
try {
list($response, $statusCode) = $this->makeRequest($request);

$eval = (object) [
'reason' => EvalReasons::DEFAULT,
'details' => DefaultReasonDetails::MISSING_CONFIG
];

switch ($statusCode) {
case 200:
$content = (string)$response->getBody();
Expand Down
45 changes: 45 additions & 0 deletions lib/Model/EvalReasons.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace DevCycle\Model;

/**
* Evaluation reasons for successful evaluations
*/
class EvalReasons
{
/**
* Default evaluation reason
*/
public const DEFAULT = 'DEFAULT';

/**
* Error evaluation reason
*/
public const ERROR = 'ERROR';
}

/**
* Default reason details
*/
class DefaultReasonDetails
{
/**
* Missing configuration reason detail
*/
public const MISSING_CONFIG = 'Missing Config';

/**
* User not targeted reason detail
*/
public const USER_NOT_TARGETED = 'User Not Targeted';

/**
* Type mismatch reason detail
*/
public const TYPE_MISMATCH = 'Variable Type Mismatch';

/**
* Evaluation error reason detail
*/
public const ERROR = 'Error';
}
62 changes: 51 additions & 11 deletions lib/Model/Variable.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ class Variable implements ModelInterface, ArrayAccess, \JsonSerializable
'_id' => 'string',
'key' => 'string',
'type' => 'string',
'value' => 'object'
'value' => 'object',
'isDefaulted' => 'bool',
'eval' => 'object'
];

/**
Expand All @@ -55,7 +57,8 @@ class Variable implements ModelInterface, ArrayAccess, \JsonSerializable
'_id' => null,
'key' => null,
'type' => null,
'value' => null
'value' => null,
'eval' => null
];

/**
Expand Down Expand Up @@ -89,7 +92,7 @@ public static function openAPIFormats(): array
'key' => 'key',
'type' => 'type',
'value' => 'value',
'isDefaulted' => 'isDefaulted'
'eval' => 'eval'
];

/**
Expand All @@ -102,7 +105,7 @@ public static function openAPIFormats(): array
'key' => 'setKey',
'type' => 'setType',
'value' => 'setValue',
'isDefaulted' => 'setIsDefaulted'
'eval' => 'setEval'
];

/**
Expand All @@ -115,7 +118,7 @@ public static function openAPIFormats(): array
'key' => 'getKey',
'type' => 'getType',
'value' => 'getValue',
'isDefaulted' => 'getIsDefaulted'
'eval' => 'getEval'
];

/**
Expand Down Expand Up @@ -199,6 +202,8 @@ public function __construct(?array $data = null)
$this->container['type'] = $data['type'] ?? null;
$this->container['value'] = $data['value'] ?? null;
$this->container['isDefaulted'] = $data['isDefaulted'] ?? false;

$this->container['eval'] = $data['eval'] ?? null;
}

/**
Expand Down Expand Up @@ -429,6 +434,36 @@ public function offsetUnset($offset):void
unset($this->container[$offset]);
}

/**
* Gets eval
*
* @return object|null
*/
public function getEval(): ?object
{
return $this->container['eval'];
}

/**
* Sets eval
*
* @param object|array|null $eval Eval context
*
* @return self
*/
public function setEval($evalObj): static
{
// Convert array to object if needed
if (is_array($evalObj)) {
$this->container['eval'] = (object) $evalObj;
} else {
$this->container['eval'] = $evalObj;
}

return $this;
}


/**
* Serializes the object to a value that can be serialized natively by json_encode().
* @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php
Expand All @@ -446,7 +481,7 @@ public function jsonSerialize():mixed
*
* @return string
*/
public function __toString()
public function __toString(): string
{
return json_encode(
ObjectSerializer::sanitizeForSerialization($this),
Expand All @@ -459,7 +494,7 @@ public function __toString()
*
* @return string
*/
public function toHeaderValue()
public function toHeaderValue(): string
{
return json_encode(ObjectSerializer::sanitizeForSerialization($this));
}
Expand All @@ -468,11 +503,16 @@ public function asResolutionDetails(): ResolutionDetails
{
$resolution = new ResolutionDetails();
$resolution->setValue($this->getValue());
$resolution->setReason(Reason::TARGETING_MATCH);
if ($this->isDefaulted()) {
$resolution->setError(new ResolutionError(ErrorCode::FLAG_NOT_FOUND(), "Defaulted"));
$resolution->setReason(Reason::DEFAULT);
if ($this->getEval() != null) {
$resolution->setReason($this->getEval()->reason);
} else {
$resolution->setReason(Reason::TARGETING_MATCH);
if ($this->isDefaulted()) {
$resolution->setError(new ResolutionError(ErrorCode::FLAG_NOT_FOUND(), "Defaulted"));
$resolution->setReason(Reason::DEFAULT);
}
}

return $resolution;
}
}
Loading
Loading