Completed
Pull Request — master (#359)
by Luc
06:39
created

parseSinglePriceDescription()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 38
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 23
nc 3
nop 1
1
<?php
2
3
namespace CultuurNet\UDB3\Cdb;
4
5
use CommerceGuys\Intl\Currency\CurrencyRepositoryInterface;
6
use CommerceGuys\Intl\Formatter\NumberFormatter;
7
use CommerceGuys\Intl\NumberFormat\NumberFormatRepositoryInterface;
8
use RuntimeException;
9
10
/**
11
 * Parses a cdbxml <pricedescription> string into name value pairs.
12
 */
13
class PriceDescriptionParser
14
{
15
    /**
16
     * @var NumberFormatRepositoryInterface
17
     */
18
    private $numberFormatRepository;
19
20
    /**
21
     * @var CurrencyRepositoryInterface
22
     */
23
    private $currencyRepository;
24
25
    /**
26
     * @var NumberFormatter
27
     */
28
    private $currencyFormatter;
29
30
    /**
31
     * @param \CommerceGuys\Intl\NumberFormat\NumberFormatRepositoryInterface $numberFormatRepository
32
     * @param \CommerceGuys\Intl\Currency\CurrencyRepositoryInterface $currencyRepository
33
     */
34
    public function __construct(
35
        NumberFormatRepositoryInterface $numberFormatRepository,
36
        CurrencyRepositoryInterface $currencyRepository
37
    ) {
38
        $this->numberFormatRepository = $numberFormatRepository;
39
        $this->currencyRepository = $currencyRepository;
40
    }
41
42
    /**
43
     * @param string $description
44
     *
45
     * @return array
46
     *   An array of price name value pairs.
47
     */
48
    public function parse($description)
49
    {
50
        $prices = array();
51
52
        $possiblePriceDescriptions = preg_split('/\s*;\s*/', $description);
53
54
        try {
55
            foreach ($possiblePriceDescriptions as $possiblePriceDescription) {
56
                $price = $this->parseSinglePriceDescription($possiblePriceDescription);
57
                $prices += $price;
58
            }
59
        } catch (RuntimeException $e) {
60
            $prices = array();
61
        }
62
63
        return $prices;
64
    }
65
66
    private function parseSinglePriceDescription($possiblePriceDescription)
67
    {
68
        $possiblePriceDescription = trim($possiblePriceDescription);
69
        $matches = [];
70
71
        $namePattern = '[\w\s]+';
72
        $valuePattern = '\€?\s*[\d,]+\s*\€?';
73
74
        $pricePattern =
75
            "/^(?<name>{$namePattern}):\s*(?<value>{$valuePattern})$/u";
76
77
        $priceDescriptionIsValid = preg_match(
78
            $pricePattern,
79
            $possiblePriceDescription,
80
            $matches
81
        );
82
83
        if (!$priceDescriptionIsValid) {
84
            throw new RuntimeException();
85
        }
86
87
        $priceName = trim($matches['name']);
88
        $priceValue = trim($matches['value']);
89
90
        $currencyFormatter = $this->getCurrencyFormatter();
91
        $currency = $this->currencyRepository->get('EUR');
92
93
        $priceValue = $currencyFormatter->parseCurrency(
94
            $priceValue,
95
            $currency
96
        );
97
98
        if (false === $priceValue) {
99
            throw new RuntimeException();
100
        }
101
102
        return [ $priceName => floatval($priceValue) ];
103
    }
104
105
    private function getCurrencyFormatter()
106
    {
107
        if (!$this->currencyFormatter) {
108
            $numberFormat = $this->numberFormatRepository->get('nl-BE');
109
            $this->currencyFormatter = new NumberFormatter(
110
                $numberFormat,
111
                NumberFormatter::CURRENCY
112
            );
113
        }
114
115
        return $this->currencyFormatter;
116
    }
117
}
118