https://github.com/solidworx/toggler
Feature toggle library for PHP
https://github.com/solidworx/toggler
feature-flags feature-toggles toggles
Last synced: 3 months ago
JSON representation
Feature toggle library for PHP
- Host: GitHub
- URL: https://github.com/solidworx/toggler
- Owner: SolidWorx
- License: mit
- Created: 2015-09-15T18:07:05.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2024-11-12T18:22:17.000Z (over 1 year ago)
- Last Synced: 2025-04-02T21:36:51.797Z (about 1 year ago)
- Topics: feature-flags, feature-toggles, toggles
- Language: PHP
- Size: 171 KB
- Stars: 21
- Watchers: 4
- Forks: 3
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Toggler

[](https://codecov.io/gh/SolidWorx/Toggler)
Toggler is a feature toggle library for PHP. It allows you to enable or disable features based on a toggle switch.
This is useful in a continues deployment environment, where you can deploy not-yet-ready features which are disabled, and just enable them when the feature is complete.
# Table of Contents
- [Requirements](#requirements)
- [Installation](#installation)
- [Composer](#composer)
- [Usage](#usage)
- [StorageFactory](#config)
- [Toggle a feature](#toggle-a-feature)
- [Toggle a feature based on context](#toggle-a-feature-based-on-context)
- [Using Symfony Expression Language](#using-symfony-expression-language)
- [Custom storage to retrieve feature settings](#custom-storage-to-retrieve-feature-settings)
- [Twig integration](#twig-integration)
- [Symfony integration](#symfony-integration)
- [Testing](#testing)
- [Contributing](#contributing)
- [Licence](#licence)
## Requirements
Toggler requires PHP 8.1+ and Symfony 6.1+
## Installation
### Composer
```bash
$ composer require solidworx/toggler:^2.0
```
## Usage
### Quick Example
```php
true,
'bar' => false
];
$toggle = new Toggle(new ArrayStorage($features));
```
You can then check if a feature is active or not using the `isActive` call
```php
isActive('foo'); // true
$toggle->isActive('bar'); // false
```
## StorageFactory
Toggler comes with many storage adapters to store the configuration. The most basic is the `ArrayStorage` class, which takes an array of features.
The `StorageFactory` class acts as a factory to create the config. You can pass it any value, and it will determine which storage adapter to use.
To get an instance of the config, you can use the static `factory` method
```php
true,
'bar' => false
];
$config = StorageFactory::factory($features); // $config will be an instance of ArrayStorage
// Using YAML
$config = StorageFactory::factory('/path/to/config.yml'); // $config will be an instance of YamlFileStorage
```
Each feature flag need to be a truthy value in order to be enabled.
The following truthy values are accepted:
* (boolean) true
* (int) 1
* '1'
* 'on'
* 'yes'
* 'y'
### Using callbacks
You can also use closures or callbacks to retrieve the value
```php
function () {
return true;
},
'bar' => [$myObject, 'checkBar']
];
```
## Storage Adapters
Toggler supports various storage adapters to store the config.
### Array
The most basic config is using an array with the `ArrayStorage` adapter.
```php
true,
'bar' => false
];
$toggle = new Toggle(new ArrayStorage($features));
// Or using the StorageFactory factory
$toggle = new Toggle(StorageFactory::factory($features));
```
### ENV
Reads values from environment variables.
```php
isActive('MY_AWESOME_FEATURE'); // true if the environment variable MY_AWESOME_FEATURE is set to a truthy value
```
### YAML
In order to use yml files for config, you need to include the [Symfony Yaml Component](http://symfony.com/doc/current/components/yaml/index.html)
To install and use the Yaml component, run the following command from the root of your project:
```bash
$ composer require symfony/yaml
```
Then you can define your config using a yaml file
```php
// config.yml
foo: true
bar: false
```
Pass the path to the yml file to your config
```php
true,
'bar' => false,
];
```
Pass the path to the PHP file to your config
```php
set('foo', true); // This will enable the foo feature
$toggle->set('bar', false); // This will disable the bar feature
```
## Toggle a feature based on context
To enable a feature only under specific conditions (E.G only enable it for users in a certain group, or only enable it for 10% of visitor etc)
Each feature in the config can take a callback, where you can return a truthy value based on any logic you want to add:
```php
function (User $user) {
return in_array('admin', $user->getGroups()); // Only enable features for users in the 'admin' group
},
'bar' => function () {
return (crc32($_SERVER['REMOTE_ADDR']) % 100) < 25; // Only enable this features for about 25% of visitors
},
'baz' => function (Request $request) {
return false !== strpos($request->headers->get('referer'), 'facebook.com'); // Only enable this features for users that come from Facebook
}
];
```
Callbacks that takes any arguments, should be called with the context:
```php
isActive('foo', [$user])) {
}
if ($toggle->isActive('bar', [$request])) {
}
```
## Using Symfony Expression Language
You can use the [Symfony Expression Language Component](http://symfony.com/doc/current/components/expression_language/index.html) to create expressions for your features.
To install and use the Expression Language component, run the following command from the root of your project:
```bash
$ composer require symfony/expression-language
```
Then you can create an expression for your feature:
```php
new Expression('valueOne > 10 and valueTwo < 10')
];
```
When checking the feature, you need to pass the context to use in your expression:
```php
isActive('foo', ['valueOne' => 25, 'valueTwo' => 5])) { // Will return true
}
```
## Twig Integration
Toggler comes with an optional Twig extension, which allows you to toggle elements from Twig templates.
To use the extension, register it with Twig
```php
addExtension(new ToggleExtension($toggle));
```
or if you use symfony, register it as a service.
**Note:** When using the [Symfony Bundle](Symfony Integration), the twig extension is automatically registered.
Then you can use the `toggle` tag in twig templates:
```twig
{% toggle 'foo' %}
Some content that will only display if foo is enabled
{% endtoggle %}
```
To add an alternative if a feature is not available, use the `else` tag
```twig
{% toggle 'foo' %}
Some content that will only display if foo is enabled
{% else %}
Some content that will only display if foo is not enabled
{% endtoggle %}
```
To use context values with the tag, you can pass it using the `with` keyword:
```twig
{% toggle 'foo' with {"valueOne" : 12} %}
Some content that will only display if foo is enabled based on the context provided
{% endtoggle %}
```
You can also use the `toggle()` function for conditions
```twig
{{ toggle('foo') ? 'Foo is enabled' : 'Foo is NOT enabled' }}
```
## Symfony Integration
Toggler comes with integration with the [Symfony](http://symfony.com/) framework.
To enable toggler inside symfony, register the bundle
```php
// config/bundles.php
return array(
...
SolidWorx\Toggler\Symfony\TogglerBundle::class => ['all' => true],
...
);
```
Then create a `config/packages/toggler.yaml` config file, to enable features
```yaml
toggler:
config:
features:
foo: true
bar: false
# Callables is also supported
baz: '@my.service.class' # Class must be callable (I.E implement the __invoke() method)
foobar: ['@my.service.class', 'foobar'] # Will call the `foobar` method on the service class
baz: ['My\Awesome\Feature\Class', 'checkFeature'] # Will call the static method `checkFeature` on the `My\Awesome\Feature\Class` class
# The last two lines can be written as the following:
foobar: '@my.service.class::foobar'
baz: 'My\Awesome\Feature\Class::checkFeature'
```
If you want to use an expression for a feature config, you can use the `@=` syntax:
```yaml
toggler:
config:
features:
foo: '@=myValue > 10'
```
If you want to use a storage class, you can use the `storage` config parameter to define a service for the storage:
```yaml
services:
my.toggler.storage:
class: SolidWorx\Toggler\Storage\RedisStorage
arguments: ['@redis']
toggler:
config:
storage: '@my.toggler.storage'
```
**Note:** The `features` and `storage` options can't be used together. You must use either the one or the other. At least one of the two must be defined.
**Note:** When using the Symfony bundle, the twig extension is automatically registered.
**Note:** The `symfony/security-core` package is required with `symfony/framework-bundle`.
### Console Commands
The Symfony Bundle comes with 2 pre-registered console commands.
#### Get the status of a feature
To see if a feature is enabled or not, run the following command
```bash
$ php bin/console toggler:get foo
```
This will output the status of a feature.
You can also get the status of multiple features by passing in multiple values:
```bash
$ php bin/console toggler:get foo bar baz
```
This will show whether the features `foo`, `bar` and `baz` is enabled or not.
##### Get the value using context values
To test if a feature will be enabled under certain conditions, you can pass context values to the command using either the `-c` or `--context` flags.
Multiple values for the context can be provided.
**Note:** Context values can only be strings. Objects are not supported.
```bash
$ php bin/console toggler:get foo -c myValue=10 -c anotherValue=25
```
#### Set the value of a feature
You can enable or disable a feature using the `toggler:set` command.
**Note:** You can only change the status of a feature if you are using a persistent storage.
```bash
$ php bin/console toggler:set foo true
```
This will enable the `foo` feature.
#### List all available features
You can list all available features using the `toggler:list` command.
```bash
$ php bin/console toggler:list
```
This will display all available features and their status.
# Testing
To run the unit tests, execute the following command
```bash
$ vendor/bin/phpunit
```
## Contributing
See [CONTRIBUTING](https://github.com/SolidWorx/Toggler/blob/master/CONTRIBUTING.md)
## License
Toggler is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
Please see the [LICENSE](LICENSE) file for the full license.