Completed
Push — master ( ab4c83...c1a587 )
by Nikola
03:53
created

HtmlParser   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 12
c 4
b 0
f 0
lcom 1
cbo 2
dl 0
loc 156
ccs 62
cts 62
cp 1
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getRates() 0 8 2
A parseRow() 0 22 3
A __construct() 0 5 1
A parseHtml() 0 7 1
A extractRates() 0 58 4
A buildRate() 0 4 1
1
<?php
2
/*
3
 * This file is part of the Exchange Rate package, an RunOpenCode project.
4
 *
5
 * Implementation of exchange rate crawler for Banca Intesa Serbia, http://www.bancaintesa.rs.
6
 *
7
 * (c) 2017 RunOpenCode
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
namespace RunOpenCode\ExchangeRate\BancaIntesaSerbia\Parser;
13
14
use RunOpenCode\ExchangeRate\BancaIntesaSerbia\Enum\RateType;
15
use RunOpenCode\ExchangeRate\Contract\RateInterface;
16
use RunOpenCode\ExchangeRate\Model\Rate;
17
use RunOpenCode\ExchangeRate\BancaIntesaSerbia\Api;
18
use Symfony\Component\DomCrawler\Crawler;
19
20
/**
21
 * Class HtmlParser
22
 *
23
 * Parse HTML document with daily rates from Banca Intesa Serbia.
24
 *
25
 * @package RunOpenCode\ExchangeRate\BancaIntesaSerbia\Parser
26
 */
27
class HtmlParser
28
{
29
    /**
30
     * @var RateInterface[]
31
     */
32
    private $rates;
33
34
    /**
35
     * @var \DateTime
36
     */
37
    private $date;
38
39
    /**
40
     * @var string
41
     */
42
    private $html;
43
44
    /**
45
     * HtmlParser constructor.
46
     * @param $node string
47
     * @param $date \DateTime
48
     */
49 6
    public function __construct($node, \DateTime $date)
50
    {
51 6
        $this->html = $node;
52 6
        $this->date = $date;
53 6
    }
54
55
    /**
56
     * @return array|\RunOpenCode\ExchangeRate\Contract\RateInterface[]
57
     */
58 6
    public function getRates()
59
    {
60 6
        if (empty($this->rates)) {
61 6
            $this->rates = $this->parseHtml($this->html, $this->date);
62
        }
63
64 6
        return $this->rates;
65
    }
66
67
    /**
68
     * @param $html string
69
     * @param \DateTime $date
70
     * @return array
71
     */
72 6
    private function parseHtml($html, \DateTime $date)
73
    {
74 6
        $crawler = new Crawler($html);
75 6
        $crawler = $crawler->filter('table');
76
77 6
        return $this->extractRates($crawler, $date);
78
    }
79
80
    /**
81
     * @param Crawler $crawler
82
     * @param \DateTime $date
83
     * @return array
84
     */
85 6
    private function extractRates(Crawler $crawler, \DateTime $date)
86
    {
87 6
        $extractedRates = array();
88
89
        $crawler->filter('tr')->each(function (Crawler $node) use ($date, &$extractedRates) {
90
91 6
            $row = $this->parseRow($node);
92
93 6
            if (null !== $row) {
94
95 6
                $extractedRates[] = $this->buildRate(
96 6
                    $row[RateType::MEDIAN] / $row['unit'],
97 6
                    $row['currencyCode'],
98 6
                    RateType::MEDIAN,
99 6
                    $date
100
                );
101
102 6
                $extractedRates[] = $this->buildRate(
103 6
                    $row[RateType::FOREIGN_EXCHANGE_BUYING] / $row['unit'],
104 6
                    $row['currencyCode'],
105 6
                    RateType::FOREIGN_EXCHANGE_BUYING,
106 6
                    $date
107
                );
108
109 6
                $extractedRates[] = $this->buildRate(
110 6
                    $row[RateType::FOREIGN_EXCHANGE_SELLING] / $row['unit'],
111 6
                    $row['currencyCode'],
112 6
                    RateType::FOREIGN_EXCHANGE_SELLING,
113 6
                    $this->date
114
                );
115
116 6
                $extractedRates[] = $this->buildRate(
117 6
                    $row[RateType::FOREIGN_CASH_BUYING] / $row['unit'],
118 6
                    $row['currencyCode'],
119 6
                    RateType::FOREIGN_CASH_BUYING,
120 6
                    $this->date
121
                );
122
123 6
                $extractedRates[] = $this->buildRate(
124 6
                    $row[RateType::FOREIGN_CASH_SELLING] / $row['unit'],
125 6
                    $row['currencyCode'],
126 6
                    RateType::FOREIGN_CASH_SELLING,
127 6
                    $this->date
128
                );
129
            }
130 6
        });
131
132
        /**
133
         * @var Rate $rate
134
         */
135 6
        foreach ($extractedRates as $key => $rate){
136 6
            if (!$rate->getValue()) {
137 6
                unset($extractedRates[$key]);
138
            }
139
        }
140
141 6
        return $extractedRates;
142
    }
143
144
    /**
145
     * @param Crawler $crawler
146
     * @return array|null
147
     */
148 6
    private function parseRow(Crawler $crawler)
149
    {
150
        $currentRow = array(
151 6
            'currencyCode' => ''
152
        );
153
154 6
        $nodeValues = $crawler->filter('td')->each(function (Crawler $node) {
155 6
            return trim($node->text());
156 6
        });
157
158 6
        if (count($nodeValues)) {
159 6
            $currentRow['currencyCode'] = trim($nodeValues[1]);
160 6
            $currentRow['unit'] = (int) trim($nodeValues[2]);
161 6
            $currentRow[RateType::FOREIGN_EXCHANGE_BUYING] = (float) trim($nodeValues[3]);
162 6
            $currentRow[RateType::MEDIAN] = (float) trim($nodeValues[4]);
163 6
            $currentRow[RateType::FOREIGN_EXCHANGE_SELLING] = (float) trim($nodeValues[5]);
164 6
            $currentRow[RateType::FOREIGN_CASH_BUYING] = (float) trim($nodeValues[6]);
165 6
            $currentRow[RateType::FOREIGN_CASH_SELLING] = (float) trim($nodeValues[7]);
166
        }
167
168 6
        return strlen($currentRow['currencyCode']) === 3 ? $currentRow : null;
169
    }
170
171
    /**
172
     * @param $value
173
     * @param $currencyCode
174
     * @param $rateType
175
     * @param $date
176
     * @return Rate
177
     */
178 6
    private function buildRate($value, $currencyCode, $rateType, $date)
179
    {
180 6
        return new Rate(Api::NAME, $value, $currencyCode, $rateType, $date, 'RSD', new \DateTime('now'), new \DateTime('now') );
181
    }
182
}
183