Skip to content

Commit

Permalink
Release 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
aliabbasrizvi committed Mar 23, 2017
2 parents d90fddc + f028b5d commit e3eef7c
Show file tree
Hide file tree
Showing 19 changed files with 605 additions and 68 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,10 @@
## 1.1.0
- Updated to send datafile revision information in log events.
- Gracefully handle empty entity IDs.
- Added event tags to track API to allow users to pass in event metadata.
- Deprecated the `eventValue` parameter from the track method. Should use `eventTags` to pass in event value instead.
- Relaxed restriction on monolog package.

## 1.0.1
- Updated to support more versions of json-schema package.

Expand Down
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
@@ -1,7 +1,7 @@
#Contributing to the Optimizely PHP SDK
# Contributing to the Optimizely PHP SDK
We welcome contributions and feedback! All contributors must sign our [Contributor License Agreement (CLA)](https://docs.google.com/a/optimizely.com/forms/d/e/1FAIpQLSf9cbouWptIpMgukAKZZOIAhafvjFCV8hS00XJLWQnWDFtwtA/viewform) to be eligible to contribute. Please read the [README](README.md) to set up your development environment, then read the guidelines below for information on submitting your code.

##Development process
## Development process

1. Create a branch off of `devel`: `git checkout -b YOUR_NAME/branch_name`.
2. Commit your changes. Make sure to add tests!
Expand All @@ -10,12 +10,12 @@ We welcome contributions and feedback! All contributors must sign our [Contribut
5. Open a pull request from `YOUR_NAME/branch_name` to `devel`.
6. A repository maintainer will review your pull request and, if all goes well, merge it!

##Pull request acceptance criteria
## Pull request acceptance criteria

* **All code must have test coverage.** We use PHPUnit. Changes in functionality should have accompanying unit tests. Bug fixes should have accompanying regression tests.
* Tests are located in `tests` with one file per class.

##License
## License

All contributions are under the CLA mentioned above. For this project, Optimizely uses the Apache 2.0 license, and so asks that by contributing your code, you agree to license your contribution under the terms of the [Apache License v2.0](http://www.apache.org/licenses/LICENSE-2.0). Your contributions should also include the following header:

Expand All @@ -39,5 +39,5 @@ All contributions are under the CLA mentioned above. For this project, Optimizel

The YEAR above should be the year of the contribution. If work on the file has been done over multiple years, list each year in the section above. Example: Optimizely writes the file and releases it in 2014. No changes are made in 2015. Change made in 2016. YEAR should be “2014, 2016”.

##Contact
## Contact
If you have questions, please contact developers@optimizely.com.
16 changes: 8 additions & 8 deletions README.md
@@ -1,35 +1,35 @@
#Optimizely PHP SDK
# 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.

##Getting Started
## Getting Started

###Installing the SDK
### Installing the SDK

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
### 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.

##Development
## Development

###Unit tests
### Unit tests

#####Running all tests
##### Running all tests
You can run all unit tests with:

```
./vendor/bin/phpunit
```

###Contributing
### Contributing

Please see [CONTRIBUTING](CONTRIBUTING.md).
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -14,7 +14,7 @@
"justinrainbow/json-schema": "^1.6 || ^2.0 || ^4.0",
"lastguest/murmurhash": "1.3.0",
"guzzlehttp/guzzle": "~5.3|~6.2",
"monolog/monolog": "1.21.0"
"monolog/monolog": "~1.21"
},
"require-dev": {
"phpunit/phpunit": "~4.8|~5.0",
Expand Down
8 changes: 4 additions & 4 deletions src/Optimizely/Bucketer.php
@@ -1,6 +1,6 @@
<?php
/**
* Copyright 2016, Optimizely
* Copyright 2016-2017, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -92,7 +92,7 @@ protected function generateBucketValue($bucketingId)
* @param $parentId mixed ID representing Experiment or Group.
* @param $trafficAllocations array Traffic allocations for variation or experiment.
*
* @returns string ID representing experiment or variation.
* @return string ID representing experiment or variation.
*/
private function findBucket($userId, $parentId, $trafficAllocations)
{
Expand Down Expand Up @@ -150,7 +150,7 @@ public function bucket(ProjectConfig $config, Experiment $experiment, $userId)
}

$userExperimentId = $this->findBucket($userId, $group->getId(), $group->getTrafficAllocation());
if (is_null($userExperimentId)) {
if (empty($userExperimentId)) {
$this->_logger->log(Logger::INFO, sprintf('User "%s" is in no experiment.', $userId));
return new Variation();
}
Expand All @@ -172,7 +172,7 @@ public function bucket(ProjectConfig $config, Experiment $experiment, $userId)

// Bucket user if not in whitelist and in group (if any).
$variationId = $this->findBucket($userId, $experiment->getId(), $experiment->getTrafficAllocation());
if (!is_null($variationId)) {
if (!empty($variationId)) {
$variation = $config->getVariationFromId($experiment->getKey(), $variationId);
$this->_logger->log(Logger::INFO,
sprintf('User "%s" is in variation %s of experiment %s.',
Expand Down
45 changes: 31 additions & 14 deletions src/Optimizely/Event/Builder/EventBuilder.php
@@ -1,6 +1,6 @@
<?php
/**
* Copyright 2016, Optimizely
* Copyright 2016-2017, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@
use Optimizely\Entity\Experiment;
use Optimizely\Event\LogEvent;
use Optimizely\ProjectConfig;
use Optimizely\Utils\EventTagUtils;

class EventBuilder
{
Expand All @@ -33,7 +34,7 @@ class EventBuilder
/**
* @const string Version of the Optimizely PHP SDK.
*/
const SDK_VERSION = '1.0.1';
const SDK_VERSION = '1.1.0';

/**
* @var string URL to send impression event to.
Expand Down Expand Up @@ -104,6 +105,7 @@ private function setCommonParams($config, $userId, $attributes)
{
$this->_eventParams[PROJECT_ID] = $config->getProjectId();
$this->_eventParams[ACCOUNT_ID] = $config->getAccountId();
$this->_eventParams[REVISION] = $config->getRevision();
$this->_eventParams[VISITOR_ID] = $userId;
$this->_eventParams[CLIENT_ENGINE] = self::SDK_TYPE;
$this->_eventParams[CLIENT_VERSION] = self::SDK_VERSION;
Expand Down Expand Up @@ -153,20 +155,34 @@ private function setImpressionParams(Experiment $experiment, $variationId)
* @param $eventKey string Key representing the event.
* @param $experiments array Experiments for which conversion event needs to be recorded.
* @param $userId string ID of user.
* @param $eventValue integer Value associated with the event.
* @param $eventTags array Hash representing metadata associated with the event.
*/
private function setConversionParams($config, $eventKey, $experiments, $userId, $eventValue)
private function setConversionParams($config, $eventKey, $experiments, $userId, $eventTags)
{
$this->_eventParams[EVENT_FEATURES] = [];
$this->_eventParams[EVENT_METRICS] = [];

if (!is_null($eventValue)) {
$this->_eventParams[EVENT_METRICS] = [
[
'name' => 'revenue',
'value' => $eventValue
]
];
if (!is_null($eventTags)) {
forEach ($eventTags as $eventTagId => $eventTagValue) {
if (is_null($eventTagValue)) {
continue;
}
$eventFeature = array(
'name' => $eventTagId,
'type' => 'custom',
'value' => $eventTagValue,
'shouldIndex' => false,
);
array_push($this->_eventParams[EVENT_FEATURES], $eventFeature);
}
$eventValue = EventTagUtils::getRevenueValue($eventTags);
if ($eventValue) {
$eventMetric = array(
'name' => EventTagUtils::REVENUE_EVENT_METRIC_NAME,
'value' => $eventValue,
);
array_push($this->_eventParams[EVENT_METRICS], $eventMetric);
}
}

$eventEntity = $config->getEvent($eventKey);
Expand All @@ -180,6 +196,7 @@ private function setConversionParams($config, $eventKey, $experiments, $userId,
array_push($this->_eventParams[LAYER_STATES], [
LAYER_ID => $experiment->getLayerId(),
ACTION_TRIGGERED => true,
REVISION => $config->getRevision(),
DECISION => [
EXPERIMENT_ID => $experiment->getId(),
VARIATION_ID => $variation->getId(),
Expand Down Expand Up @@ -218,15 +235,15 @@ public function createImpressionEvent($config, Experiment $experiment, $variatio
* @param $experiments array Experiments for which conversion event needs to be recorded.
* @param $userId string ID of user.
* @param $attributes array Attributes of the user.
* @param $eventValue integer Value associated with the event.
* @param $eventTags array Hash representing metadata associated with the event.
*
* @return LogEvent Event object to be sent to dispatcher.
*/
public function createConversionEvent($config, $eventKey, $experiments, $userId, $attributes, $eventValue)
public function createConversionEvent($config, $eventKey, $experiments, $userId, $attributes, $eventTags)
{
$this->resetParams();
$this->setCommonParams($config, $userId, $attributes);
$this->setConversionParams($config, $eventKey, $experiments, $userId, $eventValue);
$this->setConversionParams($config, $eventKey, $experiments, $userId, $eventTags);

return new LogEvent(self::$CONVERSION_ENDPOINT, $this->getParams(), self::$HTTP_VERB, self::$HTTP_HEADERS);
}
Expand Down
1 change: 1 addition & 0 deletions src/Optimizely/Event/Builder/Params.php
Expand Up @@ -17,6 +17,7 @@

define('ACCOUNT_ID', 'accountId');
define('PROJECT_ID', 'projectId');
define('REVISION', 'revision');
define('LAYER_ID', 'layerId');
define('EXPERIMENT_ID', 'experimentId');
define('VARIATION_ID', 'variationId');
Expand Down
23 changes: 23 additions & 0 deletions src/Optimizely/Exceptions/InvalidEventTagException.php
@@ -0,0 +1,23 @@
<?php
/**
* Copyright 2017, 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\Exceptions;


class InvalidEventTagException extends OptimizelyException
{
}
28 changes: 24 additions & 4 deletions src/Optimizely/Optimizely.php
@@ -1,6 +1,6 @@
<?php
/**
* Copyright 2016, Optimizely
* Copyright 2016-2017, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@

use Exception;
use Optimizely\Exceptions\InvalidAttributeException;
use Optimizely\Exceptions\InvalidEventTagException;
use Throwable;
use Monolog\Logger;
use Optimizely\Entity\Experiment;
Expand All @@ -29,6 +30,7 @@
use Optimizely\Event\Dispatcher\EventDispatcherInterface;
use Optimizely\Logger\LoggerInterface;
use Optimizely\Logger\NoOpLogger;
use Optimizely\Utils\EventTagUtils;
use Optimizely\Utils\Validator;

/**
Expand Down Expand Up @@ -240,9 +242,9 @@ public function activate($experimentKey, $userId, $attributes = null)
* @param $eventKey string Event key representing the event which needs to be recorded.
* @param $userId string ID for user.
* @param $attributes array Attributes of the user.
* @param $eventValue integer Value associated with event.
* @param $eventTags array Hash representing metadata associated with the event.
*/
public function track($eventKey, $userId, $attributes = null, $eventValue = null)
public function track($eventKey, $userId, $attributes = null, $eventTags = null)
{
if (!$this->_isValid) {
$this->_logger->log(Logger::ERROR, 'Datafile has invalid format. Failing "track".');
Expand All @@ -257,6 +259,24 @@ public function track($eventKey, $userId, $attributes = null, $eventValue = null
return;
}

if (!is_null($eventTags)) {
if (is_numeric($eventTags) && !is_string($eventTags)) {
$eventTags = array(
EventTagUtils::REVENUE_EVENT_METRIC_NAME => $eventTags,
);
$this->_logger->log(
Logger::WARNING,
'Event value is deprecated in track call. Use event tags to pass in revenue value instead.'
);
}
if (!Validator::areEventTagsValid($eventTags)) {
$this->_logger->log(Logger::ERROR, 'Provided event tags are in an invalid format.');
$this->_errorHandler->handleError(
new InvalidEventTagException('Provided event tags are in an invalid format.')
);
}
}

$event = $this->_config->getEvent($eventKey);

if (is_null($event->getKey())) {
Expand Down Expand Up @@ -284,7 +304,7 @@ public function track($eventKey, $userId, $attributes = null, $eventValue = null
$validExperiments,
$userId,
$attributes,
$eventValue
$eventTags
);
$this->_logger->log(Logger::INFO, sprintf('Tracking event "%s" for user "%s".', $eventKey, $userId));
$this->_logger->log(
Expand Down
8 changes: 8 additions & 0 deletions src/Optimizely/ProjectConfig.php
Expand Up @@ -184,6 +184,14 @@ public function getProjectId()
return $this->_projectId;
}

/**
* @return string String representing revision of the datafile.
*/
public function getRevision()
{
return $this->_revision;
}

/**
* @param $groupId string ID of the group.
*
Expand Down

0 comments on commit e3eef7c

Please sign in to comment.