CurrencyFactory::hasValidSymbol()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Adsmurai\Currency;
6
7
use Adsmurai\Currency\Contracts\Currency as CurrencyContract;
8
use Adsmurai\Currency\Contracts\CurrencyFactory as CurrencyFactoryContract;
9
use Adsmurai\Currency\Errors\InvalidCurrenciesDataError;
10
use Adsmurai\Currency\Errors\UnsupportedCurrencyISOCodeError;
11
12
final class CurrencyFactory implements CurrencyFactoryContract
13
{
14
    const DEFAULT_DATA_PATH = __DIR__.'/Data/CurrencyTypes.php';
15
16
    /** @var array */
17
    private $data;
18
19
    /** @var Currency[] */
20
    private $currencies;
21
22 128
    private function __construct(array $data)
23
    {
24 128
        $this->data = $data;
25 128
        $this->currencies = [];
26 128
    }
27
28 128
    public static function fromDataPath(string $dataPath = self::DEFAULT_DATA_PATH): CurrencyFactory
29
    {
30
        /** @var array $data */
31 128
        $data = include $dataPath;
32
33 128
        return self::fromDataArray($data);
34
    }
35
36 138
    public static function fromDataArray(array $data): CurrencyFactory
37
    {
38 138
        self::validateCurrenciesData($data);
39
40 128
        return new self($data);
41
    }
42
43
    /**
44
     * @param array $currenciesData
45
     *
46
     * @throws InvalidCurrenciesDataError
47
     */
48 138
    private static function validateCurrenciesData(array $currenciesData)
49
    {
50 138
        if (empty($currenciesData)) {
51 1
            throw new InvalidCurrenciesDataError();
52
        }
53
54 137
        foreach ($currenciesData as $ISOCode => $currencyData) {
55
            if (
56 137
                !self::hasValidISOCode($ISOCode)
57 137
                || !self::hasValidSymbol($currencyData)
58 137
                || !self::hasValidSymbolPlacement($currencyData)
59 137
                || !self::hasValidNumFractionalDigits($currencyData)
60
            ) {
61 9
                throw new InvalidCurrenciesDataError();
62
            }
63
        }
64 128
    }
65
66 128
    private static function hasValidISOCode($ISOCode): bool
67
    {
68 128
        return \is_string($ISOCode) && !empty($ISOCode);
69
    }
70
71 128
    private static function hasValidSymbol(array $currencyData): bool
72
    {
73
        return
74 128
            isset($currencyData['symbol'])
75 128
            && \is_string($currencyData['symbol'])
76 128
            && !empty($currencyData['symbol']);
77
    }
78
79 128
    private static function hasValidSymbolPlacement(array $currencyData): bool
80
    {
81
        return
82 128
            isset($currencyData['symbolPlacement'])
83 128
            && \is_int($currencyData['symbolPlacement'])
84 128
            && \in_array(
85 128
                $currencyData['symbolPlacement'],
86
                [
87 128
                    CurrencyContract::BEFORE_PLACEMENT,
88
                    CurrencyContract::AFTER_PLACEMENT,
89
                ]
90
            );
91
    }
92
93 128
    private static function hasValidNumFractionalDigits(array $currencyData): bool
94
    {
95 128
        return isset($currencyData['numFractionalDigits']) && \is_int($currencyData['numFractionalDigits']);
96
    }
97
98 129
    public function buildFromISOCode(string $ISOCode): CurrencyContract
99
    {
100 129
        if (!isset($this->data[$ISOCode])) {
101 1
            throw new UnsupportedCurrencyISOCodeError($ISOCode);
102
        }
103
104 128
        if (!isset($this->currencies[$ISOCode])) {
105 128
            $this->currencies[$ISOCode] = new Currency(
106 128
                $ISOCode,
107 128
                $this->data[$ISOCode]['symbol'],
108 128
                $this->data[$ISOCode]['numFractionalDigits'],
109 128
                $this->data[$ISOCode]['symbolPlacement'],
110 128
                (isset($this->data[$ISOCode]['name']) && !empty($this->data[$ISOCode]['name']))
111
                    ? $this->data[$ISOCode]['name']
112 128
                    : ''
113
            );
114
        }
115
116 128
        return $this->currencies[$ISOCode];
117
    }
118
119
    /** @return string[] */
120 1
    public function getSupportedCurrencyISOCodes(): array
121
    {
122 1
        return \array_keys($this->data);
123
    }
124
}
125