Skip to content

Commit 215eda7

Browse files
authored
prepare 3.1.0 release (#95)
1 parent 30f7590 commit 215eda7

File tree

13 files changed

+493
-71
lines changed

13 files changed

+493
-71
lines changed

.circleci/config.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
version: 2
2+
3+
workflows:
4+
version: 2
5+
test:
6+
jobs:
7+
- test-5.5
8+
- test-5.6
9+
- test-7.0
10+
- test-7.1
11+
- test-7.2
12+
- integration-test
13+
14+
php-docker-template: &php-docker-template
15+
steps:
16+
- checkout
17+
- run:
18+
name: install current dependencies
19+
command: composer install --no-progress
20+
- run:
21+
name: run tests with current dependency versions
22+
command: vendor/bin/phpunit --log-junit ~/phpunit/junit.xml --coverage-text tests
23+
- store_test_results:
24+
path: ~/phpunit
25+
- store_artifacts:
26+
path: ~/phpunit
27+
- run:
28+
name: run tests with highest available dependency versions
29+
command: composer update --no-progress && vendor/bin/phpunit tests
30+
- run:
31+
name: run tests with lowest available dependency versions
32+
# we skip this for 7.2 because the lowest compatible version of PHPUnit has a bug:
33+
# https://github.com/sebastianbergmann/comparator/pull/30
34+
command: |
35+
if [[ $CIRCLE_JOB != test-7.2 ]]; then
36+
composer update --prefer-lowest --no-progress && vendor/bin/phpunit tests;
37+
fi
38+
39+
jobs:
40+
test-5.6:
41+
<<: *php-docker-template
42+
docker:
43+
- image: circleci/php:5.6.34-cli-jessie
44+
test-7.0:
45+
<<: *php-docker-template
46+
docker:
47+
- image: circleci/php:7.0.28-cli-jessie
48+
test-7.1:
49+
<<: *php-docker-template
50+
docker:
51+
- image: circleci/php:7.1.15-cli-jessie
52+
test-7.2:
53+
<<: *php-docker-template
54+
docker:
55+
- image: circleci/php:7.2.3-cli-stretch
56+
57+
test-5.5: # CircleCI doesn't provide a Docker image for 5.5
58+
machine:
59+
image: circleci/classic:latest # Ubuntu 14.04
60+
steps:
61+
- run:
62+
name: install PHP and Composer
63+
command: |
64+
sudo apt-get update &&
65+
sudo apt-get install circleci-php-5.5.36 &&
66+
php -r "copy('https://getcomposer.org/installer', '/tmp/composer-setup.php');" &&
67+
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
68+
- checkout
69+
- run:
70+
name: update dependencies # the dependencies in composer.lock don't work with 5.5
71+
command: composer update --no-progress
72+
- run:
73+
name: run tests
74+
command: vendor/bin/phpunit --log-junit ~/phpunit/junit.xml --coverage-text tests
75+
- store_test_results:
76+
path: ~/phpunit
77+
- store_artifacts:
78+
path: ~/phpunit
79+
80+
integration-test:
81+
docker:
82+
- image: circleci/php:5.6.34-cli-jessie
83+
- image: redis
84+
steps:
85+
- checkout
86+
- run:
87+
name: setup apcu
88+
command: |
89+
pecl config-set php_ini /usr/local/etc/php/php.ini
90+
yes '' | sudo pecl install -f apcu-4.0.10 || true;
91+
echo "extension=apcu.so" | sudo tee -a /usr/local/etc/php/conf.d/apcu.ini;
92+
echo "apc.enable_cli = 1" | sudo tee -a /usr/local/etc/php/conf.d/apcu.ini
93+
- run: composer update --no-progress
94+
- run: vendor/bin/phpunit --log-junit ~/phpunit/junit.xml integration-tests/LDDFeatureRequesterTest.php
95+
- store_test_results:
96+
path: ~/phpunit
97+
- store_artifacts:
98+
path: ~/phpunit

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to the LaunchDarkly PHP SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).
44

5+
## [3.1.0] - 2018-04-30
6+
### Added
7+
- Analytics events for feature evaluations now have a `variation` property (the variation index) as well as `value`. This will allow for better performance in future versions of [`ld-relay`](https://github.com/launchdarkly/ld-relay) when it is used with the PHP client.
8+
### Fixed
9+
- Fixed a bug that made segment-based rules always fall through when using `LDDFeatureRequester`.
10+
511
## [3.0.0] - 2018-02-21
612
### Added
713
- Support for a new LaunchDarkly feature: reusable user segments.

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
LaunchDarkly SDK for PHP
22
===========================
33

4-
[![Code Climate](https://codeclimate.com/github/launchdarkly/php-client/badges/gpa.svg)](https://codeclimate.com/github/launchdarkly/php-client)
5-
64
[![Circle CI](https://circleci.com/gh/launchdarkly/php-client.svg?style=svg)](https://circleci.com/gh/launchdarkly/php-client)
75

86
Requirements

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.0
1+
3.1.0

circle.yml

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/LaunchDarkly/CurlEventPublisher.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ private function createArgs($payload)
6060
$args.= " -H 'Content-Type: application/json'";
6161
$args.= " -H " . escapeshellarg("Authorization: " . $this->_sdkKey);
6262
$args.= " -H 'User-Agent: PHPClient/" . LDClient::VERSION . "'";
63+
$args.= " -H 'X-LaunchDarkly-Event-Schema: " . EventPublisher::CURRENT_SCHEMA_VERSION . "'";
6364
$args.= " -H 'Accept: application/json'";
6465
$args.= " -d " . escapeshellarg($payload);
6566
$args.= " " . escapeshellarg($scheme . $this->_host . ":" . $this->_port . $this->_path . "/bulk");

src/LaunchDarkly/EventPublisher.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77
interface EventPublisher
88
{
9+
const CURRENT_SCHEMA_VERSION = 2;
10+
911
/**
1012
* @param string $sdkKey The SDK key for your account
1113
* @param mixed[] $options Client configuration settings

src/LaunchDarkly/FeatureFlag.php

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,18 @@ public function evaluate($user, $featureRequester)
9595
if ($this->isOn()) {
9696
$result = $this->_evaluate($user, $featureRequester, $prereqEvents);
9797
if ($result !== null) {
98-
return new EvalResult($result, $prereqEvents);
98+
return $result;
9999
}
100100
}
101-
$offVariation = $this->getOffVariationValue();
102-
return new EvalResult($offVariation, $prereqEvents);
101+
$offVariationValue = $this->getOffVariationValue();
102+
return new EvalResult($this->_offVariation, $offVariationValue, $prereqEvents);
103103
}
104104

105105
/**
106106
* @param $user LDUser
107107
* @param $featureRequester FeatureRequester
108108
* @param $events
109-
* @return mixed|null
109+
* @return EvalResult|null
110110
*/
111111
private function _evaluate($user, $featureRequester, &$events)
112112
{
@@ -120,21 +120,26 @@ private function _evaluate($user, $featureRequester, &$events)
120120
return null;
121121
} elseif ($prereqFeatureFlag->isOn()) {
122122
$prereqEvalResult = $prereqFeatureFlag->_evaluate($user, $featureRequester, $events);
123-
$variation = $prereqFeatureFlag->getVariation($prereq->getVariation());
124-
if ($prereqEvalResult === null || $variation === null || $prereqEvalResult !== $variation) {
123+
$variation = $prereq->getVariation();
124+
if ($prereqEvalResult === null || $variation === null || $prereqEvalResult->getVariation() !== $variation) {
125125
$prereqOk = false;
126126
}
127127
} else {
128128
$prereqOk = false;
129129
}
130-
array_push($events, Util::newFeatureRequestEvent($prereqFeatureFlag->getKey(), $user, $prereqEvalResult, null, $prereqFeatureFlag->getVersion(), $this->_key));
130+
array_push($events, Util::newFeatureRequestEvent($prereqFeatureFlag->getKey(), $user,
131+
$prereqEvalResult === null ? null : $prereqEvalResult->getVariation(),
132+
$prereqEvalResult === null ? null : $prereqEvalResult->getValue(),
133+
null, $prereqFeatureFlag->getVersion(), $this->_key));
131134
} catch (EvaluationException $e) {
132135
$prereqOk = false;
133136
}
134137
}
135138
}
136139
if ($prereqOk) {
137-
return $this->getVariation($this->evaluateIndex($user, $featureRequester));
140+
$variation = $this->evaluateIndex($user, $featureRequester);
141+
$value = $this->getVariation($variation);
142+
return new EvalResult($variation, $value, $events);
138143
}
139144
return null;
140145
}
@@ -221,6 +226,7 @@ public function isDeleted()
221226

222227
class EvalResult
223228
{
229+
private $_variation = null;
224230
private $_value = null;
225231
/** @var array */
226232
private $_prerequisiteEvents = [];
@@ -230,12 +236,21 @@ class EvalResult
230236
* @param null $value
231237
* @param array $prerequisiteEvents
232238
*/
233-
public function __construct($value, array $prerequisiteEvents)
239+
public function __construct($variation, $value, array $prerequisiteEvents)
234240
{
241+
$this->_variation = $variation;
235242
$this->_value = $value;
236243
$this->_prerequisiteEvents = $prerequisiteEvents;
237244
}
238245

246+
/**
247+
* @return int
248+
*/
249+
public function getVariation()
250+
{
251+
return $this->_variation;
252+
}
253+
239254
/**
240255
* @return null
241256
*/

src/LaunchDarkly/GuzzleEventPublisher.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public function __construct($sdkKey, array $options = array())
3939
'Content-Type' => 'application/json',
4040
'Authorization' => $this->_sdkKey,
4141
'User-Agent' => 'PHPClient/' . LDClient::VERSION,
42-
'Accept' => 'application/json'
42+
'Accept' => 'application/json',
43+
'X-LaunchDarkly-Event-Schema' => strval(EventPublisher::CURRENT_SCHEMA_VERSION)
4344
],
4445
'timeout' => $options['timeout'],
4546
'connect_timeout' => $options['connect_timeout']

src/LaunchDarkly/LDClient.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class LDClient
1919
{
2020
const DEFAULT_BASE_URI = 'https://app.launchdarkly.com';
2121
const DEFAULT_EVENTS_URI = 'https://events.launchdarkly.com';
22-
const VERSION = '3.0.0';
22+
const VERSION = '3.1.0';
2323

2424
/** @var string */
2525
protected $_sdkKey;
@@ -148,12 +148,7 @@ public function variation($key, $user, $default = false)
148148
}
149149

150150
try {
151-
if (is_null($user) || is_null($user->getKey())) {
152-
$this->_sendFlagRequestEvent($key, $user, $default, $default);
153-
$this->_logger->warning("Variation called with null user or null user key! Returning default value");
154-
return $default;
155-
}
156-
if ($user->isKeyBlank()) {
151+
if (!is_null($user) && $user->isKeyBlank()) {
157152
$this->_logger->warning("User key is blank. Flag evaluation will proceed, but the user will not be stored in LaunchDarkly.");
158153
}
159154
try {
@@ -164,7 +159,12 @@ public function variation($key, $user, $default = false)
164159
}
165160

166161
if (is_null($flag)) {
167-
$this->_sendFlagRequestEvent($key, $user, $default, $default);
162+
$this->_sendFlagRequestEvent($key, $user, null, $default, $default);
163+
return $default;
164+
}
165+
if (is_null($user) || is_null($user->getKey())) {
166+
$this->_sendFlagRequestEvent($key, $user, null, $default, $default, $flag->getVersion());
167+
$this->_logger->warning("Variation called with null user or null user key! Returning default value");
168168
return $default;
169169
}
170170
$evalResult = $flag->evaluate($user, $this->_featureRequester);
@@ -173,15 +173,18 @@ public function variation($key, $user, $default = false)
173173
$this->_eventProcessor->enqueue($e);
174174
}
175175
}
176-
if ($evalResult->getValue() !== null) {
177-
$this->_sendFlagRequestEvent($key, $user, $evalResult->getValue(), $default, $flag->getVersion());
176+
if ($evalResult !== null && $evalResult->getValue() !== null) {
177+
$this->_sendFlagRequestEvent($key, $user, $evalResult->getVariation(), $evalResult->getValue(), $default, $flag->getVersion());
178178
return $evalResult->getValue();
179+
} else {
180+
$this->_sendFlagRequestEvent($key, $user, null, $default, $default, $flag->getVersion());
181+
return $default;
179182
}
180183
} catch (\Exception $e) {
181184
$this->_logger->error("Caught $e");
182185
}
183186
try {
184-
$this->_sendFlagRequestEvent($key, $user, $default, $default);
187+
$this->_sendFlagRequestEvent($key, $user, null, $default, $default);
185188
} catch (\Exception $e) {
186189
$this->_logger->error("Caught $e");
187190
}
@@ -326,17 +329,18 @@ public function flush()
326329
/**
327330
* @param $key string
328331
* @param $user LDUser
332+
* @param $variation int | null
329333
* @param $value mixed
330334
* @param $default
331335
* @param $version int | null
332336
* @param string | null $prereqOf
333337
*/
334-
protected function _sendFlagRequestEvent($key, $user, $value, $default, $version = null, $prereqOf = null)
338+
protected function _sendFlagRequestEvent($key, $user, $variation, $value, $default, $version = null, $prereqOf = null)
335339
{
336340
if ($this->isOffline() || !$this->_send_events) {
337341
return;
338342
}
339-
$this->_eventProcessor->enqueue(Util::newFeatureRequestEvent($key, $user, $value, $default, $version, $prereqOf));
343+
$this->_eventProcessor->enqueue(Util::newFeatureRequestEvent($key, $user, $variation, $value, $default, $version, $prereqOf));
340344
}
341345

342346
protected function _get_default($key, $default)

0 commit comments

Comments
 (0)