Skip to content

Commit 9842ebb

Browse files
committed
Fix return value not type safe when default parameter is used
1 parent 868aa5b commit 9842ebb

3 files changed

Lines changed: 44 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [5.1.3](https://github.com/userfrosting/framework/compare/5.1.2...5.1.3)
8+
- [Config] Fix issue with `getBool`, `getString`, `getInt` and `getArray` where a null value could be returned even if a default parameter was provided when the data did in fact return `null`, making the return value not type safe as it should be.
9+
710
## [5.1.2](https://github.com/userfrosting/framework/compare/5.1.1...5.1.2)
811
- Add Slim [type hinting](https://github.com/slimphp/Slim/releases/tag/4.14.0) & bump minimum slim version
912

src/Config/Config.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@ class Config extends Repository
2121
{
2222
/**
2323
* Get the specified configuration value as bool.
24+
* Returns null if the key is not found, unless a default is provided, in
25+
* which case the return value is type safe (can't be null).
2426
*
2527
* @param string $key
2628
* @param bool|null $default
2729
*
28-
* @return ($default is null ? bool|null : bool) Returns null if the key is not found
30+
* @return ($default is null ? bool|null : bool)
2931
*/
3032
public function getBool(string $key, ?bool $default = null): ?bool
3133
{
32-
$value = $this->get($key, $default);
34+
$value = $this->get($key, $default) ?? $default;
3335

3436
if (!is_bool($value) && !is_null($value)) {
3537
throw new TypeException("Config key '$key' doesn't return bool.");
@@ -40,15 +42,17 @@ public function getBool(string $key, ?bool $default = null): ?bool
4042

4143
/**
4244
* Get the specified configuration value as bool.
45+
* Returns null if the key is not found, unless a default is provided, in
46+
* which case the return value is type safe (can't be null).
4347
*
4448
* @param string $key
4549
* @param string|null $default
4650
*
47-
* @return ($default is null ? string|null : string) Returns null if the key is not found
51+
* @return ($default is null ? string|null : string)
4852
*/
4953
public function getString(string $key, ?string $default = null): ?string
5054
{
51-
$value = $this->get($key, $default);
55+
$value = $this->get($key, $default) ?? $default;
5256

5357
if (!is_string($value) && !is_null($value)) {
5458
throw new TypeException("Config key '$key' doesn't return string.");
@@ -59,15 +63,17 @@ public function getString(string $key, ?string $default = null): ?string
5963

6064
/**
6165
* Get the specified configuration value as bool.
66+
* Returns null if the key is not found, unless a default is provided, in
67+
* which case the return value is type safe (can't be null).
6268
*
6369
* @param string $key
6470
* @param int|null $default
6571
*
66-
* @return ($default is null ? int|null : int) Returns null if the key is not found
72+
* @return ($default is null ? int|null : int)
6773
*/
6874
public function getInt(string $key, ?int $default = null): ?int
6975
{
70-
$value = $this->get($key, $default);
76+
$value = $this->get($key, $default) ?? $default;
7177

7278
if (!is_int($value) && !is_null($value)) {
7379
throw new TypeException("Config key '$key' doesn't return int.");
@@ -78,15 +84,17 @@ public function getInt(string $key, ?int $default = null): ?int
7884

7985
/**
8086
* Get the specified configuration value as bool.
87+
* Returns null if the key is not found, unless a default is provided, in
88+
* which case the return value is type safe (can't be null).
8189
*
8290
* @param string $key
8391
* @param mixed[]|null $default
8492
*
85-
* @return ($default is null ? mixed[]|null : mixed[]) Returns null if the key is not found
93+
* @return ($default is null ? mixed[]|null : mixed[])
8694
*/
8795
public function getArray(string $key, ?array $default = null): ?array
8896
{
89-
$value = $this->get($key, $default);
97+
$value = $this->get($key, $default) ?? $default;
9098

9199
if (!is_array($value) && !is_null($value)) {
92100
throw new TypeException("Config key '$key' doesn't return array.");

tests/Config/ConfigTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class ConfigTest extends TestCase
2020
'string' => 'foobar',
2121
'int' => 92,
2222
'array' => ['foo', 'bar'],
23+
'null' => null,
2324
];
2425

2526
public function testGetBool(): void
@@ -30,6 +31,12 @@ public function testGetBool(): void
3031
$this->assertSame(false, $repo->getBool('missing', false));
3132
$this->assertSame(null, $repo->getBool('missing'));
3233
$this->assertSame($repo->get('missing'), $repo->getBool('missing')); // Same default behavior as "get"
34+
35+
// Value is null, but not the default. Default should still be used.
36+
$this->assertSame(null, $repo->getBool('null'));
37+
$this->assertSame(false, $repo->getBool('null', false));
38+
39+
// Exception
3340
$this->expectException(TypeException::class);
3441
$repo->getBool('string');
3542
}
@@ -42,6 +49,12 @@ public function testGetString(): void
4249
$this->assertSame('barfoo', $repo->getString('missing', 'barfoo'));
4350
$this->assertSame(null, $repo->getString('missing'));
4451
$this->assertSame($repo->get('missing'), $repo->getString('missing')); // Same default behavior as "get"
52+
53+
// Value is null, but not the default. Default should still be used.
54+
$this->assertSame(null, $repo->getString('null'));
55+
$this->assertSame('non-null', $repo->getString('null', 'non-null'));
56+
57+
// Exception
4558
$this->expectException(TypeException::class);
4659
$repo->getString('bool');
4760
}
@@ -54,6 +67,12 @@ public function testGetInt(): void
5467
$this->assertSame(29, $repo->getInt('missing', 29));
5568
$this->assertSame(null, $repo->getInt('missing'));
5669
$this->assertSame($repo->get('missing'), $repo->getInt('missing')); // Same default behavior as "get"
70+
71+
// Value is null, but not the default. Default should still be used.
72+
$this->assertSame(null, $repo->getInt('null'));
73+
$this->assertSame(123, $repo->getInt('null', 123));
74+
75+
// Exception
5776
$this->expectException(TypeException::class);
5877
$repo->getInt('string');
5978
}
@@ -66,6 +85,12 @@ public function testGetArray(): void
6685
$this->assertSame(['bar', 'foo'], $repo->getArray('missing', ['bar', 'foo']));
6786
$this->assertSame(null, $repo->getArray('missing'));
6887
$this->assertSame($repo->get('missing'), $repo->getArray('missing')); // Same default behavior as "get"
88+
89+
// Value is null, but not the default. Default should still be used.
90+
$this->assertSame(null, $repo->getArray('null'));
91+
$this->assertSame(['non-null'], $repo->getArray('null', ['non-null']));
92+
93+
// Exception
6994
$this->expectException(TypeException::class);
7095
$repo->getArray('string');
7196
}

0 commit comments

Comments
 (0)