Code Monkey home page Code Monkey logo

featureflagsbundle's Introduction

Symfony FeatureFlagsBundle

Build Status Latest Stable Version Total Downloads License

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!

Documentation

Setup

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.php
public function registerBundles()
{
    $bundles = [
        // [..]
        new DZunke\FeatureFlagsBundle\DZunkeFeatureFlagsBundle(),
    ];
}

Without any Configuration all Features will be enabled! But at this point you can start developing.

Usage

Service-Container

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
<?php

namespace AcmeBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
    public function indexAction()
    {
        if ($this->get('dz.feature_flags.toggle')->isActive('FooFeature')) {
           // [...]
        }
        // [...]
    }
}

Twig

# src/AcmeBundle/Resources/views/Index/index.html.twig
{% if has_feature('FooFeature') %}
    <p>Lorem Ipsum Dolor ...</p>
{% endif %}

Argument-Usage

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 %}

Creating a Condition

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.php
namespace AcmeBundle\FeatureFlags\Condition;

use DZunke\FeatureFlagsBundle\Toggle\Conditions\AbstractCondition;
use DZunke\FeatureFlagsBundle\Toggle\Conditions\ConditionInterface;

class Foo extends AbstractCondition implements ConditionInterface
{
    public function validate($config, $argument = null)
    {
        // [..] Implement your Methods to Validate the Feature

        return true;
    }

    public function __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.yml
services:
    acme.feature_flags.condition.fo:
        class: DZunke\FeatureFlagsBundle\Toggle\Conditions\Foo
        calls:
            - [setContext, [@dz.feature_flags.context]]
        tags:
            -  { name: dz.feature_flags.toggle.condition, alias: foo }

Configuration

Example

d_zunke_feature_flags:
    flags:
        FooFeature: # feature will always be disabled
            default: false
        BarFeature: # feature will only be enabled for a list of special ClientIps
            conditions_config:
                ip_address: [192.168.0.1]
        BazFeature: # the feature will be enabled for the half of the users
            conditions_config:
                percentage:
                    percentage: 50
                    cookie: ExampleCookieForFeature
                    lifetime: 3600
        FooBarFeature:
            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"

Available Conditions

hostname: [example.local, www.example.local]
ip_address: [192.168.0.1, 192.168.0.2]
percentage:
  cookie: NameThisCookieForTheUser # Default: 84a0b3f187a1d3bfefbb51d4b93074b1e5d9102a
  percentage: 29 # Default: 100
  lifetime: 3600 # Default: 86400 - 1 day
device:
  name: regex # give regex for each valid device
# See php.net/datetime
date:
  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".

Reference

d_zunke_feature_flags:
    # the default state to return for non-existent features
    default:              true
    # feature flags for the built system
    flags:
        # Prototype
        feature:
            # general active state for the flag - if conditions used it would be irrelevant
            default:              false
            # list of configured conditions which must be true to set this flag active
            conditions_config:    []

Resources

License

FeatureFlagsBundle is licensed under the MIT license.

featureflagsbundle's People

Contributors

alexwilson avatar benr77 avatar benzwerver avatar dzunke avatar elonmir avatar gzumba avatar lucassabreu avatar mateuszsip avatar mohrekopp avatar viniciusss avatar ymhuang0808 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

featureflagsbundle's Issues

Dependency on a non-existent service "request"

Installing v4.1 on Symfony 4.4 gives me the following error when I clear the cache:

In CheckExceptionOnInvalidReferenceBehaviorPass.php line 86:
                                                                                                       
  The service "dz.feature_flags.conditions_bag" has a dependency on a non-existent service "request". 

I can't see where the reference to "request" is coming from. Any ideas?
Thanks

Deprecation notices on PHP 8.1

Under PHP 8.1 I get the following deprecation notices:

PHP Deprecated:  Return type of DZunke\FeatureFlagsBundle\Toggle\ConditionBag::getIterator() should 
either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] 
attribute should be used to temporarily suppress the notice in /var/www/app/vendor/dzunke/feature-flags-
bundle/DZunke/FeatureFlagsBundle/Toggle/ConditionBag.php on line 18

PHP Deprecated:  Return type of DZunke\FeatureFlagsBundle\Toggle\ConditionBag::count() should either 
be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to
 temporarily suppress the notice in /var/www/app/vendor/dzunke/feature-flags-
bundle/DZunke/FeatureFlagsBundle/Toggle/ConditionBag.php on line 26

Percentage toggle condition improvement

In case of multiple call to isActive() on a flag having percentage condition, there is multiple call to setcookie function, which can cause error because of too big response header (each Set-Cookie: ... will be in the response header).

To avoid this, you can, for example, add something like this: $this->request->cookies->set($config['cookie'], $value); after setcookie() function... Not very beautiful, but it works ;-)

Thx.

Expose service visibility

User Deprecated: The "dz.feature_flags.toggle" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.

If I understand the documentation correclty the service dz.feature_flags.toggle needs to be public.
I added a PR to make the change.

Upgrade to Symfony3

What would be required to upgrade this bundle to work with Symfony3? Is it a lot of work?

I think this bundle is really awesome and I would love to use it in my symfony3 project!

Question: Any plans for supporting Symfony 4.*?

Hi @DZunke, thanks for this useful package.

I'm in the process of upgrading a legacy codebase from Symfony 3.4 to 4.1.
And I was wondering if you have plans for supporting Sy4 anytime soon "like within 48 hours"!?
It's ok if you don't have time for it now, I may get someone or myself to handle it and contribute back, if you don't mind.

Best,

Symfony 2.3 is not yet at EOL

Hey,

In a8beb81 Symfony 2.3 has been removed from the composer dependency range, with the justification that it is EOL. According to the Symfony roadmap, it is not EOL May 2017, and will still be seeing security patches until this date.

Could you please reverse the change to composer.json until next May (under the proviso that there not be support for incompatibilities!), as alongside #3 (pretty please!) there are a bunch of features in v1.1.0 which greatly increase what is possible with this bundle in "legacy" Symfony applications even when support for those versions is finally dropped in this bundle.

Happy to PR if you haven't the time!

Cheers,
Alex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.