DownloadAbstract   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 13
c 0
b 0
f 0
lcom 1
cbo 4
dl 0
loc 133
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 2
A getClient() 0 4 1
A setClient() 0 4 1
A getSourceUri() 0 4 1
A setSourceUri() 0 6 1
A getUserAgent() 0 8 1
A getContent() 0 12 3
A loadContent() 0 20 3
1
<?php
2
declare(strict_types=1);
3
4
namespace Crossjoin\Browscap\Source;
5
6
use Crossjoin\Browscap\Browscap;
7
use Crossjoin\Browscap\Exception\SourceConditionNotSatisfiedException;
8
use Crossjoin\Browscap\Exception\SourceUnavailableException;
9
use GuzzleHttp\Client;
10
use GuzzleHttp\Exception\GuzzleException;
11
use Psr\Http\Message\StreamInterface;
12
13
/**
14
 * Class DownloadAbstract
15
 *
16
 * @package Crossjoin\Browscap\Source
17
 * @author Christoph Ziegenberg <[email protected]>
18
 * @link https://github.com/crossjoin/browscap
19
 */
20
abstract class DownloadAbstract
21
{
22
    /**
23
     * The format for the user agent to set for all requests made by the class
24
     */
25
    const USER_AGENT_FORMAT = '%libName %libVersion (%client)';
26
27
    /**
28
     * The URI to get the current Browscap data (in the configured format)
29
     *
30
     * @var string
31
     */
32
    protected $sourceUri;
33
34
    /**
35
     * @var Client
36
     */
37
    protected $client;
38
39
    /**
40
     * Download constructor.
41
     *
42
     * @param string $sourceUri
43
     * @param array $clientOptions
44
     *
45
     * @throws SourceConditionNotSatisfiedException
46
     */
47
    public function __construct(string $sourceUri, array $clientOptions = [])
48
    {
49
        // Set user agent
50
        if (!array_key_exists('headers', $clientOptions)) {
51
            $clientOptions['headers'] = [];
52
        }
53
        $clientOptions['headers']['User-Agent'] = $this->getUserAgent();
54
55
        $this->setClient(new Client($clientOptions));
56
        $this->setSourceUri($sourceUri);
57
    }
58
59
    /**
60
     * @return Client
61
     */
62
    public function getClient() : Client
63
    {
64
        return $this->client;
65
    }
66
67
    /**
68
     * @param Client $client
69
     */
70
    protected function setClient(Client $client)
71
    {
72
        $this->client = $client;
73
    }
74
75
    /**
76
     * @return string
77
     */
78
    public function getSourceUri() : string
79
    {
80
        return $this->sourceUri;
81
    }
82
83
    /**
84
     * @param string $sourceUri
85
     *
86
     * @return DownloadAbstract
87
     */
88
    protected function setSourceUri(string $sourceUri) : DownloadAbstract
89
    {
90
        $this->sourceUri = $sourceUri;
91
92
        return $this;
93
    }
94
95
    /**
96
     * @return string
97
     */
98
    protected function getUserAgent()
99
    {
100
        return str_replace(
101
            array('%libName', '%libVersion', '%client'),
102
            array('Crossjoin\Browscap', Browscap::VERSION, 'GuzzleHttp'),
103
            self::USER_AGENT_FORMAT
104
        );
105
    }
106
107
    /**
108
     * @inheritdoc
109
     *
110
     * @throws SourceUnavailableException
111
     * @throws \RuntimeException
112
     */
113
    public function getContent() : \Generator
114
    {
115
        $stream = $this->loadContent($this->getSourceUri());
116
117
        if ($stream->isReadable() === false) {
118
            throw new SourceUnavailableException('Source stream is not readable.', 1459162267);
119
        }
120
121
        while (($data = $stream->read(4096)) !== '') {
122
            yield $data;
123
        }
124
    }
125
126
    /**
127
     * @param $uri
128
     *
129
     * @return StreamInterface
130
     * @throws SourceUnavailableException
131
     */
132
    protected function loadContent($uri) : StreamInterface
133
    {
134
        try {
135
            $response = $this->getClient()->request('GET', $uri);
136
137
            // Check status code
138
            if ($response->getStatusCode() !== 200) {
139
                throw new SourceUnavailableException(
140
                    'HTTP error: ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase(),
141
                    1459162268
142
                );
143
            }
144
145
            return $response->getBody();
146
        } catch (GuzzleException $e) {
147
            throw new SourceUnavailableException(
148
                'Error loading the source, see previous exception for details.', 1459162269, $e
149
            );
150
        }
151
    }
152
}
153