DecimalNumber::hydrate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 2
crap 1
1
<?php declare(strict_types=1);
2
3
namespace Igni\Storage\Mapping\Strategy;
4
5
use Igni\Storage\Exception\MappingException;
6
use Igni\Storage\Mapping\MappingStrategy;
7
8
final class DecimalNumber implements MappingStrategy, DefaultAttributesProvider
9
{
10 4
    public static function hydrate(&$value, array $attributes = []): void
11
    {
12 4
        $value = self::formatDecimalNumber((string) $value, $attributes);
13 3
    }
14
15 2
    public static function extract(&$value, array $attributes = []): void
16
    {
17 2
        $value = self::formatDecimalNumber((string) $value, $attributes);
18 2
    }
19
20 4
    public static function getDefaultAttributes(): array
21
    {
22
        return [
23 4
            'scale' => 2,
24
            'precision' => 10,
25
        ];
26
    }
27
28 6
    private static function formatDecimalNumber(string $number, array $attributes): string
29
    {
30 6
        if ($attributes['scale'] > $attributes['precision']) {
31 1
            throw MappingException::forInvalidAttributeValue(
32 1
                'scale',
33 1
                $attributes['scale'],
34 1
                'Attribute `scale` must be lower than `precision`.'
35
            );
36
        }
37
38 5
        $parts = explode('.', $number);
39 5
        $decimals = $attributes['precision'] - $attributes['scale'];
40
41 5
        if (strlen($parts[0]) > $decimals) {
42 1
            $parts[0] = str_repeat('9', $decimals);
43
        }
44
45 5
        $number = $parts[0] . '.' . ($parts[1] ?? '');
46
47 5
        return bcadd($number, '0', $attributes['scale']);
48
    }
49
}
50