BitcoinMoneyParser   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 54
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 10
eloc 28
c 0
b 0
f 0
dl 0
loc 54
ccs 0
cts 28
cp 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B parse() 0 41 9
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the ngutech/bitcoin-interop project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace NGUtech\Bitcoin\Service;
10
11
use Money\Currencies;
12
use Money\Currency;
13
use Money\Exception\ParserException;
14
use Money\Money;
15
use Money\MoneyParser;
16
17
final class BitcoinMoneyParser implements MoneyParser
18
{
19
    private Currencies $currencies;
20
21
    public function __construct(Currencies $currencies)
22
    {
23
        $this->currencies = $currencies;
24
    }
25
26
    /**
27
     * @param string $money
28
     * @param null|Currency $forceCurrency
29
     */
30
    public function parse($money, $forceCurrency = null)
31
    {
32
        if (is_string($money) === false) {
0 ignored issues
show
introduced by
The condition is_string($money) === false is always false.
Loading history...
33
            throw new ParserException('Formatted raw money should be string, e.g. ₿0.1');
34
        }
35
36
        $regex = '/^(?<amount>-?(?<symbol>[₿฿Ƀ])?\d+(?:\.\d+)?)\s?(?<currency>BTC|XBT)?$/iu';
37
        if (!preg_match($regex, $money, $matches)) {
38
            throw new ParserException('Value cannot be parsed as Bitcoin.');
39
        }
40
41
        if (!isset($matches['symbol']) && !isset($matches['currency'])) {
42
            throw new ParserException('Value currency cannot be parsed as Bitcoin.');
43
        }
44
45
        $currency = $forceCurrency ?: new Currency(strtoupper($matches['currency'] ?? BitcoinCurrencies::BTC));
46
47
        $amount = preg_replace('/[₿฿Ƀ]/u', '', $matches['amount']);
48
        $subunit = $this->currencies->subunitFor($currency);
49
        $decimalSeparator = strpos($amount, '.');
50
51
        if (false !== $decimalSeparator) {
52
            $amount = rtrim($amount, '0');
53
            $lengthAmount = strlen($amount);
54
            $amount = str_replace('.', '', $amount);
55
            $amount .= str_pad('', ($lengthAmount - $decimalSeparator - $subunit - 1) * -1, '0');
56
        } else {
57
            $amount .= str_pad('', $subunit, '0');
58
        }
59
60
        if (substr($amount, 0, 1) === '-') {
61
            $amount = '-'.ltrim(substr($amount, 1), '0');
62
        } else {
63
            $amount = ltrim($amount, '0');
64
        }
65
66
        if ('' === $amount) {
67
            $amount = '0';
68
        }
69
70
        return new Money($amount, $currency);
71
    }
72
}
73