Test Setup Failed
Push — master ( 0b55d7...07e840 )
by Andre
01:56
created

HttpClient::batch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 7
c 2
b 0
f 0
dl 0
loc 12
rs 10
cc 1
nc 1
nop 3
1
<?php
2
3
namespace TheIconic\Tracking\GoogleAnalytics\Network;
4
5
6
use Http\Discovery\MessageFactoryDiscovery;
7
use TheIconic\Tracking\GoogleAnalytics\AnalyticsResponse;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\ResponseInterface;
10
use Http\Client\HttpAsyncClient;
11
use Http\Discovery\HttpAsyncClientDiscovery;
12
use Http\Discovery\Psr17FactoryDiscovery;
13
use Http\Message\RequestFactory;
14
use Http\Promise\Promise;
15
16
/**
17
 * Class HttpClient
18
 *
19
 * @package TheIconic\Tracking\GoogleAnalytics
20
 */
21
class HttpClient
22
{
23
    /**
24
     * User agent for the client.
25
     */
26
    const PHP_GA_MEASUREMENT_PROTOCOL_USER_AGENT =
27
        'THE ICONIC GA Measurement Protocol PHP Client (https://github.com/theiconic/php-ga-measurement-protocol)';
28
29
    /**
30
     * Timeout in seconds for the request connection and actual request execution.
31
     * Using the same value you can find in Google's PHP Client.
32
     */
33
    const REQUEST_TIMEOUT_SECONDS = 100;
34
35
    /**
36
     * HTTP client.
37
     *
38
     * @var HttpAsyncClient
39
     */
40
    private $client;
41
42
    /**
43
     * @var RequestFactory
44
     */
45
    private $requestFactory = null;
46
47
    /**
48
     * Holds the promises (async responses).
49
     *
50
     * @var Promise[]
51
     */
52
    private static $promises = [];
53
54
    /**
55
     * Sets HTTP client.
56
     *
57
     * @internal
58
     * @param HttpAsyncClient $client
59
     */
60
    public function setClient(HttpAsyncClient $client)
61
    {
62
        $this->client = $client;
63
    }
64
65
    /**
66
     * Gets HTTP client for internal class use.
67
     *
68
     * @return HttpAsyncClient
69
     *
70
     * @throws \Http\Discovery\Exception\NotFoundException
71
     */
72
    private function getClient()
73
    {
74
        if ($this->client === null) {
75
            // @codeCoverageIgnoreStart
76
            $this->setClient(HttpAsyncClientDiscovery::find());
77
        }
78
        // @codeCoverageIgnoreEnd
79
80
        return $this->client;
81
    }
82
83
    /**
84
     * Sets HTTP request factory.
85
     *
86
     * @param $requestFactory
87
     *
88
     * @internal
89
     */
90
    public function setRequestFactory($requestFactory)
91
    {
92
        $this->requestFactory = $requestFactory;
93
    }
94
95
    /**
96
     * @return RequestFactory|null
97
     *
98
     * @throws \Http\Discovery\Exception\NotFoundException
99
     */
100
    private function getRequestFactory()
101
    {
102
        if (null === $this->requestFactory) {
103
            $this->setRequestFactory(MessageFactoryDiscovery::find());
104
        }
105
106
        return $this->requestFactory;
107
    }
108
109
    /**
110
     * Sends request to Google Analytics.
111
     *
112
     * @internal
113
     * @param string $url
114
     * @param array $options
115
     * @return AnalyticsResponse
116
     *
117
     * @throws \Exception If processing the request is impossible (eg. bad configuration).
118
     * @throws \Http\Discovery\Exception\NotFoundException
119
     */
120
    public function post($url, array $options = [])
121
    {
122
        $request = $this->getRequestFactory()->createRequest(
123
            'GET',
124
            $url,
125
            ['User-Agent' => self::PHP_GA_MEASUREMENT_PROTOCOL_USER_AGENT]
126
        );
127
128
        //return $this->getClient()->sendAsyncRequest($request, $options);
129
130
        return $this->sendRequest($request, $options);
131
    }
132
133
    /**
134
     * Sends batch request to Google Analytics.
135
     *
136
     * @internal
137
     * @param string $url
138
     * @param array $batchUrls
139
     * @param array $options
140
     * @return AnalyticsResponse
141
     */
142
    public function batch($url, array $batchUrls, array $options = [])
143
    {
144
        $body = implode(PHP_EOL, $batchUrls);
145
146
        $request = $this->getRequestFactory()->createReques(
0 ignored issues
show
Bug introduced by
The method createReques() does not exist on Http\Message\RequestFactory. Did you maybe mean createRequest()? ( Ignorable by Annotation )

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

146
        $request = $this->getRequestFactory()->/** @scrutinizer ignore-call */ createReques(

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...
147
            'POST',
148
            $url,
149
            ['User-Agent' => self::PHP_GA_MEASUREMENT_PROTOCOL_USER_AGENT],
150
            $body
151
        );
152
153
        return $this->sendRequest($request, $options);
154
    }
155
156
    private function sendRequest($request, array $options = [])
157
    {
158
        $opts = $this->parseOptions($options);
159
        $response = $this->getClient()->sendAsyncRequest($request);
160
161
        if ($opts['async']) {
162
            self::$promises[] = $response;
163
        } else {
164
            $response = $response->wait();
165
        }
166
167
        return $this->getAnalyticsResponse($request, $response);
168
    }
169
170
    /**
171
     * Parse the given options and fill missing fields with default values.
172
     *
173
     * @param array $options
174
     * @return array
175
     */
176
    private function parseOptions(array $options)
177
    {
178
        $defaultOptions = [
179
            'timeout' => static::REQUEST_TIMEOUT_SECONDS,
180
            'async' => false,
181
        ];
182
183
        $opts = [];
184
        foreach ($defaultOptions as $option => $value) {
185
            $opts[$option] = isset($options[$option]) ? $options[$option] : $defaultOptions[$option];
186
        }
187
188
        if (!is_int($opts['timeout']) || $opts['timeout'] <= 0) {
189
            throw new \UnexpectedValueException('The timeout must be an integer with a value greater than 0');
190
        }
191
192
        if (!is_bool($opts['async'])) {
193
            throw new \UnexpectedValueException('The async option must be boolean');
194
        }
195
196
        return $opts;
197
    }
198
199
    /**
200
     * Creates an analytics response object.
201
     *
202
     * @param RequestInterface $request
203
     * @param ResponseInterface|PromiseInterface $response
0 ignored issues
show
Bug introduced by
The type TheIconic\Tracking\Googl...etwork\PromiseInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
204
     * @return AnalyticsResponse
205
     */
206
    protected function getAnalyticsResponse(RequestInterface $request, $response)
207
    {
208
        return new AnalyticsResponse($request, $response);
209
    }
210
}