Skip to content

Commit

Permalink
Add default value support (#4)
Browse files Browse the repository at this point in the history
- Globally from the package config level
- From the Facade or the global helper
  • Loading branch information
clemblanco authored Feb 23, 2023
1 parent 73869ed commit dc59657
Show file tree
Hide file tree
Showing 17 changed files with 291 additions and 116 deletions.
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Latest Version on Packagist](https://img.shields.io/packagist/v/pod-point/laravel-configcat.svg?style=flat-square)](https://packagist.org/packages/pod-point/laravel-configcat)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/pod-point/laravel-configcat/run-tests.yml?branch=main&label=tests)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/Pod-Point/laravel-configcat/blob/main/LICENSE.md)
[![Total Downloads](https://img.shields.io/packagist/dt/pod-point/laravel-configcat.svg?style=flat-square)](https://packagist.org/packages/pod-point/laravel-configcat)

Implement feature flags within your Laravel application using [ConfigCat](https://configcat.com) cloud service.
Expand All @@ -17,15 +17,15 @@ composer require pod-point/laravel-configcat

### Publishing the config file

The configuration for this package comes with sensible defaults but there is one mandatory entry you will need to configure, which is your [ConfigCat SDK key](https://app.configcat.com/sdkkey). To do so, publish the configuration file for this package by running:
Next, you should publish the Laravel package configuration file using the `vendor:publish` Artisan command. It will be placed in your application's config directory:

```bash
php artisan vendor:publish --provider="PodPoint\ConfigCat\ConfigCatServiceProvider"
```

You will then be able to specify you SDK `key` within the freshly published configuration file under `config/configcat.php`.
Don't forget to specify your [ConfigCat SDK `key`](https://app.configcat.com/sdkkey) within the freshly published Laravel configuration file under `config/configcat.php`.

See [`config/configcat.php`](config/configcat.php) for more details.
The Laravel configuration for this package comes with sensible defaults. See [`config/configcat.php`](https://github.com/Pod-Point/laravel-configcat/blob/main/config/configcat.php) for more details.

## Usage

Expand All @@ -43,7 +43,19 @@ $flag = configcat('new_registration_flow');

> **Note:** You can define the actual value of a feature flag to be `bool(true)` or `bool(false)` on ConfigCat but not only, it can also be [a number or a text setting](https://configcat.com/docs/main-concepts/#about-setting-types).
If the feature flag is undefined or something went wrong, `bool(false)` will be returned by default.
If the feature flag is undefined or something went wrong, `bool(false)` will be returned by default, however you can change this by specifying a default value **only when using the Facade or the global helper** to retrieve the feature flag value using:

```php
use PodPoint\ConfigCat\Facades\ConfigCat;

$flag = ConfigCat::get('new_registration_flow', true);

$flag = configcat('new_registration_flow', true);
```

You can also globally sepcify a default value from the [`config/configcat.php`](https://github.com/Pod-Point/laravel-configcat/blob/main/config/configcat.php) file.

:warning: **Only** `boolean`, `string`, `integer` or `float` default value types are supported as these are the only [setting types](https://configcat.com/docs/main-concepts/#about-setting-types) available from ConfigCat.

### Validation rule

Expand Down Expand Up @@ -116,7 +128,7 @@ The following view content will only be rendered if the feature flag is truthy:

The [User Object](https://configcat.com/docs/sdk-reference/php/#user-object) is essential if you'd like to use ConfigCat's [Targeting](https://configcat.com/docs/advanced/targeting) feature.

ConfigCat needs to understand the representation of your users from your application. To do so, you will need to map your user into a `ConfigCat\User` object. This can be done directly from the [`config/configcat.php`](config/configcat.php) file. Here is an example:
ConfigCat needs to understand the representation of your users from your application. To do so, you will need to map your user into a `ConfigCat\User` object. This can be done directly from the [`config/configcat.php`](https://github.com/Pod-Point/laravel-configcat/blob/main/config/configcat.php) file. Here is an example:

```php
'user' => function (\App\Models\User $user) {
Expand All @@ -135,13 +147,13 @@ use App\Models\User;
use PodPoint\ConfigCat\Facades\ConfigCat;

$user = User::where('email', 'taylor@laravel.com')->firstOrFail();
ConfigCat::get('new_registration_flow', $user);
ConfigCat::get('new_registration_flow', $default, $user);
```

This is also applicable for the global helper and the Blade directive:

```php
configcat('new_registration_flow', $user);
configcat('new_registration_flow', $default, $user);
```

```blade
Expand All @@ -156,7 +168,7 @@ configcat('new_registration_flow', $user);

This package supports native Laravel caching and logging capabilities in order to cache the feature flag values from ConfigCat's CDN as well as log any information when resolving feature flags. We've setup some sensible defaults but various levels of caching and logging can be configured.

See [`config/configcat.php`](config/configcat.php) for more info.
See [`config/configcat.php`](https://github.com/Pod-Point/laravel-configcat/blob/main/config/configcat.php) for more info.

### Test support: mock, fake & overrides

Expand Down Expand Up @@ -194,9 +206,9 @@ ConfigCat::fake(['new_registration_flow' => true]);

When running tests within a browser which doesn't share the same instance of the application, using mocks or fakes is not applicable. This is why we provide some overrides through ConfigCat SDK which will make the client under the hood localhost only and will use a locally generated `json` file in order to read the feature flags for the system under test.

First of all, you will need to make sure to enable `overrides` from [`config/configcat.php`](config/configcat.php). You could also optionally configure the file path for the `json` file if you wish to. The file will be automatically created for you when using overrides.
First of all, you will need to make sure to enable `overrides` from [`config/configcat.php`](https://github.com/Pod-Point/laravel-configcat/blob/main/config/configcat.php). You could also optionally tweak the file path for the `json` file if you wish to. The file will be automatically created for you when using overrides.

Similarly to `ConfigCat::fake()` you can configure some predefined feature flags which will be saved into a `json` file:
Similarly to `ConfigCat::fake()` you can come up with some predefined feature flags which will be saved into a `json` file:

```php
use PodPoint\ConfigCat\Facades\ConfigCat;
Expand All @@ -218,7 +230,7 @@ Please see our [Releases](https://github.com/pod-point/laravel-configcat/release

## Contributing

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
Please see [CONTRIBUTING](https://github.com/Pod-Point/laravel-configcat/blob/main/CONTRIBUTING.md) for details.

## Credits

Expand All @@ -229,7 +241,7 @@ Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

## License

The MIT License (MIT). Please see [License File](LICENCE.md) for more information.
The MIT License (MIT). Please see [License File](https://github.com/Pod-Point/laravel-configcat/blob/main/LICENCE.md) for more information.

---

Expand Down
17 changes: 16 additions & 1 deletion config/configcat.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,26 @@
|--------------------------------------------------------------------------
|
| SDK Key to access your feature flag and setting. Get it from ConfigCat
| Dashboard. This is required in order to use this package.
| Dashboard. This is a hard requirement in order to use this package.
| An invalid key like 'none' could be used when you are willing to
| make the package "offline" and only use default values.
*/

'key' => env('CONFIGCAT_KEY', 'none'),

/*
|--------------------------------------------------------------------------
| Default value
|--------------------------------------------------------------------------
|
| Here you can define the value which will be returned every time there
| is a problem trying to reach for ConfigCat CDN or when the feature
| flag you are trying to retrieve could not be found. This can be
| overriden when using ConfigCat::get() or configcat() too.
*/

'default' => false,

/*
|--------------------------------------------------------------------------
| ConfigCat Logging
Expand Down
14 changes: 10 additions & 4 deletions src/ConfigCat.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@ class ConfigCat implements FeatureFlagProviderContract
{
/** @var ConfigCatClient */
protected $configCatClient;
/** @var mixed */
public $defaultValue = false;
/** @var callable|null */
protected $userHandler = null;
/** @var string|null */
protected $overridesFilePath;

public function __construct(
ClientInterface $configCatClient,
$defaultValue = false,
callable $userHandler = null,
string $overridesFilePath = null
) {
$this->configCatClient = $configCatClient;
$this->defaultValue = $defaultValue;
$this->userHandler = $userHandler;
$this->overridesFilePath = $overridesFilePath;
}
Expand All @@ -34,14 +38,16 @@ public function __construct(
* will return false if the flag is undefined or if something went wrong.
*
* @param string $featureKey
* @param mixed|null $default
* @param mixed|null $user
* @return bool|string|int
* @return mixed
*/
public function get(string $featureKey, $user = null)
public function get(string $featureKey, $default = null, $user = null)
{
$user = $this->transformUser($user ?: auth()->user());
$default = is_null($default) ? $this->defaultValue : $default;
$user = $this->transformUser(is_null($user) ? auth()->user() : $user);

return $this->configCatClient->getValue($featureKey, false, $user);
return $this->configCatClient->getValue($featureKey, $default, $user);
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/ConfigCatServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,15 @@ private function registerConfigCatClient()
private function registerFacade()
{
$this->app->singleton('configcat', function ($app) {
$default = $app['config']['configcat.default'];

if (! is_bool($default) && ! is_string($default) && ! is_int($default) && ! is_float($default)) {
throw new \InvalidArgumentException('The default value can only be of type boolean, string, integer or float.');
}

return new ConfigCat(
$app->make(ClientInterface::class),
$default,
$app['config']['configcat.user'],
$app['config']['configcat.overrides.enabled']
? $app['config']['configcat.overrides.file']
Expand Down
5 changes: 3 additions & 2 deletions src/Contracts/FeatureFlagProviderContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ interface FeatureFlagProviderContract
{
/**
* @param string $featureKey
* @param mixed|null $default
* @param mixed|null $user
* @return bool|string|int
* @return mixed
*/
public function get(string $featureKey, $user = null);
public function get(string $featureKey, $default = null, $user = null);

/**
* @param array $flagsToOverride
Expand Down
2 changes: 1 addition & 1 deletion src/Facades/ConfigCat.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use PodPoint\ConfigCat\Support\ConfigCatFake;

/**
* @method static bool|string|int get(string $featureKey, $user = null)
* @method static mixed get(string $featureKey, $default = null, $user = null)
* @method static void override(array $flagsToOverride = [])
*
* @see \PodPoint\ConfigCat\ConfigCat
Expand Down
8 changes: 5 additions & 3 deletions src/Support/ConfigCatFake.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ public function fake($featureFlags = []): self
* feature flag is undefined.
*
* @param string $featureKey
* @return bool|string|int
* @param mixed|null $default
* @param mixed|null $user
* @return mixed
*/
public function get(string $featureKey)
public function get(string $featureKey, $default = null, $user = null)
{
$featureValue = $this->featureFlags[$featureKey] ?? false;
$featureValue = $this->featureFlags[$featureKey] ?? ($default ?: $this->provider->defaultValue);

if (is_array($featureValue)) {
$execution = $this->getCount($featureKey);
Expand Down
9 changes: 4 additions & 5 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
* If no feature flag is found, false will be returned.
*
* @param string $featureKey
* @param mixed|null $default
* @param mixed|null $user
* @return bool|string|int
* @return mixed
*/
function configcat(string $featureKey, $user = null)
function configcat(string $featureKey, $default = null, $user = null)
{
return $user
? ConfigCat::get($featureKey, $user)
: ConfigCat::get($featureKey);
return call_user_func_array([ConfigCat::class, 'get'], func_get_args());
}
}
2 changes: 1 addition & 1 deletion tests/Feature/BladeDirectivesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function test_it_will_consider_an_unknown_feature_flag_to_be_disabled()
public function test_it_will_consider_a_feature_flag_as_a_number_setting_to_be_disabled()
{
ConfigCat::fake([
'enabled_feature' => 123,
'enabled_feature' => 1234,
'disabled_feature' => false,
]);

Expand Down
Loading

0 comments on commit dc59657

Please sign in to comment.