Skip to content

Commit b93d48c

Browse files
Merge pull request #13 from filipgolonka/master
Allow to enable feature flag based on request parameters
2 parents 92847c4 + 1d76926 commit b93d48c

File tree

4 files changed

+145
-10
lines changed

4 files changed

+145
-10
lines changed

src/Feature.php

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
class Feature
1212
{
1313
/**
14-
* @var array
14+
* @var string
1515
*/
1616
private $name;
1717

@@ -30,6 +30,11 @@ class Feature
3030
*/
3131
private $percentage = 0;
3232

33+
/**
34+
* @var string|null
35+
*/
36+
private $requestParam;
37+
3338
/**
3439
* @param string $name
3540
* @param string|null $settings
@@ -38,7 +43,13 @@ public function __construct($name, $settings = null)
3843
{
3944
$this->name = $name;
4045
if ($settings) {
41-
list($rawPercentage, $rawUsers, $rawGroups) = explode('|', $settings);
46+
$settings = explode('|', $settings);
47+
if (count($settings) == 4) {
48+
$rawRequestParam = array_pop($settings);
49+
$this->requestParam = $rawRequestParam;
50+
}
51+
52+
list($rawPercentage, $rawUsers, $rawGroups) = $settings;
4253
$this->percentage = (int) $rawPercentage;
4354
$this->users = !empty($rawUsers) ? explode(',', $rawUsers) : array();
4455
$this->groups = !empty($rawGroups) ? explode(',', $rawGroups) : array();
@@ -79,7 +90,8 @@ public function serialize()
7990
return implode('|', array(
8091
$this->percentage,
8192
implode(',', $this->users),
82-
implode(',', $this->groups)
93+
implode(',', $this->groups),
94+
$this->requestParam,
8395
));
8496
}
8597

@@ -139,6 +151,22 @@ public function getGroups()
139151
return $this->groups;
140152
}
141153

154+
/**
155+
* @return string|null
156+
*/
157+
public function getRequestParam()
158+
{
159+
return $this->requestParam;
160+
}
161+
162+
/**
163+
* @param string|null $requestParam
164+
*/
165+
public function setRequestParam($requestParam)
166+
{
167+
$this->requestParam = $requestParam;
168+
}
169+
142170
/**
143171
* Clear the feature of all configuration
144172
*/
@@ -147,22 +175,27 @@ public function clear()
147175
$this->groups = array();
148176
$this->users = array();
149177
$this->percentage = 0;
178+
$this->requestParam = '';
150179
}
151180

152181
/**
153182
* Is the feature active?
154183
*
155184
* @param Rollout $rollout
156185
* @param RolloutUserInterface|null $user
186+
* @param array $requestParameters
157187
* @return bool
158188
*/
159-
public function isActive(Rollout $rollout, RolloutUserInterface $user = null)
189+
public function isActive(Rollout $rollout, RolloutUserInterface $user = null, array $requestParameters = array())
160190
{
161191
if (null == $user) {
162-
return $this->percentage == 100;
192+
return $this->isParamInRequestParams($requestParameters) || $this->percentage == 100;
163193
}
164194

165-
return $this->isUserInPercentage($user) || $this->isUserInActiveUsers($user) || $this->isUserInActiveGroup($user, $rollout);
195+
return $this->isParamInRequestParams($requestParameters) ||
196+
$this->isUserInPercentage($user) ||
197+
$this->isUserInActiveUsers($user) ||
198+
$this->isUserInActiveGroup($user, $rollout);
166199
}
167200

168201
/**
@@ -174,9 +207,24 @@ public function toArray()
174207
'percentage' => $this->percentage,
175208
'groups' => $this->groups,
176209
'users' => $this->users,
210+
'requestParam' => $this->requestParam,
177211
);
178212
}
179213

214+
/**
215+
* @param array $requestParameters
216+
* @return bool
217+
*/
218+
private function isParamInRequestParams(array $requestParameters)
219+
{
220+
$param = explode('=', $this->requestParam);
221+
$key = array_shift($param);
222+
$value = array_shift($param);
223+
224+
return $key && array_key_exists($key, $requestParameters) &&
225+
(empty($value) || $requestParameters[$key] == $value);
226+
}
227+
180228
/**
181229
* @param RolloutUserInterface $user
182230
* @return bool

src/Rollout.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,16 @@ public function defineGroup($group, \Closure $closure)
119119
}
120120

121121
/**
122-
* @param string $feature
122+
* @param string $feature
123123
* @param RolloutUserInterface|null $user
124+
* @param array $requestParameters
124125
* @return bool
125126
*/
126-
public function isActive($feature, RolloutUserInterface $user = null)
127+
public function isActive($feature, RolloutUserInterface $user = null, array $requestParameters = array())
127128
{
128129
$feature = $this->get($feature);
129130

130-
return $feature ? $feature->isActive($this, $user) : false;
131+
return $feature ? $feature->isActive($this, $user, $requestParameters) : false;
131132
}
132133

133134
/**
@@ -155,6 +156,31 @@ public function deactivatePercentage($feature)
155156
}
156157
}
157158

159+
/**
160+
* @param string $feature
161+
* @param string $requestParam
162+
*/
163+
public function activateRequestParam($feature, $requestParam)
164+
{
165+
$feature = $this->get($feature);
166+
if ($feature) {
167+
$feature->setRequestParam($requestParam);
168+
$this->save($feature);
169+
}
170+
}
171+
172+
/**
173+
* @param string $feature
174+
*/
175+
public function deactivateRequestParam($feature)
176+
{
177+
$feature = $this->get($feature);
178+
if ($feature) {
179+
$feature->setRequestParam('');
180+
$this->save($feature);
181+
}
182+
}
183+
158184
/**
159185
* @param string $group
160186
* @param RolloutUserInterface $user

tests/FeatureTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Opensoft\Rollout\Feature;
4+
5+
/**
6+
* @author Filip Golonka <[email protected]>
7+
*/
8+
class FeatureTest extends \PHPUnit_Framework_TestCase
9+
{
10+
public function testParseOldSettingsFormat()
11+
{
12+
$feature = new Feature('chat', '100|4,12|fivesonly');
13+
14+
$this->assertEquals(100, $feature->getPercentage());
15+
$this->assertEquals([4, 12], $feature->getUsers());
16+
$this->assertEquals(['fivesonly'], $feature->getGroups());
17+
}
18+
19+
public function testParseNewSettingsFormat()
20+
{
21+
$feature = new Feature('chat', '100|4,12|fivesonly|FF_facebookIntegration=1');
22+
23+
$this->assertEquals(100, $feature->getPercentage());
24+
$this->assertEquals([4, 12], $feature->getUsers());
25+
$this->assertEquals(['fivesonly'], $feature->getGroups());
26+
$this->assertEquals('FF_facebookIntegration=1', $feature->getRequestParam());
27+
}
28+
}

tests/RolloutTest.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public function testDeactivatingAFeatureCompletely()
7272
$this->rollout->activateGroup('chat', 'fivesonly');
7373
$this->rollout->activateUser('chat', new RolloutUser(51));
7474
$this->rollout->activatePercentage('chat', 100);
75+
$this->rollout->activateRequestParam('chat', 'FF_facebookIntegration=1');
7576
$this->rollout->activate('chat');
7677
$this->rollout->deactivate('chat');
7778

@@ -84,6 +85,9 @@ public function testDeactivatingAFeatureCompletely()
8485
// it should remove the percentage
8586
$this->assertFalse($this->rollout->isActive('chat', new RolloutUser(24)));
8687

88+
// it should remove the request param
89+
$this->assertFalse($this->rollout->isActive('chat', null, array('FF_facebookIntegration', true)));
90+
8791
// it should be removed globally
8892
$this->assertFalse($this->rollout->isActive('chat'));
8993
}
@@ -204,6 +208,25 @@ public function testDeactivatingThePercentageOfUsers()
204208
$this->assertFalse($this->rollout->isActive('chat', new RolloutUser(24)));
205209
}
206210

211+
public function testActivatingRequestParam()
212+
{
213+
$this->rollout->activateRequestParam('chat', 'FF_facebookIntegration=1');
214+
215+
$this->assertTrue($this->rollout->isActive('chat', null, ['FF_facebookIntegration' => true]));
216+
217+
$this->assertFalse($this->rollout->isActive('chat', null, ['FF_anotherFeature' => true]));
218+
}
219+
220+
public function testDeactivatingRequestParam()
221+
{
222+
$this->rollout->activateRequestParam('chat', 'FF_facebookIntegration=1');
223+
$this->rollout->deactivateRequestParam('chat');
224+
225+
$this->assertFalse($this->rollout->isActive('chat', null, ['FF_facebookIntegration' => true]));
226+
227+
$this->assertFalse($this->rollout->isActive('chat', null, ['FF_anotherFeature' => true]));
228+
}
229+
207230
public function testDeactivatingTheFeatureGlobally()
208231
{
209232
$this->rollout->activate('chat');
@@ -232,19 +255,29 @@ public function testGet()
232255
$this->rollout->activateGroup('chat', 'greeters');
233256
$this->rollout->activate('signup');
234257
$this->rollout->activateUser('chat', new RolloutUser(42));
258+
$this->rollout->activateRequestParam('chat', 'FF_facebookIntegration=1');
235259

236260
// it should return the feature object
237261
$feature = $this->rollout->get('chat');
238262
$this->assertContains('caretakers', $feature->getGroups());
239263
$this->assertContains('greeters', $feature->getGroups());
240264
$this->assertEquals(10, $feature->getPercentage());
241265
$this->assertContains(42, $feature->getUsers());
242-
$this->assertEquals(array('groups' => array('caretakers', 'greeters'), 'percentage' => 10, 'users' => array('42')), $feature->toArray());
266+
$this->assertEquals(
267+
array(
268+
'groups' => array('caretakers', 'greeters'),
269+
'percentage' => 10,
270+
'users' => array('42'),
271+
'requestParam' => 'FF_facebookIntegration=1'
272+
),
273+
$feature->toArray()
274+
);
243275

244276
$feature = $this->rollout->get('signup');
245277
$this->assertEmpty($feature->getGroups());
246278
$this->assertEmpty($feature->getUsers());
247279
$this->assertEquals(100, $feature->getPercentage());
280+
$this->assertEmpty($feature->getRequestParam());
248281
}
249282

250283
public function testRemove()

0 commit comments

Comments
 (0)