public function getVariationForFeatureRollout(FeatureFlag $featureFlag, $userId, $userAttributes)
    {
        $bucketing_id = $this->getBucketingId($userId, $userAttributes);
        $featureFlagKey = $featureFlag->getKey();
        $rollout_id = $featureFlag->getRolloutId();
        if (empty($rollout_id)) {
            $this->_logger->log(
                Logger::DEBUG,
                "Feature flag '{$featureFlagKey}' is not used in a rollout."
            );
            return null;
        }
        $rollout = $this->_projectConfig->getRolloutFromId($rollout_id);
        if ($rollout && !($rollout->getId())) {
            // Error logged and thrown in getRolloutFromId
            return null;
        }

        $rolloutRules = $rollout->getExperiments();
        if (sizeof($rolloutRules) == 0) {
            return null;
        }

        // Evaluate all rollout rules except for last one
        for ($i = 0; $i < sizeof($rolloutRules) - 1; $i++) {
            $experiment = $rolloutRules[$i];

            // Evaluate if user meets the audience condition of this rollout rule
            if (!Validator::isUserInExperiment($this->_projectConfig, $experiment, $userAttributes, $this->_logger)) {
                $this->_logger->log(
                    Logger::DEBUG,
                    sprintf("User '%s' did not meet the audience conditions to be in rollout rule '%s'.", $userId, $experiment->getKey())
                );
                // Evaluate this user for the next rule
                continue;
            }

            // Evaluate if user satisfies the traffic allocation for this rollout rule
            $variation = $this->_bucketer->bucket($this->_projectConfig, $experiment, $bucketing_id, $userId);
            if ($variation && $variation->getKey()) {
                return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_ROLLOUT);
            }
            break;
        }
        // Evaluate Everyone Else Rule / Last Rule now
        $experiment = $rolloutRules[sizeof($rolloutRules)-1];

        // Evaluate if user meets the audience condition of Everyone Else Rule / Last Rule now
        if (!Validator::isUserInExperiment($this->_projectConfig, $experiment, $userAttributes, $this->_logger)) {
            $this->_logger->log(
                Logger::DEBUG,
                sprintf("User '%s' did not meet the audience conditions to be in rollout rule '%s'.", $userId, $experiment->getKey())
            );
            return null;
        }

        $variation = $this->_bucketer->bucket($this->_projectConfig, $experiment, $bucketing_id, $userId);
        if ($variation && $variation->getKey()) {
            return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_ROLLOUT);
        }
        return null;
    }
public function getVariationForFeatureRollout(FeatureFlag $featureFlag, $userId, $userAttributes)
    {
        $bucketing_id = $this->getBucketingId($userId, $userAttributes);
        $featureFlagKey = $featureFlag->getKey();
        $rollout_id = $featureFlag->getRolloutId();
        if (empty($rollout_id)) {
            $this->_logger->log(
                Logger::DEBUG,
                "Feature flag '{$featureFlagKey}' is not used in a rollout."
            );
            return null;
        }
        $rollout = $this->_projectConfig->getRolloutFromId($rollout_id);
        if ($rollout && !($rollout->getId())) {
            // Error logged and thrown in getRolloutFromId
            return null;
        }

        $rolloutRules = $rollout->getExperiments();
        if (sizeof($rolloutRules) == 0) {
            return null;
        }

        // Evaluate all rollout rules except for last one
        for ($i = 0; $i < sizeof($rolloutRules) - 1; $i++) {
            $experiment = $rolloutRules[$i];

            // Evaluate if user meets the audience condition of this rollout rule
            if (!Validator::isUserInExperiment($this->_projectConfig, $experiment, $userAttributes, $this->_logger)) {
                $this->_logger->log(
                    Logger::DEBUG,
                    sprintf("User '%s' did not meet the audience conditions to be in rollout rule '%s'.", $userId, $experiment->getKey())
                );
                // Evaluate this user for the next rule
                continue;
            }

            // Evaluate if user satisfies the traffic allocation for this rollout rule
            $variation = $this->_bucketer->bucket($this->_projectConfig, $experiment, $bucketing_id, $userId);
            if ($variation && $variation->getKey()) {
                return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_ROLLOUT);
            }
            break;
        }
        // Evaluate Everyone Else Rule / Last Rule now
        $experiment = $rolloutRules[sizeof($rolloutRules)-1];

        // Evaluate if user meets the audience condition of Everyone Else Rule / Last Rule now
        if (!Validator::isUserInExperiment($this->_projectConfig, $experiment, $userAttributes, $this->_logger)) {
            $this->_logger->log(
                Logger::DEBUG,
                sprintf("User '%s' did not meet the audience conditions to be in rollout rule '%s'.", $userId, $experiment->getKey())
            );
            return null;
        }

        $variation = $this->_bucketer->bucket($this->_projectConfig, $experiment, $bucketing_id, $userId);
        if ($variation && $variation->getKey()) {
            return new FeatureDecision($experiment, $variation, FeatureDecision::DECISION_SOURCE_ROLLOUT);
        }
        return null;
    }
public function getVariationForFeatureRollout ( FeatureFlag $ featureFlag , $ userId , $ userAttributes ) { $ bucketing_id = $ this -> getBucketingId ( $ userId , $ userAttributes ) ; $ featureFlagKey = $ featureFlag -> getKey ( ) ; $ rollout_id = $ featureFlag -> getRolloutId ( ) ; if ( empty ( $ rollout_id ) ) { $ this -> _logger -> log ( Logger :: DEBUG , "Feature flag '{$featureFlagKey}' is not used in a rollout." ) ; return null ; } $ rollout = $ this -> _projectConfig -> getRolloutFromId ( $ rollout_id ) ; if ( $ rollout && ! ( $ rollout -> getId ( ) ) ) { // Error logged and thrown in getRolloutFromId return null ; } $ rolloutRules = $ rollout -> getExperiments ( ) ; if ( sizeof ( $ rolloutRules ) == 0 ) { return null ; } // Evaluate all rollout rules except for last one for ( $ i = 0 ; $ i < sizeof ( $ rolloutRules ) - 1 ; $ i ++ ) { $ experiment = $ rolloutRules [ $ i ] ; // Evaluate if user meets the audience condition of this rollout rule if ( ! Validator :: isUserInExperiment ( $ this -> _projectConfig , $ experiment , $ userAttributes , $ this -> _logger ) ) { $ this -> _logger -> log ( Logger :: DEBUG , sprintf ( "User '%s' did not meet the audience conditions to be in rollout rule '%s'." , $ userId , $ experiment -> getKey ( ) ) ) ; // Evaluate this user for the next rule continue ; } // Evaluate if user satisfies the traffic allocation for this rollout rule $ variation = $ this -> _bucketer -> bucket ( $ this -> _projectConfig , $ experiment , $ bucketing_id , $ userId ) ; if ( $ variation && $ variation -> getKey ( ) ) { return new FeatureDecision ( $ experiment , $ variation , FeatureDecision :: DECISION_SOURCE_ROLLOUT ) ; } break ; } // Evaluate Everyone Else Rule / Last Rule now $ experiment = $ rolloutRules [ sizeof ( $ rolloutRules ) - 1 ] ; // Evaluate if user meets the audience condition of Everyone Else Rule / Last Rule now if ( ! Validator :: isUserInExperiment ( $ this -> _projectConfig , $ experiment , $ userAttributes , $ this -> _logger ) ) { $ this -> _logger -> log ( Logger :: DEBUG , sprintf ( "User '%s' did not meet the audience conditions to be in rollout rule '%s'." , $ userId , $ experiment -> getKey ( ) ) ) ; return null ; } $ variation = $ this -> _bucketer -> bucket ( $ this -> _projectConfig , $ experiment , $ bucketing_id , $ userId ) ; if ( $ variation && $ variation -> getKey ( ) ) { return new FeatureDecision ( $ experiment , $ variation , FeatureDecision :: DECISION_SOURCE_ROLLOUT ) ; } return null ; }
Get the variation if the user is bucketed into rollout for this feature flag
Evaluate the user for rules in priority order by seeing if the user satisfies the audience.
Fall back onto the everyone else rule if the user is ever excluded from a rule due to traffic allocation.

@param  FeatureFlag $featureFlag    The feature flag the user wants to access
@param  string      $userId         user id
@param  array       $userAttributes user userAttributes
@return Decision  if a variation is returned for the user
null  if feature flag is not used in a rollout or
no rollout found against the rollout ID or
no variation is returned for the user
Get the variation if the user is bucketed into rollout for this feature flag Evaluate the user for rules in priority order by seeing if the user satisfies the audience . Fall back onto the everyone else rule if the user is ever excluded from a rule due to traffic allocation .