Skip to content

Commit

Permalink
Merge pull request #26 from optimizely/devel
Browse files Browse the repository at this point in the history
Merge into master
  • Loading branch information
aliabbasrizvi committed Dec 13, 2016
2 parents f32e81a + 43412c6 commit 5a30f6c
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 19 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -3,6 +3,7 @@ php:
- '5.5'
- '5.6'
- '7.0'
- '7.1'
- 'hhvm'
before_install:
- composer install --dev
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,2 +1,6 @@
## 1.0.0
- General release of Optimizely X Full Stack PHP SDK. No breaking changes from previous version.
- Introduced curl based event dispatcher.

## 0.1.0
- Beta release of the Optimizely X Full Stack PHP SDK.
7 changes: 6 additions & 1 deletion README.md
@@ -1,6 +1,7 @@
#Optimizely PHP SDK
[![Build Status](https://travis-ci.org/optimizely/php-sdk.svg?branch=master)](https://travis-ci.org/optimizely/php-sdk)
[![Coverage Status](https://coveralls.io/repos/github/optimizely/php-sdk/badge.svg?branch=master)](https://coveralls.io/github/optimizely/php-sdk?branch=master)
[![Total Downloads](https://poser.pugx.org/optimizely/optimizely-sdk/downloads)](https://packagist.org/packages/optimizely/optimizely-sdk)
[![Apache 2.0](https://img.shields.io/github/license/nebula-plugins/gradle-extra-configurations-plugin.svg)](http://www.apache.org/licenses/LICENSE-2.0)

This repository houses the PHP SDK for Optimizely Full Stack.
Expand All @@ -9,7 +10,11 @@ This repository houses the PHP SDK for Optimizely Full Stack.

###Installing the SDK

The Optimizely PHP SDK will be available through [Composer](https://getcomposer.org/). Instructions coming soon.
The Optimizely PHP SDK can be installed through [Composer](https://getcomposer.org/). Please use the following command:

```
php composer.phar require optimizely/optimizely-sdk
```

###Using the SDK
See the Optimizely Full Stack [developer documentation](https://developers.optimizely.com/x/solutions/sdks/reference/?language=php) to learn how to set up your first Full Stack project and use the SDK.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -18,7 +18,7 @@
},
"require-dev": {
"phpunit/phpunit": "~4.8|~5.0",
"satooshi/php-coveralls": "dev-master"
"satooshi/php-coveralls": "v1.0.1"
},
"autoload": {
"psr-4": {
Expand Down
2 changes: 1 addition & 1 deletion src/Optimizely/Event/Builder/EventBuilder.php
Expand Up @@ -33,7 +33,7 @@ class EventBuilder
/**
* @const string Version of the Optimizely PHP SDK.
*/
const SDK_VERSION = '0.1.0';
const SDK_VERSION = '1.0.0';

/**
* @var string URL to send impression event to.
Expand Down
45 changes: 45 additions & 0 deletions src/Optimizely/Event/Dispatcher/CurlEventDispatcher.php
@@ -0,0 +1,45 @@
<?php
/**
* Copyright 2016, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Optimizely\Event\Dispatcher;

use Exception;
use Optimizely\Event\LogEvent;

/**
* Class CurlEventDispatcher
*
* @package Optimizely\Event\Dispatcher
*/
class CurlEventDispatcher implements EventDispatcherInterface
{
public function dispatchEvent(LogEvent $event)
{
$cmd = "curl";
$cmd.= " -X ".$event->getHttpVerb();
foreach($event->getHeaders() as $type => $value) {
$cmd.= " -H '".$type.": ".$value."'";
}
$cmd.= " -d '".json_encode($event->getParams())."'";
$cmd.= " '".$event->getUrl()."' > /dev/null 2>&1 &";
exec($cmd, $output, $exit_code);

if ($exit_code !== 0) {
throw new Exception('Curl command failed.');
}
}
}
10 changes: 5 additions & 5 deletions src/Optimizely/ProjectConfig.php
Expand Up @@ -129,11 +129,11 @@ public function __construct($datafile, $logger, $errorHandler)
$this->_projectId = $config['projectId'];
$this->_revision = $config['revision'];

$groups = $config['groups'];
$experiments = $config['experiments'];
$events = $config['events'];
$attributes = $config['attributes'];
$audiences = $config['audiences'];
$groups = $config['groups'] ?: [];
$experiments = $config['experiments'] ?: [];
$events = $config['events'] ?: [];
$attributes = $config['attributes'] ?: [];
$audiences = $config['audiences'] ?: [];

$this->_groupIdMap = ConfigParser::generateMap($groups, 'id', Group::class);
$this->_experimentKeyMap = ConfigParser::generateMap($experiments, 'key', Experiment::class);
Expand Down
12 changes: 6 additions & 6 deletions tests/EventTests/EventBuilderTest.php
Expand Up @@ -48,7 +48,7 @@ public function testCreateImpressionEventNoAttributes()
'layerId' => '7719770039',
'visitorId' => 'testUserId',
'clientEngine' => 'php-sdk',
'clientVersion' => '0.1.0',
'clientVersion' => '1.0.0',
'timestamp' => time() * 1000,
'isGlobalHoldback' => false,
'userFeatures' => [],
Expand Down Expand Up @@ -82,7 +82,7 @@ public function testCreateImpressionEventWithAttributes()
'layerId' => '7719770039',
'visitorId' => 'testUserId',
'clientEngine' => 'php-sdk',
'clientVersion' => '0.1.0',
'clientVersion' => '1.0.0',
'timestamp' => time() * 1000,
'isGlobalHoldback' => false,
'userFeatures' => [[
Expand Down Expand Up @@ -126,7 +126,7 @@ public function testCreateConversionEventNoAttributesNoValue()
'accountId' => '1592310167',
'visitorId' => 'testUserId',
'clientEngine' => 'php-sdk',
'clientVersion' => '0.1.0',
'clientVersion' => '1.0.0',
'userFeatures' => [],
'isGlobalHoldback' => false,
'timestamp' => time() * 1000,
Expand Down Expand Up @@ -168,7 +168,7 @@ public function testCreateConversionEventWithAttributesNoValue()
'accountId' => '1592310167',
'visitorId' => 'testUserId',
'clientEngine' => 'php-sdk',
'clientVersion' => '0.1.0',
'clientVersion' => '1.0.0',
'isGlobalHoldback' => false,
'timestamp' => time() * 1000,
'eventFeatures' => [],
Expand Down Expand Up @@ -221,7 +221,7 @@ public function testCreateConversionEventNoAttributesWithValue()
'accountId' => '1592310167',
'visitorId' => 'testUserId',
'clientEngine' => 'php-sdk',
'clientVersion' => '0.1.0',
'clientVersion' => '1.0.0',
'userFeatures' => [],
'isGlobalHoldback' => false,
'timestamp' => time() * 1000,
Expand Down Expand Up @@ -266,7 +266,7 @@ public function testCreateConversionEventWithAttributesWithValue()
'accountId' => '1592310167',
'visitorId' => 'testUserId',
'clientEngine' => 'php-sdk',
'clientVersion' => '0.1.0',
'clientVersion' => '1.0.0',
'isGlobalHoldback' => false,
'timestamp' => time() * 1000,
'eventFeatures' => [],
Expand Down
36 changes: 34 additions & 2 deletions tests/OptimizelyTest.php
Expand Up @@ -156,8 +156,6 @@ public function testValidateInputsInvalidFileJsonValidationSkipped()
$validateInputsMethod->invoke(new Optimizely('Random datafile', null, null, null, true),
'Random datafile', true)
);

$this->expectOutputRegex('/Provided "datafile" is in an invalid format./');
}

public function testValidatePreconditionsExperimentNotRunning()
Expand Down Expand Up @@ -277,6 +275,40 @@ public function testActivateInvalidAttributes()
$this->assertNull($optlyObject->activate('test_experiment', 'test_user', 42));
}

public function testActivateUserInNoVariation()
{
$userAttributes = [
'device_type' => 'iPhone',
'company' => 'Optimizely',
'location' => 'San Francisco'
];

$this->eventBuilderMock->expects($this->never())
->method('createImpressionEvent');

$this->loggerMock->expects($this->exactly(3))
->method('log');
$this->loggerMock->expects($this->at(0))
->method('log')
->with(Logger::DEBUG, 'Assigned bucket 8495 to user "not_in_variation_user".');
$this->loggerMock->expects($this->at(1))
->method('log')
->with(Logger::INFO,
'User "not_in_variation_user" is in no variation.');
$this->loggerMock->expects($this->at(2))
->method('log')
->with(Logger::INFO, 'Not activating user "not_in_variation_user".');

$optlyObject = new Optimizely($this->datafile, new ValidEventDispatcher(), $this->loggerMock);

$eventBuilder = new \ReflectionProperty(Optimizely::class, '_eventBuilder');
$eventBuilder->setAccessible(true);
$eventBuilder->setValue($optlyObject, $this->eventBuilderMock);

// Call activate
$this->assertNull($optlyObject->activate('test_experiment', 'not_in_variation_user', $userAttributes));
}

public function testActivateNoAudienceNoAttributes()
{
$this->eventBuilderMock->expects($this->once())
Expand Down
7 changes: 4 additions & 3 deletions tests/UtilsTests/ConditionEvaluatorTest.php
Expand Up @@ -29,7 +29,7 @@ class ConditionEvaluatorTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
$decoder = new ConditionDecoder();
$conditions = "[\"and\", [\"or\", [\"or\", {\"name\": \"device_type\", \"type\": \"custom_attribute\", \"value\": \"iPhone\"}]], [\"or\", [\"or\", {\"name\": \"location\", \"type\": \"custom_attribute\", \"value\": \"San Francisco\"}]]]";
$conditions = "[\"and\", [\"or\", [\"or\", {\"name\": \"device_type\", \"type\": \"custom_attribute\", \"value\": \"iPhone\"}]], [\"or\", [\"or\", {\"name\": \"location\", \"type\": \"custom_attribute\", \"value\": \"San Francisco\"}]], [\"or\", [\"not\", [\"or\", {\"name\": \"browser\", \"type\": \"custom_attribute\", \"value\": \"Firefox\"}]]]]";
$decoder->deserializeAudienceConditions($conditions);

$this->conditionsList = $decoder->getConditionsList();
Expand All @@ -41,7 +41,7 @@ public function testEvaluateConditionsMatch()
$userAttributes = [
'device_type' => 'iPhone',
'location' => 'San Francisco',
'browser' => 'chrome'
'browser' => 'Chrome'
];

$this->assertTrue($this->conditionEvaluator->evaluate($this->conditionsList, $userAttributes));
Expand All @@ -51,8 +51,9 @@ public function testEvaluateConditionsMatch()
public function testEvaluateConditionsDoNotMatch()
{
$userAttributes = [
'device_type' => 'iPhone',
'location' => 'San Francisco',
'browser' => 'chrome'
'browser' => 'Firefox'
];

$this->assertFalse($this->conditionEvaluator->evaluate($this->conditionsList, $userAttributes));
Expand Down

0 comments on commit 5a30f6c

Please sign in to comment.