Orchard feature Flag Library
===

The features library allows features to be committed to production and
selectively hidden based on configuration in individual environments.

*Note*: if the build for `theorchard/orchard:master` and `theorchard/api:master`
is red, do not merge. Both repositories are (at the moment) tightly coupled. 

Basic Usage
---

Feature reads from configs/feature.yml, a YAML file in the following format.

### Sample YAML Configuration File

```YAML
# TEST YAML FILE
feature1:
  # Note that only one variant can be enabled at a time
  feature_1_true_variant: 1
  feature_2_false_variant: 0
  feature_3_false_variant: 0  
  control: 0
feature2:
  feature2_user_variant:
    users:
    - 29279
    - 8736
```

### Control Variant

Each feature should have a control variant: 

* In A/B testing: the control variant has a population against which we measure success of the other variants. 
* In a rollout strategy, you should keep at least 1% of the user base in the control variant, to make sure everything goes well and progressively check metrics. When the feature is deployed (99%) wait a little before moving the users out of the control variant. 

### YAML Syntax

The features.yml file should be compliant with [YAML 1.2 Spec](http://www.yaml.org/spec/1.2/spec.html). Here are some highlights:
* Block collections use indentation for scope and begin each entry on its own line.
* Mappings use a colon and space (“: ”) to mark each key: value pair. 
* Comments begin with an octothorpe (also called a “hash”, “sharp”, “pound”, or “number sign” - “#”).

### Initialization

This is handled in the Orchard Bootstrap file, and you can expect 
that the following code has been run and the feature methods are
available.

```PHP
$featureConfig = Yaml::parse(__DIR__ . '/../../../../configs/features.yml');
featureUtils::bootstrap($featureConfig);
```
### Testing For features In Code

This is the most simple test, that a feature and variant are allowed.
Note that only one variant for a feature can be enabled at a time.

```PHP
if (feature::isEnabled('feature1', 'feature_1_true_variant')) {
    // Now this code is feature-restricted
}
```
Additionally a feature can be enabled only for certain users or other contexts:
```PHP
$user1 = array('username' => 'user1');
$context = array('user' => $user1);
if (feature::isEnabled('feature1', 'feature_1_true_variant', $context) {
    //Now this code is feature-restricted
}
```

Style Guidelines
---
### Casing
All lower case, underscores between words. Don’t use hyphens.

GOOD: 
```
foo_bar
```
BAD: 
```
fooBar
```
```
Foo_Bar
```

### Feature Name Selection
Choose a concise, but descriptive name for the feature flag. Don’t use its JIRA ticket number. For example: [VS-130 Create "Unmonetized Streams" Channel for Users](http://jira.theorchard.com/browse/VS-130)

GOOD: 
```
unmonetized_streams
```
EH:
```
unmonetized_streams_channel
```
BAD:
```
streams
```
```
for-users
```
```
VS-130
```

Q: Why can’t we just use JIRA ticket numbers?
A: Sometimes, a feature expands beyond a single JIRA ticket number. However, you can add a comment line above your Feature Name to indicate the JIRA ticket. For example:

```
# VS-130
unmonetized_streams:
```

### Specifying Variants within a Feature
Only one variant should be enabled per feature.

GOOD:
```
test0: # test0 is the feature
  soup: 1 # soup is the enabled variant
  salad: 0 # salad is the disabled variant
  control: 0 # this is the control group
 ```

BAD:
```
test0:
  soup: 1
  salad: 1
 ```

**Explanation**: In a dev environment, if salad needs to be enabled, then soup should be disabled. A variant is exclusive; it cannot encompass other variants. Otherwise, if a feature has 3 variants, instead of having 3 uniques, it has 6 unique possibilities (A, B, C, AB, AC, BC).

### Variant Name Selection
Choose a concise, but descriptive name for the variant of the feature. In scenarios where there are no variants, use enabled:

```
# VS-130
unmonetized_streams:
  enabled: 1
  control: 0
```

### Specifying Users
@todo

### URL injection on QA
You can enable feature flags in workstation and OA on QA using URL queries. For example,

```
workstation.qaorch.com?feature=project_manager&feature_variant=enabled&feature_cookie=1
```

will enable the `project_manager` feature for the current user.

TODO / Outstanding Issues & Suggestions
---
* Find a hash system that allows us to split our population (users) evenly, so we can perform a modulo and see what part of the population they're in (range: 0-99)
* Determine alternate ways to pass feature flags to Views (helpers)
* We might want to put together a simple Web interface to control that Yaml file and throw some validation on syntax, collisions, etc.

