Completed
Branch 2.0-dev (d250b8)
by Jan-Petter
03:02
created

URI::__construct()   B

Complexity

Conditions 2
Paths 8

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 27
rs 8.8571
cc 2
eloc 20
nc 8
nop 3
1
<?php
2
namespace vipnytt\RobotsTxtParser;
3
4
use GuzzleHttp;
5
6
/**
7
 * Class ClientURI
8
 *
9
 * @package vipnytt\RobotsTxtParser\Client
10
 */
11
class URI extends Input
12
{
13
    const GUZZLE_HTTP_CONFIG = [
14
        'allow_redirects' => [
15
            'max' => self::MAX_REDIRECTS,
16
            'referer' => true,
17
            'strict' => true,
18
        ],
19
        'decode_content' => true,
20
        'headers' => [
21
            'Accept' => 'text/plain;q=1.0, text/*;q=0.8, */*;q=0.1',
22
            'Accept-Charset' => 'utf-8;q=1.0, *;q=0.1',
23
            'Accept-Encoding' => 'identity;q=1.0, *;q=0.1',
24
            'User-Agent' => 'RobotsTxtParser-VIPnytt/2.0 (+https://github.com/VIPnytt/RobotsTxtParser/blob/master/README.md)',
25
        ],
26
        'http_errors' => false,
27
        'verify' => true,
28
    ];
29
    /**
30
     * HTTP Status code
31
     * @var int
32
     */
33
    protected $statusCode;
34
    /**
35
     * Parent Client class
36
     * @var Input
37
     */
38
    private $client;
39
    /**
40
     * RequestClient timestamp
41
     * @var int
42
     */
43
    private $time;
44
    /**
45
     * Cache-Control max-age
46
     * @var int
47
     */
48
    private $maxAge;
49
    /**
50
     * Robots.txt contents
51
     * @var string
52
     */
53
    private $contents;
54
55
    /**
56
     * Robots.txt character encoding
57
     * @var string
58
     */
59
    private $encoding;
60
61
    /**
62
     * RequestClient constructor.
63
     *
64
     * @param string $baseUri
65
     * @param array $guzzleConfig
66
     * @param int|null $byteLimit
67
     */
68
    public function __construct($baseUri, array $guzzleConfig = [], $byteLimit = self::BYTE_LIMIT)
69
    {
70
        $baseUri = $this->urlBase($this->urlEncode($baseUri));
71
        try {
72
            $client = new GuzzleHttp\Client(
73
                array_merge_recursive(
74
                    self::GUZZLE_HTTP_CONFIG,
75
                    $guzzleConfig,
76
                    [
77
                        'base_uri' => $baseUri,
78
                    ]
79
                )
80
            );
81
            $response = $client->request('GET', self::PATH);
82
            $this->time = time();
83
            $this->statusCode = $response->getStatusCode();
84
            $this->contents = $response->getBody()->getContents();
85
            $this->encoding = $this->headerEncoding($response->getHeader('content-type'));
86
            $this->maxAge = $this->headerMaxAge($response->getHeader('cache-control'));
87
        } catch (GuzzleHttp\Exception\TransferException $e) {
88
            $this->statusCode = 523;
89
            $this->contents = '';
90
            $this->encoding = self::ENCODING;
91
            $this->maxAge = 0;
92
        }
93
        $this->client = parent::__construct($baseUri, $this->statusCode, $this->contents, $this->encoding, $byteLimit);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $this->client is correct as parent::__construct($bas...->encoding, $byteLimit) (which targets vipnytt\RobotsTxtParser\Input::__construct()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
94
    }
95
96
    /**
97
     * Content-Type encoding HTTP header
98
     *
99
     * @param array $headers
100
     * @return string
101
     */
102
    private function headerEncoding(array $headers)
103
    {
104
        if (($value = $this->parseHeader($headers, 'charset', ';')) !== false) {
105
            return $value;
106
        }
107
        return self::ENCODING;
108
    }
109
110
    /**
111
     * Client header
112
     *
113
     * @param array $headers
114
     * @param string $part
115
     * @param string $delimiter
116
     * @return string|false
117
     */
118
    private function parseHeader(array $headers, $part, $delimiter = ";")
119
    {
120
        foreach ($headers as $header) {
121
            $split = array_map('trim', mb_split($delimiter, $header));
122
            foreach ($split as $string) {
123 View Code Duplication
                if (mb_stripos($string, $part . '=') === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
                    return mb_split('=', $string, 2)[1];
125
                }
126
            }
127
        }
128
        return false;
129
    }
130
131
    /**
132
     * Cache-Control max-age HTTP header
133
     *
134
     * @param array $headers
135
     * @return int
136
     */
137
    private function headerMaxAge(array $headers)
138
    {
139
        if (($value = $this->parseHeader($headers, 'max-age', ',')) !== false) {
140
            return intval($value);
141
        }
142
        return 0;
143
    }
144
145
    /**
146
     * Base URI
147
     *
148
     * @return string
149
     */
150
    public function getBaseUri()
151
    {
152
        return $this->base;
153
    }
154
155
    /**
156
     * Status code
157
     *
158
     * @return int
159
     */
160
    public function getStatusCode()
161
    {
162
        return $this->statusCode;
163
    }
164
165
    /**
166
     * URL content
167
     *
168
     * @return string
169
     */
170
    public function getContents()
171
    {
172
        return $this->contents;
173
    }
174
175
    /**
176
     * Encoding
177
     *
178
     * @return string
179
     */
180
    public function getEncoding()
181
    {
182
        return $this->encoding;
183
    }
184
185
    /**
186
     * Next update timestamp
187
     *
188
     * @return int
189
     */
190
    public function nextUpdate()
191
    {
192
        return $this->time + self::CACHE_TIME;
193
    }
194
195
    /**
196
     * Valid until timestamp
197
     *
198
     * @return int
199
     */
200
    public function validUntil()
201
    {
202
        return $this->time + max(self::CACHE_TIME, $this->maxAge);
203
    }
204
205
    /**
206
     * Client class
207
     *
208
     * @return Input
209
     */
210
    public function getClientClass()
211
    {
212
        return $this->client;
213
    }
214
}
215