The Bundle will allow you to implement Feature Flags to your Application. Please Note that there is no Interface available, so the Flags must be configured directly in Symfony-Configs.
- Use Versions ^2.0 if Symfony 3.0 Support is wanted!
- Use Versions ^4.0 if Symfony 4.2 Support is wanted!
- Use Versions ^5.0 if Symfony 4.3 or 5.x Support is wanted!
- Use Versions ^6.0 if Symfony 6.0 Support is wanted!
- Use Versions ^6.1 if Symfony >6.1 Support is wanted!
You can add the Bundle by running Composer on your shell or adding it directly to your composer.json
php composer.phar require dzunke/feature-flags-bundle:"^6.1""require" : {
"dzunke/feature-flags-bundle": "^6.1"
}The Namespace will be registered by autoloading with Composer but to use the integrated features for symfony you have to register the Bundle.
# app/AppKernel.phppublicfunctionregisterBundles()
{
$bundles = [
// [..]newDZunke\FeatureFlagsBundle\DZunkeFeatureFlagsBundle(),
];
}Without any Configuration all Features will be enabled! But at this point you can start developing.
The simplest way to use the Bundle is to get the Container and request the state of a Feature. Note: Features that are not configured are enabled by default.
# src/AcmeBundle/Controller/IndexController.php<?phpnamespaceAcmeBundle\Controller;
useSymfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
publicfunctionindexAction()
{
if ($this->get('dz.feature_flags.toggle')->isActive('FooFeature')) {
// [...]
}
// [...]
}
}# src/AcmeBundle/Resources/views/Index/index.html.twig
{% ifhas_feature('FooFeature') %}
<p>Lorem Ipsum Dolor ...</p>
{% endif %}On every check you can give arguments to the check if you want to specify the check. The Arguments for a Flag can be definied by an array on the validation method. The Keys must be named like the condition itself. Please Note that if the Condition does not support the Arguments they would be ignored.
# src/AcmeBundle/Resources/views/Index/index.html.twig
{% if has_feature('FooBarFeature', {'device':'tablet'}) %}
<p>Lorem Ipsum Dolor ...</p>
{% endif %}At first the Condition must be created. The Condition must implement the ConditionInterface. There is a general context available.
<?php# src/AcmeBundle/FeatureFlags/Condition/Foo.phpnamespaceAcmeBundle\FeatureFlags\Condition;
useDZunke\FeatureFlagsBundle\Toggle\Conditions\AbstractCondition;
useDZunke\FeatureFlagsBundle\Toggle\Conditions\ConditionInterface;
class Foo extends AbstractCondition implements ConditionInterface
{
publicfunctionvalidate($config, $argument = null)
{
// [..] Implement your Methods to Validate the Featurereturntrue;
}
publicfunction__toString()
{
return'Foo';
}
}After the Class was created it must be defined as a Tagged-Service. With this Tag and the Alias the Condition would be loaded. At this point there is many space to extend the Condition by adding calls or arguments.
# src/AcmeBundle/Resources/config/services.ymlservices:
acme.feature_flags.condition.fo:
class: DZunke\FeatureFlagsBundle\Toggle\Conditions\Foocalls:
- [setContext, [@dz.feature_flags.context]]tags:
- { name: dz.feature_flags.toggle.condition, alias: foo }d_zunke_feature_flags:
flags:
FooFeature: # feature will always be disableddefault: falseBarFeature: # feature will only be enabled for a list of special ClientIpsconditions_config:
ip_address: [192.168.0.1]BazFeature: # the feature will be enabled for the half of the usersconditions_config:
percentage:
percentage: 50cookie: ExampleCookieForFeaturelifetime: 3600FooBarFeature:
conditions_config:
device:
tablet: "/ipad|playbook|android|kindle|opera mobi|arm|(^.*android(?:(?!mobile).)*$)/i"mobile: "/iphone|ipod|bb10|meego|blackberry|windows\\sce|palm|windows phone|((android.*mobile))|mobile/i"hostname: [example.local, www.example.local]ip_address: [192.168.0.1, 192.168.0.2]percentage:
cookie: NameThisCookieForTheUser # Default: 84a0b3f187a1d3bfefbb51d4b93074b1e5d9102apercentage: 29# Default: 100lifetime: 3600# Default: 86400 - 1 daydevice:
name: regex # give regex for each valid device# See php.net/datetimedate:
start_date: "2016-09-01"# Start date, accepts DateTime constructor values. Defaults to "now".end_date: "2016-09-03"# End date, accepts DateTime constructor values. Defaults to "now".d_zunke_feature_flags:
# the default state to return for non-existent featuresdefault: true# feature flags for the built systemflags:
# Prototypefeature:
# general active state for the flag - if conditions used it would be irrelevantdefault: false# list of configured conditions which must be true to set this flag activeconditions_config: []FeatureFlagsBundle is licensed under the MIT license.