OpensoftRolloutBundle
A Symfony3 Bundle for opensoft/rollout, (*1)
, (*2)
Obligatory Screenshot
, (*3)
Installation
1) Install via composer
Add the bundle via composer, (*4)
composer require opensoft/rollout-bundle
And activate it inside your app\AppKernel.php
, (*5)
new Opensoft\RolloutBundle\OpensoftRolloutBundle(),
2) Configuration
Add the following to your configuration (supports auto-wiring), (*6)
opensoft_rollout:
user_provider_service: [YOUR USER PROVIDER SERVICE]
storage_service: [YOUR STORAGE SERVICE FOR ROLLOUT]
-
user_provider_service
: Add the service id (generally the FQDN with auto-wiring) of the UserProvider to which you added the Rollout UserProviderInterface
-
storage_service
: Defaults to Opensoft\Rollout\Storage\ArrayStorage
, but you can also use the included Opensoft\RolloutBundle\Storage\Doctrine\DoctrineORMStorage
or create your own (see below for implementation)
3) Implement Interfaces
RolloutUserInterface
Any rollout user must implement the RolloutUserInterface
. Often, this will be your main user object in the application., (*7)
<?php
use Opensoft/Rollout/RolloutUserInterface;
class User implements RolloutUserInterface
{
/**
* @return string
*/
public function getRolloutIdentifier()
{
return $this->email;
}
}
UserProviderInterface
Expose individual users to the rollout interface by implementing the UserProviderInterface
, (*8)
<?php
use Doctrine\ORM\EntityRepository;
use Opensoft\RolloutBundle\Rollout\UserProviderInterface;
class UserRepository extends EntityRepository implements UserProviderInterface
{
/**
* @param mixed $id
* @return RolloutUserInterface|null
*/
public function findByRolloutIdentifier($id)
{
return $this->findOneBy(array('email' => $id));
}
}
GroupDefinitionInterface
Provide different groups of users to your rollout., (*9)
Tag all of your group definitions with the DIC tag rollout.group
to expose them to the rollout interface, (*10)
<?php
use Opensoft\RolloutBundle\Rollout\GroupDefinitionInterface;
class AcmeEmployeeGroupDefinition implements GroupDefinitionInterface
{
/**
* @return string
*/
public function getName()
{
return 'acme_employee';
}
/**
* @return string
*/
public function getDescription()
{
return 'This group contains acme company employees';
}
/**
* @return \Closure
*/
public function getCallback()
{
return function(RolloutUserInterface $user) {
// Is this user an employee of acme?
return strpos($user->getEmail(), 'acme.com') !== false;
};
}
}
StorageInterface
Implement a custom storage solution., (*11)
Note: The rollout StorageInterface
changed in version 2.0.0
., (*12)
<?php
use Opensoft\Rollout\Storage\StorageInterface;
class MyStorage implements StorageInterface
{
/**
* @param string $key
* @return mixed|null Null if the value is not found
*/
public function get($key)
{
// implement get
}
/**
* @param string $key
* @param mixed $value
*/
public function set($key, $value)
{
// implement set
}
/**
* @param string $key
* @since 2.0.0
*/
public function remove($key)
{
// implement remove
}
}
4) Activate Routing
Add the following to your app/Resources/config/routing.yml
file:, (*13)
opensoft_rollout:
resource: "@OpensoftRolloutBundle/Resources/config/routing.yml"
prefix: /admin/rollout
Usage
Check if a feature is enabled in a controller, (*14)
if ($this->get('rollout')->isActive('chat', $this->getUser())) {
// do some chat related feature work
}
Twig example:, (*15)
{% if rollout_is_active('chat', app.user) %}
<!-- show a chat interface -->
{% endif %}
Further Reading
- https://github.com/FetLife/rollout
- http://blog.travis-ci.com/2014-03-04-use-feature-flags-to-ship-changes-with-confidence/
- http://code.flickr.net/2009/12/02/flipping-out/
- http://en.wikipedia.org/wiki/Feature_toggle