Passed
Push — main ( 189a60...255c0f )
by Yevhenii
02:11
created

AbstractProvider   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 38
c 1
b 0
f 0
dl 0
loc 127
ccs 0
cts 38
cp 0
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A setUrl() 0 3 1
A doParseRequest() 0 21 4
A start() 0 12 3
A __construct() 0 7 2
A parseHtml() 0 21 2
A setParseRules() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SteamMarketProviders\ParserManager\Parser\Provider;
6
7
use PHPHtmlParser\Dom;
8
use PHPHtmlParser\Exceptions\ChildNotFoundException;
9
use PHPHtmlParser\Exceptions\CircularException;
10
use PHPHtmlParser\Exceptions\ContentLengthException;
11
use PHPHtmlParser\Exceptions\LogicalException;
12
use PHPHtmlParser\Exceptions\NotLoadedException;
13
use PHPHtmlParser\Exceptions\StrictException;
14
use SteamMarketProviders\ParserManager\Builder\ParseRulesBuilder;
15
use SteamMarketProviders\ParserManager\Contract\StrategyInterface;
16
use SteamMarketProviders\ParserManager\Contract\UrlBuilderInterface;
17
use SteamMarketProviders\ParserManager\Exception\HttpException;
18
use SteamMarketProviders\ParserManager\Http\Strategy\GuzzleStrategy;
19
use Throwable;
20
21
abstract class AbstractProvider
22
{
23
    /**
24
     * @var ParseRulesBuilder|null
25
     */
26
    private null|ParseRulesBuilder $parseRulesBuilder = null;
27
28
    /**
29
     * @var UrlBuilderInterface|null
30
     */
31
    private null|UrlBuilderInterface $urlBuilder = null;
32
33
    /**
34
     * @var Dom
35
     */
36
    private Dom $dom;
37
38
    /**
39
     * @param StrategyInterface|null $strategy
40
     */
41
    public function __construct(private null|StrategyInterface $strategy = null)
42
    {
43
        if (!$this->strategy) {
44
            $this->strategy = new GuzzleStrategy();
45
        }
46
47
        $this->dom = new Dom();
48
    }
49
50
    /**
51
     * @param int $page
52
     * @return UrlBuilderInterface
53
     */
54
    abstract protected function createUrl(int $page): UrlBuilderInterface;
55
56
    /**
57
     * @return ParseRulesBuilder
58
     */
59
    abstract protected function createParseRules(): ParseRulesBuilder;
60
61
    /**
62
     * @param UrlBuilderInterface $urlBuilder
63
     * @return void
64
     */
65
    public function setUrl(UrlBuilderInterface $urlBuilder): void
66
    {
67
        $this->urlBuilder = $urlBuilder;
68
    }
69
70
    /**
71
     * @param ParseRulesBuilder $parseRulesBuilder
72
     * @return void
73
     */
74
    public function setParseRules(ParseRulesBuilder $parseRulesBuilder): void
75
    {
76
        $this->parseRulesBuilder = $parseRulesBuilder;
77
    }
78
79
    final public function start(int $page): array
80
    {
81
        if (!$this->urlBuilder) {
82
            $this->urlBuilder = $this->createUrl($page);
83
        }
84
85
        if (!$this->parseRulesBuilder) {
86
            $this->parseRulesBuilder = $this->createParseRules();
87
        }
88
89
        $response = $this->doParseRequest();
90
        return $this->parseHtml($response);
91
92
    }
93
94
    private function doParseRequest(): string
95
    {
96
        try {
97
            $response = $this->strategy->sendRequest($this->urlBuilder->build());
0 ignored issues
show
Bug introduced by
The method sendRequest() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
            /** @scrutinizer ignore-call */ 
98
            $response = $this->strategy->sendRequest($this->urlBuilder->build());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method build() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
            $response = $this->strategy->sendRequest($this->urlBuilder->/** @scrutinizer ignore-call */ build());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
98
99
            $code = $response->getStatus();
100
            if ($code !== 200) {
101
                throw new HttpException("");
102
            }
103
104
            $response = $response->getBody();
105
106
            if (!$response->success) {
0 ignored issues
show
Bug introduced by
The property success does not exist on string.
Loading history...
107
                throw new HttpException("");
108
            }
109
110
        } catch (Throwable $throwable) {
111
            throw new HttpException($throwable->getMessage());
112
        }
113
114
        return $response->results_html;
0 ignored issues
show
Bug introduced by
The property results_html does not exist on string.
Loading history...
115
    }
116
117
    /**
118
     * @param string $html
119
     * @return array
120
     * @throws ChildNotFoundException
121
     * @throws CircularException
122
     * @throws ContentLengthException
123
     * @throws LogicalException
124
     * @throws NotLoadedException
125
     * @throws StrictException
126
     */
127
    private function parseHtml(string $html): array
128
    {
129
        $this->dom->loadStr($html);
130
131
        $contents = $this->dom->find('.market_listing_row_link');
132
133
        $data = [];
134
135
        foreach ($contents as $row) {
136
            $link = $row->getAttribute('href');
137
            $name = $row->find('.market_listing_item_name_block > span');
138
            $prices = $row->find('.market_listing_their_price .normal_price span');
139
140
            $data[] = [
141
                'link'=> $link,
142
                'name' => $name->innerHtml,
143
                'price' => $prices->innerHtml
144
            ];
145
        }
146
147
        return $data;
148
    }
149
}
150