ModelOffersHtmlProvider::buildBaseUrl()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 3
dl 0
loc 14
rs 10
c 0
b 0
f 0
ccs 8
cts 8
cp 1
crap 2
1
<?php
2
/**
3
 * File: ModelOffersHtmlProvider.php
4
 *
5
 * @author      Maciej Sławik <[email protected]>
6
 * Github:      https://github.com/maciejslawik
7
 */
8
9
namespace MSlwk\Otomoto\App\Stats;
10
11
use MSlwk\Otomoto\App\Base\UrlPoviderInterface;
12
use MSlwk\Otomoto\App\Manufacturer\Data\ManufacturerDTOInterface;
13
use MSlwk\Otomoto\App\Manufacturer\Url\ManufacturerUrlSuffixProviderInterface;
14
use MSlwk\Otomoto\App\Model\Data\ModelDTOInterface;
15
use MSlwk\Otomoto\App\Model\Url\ModelUrlSuffixProviderInterface;
16
use MSlwk\Otomoto\App\Stats\Filter\FilterArray;
17
use MSlwk\Otomoto\App\Stats\Filter\FilterInterface;
18
use MSlwk\Otomoto\App\Stats\Pager\PagerInterface;
19
use MSlwk\Otomoto\Middleware\Webpage\Adapter\GETHandlerInterface;
20
use MSlwk\Otomoto\Middleware\Webpage\Data\UrlDTO;
21
use MSlwk\Otomoto\Middleware\Webpage\Data\UrlDTOArray;
22
use MSlwk\Otomoto\Middleware\Webpage\Data\WebpageDTOArray;
23
use MSlwk\Otomoto\Middleware\Webpage\Data\WebpageDTOInterface;
24
use MSlwk\Otomoto\Middleware\Webpage\Factory\GETHandlerAdapterFactoryInterface;
25
use Symfony\Component\DomCrawler\Crawler;
26
27
/**
28
 * Class ModelOffersHtmlProvider
29
 * @package MSlwk\Otomoto\App\Stats
30
 */
31
class ModelOffersHtmlProvider
32
{
33
    const HTML_PAGER_SELECTOR = 'ul.om-pager';
34
    const HTML_PAGER_ELEMENT_SELECTOR = 'span.page';
35
    const HTML_OFFER_LIST_SELECTOR = 'div.offers.list';
36
37
    /**
38
     * @var GETHandlerAdapterFactoryInterface
39
     */
40
    private $adapterFactory;
41
42
    /**
43
     * @var UrlPoviderInterface
44
     */
45
    private $urlPovider;
46
47
    /**
48
     * @var ManufacturerUrlSuffixProviderInterface
49
     */
50
    private $manufacturerUrlSuffixProvider;
51
52
    /**
53
     * @var ModelUrlSuffixProviderInterface
54
     */
55
    private $modelUrlSuffixProvider;
56
57
    /**
58
     * @var PagerInterface
59
     */
60
    private $pager;
61
62
    /**
63
     * @var GETHandlerInterface
64
     */
65
    private $GETAdapter;
66
67
    /**
68
     * ModelOffersHtmlProvider constructor.
69
     * @param GETHandlerAdapterFactoryInterface $adapterFactory
70
     * @param UrlPoviderInterface $urlPovider
71
     * @param ManufacturerUrlSuffixProviderInterface $manufacturerUrlSuffixProvider
72
     * @param ModelUrlSuffixProviderInterface $modelUrlSuffixProvider
73
     * @param PagerInterface $pager
74
     */
75 2
    public function __construct(
76
        GETHandlerAdapterFactoryInterface $adapterFactory,
77
        UrlPoviderInterface $urlPovider,
78
        ManufacturerUrlSuffixProviderInterface $manufacturerUrlSuffixProvider,
79
        ModelUrlSuffixProviderInterface $modelUrlSuffixProvider,
80
        PagerInterface $pager
81
    ) {
82 2
        $this->adapterFactory = $adapterFactory;
83 2
        $this->urlPovider = $urlPovider;
84 2
        $this->manufacturerUrlSuffixProvider = $manufacturerUrlSuffixProvider;
85 2
        $this->modelUrlSuffixProvider = $modelUrlSuffixProvider;
86 2
        $this->pager = $pager;
87 2
    }
88
89
    /**
90
     * @param ManufacturerDTOInterface $manufacturer
91
     * @param ModelDTOInterface $model
92
     * @param FilterArray $filters
93
     * @return string
94
     */
95 1
    public function getAllPagesHtml(
96
        ManufacturerDTOInterface $manufacturer,
97
        ModelDTOInterface $model,
98
        FilterArray $filters
99
    ): string {
100 1
        $baseUrl = $this->buildBaseUrl($manufacturer, $model, $filters);
101 1
        $this->GETAdapter = $this->adapterFactory->create();
102
103 1
        $baseUrlDTO = new UrlDTOArray(new UrlDTO($baseUrl));
104 1
        $baseWebpageDTO = $this->GETAdapter->getWebpages($baseUrlDTO)->current();
105
106 1
        $lastPage = $this->getLastPageNumber($baseWebpageDTO);
107 1
        $allPagesDTOs = new WebpageDTOArray();
108 1
        if ($lastPage >= 2) {
109 1
            $allPagesDTOs = $this->getNextPages($lastPage, $baseUrl);
110
        }
111 1
        $allPagesDTOs->add($baseWebpageDTO);
112
113 1
        $html = $this->extractOffersHtml($allPagesDTOs);
114
115 1
        return $html;
116
    }
117
118
    /**
119
     * @param ManufacturerDTOInterface $manufacturer
120
     * @param ModelDTOInterface $model
121
     * @param FilterArray $filters
122
     * @return string
123
     */
124 1
    private function buildBaseUrl(
125
        ManufacturerDTOInterface $manufacturer,
126
        ModelDTOInterface $model,
127
        FilterArray $filters
128
    ): string {
129 1
        $baseUrl = $this->urlPovider->getBaseUrl();
130 1
        $baseUrl .= $this->manufacturerUrlSuffixProvider->getUrlSuffix($manufacturer);
131 1
        $baseUrl .= $this->modelUrlSuffixProvider->getUrlSuffix($model);
132 1
        $baseUrl .= '?';
133
        /** @var FilterInterface $filter */
134 1
        foreach ($filters as $filter) {
135 1
            $baseUrl .= "{$filter->getName()}={$filter->getValue()}&";
136
        }
137 1
        return $baseUrl;
138
    }
139
140
    /**
141
     * @param WebpageDTOInterface $baseWebpageDTO
142
     * @return int
143
     */
144 1
    private function getLastPageNumber(WebpageDTOInterface $baseWebpageDTO): int
145
    {
146 1
        $crawler = new Crawler($baseWebpageDTO->getHtml());
147
        $pagerListItems = $crawler
148 1
            ->filter(self::HTML_PAGER_SELECTOR)
149 1
            ->filter(self::HTML_PAGER_ELEMENT_SELECTOR);
150 1
        $lastPagerItem = $pagerListItems->getNode($pagerListItems->count() - 2);
151 1
        return $lastPagerItem ? (int)$lastPagerItem->textContent : 0;
152
    }
153
154
    /**
155
     * @param int $lastPage
156
     * @param string $baseUrl
157
     * @return WebpageDTOArray
158
     */
159 1
    private function getNextPages(int $lastPage, string $baseUrl): WebpageDTOArray
160
    {
161 1
        $urlDTOs = new UrlDTOArray();
162 1
        for ($i = 2; $i <= $lastPage; $i++) {
163 1
            $urlDTO = new UrlDTO($baseUrl . $this->pager->getPagerParameter($i));
164 1
            $urlDTOs->add($urlDTO);
165
        }
166
167 1
        $allPagesDTOs = $this->GETAdapter->getWebpages($urlDTOs);
168 1
        return $allPagesDTOs;
169
    }
170
171
    /**
172
     * @param WebpageDTOArray $allPagesDTOs
173
     * @return string
174
     */
175 1
    private function extractOffersHtml(WebpageDTOArray $allPagesDTOs): string
176
    {
177 1
        $html = '';
178 1
        foreach ($allPagesDTOs as $pageDTO) {
179 1
            $crawler = new Crawler($pageDTO->getHtml());
180 1
            $offersList = $crawler->filter(self::HTML_OFFER_LIST_SELECTOR);
181 1
            if ($offersList->count()) {
182 1
                $html .= $offersList->html();
183
            }
184
        }
185 1
        return $html;
186
    }
187
}
188