StatsHtmlScrapper   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 27
dl 0
loc 96
rs 10
c 0
b 0
f 0
ccs 24
cts 24
cp 1
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A offersFound() 0 3 3
A __construct() 0 8 1
A scrapModelStats() 0 14 1
A getAverageStats() 0 11 2
1
<?php
2
/**
3
 * File: StatsHtmlScrapper.php
4
 *
5
 * @author      Maciej Sławik <[email protected]>
6
 * Github:      https://github.com/maciejslawik
7
 */
8
9
namespace MSlwk\Otomoto\App\Stats\Scrapper;
10
11
use MSlwk\Otomoto\App\Exception\OffersNotFoundException;
12
use MSlwk\Otomoto\App\Stats\Data\StatsDTO;
13
use MSlwk\Otomoto\App\Stats\Data\StatsDTOInterface;
14
use MSlwk\Otomoto\App\Stats\Scrapper\Data\AverageDataScrapperInterface;
15
use Symfony\Component\DomCrawler\Crawler;
16
17
/**
18
 * Class StatsHtmlScrapper
19
 * @package MSlwk\Otomoto\App\Stats\Scrapper
20
 */
21
class StatsHtmlScrapper implements StatsHtmlScrapperInterface
22
{
23
    const HTML_OFFER_SELECTOR = 'article.offer-item.is-row';
24
25
    /**
26
     * @var AverageDataScrapperInterface
27
     */
28
    private $mileageScrapper;
29
30
    /**
31
     * @var AverageDataScrapperInterface
32
     */
33
    private $yearScrapper;
34
35
    /**
36
     * @var AverageDataScrapperInterface
37
     */
38
    private $priceScrapper;
39
40
    /**
41
     * @var array
42
     */
43
    private $mileages = [];
44
45
    /**
46
     * @var array
47
     */
48
    private $prices = [];
49
50
    /**
51
     * @var array
52
     */
53
    private $years = [];
54
55
    /**
56
     * StatsHtmlScrapper constructor.
57
     * @param AverageDataScrapperInterface $mileageScrapper
58
     * @param AverageDataScrapperInterface $yearScrapper
59
     * @param AverageDataScrapperInterface $priceScrapper
60
     */
61 3
    public function __construct(
62
        AverageDataScrapperInterface $mileageScrapper,
63
        AverageDataScrapperInterface $yearScrapper,
64
        AverageDataScrapperInterface $priceScrapper
65
    ) {
66 3
        $this->mileageScrapper = $mileageScrapper;
67 3
        $this->yearScrapper = $yearScrapper;
68 3
        $this->priceScrapper = $priceScrapper;
69 3
    }
70
71
    /**
72
     * @param string $html
73
     * @return StatsDTOInterface
74
     */
75 2
    public function scrapModelStats(string $html): StatsDTOInterface
76
    {
77 2
        $crawler = new Crawler($html);
78 2
        $carInstances = $crawler->filter(self::HTML_OFFER_SELECTOR);
79
80
        $carInstances->each(function (Crawler $crawler) use (&$mileages, &$prices, &$years) {
81 1
            $this->mileages[] = $this->mileageScrapper->getAverageData($crawler);
82 1
            $this->prices[] = $this->priceScrapper->getAverageData($crawler);
83 1
            $this->years[] = $this->yearScrapper->getAverageData($crawler);
84 2
        });
85
86 2
        $stats = $this->getAverageStats($this->mileages, $this->prices, $this->years);
87
88 1
        return $stats;
89
    }
90
91
    /**
92
     * @param $mileages
93
     * @param $prices
94
     * @param $years
95
     * @return StatsDTOInterface
96
     * @throws OffersNotFoundException
97
     */
98 2
    private function getAverageStats(array $mileages, array $prices, array $years): StatsDTOInterface
99
    {
100 2
        $stats = new StatsDTO();
101
102 2
        if (!$this->offersFound()) {
103 1
            throw new OffersNotFoundException('No offers were found');
104
        }
105 1
        $stats->setAverageMileage(array_sum($mileages) / count($mileages));
106 1
        $stats->setAveragePrice(array_sum($prices) / count($prices));
107 1
        $stats->setAverageYear(array_sum($years) / count($years));
108 1
        return $stats;
109
    }
110
111
    /**
112
     * @return bool
113
     */
114 2
    private function offersFound(): bool
115
    {
116 2
        return count($this->mileages) && count($this->prices) && count($this->years);
117
    }
118
}
119