features-bundle
This Symfony bundle provides a way of managing features within a project. A common use-case is to have a certain feature only active under certain condition. Examples would be that you want to activate a feature when the use has a certain role, or when you are not in a production environment (think of testing).
With this bundle you can configure features to be active or inactive. Using resolvers you decide when a feature is active or not.
Requirements:
- PHP 5.5 or higher, including php 7
- Symfony 2.7 or higher, including 3.0
Recommended installation is via composer: composer require yannickl88/features-bundle
.
After that, you need to register the bundle in the kernel of your application:
<?php
// app/AppKernel.php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
new Yannickl88\FeaturesBundle\FeaturesBundle(),
// …
];
}
}
Usage
All configuration is done using services and your application config. For the following example we want to enable a feature when the GET parameter beta
is set to on
.
So configuring your feature in the config.yml
of your application.
features:
tags:
beta: # our feature tag
request: ["beta", "on"] # 'app.features.request_resolver' will resolve this key
Here we define a feature tag beta
which will be resolved with the request
resolver. Now we need to configure the request
resolver. We do this with the following service definition:
yml
services:
app.features.request_resolver:
class: App\Feature\RequestResolver
arguments:
- "@request_stack"
tags:
# config-key is set to resolve the configured key: "request" with the options "beta" and "on"
- { name: features.resolver, config-key: request }
Here we create the app.features.request_resolver
service and tag it with features.resolver
. This will then be picked up by the bundle and be registered so we can use it in our feature tags. What we also provide is a config-key
value. This is the key that we defined in the config.yml
under the beta
tag. This will glue your config to your resolver.
Final thing to do is implement the RequestResolver
:
```php
namespace App\Feature;
use Symfony\Component\HttpFoundation\RequestStack;
use Yannickl88\FeaturesBundle\Feature\FeatureResolverInterface;
class RequestResolver implements FeatureResolverInterface
{
private $request_stack;
public function __construct(RequestStack $request_stack)
{
$this->request_stack = $request_stack;
}
/**
* {@inheritdoc}
*/
public function isActive(array $options = [])
{
// Feature is inactive when there is no request
if (null === $request = $this->request_stack->getMasterRequest()) {
return false;
}
// $options contains ["beta", "on"] for the 'beta' feature tag
list($key, $expected_value) = $options;
return $request->get($key) === $expected_value;
}
}
yml
Now we can start using the feature in our code. So if I want to check for a feature I can inject it as follows:
services:
app.some.service:
class: App\Some\Service
arguments:
- "@features.tag"
tags:
- { name: features.tag, tag: beta }
php
Notice here that we do not inject the feature directly, but tag the service. The bundle will replace the feature for you. So you can use it as follows in your code:
namespace App\Some;
use Yannickl88\FeaturesBundle\Feature\Feature;
class Service
{
private $feature;
public function __construct(Feature $feature)
{
$this->feature = $feature;
}
public function someMethod()
{
if ($this->feature->isActive()) {
// do some extra beta logic when this feature is active
}
}
}
``
?beta=on` to my URL. The feature will trigger.
So if I now add
Note: If you remove the tag, it will inject a deprecated feature. This deprecated feature will trigger a warning when the isActive
is used so you will quickly see where unused feature are used.
Twig
If it also possible to check a feature in your twig templates. Simply use the feature
function to check if a feature is enabled.
{% if feature("beta") %}
{# do some extra beta logic when this feature is active #}
{% endif %}
Advanced Topics
It is possible to configure multiple resolvers per feature tag. You can simply keep adding more in the config.yml
. So in the example we can extend it to:
yml
features:
tags:
beta:
request: ["beta", "on"]
other: ~
more: ["foo"]
All resolvers must now resolve to true
in order for this feature to be active. This is usefull if you want to check for multiple conditions.
Furthermore, if you want to have multiple resolvers where only one needs to resolve to true
, you can use the chain resolver. This can be done as follows:
yml
features:
tags:
beta:
chain:
request: ["beta", "on"]
other: ~
more: ["foo"]
Notice here we have as resolver chain
and under this we have your config as before.
Copyright (c) 2016 Yannick de Lange
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-
Added better autowiring support (#11)
By web-flow, 1 year ago
-
Remove redundant brace (#10)
By yannickl88, 1 year ago
-
Added autowire support (#8)
By yannickl88, 1 year ago
-
Made the bundle compatible with SF4 (#7)
By yannickl88, 1 year ago
-
Merge pull request #6 from greg0ire/make_composer_outdated_empty
By web-flow, 1 year ago
-
removed the 3.0 from travis and require phpunit 5
By yannickl88, 1 year ago
-
Allow Twig 2
By greg0ire, 1 year ago
-
Migrate to phpunit 6
By greg0ire, 1 year ago
-
Merge pull request #4 from greg0ire/document_how_to_register_the_bundle
By web-flow, 1 year ago
-
Document how to register the bundle
By greg0ire, 1 year ago
-
Fixed issue with feature tag names not being using in the same syntax
By yannickl88, 2 years ago
-
Updated README.md to include the chain resolver.
By yannickl88, 3 years ago
-
Fixed typo in unit test :D
By yannickl88, 3 years ago
-
Fixed typo
By yannickl88, 3 years ago
-
Added support for a chain resolver
By yannickl88, 3 years ago
-
Made feature container lazy load features
By yannickl88, 3 years ago
-
Updated readme
By yannickl88, 3 years ago
-
Added twig support for checking features
By yannickl88, 3 years ago
-
Update README.md
By yannickl88, 3 years ago
-
Update README.md
By yannickl88, 3 years ago
-
Update README.md
By yannickl88, 3 years ago
-
Update README.md
By yannickl88, 3 years ago
-
Update README.md
By yannickl88, 3 years ago
-
Added missing @param
By yannickl88, 3 years ago
-
Cleanup
By yannickl88, 3 years ago
-
Added unit tests
By yannickl88, 3 years ago
-
Made feature resolve at run-time
By yannickl88, 3 years ago
-
Cleaned up extension a bit
By yannickl88, 3 years ago
-
Added missing @author tags
By yannickl88, 3 years ago
-
Extended test to work with two resolvers
By yannickl88, 3 years ago