Skip to content

Commit 61b77c0

Browse files
committed
updates
1 parent 855fd20 commit 61b77c0

File tree

5 files changed

+92
-16
lines changed

5 files changed

+92
-16
lines changed

README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ This SDK is compatible with [Featurevisor](https://featurevisor.com/) v2.0 proje
2424
- [Set sticky afterwards](#set-sticky-afterwards)
2525
- [Setting datafile](#setting-datafile)
2626
- [Updating datafile](#updating-datafile)
27-
- [Interval-based update](#interval-based-update)
2827
- [Logging](#logging)
28+
- [Levels](#levels)
2929
- [Customizing levels](#customizing-levels)
3030
- [Handler](#handler)
3131
- [Events](#events)
@@ -347,18 +347,21 @@ The triggers for setting the datafile again can be:
347347
- a specific event in your application (like a user action), or
348348
- an event served via websocket or server-sent events (SSE)
349349

350-
### Interval-based update
351-
352-
Here's an example of using interval-based update:
353-
354-
@TODO
355-
356350
## Logging
357351

358352
By default, Featurevisor SDKs will print out logs to the console for `info` level and above.
359353
Featurevisor PHP-SDK by default uses [PSR-3 standard](https://www.php-fig.org/psr/psr-3/) simple implementation.
360354
You can also choose from many mature implementations like e.g. [Monolog](https://github.com/Seldaek/monolog)
361355

356+
### Levels
357+
358+
These are all the available log levels:
359+
360+
- `error`
361+
- `warning`
362+
- `info`
363+
- `debug`
364+
362365
### Customizing levels
363366

364367
If you choose `debug` level to make the logs more verbose, you can set it at the time of SDK initialization.
@@ -416,8 +419,6 @@ Featurevisor SDK implements a simple event emitter that allows you to listen to
416419

417420
You can listen to these events that can occur at various stages in your application:
418421

419-
@TODO: verify these events
420-
421422
### `datafile_set`
422423

423424
```php
@@ -515,8 +516,8 @@ $myCustomHook = [
515516
// rest of the properties below are all optional per hook
516517

517518
// before evaluation
518-
'before' => function (options) {
519-
$type = $options['type']; // `feature` | `variation` | `variable`
519+
'before' => function ($options) {
520+
$type = $options['type']; // `flag` | `variation` | `variable`
520521
$featureKey = $options['featureKey'];
521522
$variableKey = $options['variableKey']; // if type is `variable`
522523
$context = $options['context'];

src/Featurevisor.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Closure;
66
use Psr\Log\LoggerInterface;
7-
use Psr\Log\NullLogger;
7+
use Psr\Log\LogLevel;
88

99
class Featurevisor
1010
{
@@ -18,6 +18,7 @@ class Featurevisor
1818
/**
1919
* @param array{
2020
* datafile?: string|array<string, mixed>,
21+
* logLevel?: LogLevel::*|string,
2122
* logger?: LoggerInterface,
2223
* context?: array<string, mixed>,
2324
* sticky?: array<string, mixed>,
@@ -33,7 +34,9 @@ class Featurevisor
3334
*/
3435
public static function createInstance(array $options): self
3536
{
36-
$logger = $options['logger'] ?? new NullLogger();
37+
$logger = $options['logger'] ?? Logger::create([
38+
'level' => $options['logLevel'] ?? Logger::DEFAULT_LEVEL,
39+
]);
3740

3841
return new self(
3942
isset($options['datafile'])
@@ -114,6 +117,13 @@ public function getFeature(string $featureKey): ?array
114117
return $this->datafileReader->getFeature($featureKey);
115118
}
116119

120+
public function setLogLevel(string $level): void
121+
{
122+
if (method_exists($this->logger, 'setLevel')) {
123+
$this->logger->setLevel($level);
124+
}
125+
}
126+
117127
public function addHook(array $hook): ?callable
118128
{
119129
return $this->hooksManager->add($hook);

src/Logger.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ public static function create(array $options = []): self
4444
);
4545
}
4646

47-
public function __construct(string $level = self::DEFAULT_LEVEL, Closure $handler = null)
47+
public function __construct(string $level = self::DEFAULT_LEVEL, ?Closure $handler = null)
4848
{
4949
$this->handler = $handler ?? static fn ($level, $message, array $context) => self::defaultLogHandler($level, $message, $context);
50-
$this->level = $level;
50+
$this->setLevel($level);
5151
}
5252

5353
public function setLevel(string $level): void
@@ -61,7 +61,13 @@ public function setLevel(string $level): void
6161

6262
public function log($level, $message, array $context = []): void
6363
{
64-
$shouldHandle = array_search($this->level, self::ALL_LEVELS) >= array_search($level, self::ALL_LEVELS);
64+
$level = (string) $level;
65+
66+
if (!in_array($level, self::ALL_LEVELS, true)) {
67+
throw new InvalidArgumentException('Invalid log level');
68+
}
69+
70+
$shouldHandle = array_search($this->level, self::ALL_LEVELS, true) >= array_search($level, self::ALL_LEVELS, true);
6571

6672
if (!$shouldHandle) {
6773
return;
@@ -85,4 +91,5 @@ private static function defaultLogHandler($level, $message, ?array $details = nu
8591
) . PHP_EOL
8692
);
8793
}
94+
8895
}

tests/FeaturevisorTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,58 @@ public function testShouldCreateInstanceWithDatafileContent()
2323
self::assertTrue(method_exists($sdk, 'getVariation'));
2424
}
2525

26+
public function testShouldCreateInstanceWithLogLevel()
27+
{
28+
$logs = [];
29+
$sdk = Featurevisor::createInstance([
30+
'logLevel' => LogLevel::DEBUG,
31+
'logger' => Logger::create([
32+
'level' => LogLevel::ERROR,
33+
'handler' => function ($level, $message, $context) use (&$logs) {
34+
$logs[] = compact('level', 'message', 'context');
35+
},
36+
]),
37+
'datafile' => [
38+
'schemaVersion' => '2',
39+
'revision' => '1.0',
40+
'features' => [],
41+
'segments' => [],
42+
],
43+
]);
44+
45+
$sdk->setContext(['userId' => '123']);
46+
47+
// logger option should take precedence over logLevel option
48+
self::assertCount(0, $logs);
49+
}
50+
51+
public function testShouldSetLogLevelAfterInitialization()
52+
{
53+
$logs = [];
54+
$sdk = Featurevisor::createInstance([
55+
'logger' => Logger::create([
56+
'level' => LogLevel::ERROR,
57+
'handler' => function ($level, $message, $context) use (&$logs) {
58+
$logs[] = compact('level', 'message', 'context');
59+
},
60+
]),
61+
'datafile' => [
62+
'schemaVersion' => '2',
63+
'revision' => '1.0',
64+
'features' => [],
65+
'segments' => [],
66+
],
67+
]);
68+
69+
$sdk->setContext(['userId' => '123']);
70+
self::assertCount(0, $logs);
71+
72+
$sdk->setLogLevel(LogLevel::DEBUG);
73+
$sdk->setContext(['country' => 'nl']);
74+
self::assertCount(1, $logs);
75+
self::assertSame('debug', $logs[0]['level']);
76+
}
77+
2678
public function testShouldConfigurePlainBucketBy()
2779
{
2880
$capturedBucketKey = '';

tests/HelpersTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,16 @@ public function testShouldResolveSupportedTypes()
2020
self::assertSame(['1', '2'], Helpers::getValueByType(['1', '2'], 'array'));
2121
self::assertSame(1, Helpers::getValueByType('1', 'integer'));
2222
self::assertSame(1.1, Helpers::getValueByType('1.1', 'double'));
23+
self::assertSame(['x' => 1], Helpers::getValueByType(['x' => 1], 'json'));
2324
}
2425

2526
public function testShouldReturnNullForNullValue()
2627
{
2728
self::assertNull(Helpers::getValueByType(null, 'string'));
2829
}
30+
31+
public function testShouldReturnNullWhenCallablePassedForString()
32+
{
33+
self::assertNull(Helpers::getValueByType(static fn () => true, 'string'));
34+
}
2935
}

0 commit comments

Comments
 (0)