{"id":21009805,"url":"https://github.com/novaway/novawayfeatureflagbundle","last_synced_at":"2025-04-07T13:05:22.460Z","repository":{"id":11819061,"uuid":"70668345","full_name":"novaway/NovawayFeatureFlagBundle","owner":"novaway","description":"KISS bundle to manage features flags in your Symfony applications.","archived":false,"fork":false,"pushed_at":"2025-02-22T09:40:34.000Z","size":327,"stargazers_count":17,"open_issues_count":3,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-31T12:04:10.179Z","etag":null,"topics":["feature-flags","hacktoberfest","symfony","symfony-bundle","toggle-switches"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/novaway.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-12T06:07:18.000Z","updated_at":"2025-03-11T14:37:54.000Z","dependencies_parsed_at":"2023-12-08T07:39:16.609Z","dependency_job_id":"09cf1ce7-e985-426e-8627-626470b1ff89","html_url":"https://github.com/novaway/NovawayFeatureFlagBundle","commit_stats":{"total_commits":82,"total_committers":7,"mean_commits":"11.714285714285714","dds":"0.13414634146341464","last_synced_commit":"498c0b9fcf2cc1507fe641d26f184435478ec1bd"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novaway%2FNovawayFeatureFlagBundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novaway%2FNovawayFeatureFlagBundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novaway%2FNovawayFeatureFlagBundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novaway%2FNovawayFeatureFlagBundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/novaway","download_url":"https://codeload.github.com/novaway/NovawayFeatureFlagBundle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247657276,"owners_count":20974344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["feature-flags","hacktoberfest","symfony","symfony-bundle","toggle-switches"],"created_at":"2024-11-19T09:17:58.960Z","updated_at":"2025-04-07T13:05:22.443Z","avatar_url":"https://github.com/novaway.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FeatureFlagBundle\n\n[![Build Status](https://github.com/novaway/NovawayFeatureFlagBundle/actions/workflows/tests.yml/badge.svg)](https://actions-badge.atrox.dev/novaway/NovawayFeatureFlagBundle/goto?ref=master)\n![Coverage](coverage_badge.svg)\n[![License](https://poser.pugx.org/novaway/feature-flag-bundle/license)](https://packagist.org/packages/novaway/feature-flag-bundle)\n[![Latest Stable Version](https://poser.pugx.org/novaway/feature-flag-bundle/v/stable)](https://packagist.org/packages/novaway/feature-flag-bundle)\n[![Latest Unstable Version](https://poser.pugx.org/novaway/feature-flag-bundle/v/unstable)](https://packagist.org/packages/novaway/feature-flag-bundle)\n[![Total Downloads](https://poser.pugx.org/novaway/feature-flag-bundle/downloads)](https://packagist.org/packages/novaway/feature-flag-bundle)\n\nThe FeatureFlagBundle is a bundle to manage features flags in your Symfony applications.\n\n⚠️ You're currently reading the documentation for the next major version. Refer to the [2.x documentation](https://github.com/novaway/NovawayFeatureFlagBundle/tree/2.x) to read the stable version documentation.\n\n## Compatibility\n\nThis bundle is tested with at least all maintained Symfony version.\n\n## Documentation\n\n###  Install it\n\nInstall extension using [composer](https://getcomposer.org):\n\n```bash\ncomposer require novaway/feature-flag-bundle\n```\n\nIf you don't use Flex, enable the bundle in your `config/bundles.php` file:\n\n```php\n\u003c?php\n\nreturn [\n    // ...\n    Novaway\\Bundle\\FeatureFlagBundle\\NovawayFeatureFlagBundle::class =\u003e ['all' =\u003e true],\n];\n```\n\n###  Configuration\n\nTo configure and register a feature manager you need a factory service. You may also need to change some options to the factory.\n\n```yaml\n# ...\nnovaway_feature_flag:\n    default_manager: default\n    managers:\n        default:\n            factory: 'novaway_feature_flag.factory.array'\n            options:\n                features:\n                    my_feature_1: false\n                    my_feature_2: true\n                    my_feature3: '%env(bool:FEATURE_ENVVAR)%'\n```\n\nThe factories that come with this bundle can be found in the table below.\n\n| Factory service id                 | Options    |\n|------------------------------------|------------|\n| novaway_feature_flag.factory.array | `features` |\n\n#### Example configuration\n\n```yaml\n# ...\nnovaway_feature_flag:\n    default_manager: default\n    managers:\n        default:\n            factory: novaway_feature_flag.factory.array\n            options:\n                features:\n                    my_feature_1:\n                        enabled: false\n                        description: MyFeature1 description text\n                    my_feature_2:\n                        enabled: true\n                        description: MyFeature2 description text\n                    my_feature3:\n                        enabled: '%env(bool:FEATURE_ENVVAR)%'\n                        description: MyFeature3 description text\n```\n\nYou can declare multiple managers. Multiple providers is useful if you want to use different storage providers or to isolate your features flags.\n\n```yaml\n# ...\nnovaway_feature_flag:\n    default_manager: manager_foo\n    managers:\n        manager_foo:\n            factory: novaway_feature_flag.factory.array\n            options:\n                features:\n                    my_feature_1:\n                        enabled: false\n                        description: MyFeature1 description text\n                    my_feature_2:\n                        enabled: true\n                        description: MyFeature2 description text\n                    my_feature3:\n                        enabled: '%env(bool:FEATURE_ENVVAR)%'\n                        description: MyFeature3 description text\n        manager_bar:\n            factory: novaway_feature_flag.factory.array\n            options:\n                features:\n                    my_feature_4:\n                        enabled: false\n                        description: MyFeature4 description text\n                    my_feature_5: []\n                    my_feature_6: ~\n                    my_feature_7: false\n```\n\nWhen several managers are defined, they are registered in the Symfony dependency injection container as services with the following naming convention: `novaway_feature_flag.manager.\u003cmanager_name\u003e`.\n\nFor example, the `manager_bar` is accessible with the following service name: `novaway_feature_flag.manager.manager_bar`.\n\nManager storage are also registered in the Symfony dependency injection container as services with the following naming convention: `novaway_feature_flag.storage.\u003cmanager_name\u003e`.\n\n#### Use it as a service\n\nThe bundle adds a global `novaway_feature_flag.manager` (also bind to `FeatureManager`) service you can use in your PHP classes.\n\nIn the case you have defined several managers, the service use the `ChainedFeatureManager` class to chain all declared managers.\n\n```php\nuse Novaway\\Bundle\\FeatureFlagBundle\\Manager\\FeatureManager;\n// ...\n\nclass MyController extends Controller\n{\n    public function myAction(FeatureManager $featureManager): Response\n    {\n        if ($featureManager-\u003eisEnabled('my_feature_1')) {\n            // my_feature_1 is enabled\n        }\n\n        if ($featureManager-\u003eisDisabled('my_feature_2')) {\n            // my_feature_2 is not enabled\n        }\n\n        // ...\n    }\n}\n```\n\n#### In your Twig templates\n\nYou can also check a flag in your templates:\n\n```twig\n{% if isFeatureEnabled('my_feature_1') %}\n    {% include 'feature1_template.html.twig' %}\n{% endif %}\n\n{% if isFeatureDisabled('my_feature_2') %}\n    {% include 'feature2_template.html.twig' %}\n{% endif %}\n```\n\n#### In the routing configuration\n\nThe package allows you to restrict a controller access by adding some configuration in your routing definition.\n\n```yaml\n# app/config/routing.yml\nmy_first_route:\n    path: /my/first/route\n    defaults:\n        _controller: AppBundle:Default:index\n        _features:\n            - { feature: my_feature_key, enabled: false } # The action is accessible if \"my_feature_key\" is disabled\n\nmy_second_route:\n    path: /my/second-route\n    defaults:\n        _controller: AppBundle:Default:second\n        _features:\n            - { feature: foo } # The action is accessible if \"foo\" is enabled ...\n            - { feature: bar, enabled: true } # ... and \"bar\" feature is also enabled\n            - { feature: feature-42, enabled: true, exceptionClass: Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException } # will throw a BadRequestHttpException if \"feature-42\" is disabled\n            - { feature: feature-44, enabled: true, exceptionFactory: Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpExceptionFactory } # will use the BadRequestHttpExceptionFactory registered factory class to create the exception to be thrown\n```\n\n#### As a controller attribute\n\nYou can also restrict a controller access with attributes, two attributes are available:\n\n* `Novaway\\Bundle\\FeatureFlagBundle\\Attribute\\FeatureEnabled`\n* `Novaway\\Bundle\\FeatureFlagBundle\\Attribute\\FeatureDisabled`\n\n```php\n#[FeatureEnabled(name: \"foo\")]\nclass MyController extends Controller\n{\n    #[FeatureEnabled(name: \"foo\", exceptionClass: BadRequestHttpException::class)]\n    public function annotationFooEnabledAction(): Response\n    {\n        return new Response('MyController::annotationFooEnabledAction');\n    }\n\n    #[FeatureDisabled(name: \"foo\", exceptionFactory: MyExceptionFactory::class)]\n    public function annotationFooDisabledAction(): Response\n    {\n        return new Response('MyController::annotationFooDisabledAction');\n    }\n}\n```\n\n### Implement your own storage provider\n\n1. First your need to create your storage provider class which implement the `Novaway\\Bundle\\FeatureFlagBundle\\Storage\\StorageInterface` interface\n2. Register it in the Symfony dependency injection container\n3. Specify the storage you want to use in a manager configuration\n\n```yaml\nnovaway_feature_flag:\n    manager:\n        manager_name:\n            storage: your.custom.service.name\n            options:\n                # arguments need to create the storage service\n```\n\nWhen you create a storage, the static method `create` is called to create the storage instance.\n\n## License\n\nThis library is published under [MIT license](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnovaway%2Fnovawayfeatureflagbundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnovaway%2Fnovawayfeatureflagbundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnovaway%2Fnovawayfeatureflagbundle/lists"}