Skip to content

Commit dacfdc5

Browse files
onufrykaliabbasrizvi
authored andcommitted
Introduce event tags (#33)
1 parent d818b99 commit dacfdc5

File tree

10 files changed

+489
-39
lines changed

10 files changed

+489
-39
lines changed

src/Optimizely/Bucketer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -92,7 +92,7 @@ protected function generateBucketValue($bucketingId)
9292
* @param $parentId mixed ID representing Experiment or Group.
9393
* @param $trafficAllocations array Traffic allocations for variation or experiment.
9494
*
95-
* @returns string ID representing experiment or variation.
95+
* @return string ID representing experiment or variation.
9696
*/
9797
private function findBucket($userId, $parentId, $trafficAllocations)
9898
{

src/Optimizely/Event/Builder/EventBuilder.php

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
2222
use Optimizely\Entity\Experiment;
2323
use Optimizely\Event\LogEvent;
2424
use Optimizely\ProjectConfig;
25+
use Optimizely\Utils\EventTagUtils;
2526

2627
class EventBuilder
2728
{
@@ -153,20 +154,34 @@ private function setImpressionParams(Experiment $experiment, $variationId)
153154
* @param $eventKey string Key representing the event.
154155
* @param $experiments array Experiments for which conversion event needs to be recorded.
155156
* @param $userId string ID of user.
156-
* @param $eventValue integer Value associated with the event.
157+
* @param $eventTags array Hash representing metadata associated with the event.
157158
*/
158-
private function setConversionParams($config, $eventKey, $experiments, $userId, $eventValue)
159+
private function setConversionParams($config, $eventKey, $experiments, $userId, $eventTags)
159160
{
160161
$this->_eventParams[EVENT_FEATURES] = [];
161162
$this->_eventParams[EVENT_METRICS] = [];
162163

163-
if (!is_null($eventValue)) {
164-
$this->_eventParams[EVENT_METRICS] = [
165-
[
166-
'name' => 'revenue',
167-
'value' => $eventValue
168-
]
169-
];
164+
if (!is_null($eventTags)) {
165+
forEach ($eventTags as $eventTagId => $eventTagValue) {
166+
if (is_null($eventTagValue)) {
167+
continue;
168+
}
169+
$eventFeature = array(
170+
'id' => $eventTagId,
171+
'type' => 'custom',
172+
'value' => $eventTagValue,
173+
'shouldIndex' => false,
174+
);
175+
array_push($this->_eventParams[EVENT_FEATURES], $eventFeature);
176+
}
177+
$eventValue = EventTagUtils::getRevenueValue($eventTags);
178+
if ($eventValue) {
179+
$eventMetric = array(
180+
'name' => EventTagUtils::REVENUE_EVENT_METRIC_NAME,
181+
'value' => $eventValue,
182+
);
183+
array_push($this->_eventParams[EVENT_METRICS], $eventMetric);
184+
}
170185
}
171186

172187
$eventEntity = $config->getEvent($eventKey);
@@ -218,15 +233,15 @@ public function createImpressionEvent($config, Experiment $experiment, $variatio
218233
* @param $experiments array Experiments for which conversion event needs to be recorded.
219234
* @param $userId string ID of user.
220235
* @param $attributes array Attributes of the user.
221-
* @param $eventValue integer Value associated with the event.
236+
* @param $eventTags array Hash representing metadata associated with the event.
222237
*
223238
* @return LogEvent Event object to be sent to dispatcher.
224239
*/
225-
public function createConversionEvent($config, $eventKey, $experiments, $userId, $attributes, $eventValue)
240+
public function createConversionEvent($config, $eventKey, $experiments, $userId, $attributes, $eventTags)
226241
{
227242
$this->resetParams();
228243
$this->setCommonParams($config, $userId, $attributes);
229-
$this->setConversionParams($config, $eventKey, $experiments, $userId, $eventValue);
244+
$this->setConversionParams($config, $eventKey, $experiments, $userId, $eventTags);
230245

231246
return new LogEvent(self::$CONVERSION_ENDPOINT, $this->getParams(), self::$HTTP_VERB, self::$HTTP_HEADERS);
232247
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
/**
3+
* Copyright 2017, Optimizely
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace Optimizely\Exceptions;
19+
20+
21+
class InvalidEventTagException extends OptimizelyException
22+
{
23+
}

src/Optimizely/Optimizely.php

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
use Exception;
2020
use Optimizely\Exceptions\InvalidAttributeException;
21+
use Optimizely\Exceptions\InvalidEventTagException;
2122
use Throwable;
2223
use Monolog\Logger;
2324
use Optimizely\Entity\Experiment;
@@ -29,6 +30,7 @@
2930
use Optimizely\Event\Dispatcher\EventDispatcherInterface;
3031
use Optimizely\Logger\LoggerInterface;
3132
use Optimizely\Logger\NoOpLogger;
33+
use Optimizely\Utils\EventTagUtils;
3234
use Optimizely\Utils\Validator;
3335

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

262+
if (!is_null($eventTags)) {
263+
if (is_numeric($eventTags) && !is_string($eventTags)) {
264+
$eventTags = array(
265+
EventTagUtils::REVENUE_EVENT_METRIC_NAME => $eventTags,
266+
);
267+
$this->_logger->log(
268+
Logger::WARNING,
269+
'Event value is deprecated in track call. Use event tags to pass in revenue value instead.'
270+
);
271+
}
272+
if (!Validator::areEventTagsValid($eventTags)) {
273+
$this->_logger->log(Logger::ERROR, 'Provided event tags are in an invalid format.');
274+
$this->_errorHandler->handleError(
275+
new InvalidEventTagException('Provided event tags are in an invalid format.')
276+
);
277+
}
278+
}
279+
260280
$event = $this->_config->getEvent($eventKey);
261281

262282
if (is_null($event->getKey())) {
@@ -284,7 +304,7 @@ public function track($eventKey, $userId, $attributes = null, $eventValue = null
284304
$validExperiments,
285305
$userId,
286306
$attributes,
287-
$eventValue
307+
$eventTags
288308
);
289309
$this->_logger->log(Logger::INFO, sprintf('Tracking event "%s" for user "%s".', $eventKey, $userId));
290310
$this->_logger->log(
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
* Copyright 2017, Optimizely
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace Optimizely\Utils;
19+
20+
class EventTagUtils
21+
{
22+
/**
23+
* @const string Reserved word for event tag representing event revenue value.
24+
*/
25+
const REVENUE_EVENT_METRIC_NAME = 'revenue';
26+
27+
/**
28+
* Grab the revenue value from the event tags. "revenue" is a reserved keyword.
29+
*
30+
* @param $eventTags array Representing metadata associated with the event.
31+
* @return integer Revenue value as an integer number or null if revenue can't be retrieved from the event tags
32+
*/
33+
public static function getRevenueValue($eventTags) {
34+
if (!$eventTags) {
35+
return null;
36+
}
37+
if (!is_array($eventTags)) {
38+
return null;
39+
}
40+
41+
if (!isset($eventTags[self::REVENUE_EVENT_METRIC_NAME]) or !$eventTags[self::REVENUE_EVENT_METRIC_NAME]) {
42+
return null;
43+
}
44+
45+
$raw_value = $eventTags[self::REVENUE_EVENT_METRIC_NAME];
46+
if (!is_int($raw_value)) {
47+
return null;
48+
}
49+
50+
return $raw_value;
51+
}
52+
}

src/Optimizely/Utils/Validator.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ class Validator
2626
/**
2727
* @param $datafile string JSON string representing the project.
2828
*
29-
* @return boolean representing whether schema is valid or not.
29+
* @return boolean Representing whether schema is valid or not.
3030
*/
3131
public static function validateJsonSchema($datafile)
3232
{
@@ -41,13 +41,23 @@ public static function validateJsonSchema($datafile)
4141
/**
4242
* @param $attributes mixed Attributes of the user.
4343
*
44-
* @return boolean representing whether attributes are valid or not.
44+
* @return boolean Representing whether attributes are valid or not.
4545
*/
4646
public static function areAttributesValid($attributes)
4747
{
4848
return is_array($attributes) && count(array_filter(array_keys($attributes), 'is_int')) == 0;
4949
}
5050

51+
/**
52+
* @param $eventTags mixed Event tags to be validated.
53+
*
54+
* @return boolean Representing whether event tags are valid or not.
55+
*/
56+
public static function areEventTagsValid($eventTags)
57+
{
58+
return is_array($eventTags) && count(array_filter(array_keys($eventTags), 'is_int')) == 0;
59+
}
60+
5161
/**
5262
* @param $config ProjectConfig Configuration for the project.
5363
* @param $experiment Experiment Entity representing the experiment.

0 commit comments

Comments
 (0)