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