Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: optimizely/php-sdk
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: optimizely/php-sdk
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: mke
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.

Commits on May 30, 2023

  1. Copy the full SHA
    38f9db1 View commit details
  2. Copy the full SHA
    91aa14c View commit details
  3. Copy the full SHA
    0051573 View commit details
  4. Copy the full SHA
    c31820a View commit details

Commits on May 31, 2023

  1. Copy the full SHA
    833e6bb View commit details
  2. Copy the full SHA
    785389f View commit details
  3. Copy the full SHA
    47fcac7 View commit details
  4. Copy the full SHA
    e7c18c7 View commit details
  5. Copy the full SHA
    610279a View commit details

Commits on Jun 1, 2023

  1. Copy the full SHA
    2d1b5a1 View commit details
  2. Copy the full SHA
    af21844 View commit details
  3. Copy the full SHA
    1567ac2 View commit details
  4. Copy the full SHA
    12a9b70 View commit details
  5. Copy the full SHA
    e59ed4b View commit details
  6. Copy the full SHA
    a15ce19 View commit details
  7. Refine decide.php

    mikechu-optimizely committed Jun 1, 2023
    Copy the full SHA
    3a13a5e View commit details

Commits on Jun 2, 2023

  1. Copy the full SHA
    82faf92 View commit details
  2. Copy the full SHA
    e05a86f View commit details
  3. Copy the full SHA
    00a2522 View commit details
  4. Copy the full SHA
    cc16486 View commit details
  5. Copy the full SHA
    8453c4a View commit details
  6. Copy the full SHA
    8774b37 View commit details

Commits on Jun 5, 2023

  1. Copy the full SHA
    626c7d4 View commit details
  2. Copy the full SHA
    96bb0c0 View commit details
  3. Copy the full SHA
    fcb1ee4 View commit details
  4. Copy the full SHA
    aabd432 View commit details
  5. Copy the full SHA
    5378d93 View commit details
  6. Copy the full SHA
    165c566 View commit details
  7. Copy the full SHA
    bb0eeaf View commit details
  8. Copy the full SHA
    b29dead View commit details
  9. Copy the full SHA
    e7781de View commit details
  10. Copy the full SHA
    035747e View commit details
  11. Copy the full SHA
    01af3ee View commit details

Commits on Jun 6, 2023

  1. Added second part for forced decisions - not necessary, just a advanc…

    …ed addition. And Optimizely config.
    Mat001 committed Jun 6, 2023
    Copy the full SHA
    94d211e View commit details
Showing with 1,206 additions and 0 deletions.
  1. +41 −0 .devcontainer/devcontainer.json
  2. +144 −0 bug-bash/Decide.php
  3. +134 −0 bug-bash/DecideAll.php
  4. +150 −0 bug-bash/DecideForKeys.php
  5. +171 −0 bug-bash/ForcedDecision.php
  6. +321 −0 bug-bash/ForcedDecisionPart2.php
  7. +112 −0 bug-bash/OptiConfig.php
  8. +118 −0 bug-bash/TrackEvent.php
  9. +15 −0 bug-bash/_bug-bash-autoload.php
41 changes: 41 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/php
{
"name": "PHP",

"remoteEnv": {
"SDK_ROOT": "/workspaces/php-sdk",
"XDEBUG_CONFIG": "log_level=0",
},

// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/php:0-8.2",

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

"postStartCommand": "composer install",

// Configure tool-specific properties.
// "customizations": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
8080
],
"customizations": {
"vscode": {
"extensions": [
"bmewburn.vscode-intelephense-client",
"xdebug.php-debug",
"DEVSENSE.composer-php-vscode"
]
}
}

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "sudo chmod a+x \"$(pwd)\" && sudo rm -rf /var/www/html && sudo ln -s \"$(pwd)\" /var/www/html"

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
144 changes: 144 additions & 0 deletions bug-bash/Decide.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?php

namespace Optimizely\BugBash;

require_once '../vendor/autoload.php';
require_once '../bug-bash/_bug-bash-autoload.php';

use Monolog\Logger;
use Optimizely\Decide\OptimizelyDecideOption;
use Optimizely\Logger\DefaultLogger;
use Optimizely\Notification\NotificationType;
use Optimizely\Optimizely;
use Optimizely\OptimizelyFactory;
use Optimizely\OptimizelyUserContext;

// 1. Change this SDK key to your project's SDK Key
const SDK_KEY = '<your-sdk-key>';

// 2. Change this to your flag key
const FLAG_KEY = '<your-flag-key>';

// 3. Uncomment each scenario 1 by 1 modifying the contents of the method
// to test additional scenarios.

$test = new DecideTests();
$test->verifyDecisionProperties();
// $test->testWithVariationsOfDecideOptions();
// $test->verifyLogsImpressionsEventsDispatched();
// $test->verifyResultsPageInYourProjectShowsImpressionEvent();
// $test->verifyDecisionListenerWasCalled();
// $test->verifyAnInvalidFlagKeyIsHandledCorrectly();

// 4. Change the current folder into the bug-bash directory
// cd bug-bash/

// 5. Run the following command to execute the uncommented tests above:
// php Decide.php

// https://docs.developers.optimizely.com/feature-experimentation/docs/decide-methods-php
class DecideTests
{
// verify decision return properties with default DecideOptions
public function verifyDecisionProperties(): void
{
$decision = $this->userContext->decide(FLAG_KEY);

$this->printDecision($decision, "Check that the following decision properties are expected for user $this->userId");
}

// test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables)
public function testWithVariationsOfDecideOptions(): void
{
$options = [
OptimizelyDecideOption::INCLUDE_REASONS,
// OptimizelyDecideOption::DISABLE_DECISION_EVENT,
// OptimizelyDecideOption::ENABLED_FLAGS_ONLY, // ⬅️ Disable some of your flags
// OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE,
// OptimizelyDecideOption::EXCLUDE_VARIABLES,
];

$decision = $this->userContext->decide(FLAG_KEY, $options);

$this->printDecision($decision, 'Modify the OptimizelyDecideOptions and check the decision variables expected');
}

// verify in logs that impression event of this decision was dispatched
public function verifyLogsImpressionsEventsDispatched(): void
{
// 💡️ Create a new flag with an A/B Test eg "product_version"
$featureFlagKey = 'product_version';
$logger = new DefaultLogger(Logger::DEBUG);
$localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY);
$localUserContext = $localOptimizelyClient->createUserContext($this->userId);

// review the DEBUG output, ensuring you see an impression log
// "Dispatching impression event to URL https://logx.optimizely.com/v1/events with params..."
$localUserContext->decide($featureFlagKey);
}

// verify on Results page that impression even was created
public function verifyResultsPageInYourProjectShowsImpressionEvent(): void
{
print "Go to your project's results page and verify decisions events are showing (5 min delay)";
}

// verify that decision listener contains correct information
public function verifyDecisionListenerWasCalled(): void
{
// Check that this was called during the...
$onDecision = function ($type, $userId, $attributes, $decisionInfo) {
print ">>> [$this->outputTag] OnDecision:
type: $type,
userId: $userId,
attributes: " . print_r($attributes, true) . "
decisionInfo: " . print_r($decisionInfo, true) . "\r\n";
};
$this->optimizelyClient->notificationCenter->addNotificationListener(
NotificationType::DECISION,
$onDecision
);

// ...decide.
$this->userContext->decide(FLAG_KEY);
}

// verify that invalid flag key is handled correctly
public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void
{
$logger = new DefaultLogger(Logger::ERROR);
$localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY);
$userId = 'user-' . mt_rand(10, 99);
$localUserContext = $localOptimizelyClient->createUserContext($userId);

// ensure you see an error -- Optimizely.ERROR: FeatureFlag Key "a_key_not_in_the_project" is not in datafile.
$localUserContext->decide("a_key_not_in_the_project");
}

private Optimizely $optimizelyClient;
private string $userId;
private ?OptimizelyUserContext $userContext;
private string $outputTag = "Decide";

public function __construct()
{
$this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY);

$this->userId = 'user-' . mt_rand(10, 99);
$attributes = ['age' => 25, 'country' => 'canada', 'abandoned_cart' => false];
$this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes);
}

private function printDecision($decision, $message): void
{
$enabled = $decision->getEnabled() ? "true" : "false";

print ">>> [$this->outputTag] $message:
enabled: $enabled,
flagKey: {$decision->getFlagKey()},
ruleKey: {$decision->getRuleKey()},
variationKey: {$decision->getVariationKey()},
variables: " . print_r($decision->getVariables(), true) . ",
reasons: " . print_r($decision->getReasons(), true) . "\r\n";
}
}
134 changes: 134 additions & 0 deletions bug-bash/DecideAll.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php

namespace Optimizely\BugBash;

require_once '../vendor/autoload.php';
require_once '../bug-bash/_bug-bash-autoload.php';

use Monolog\Logger;
use Optimizely\Decide\OptimizelyDecideOption;
use Optimizely\Logger\DefaultLogger;
use Optimizely\Notification\NotificationType;
use Optimizely\Optimizely;
use Optimizely\OptimizelyFactory;
use Optimizely\OptimizelyUserContext;

// 1. Change this SDK key to your project's SDK Key
const SDK_KEY = '<your-sdk-key>';

// 2. Create additional flag keys in your project (2+)

// 3. Uncomment each scenario 1 by 1 modifying the contents of the method
// to test additional scenarios.

$test = new DecideAllTests();
$test->verifyDecisionProperties();
// $test->testWithVariousCombinationsOfOptions();
// $test->verifyLogImpressionEventDispatched();
// $test->verifyResultsPageShowsImpressionEvents();
// $test->verifyDecisionListenerContainsCorrectInformation();

// 4. Change the current folder into the bug-bash directory if you're not already there:
// cd bug-bash/

// 5. Run the following command to execute the uncommented tests above:
// php DecideAll.php

// https://docs.developers.optimizely.com/feature-experimentation/docs/decide-methods-php
class DecideAllTests
{
// verify decide all returns properties without specifying default options
public function verifyDecisionProperties(): void
{
$decision = $this->userContext->decideAll();

$this->printDecisions($decision, "Check that all of the decisions' multiple properties are expected for user `$this->userId`");
}

// test with all and variations/combinations of options
public function testWithVariousCombinationsOfOptions(): void
{
$options = [
OptimizelyDecideOption::INCLUDE_REASONS,
// OptimizelyDecideOption::DISABLE_DECISION_EVENT,
// OptimizelyDecideOption::ENABLED_FLAGS_ONLY, // ⬅️ Disable some of your flags
// OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE,
OptimizelyDecideOption::EXCLUDE_VARIABLES,
];

$decisions = $this->userContext->decideAll($options);

$this->printDecisions($decisions, "Check that all of your flags' decisions respected the options passed.");
}

// verify in logs that impression event of this decision was dispatched
public function verifyLogImpressionEventDispatched(): void
{
// 💡️ Be sure you have >=1 of your project's flags has an EXPERIMENT type
$logger = new DefaultLogger(Logger::DEBUG);
$localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY);
$localUserContext = $localOptimizelyClient->createUserContext($this->userId);

// review the DEBUG output, ensuring you see an impression log for each *EXPERIMENT* with a message like
// "Dispatching impression event to URL https://logx.optimizely.com/v1/events with params..."
// ⚠️ Rollout flag types should not dispatch and impression event
$localUserContext->decideAll();
}

// verify on Results page that impression events was created
public function verifyResultsPageShowsImpressionEvents(): void
{
print "After about 5-10 minutes, go to your project's results page and verify decisions events are showing.";
}

// verify that decision listener contains correct information
public function verifyDecisionListenerContainsCorrectInformation(): void
{
// Check that this was called for each of your project flag keys
$onDecision = function ($type, $userId, $attributes, $decisionInfo) {
print ">>> [$this->outputTag] OnDecision:
type: $type,
userId: $userId,
attributes: " . print_r($attributes, true) . "
decisionInfo: " . print_r($decisionInfo, true) . "\r\n";
};
$this->optimizelyClient->notificationCenter->addNotificationListener(
NotificationType::DECISION,
$onDecision
);

$this->userContext->decideAll();
}

private Optimizely $optimizelyClient;
private string $userId;
private ?OptimizelyUserContext $userContext;
private string $outputTag = "Decide All";

public function __construct()
{
$this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY);

$this->userId = 'user-' . mt_rand(10, 99);
$attributes = ['country' => 'nederland', 'age' => 43, 'is_return_visitor' => true];
$this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes);
}

private function printDecisions($decisions, $message): void
{
$count = 0;
foreach ($decisions as $decision) {
$enabled = $decision->getEnabled() ? "true" : "false";

print ">>> [$this->outputTag #$count] $message:
enabled: $enabled,
flagKey: {$decision->getFlagKey()},
ruleKey: {$decision->getRuleKey()},
variationKey: {$decision->getVariationKey()},
variables: " . print_r($decision->getVariables(), true) . ",
reasons: " . print_r($decision->getReasons(), true) . "\r\n";

$count++;
}
}
}
Loading