diff --git a/.gitignore b/.gitignore index 1cf0182..587fce5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ composer.lock phpunit.xml /vendor/ +.idea \ No newline at end of file diff --git a/src/Feature.php b/src/Feature.php index ba68a1e..fb272e1 100644 --- a/src/Feature.php +++ b/src/Feature.php @@ -216,8 +216,12 @@ public function clear() * @param array $requestParameters * @return bool */ - public function isActive(Rollout $rollout, RolloutUserInterface $user = null, array $requestParameters = array()) - { + public function isActive( + Rollout $rollout, + RolloutUserInterface $user = null, + array $users = array(), + array $requestParameters = array() + ) { if (null == $user) { return $this->isParamInRequestParams($requestParameters) || $this->percentage == 100 @@ -225,7 +229,7 @@ public function isActive(Rollout $rollout, RolloutUserInterface $user = null, ar } return $this->isParamInRequestParams($requestParameters) || - $this->isUserInPercentage($user) || + $this->isUserInPercentage($user, $users) || $this->isUserInActiveUsers($user) || $this->isInActiveGroup($rollout, $user); } @@ -262,9 +266,25 @@ private function isParamInRequestParams(array $requestParameters) * @param RolloutUserInterface $user * @return bool */ - private function isUserInPercentage(RolloutUserInterface $user) + private function isUserInPercentage(RolloutUserInterface $user, array $users) { - return abs(crc32($user->getRolloutIdentifier()) % 100) < $this->percentage; + if ($this->percentage === 100) { + return true; + } + + if ($this->percentage === 0) { + return false; + } + + $limit = ceil(($this->percentage / 100) * count($users)); + $users = array_slice($users, 0, $limit); + foreach ($users as $userData) { + if ($userData['slug'] === $user->getRolloutIdentifier()) { + return true; + } + } + + return false; } /** diff --git a/src/Rollout.php b/src/Rollout.php index c5d8db5..aa53d56 100644 --- a/src/Rollout.php +++ b/src/Rollout.php @@ -124,11 +124,15 @@ public function defineGroup($group, \Closure $closure) * @param array $requestParameters * @return bool */ - public function isActive($feature, RolloutUserInterface $user = null, array $requestParameters = array()) - { + public function isActive( + $feature, + RolloutUserInterface $user = null, + array $users = array(), + array $requestParameters = array() + ) { $feature = $this->get($feature); - return $feature ? $feature->isActive($this, $user, $requestParameters) : false; + return $feature && $feature->isActive($this, $user, $users, $requestParameters); } /** @@ -301,7 +305,7 @@ private function featuresKey() /** * @param Feature $feature */ - protected function save(Feature $feature) + public function save(Feature $feature) { $name = $feature->getName(); $this->storage->set($this->key($name), $feature->serialize());