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 | use React\Http\Browser; |
||||
17 | use React\EventLoop\Factory; |
||||
18 | |||||
19 | /** |
||||
20 | * Class HttpClient |
||||
21 | * |
||||
22 | * @package TheIconic\Tracking\GoogleAnalytics |
||||
23 | */ |
||||
24 | class HttpClient |
||||
25 | { |
||||
26 | /** |
||||
27 | * User agent for the client. |
||||
28 | */ |
||||
29 | const PHP_GA_MEASUREMENT_PROTOCOL_USER_AGENT = |
||||
30 | 'THE ICONIC GA Measurement Protocol PHP Client (https://github.com/theiconic/php-ga-measurement-protocol)'; |
||||
31 | |||||
32 | /** |
||||
33 | * Timeout in seconds for the request connection and actual request execution. |
||||
34 | * Using the same value you can find in Google's PHP Client. |
||||
35 | */ |
||||
36 | const REQUEST_TIMEOUT_SECONDS = 100; |
||||
37 | |||||
38 | /** |
||||
39 | * HTTP client. |
||||
40 | * |
||||
41 | * @var Browser |
||||
42 | */ |
||||
43 | private $client; |
||||
44 | |||||
45 | /** |
||||
46 | * @var Factory |
||||
47 | */ |
||||
48 | private $requestFactory = null; |
||||
49 | |||||
50 | /** |
||||
51 | * Holds the promises (async responses). |
||||
52 | * |
||||
53 | * @var Promise[] |
||||
54 | */ |
||||
55 | private static $promises = []; |
||||
0 ignored issues
–
show
introduced
by
![]() |
|||||
56 | |||||
57 | /** |
||||
58 | * Sets HTTP client. |
||||
59 | * |
||||
60 | * @internal |
||||
61 | * @param Browser $client |
||||
62 | */ |
||||
63 | public function setClient(Browser $client) |
||||
64 | { |
||||
65 | $this->client = $client; |
||||
66 | } |
||||
67 | |||||
68 | /** |
||||
69 | * Gets HTTP client for internal class use. |
||||
70 | * |
||||
71 | * @return Browser |
||||
72 | * |
||||
73 | * @throws \Http\Discovery\Exception\NotFoundException |
||||
74 | */ |
||||
75 | private function getClient() |
||||
76 | { |
||||
77 | if ($this->client === null) { |
||||
78 | // @codeCoverageIgnoreStart |
||||
79 | //$loop = \React\EventLoop\Factory::create(); |
||||
80 | $this->setClient(new Browser($this->getRequestFactory())); |
||||
0 ignored issues
–
show
$this->getRequestFactory() of type React\EventLoop\Factory is incompatible with the type React\EventLoop\LoopInterface expected by parameter $loop of React\Http\Browser::__construct() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
81 | } |
||||
82 | // @codeCoverageIgnoreEnd |
||||
83 | |||||
84 | return $this->client; |
||||
85 | } |
||||
86 | |||||
87 | /** |
||||
88 | * Sets HTTP request factory. |
||||
89 | * |
||||
90 | * @param $requestFactory |
||||
91 | * |
||||
92 | * @internal |
||||
93 | */ |
||||
94 | public function setRequestFactory($requestFactory) |
||||
95 | { |
||||
96 | $this->requestFactory = $requestFactory; |
||||
97 | } |
||||
98 | |||||
99 | /** |
||||
100 | * @return Factory|null |
||||
101 | * |
||||
102 | * @throws \Http\Discovery\Exception\NotFoundException |
||||
103 | */ |
||||
104 | private function getRequestFactory() |
||||
105 | { |
||||
106 | if (null === $this->requestFactory) { |
||||
107 | $this->setRequestFactory(Factory::create()); |
||||
108 | } |
||||
109 | |||||
110 | return $this->requestFactory; |
||||
111 | } |
||||
112 | |||||
113 | /** |
||||
114 | * Sends request to Google Analytics. |
||||
115 | * |
||||
116 | * @internal |
||||
117 | * @param string $url |
||||
118 | * @param array $options |
||||
119 | * @return AnalyticsResponse |
||||
120 | * |
||||
121 | * @throws \Exception If processing the request is impossible (eg. bad configuration). |
||||
122 | * @throws \Http\Discovery\Exception\NotFoundException |
||||
123 | */ |
||||
124 | public function post($url, array $options = []) |
||||
125 | { |
||||
126 | |||||
127 | return $this->sendRequest($url, $options); |
||||
0 ignored issues
–
show
Are you sure the usage of
$this->sendRequest($url, $options) targeting TheIconic\Tracking\Googl...tpClient::sendRequest() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
128 | } |
||||
129 | |||||
130 | /** |
||||
131 | * Sends batch request to Google Analytics. |
||||
132 | * |
||||
133 | * @internal |
||||
134 | * @param string $url |
||||
135 | * @param array $batchUrls |
||||
136 | * @param array $options |
||||
137 | * @return AnalyticsResponse |
||||
138 | */ |
||||
139 | public function batch($url, array $batchUrls, array $options = []) |
||||
140 | { |
||||
141 | $body = implode(PHP_EOL, $batchUrls); |
||||
142 | |||||
143 | $request = $this->getRequestFactory()->createReques( |
||||
0 ignored issues
–
show
The method
createReques() does not exist on React\EventLoop\Factory . Did you maybe mean create() ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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. ![]() |
|||||
144 | 'POST', |
||||
145 | $url, |
||||
146 | ['User-Agent' => self::PHP_GA_MEASUREMENT_PROTOCOL_USER_AGENT], |
||||
147 | $body |
||||
148 | ); |
||||
149 | |||||
150 | return $this->sendRequest($request, $options); |
||||
0 ignored issues
–
show
Are you sure the usage of
$this->sendRequest($request, $options) targeting TheIconic\Tracking\Googl...tpClient::sendRequest() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
151 | } |
||||
152 | |||||
153 | private function sendRequest($request, array $options = []) |
||||
154 | { |
||||
155 | $opts = $this->parseOptions($options); |
||||
0 ignored issues
–
show
|
|||||
156 | $response = $this->getClient()->get( $request )->then( |
||||
0 ignored issues
–
show
|
|||||
157 | function ($request, ResponseInterface $response) { |
||||
158 | return $this->getAnalyticsResponse($request, $response); |
||||
159 | }); |
||||
160 | |||||
161 | $this->getRequestFactory()->run(); |
||||
0 ignored issues
–
show
The method
run() does not exist on React\EventLoop\Factory .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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. ![]() |
|||||
162 | |||||
163 | } |
||||
164 | |||||
165 | /** |
||||
166 | * Parse the given options and fill missing fields with default values. |
||||
167 | * |
||||
168 | * @param array $options |
||||
169 | * @return array |
||||
170 | */ |
||||
171 | private function parseOptions(array $options) |
||||
172 | { |
||||
173 | $defaultOptions = [ |
||||
174 | 'timeout' => static::REQUEST_TIMEOUT_SECONDS, |
||||
175 | 'async' => false, |
||||
176 | ]; |
||||
177 | |||||
178 | $opts = []; |
||||
179 | foreach ($defaultOptions as $option => $value) { |
||||
180 | $opts[$option] = isset($options[$option]) ? $options[$option] : $defaultOptions[$option]; |
||||
181 | } |
||||
182 | |||||
183 | if (!is_int($opts['timeout']) || $opts['timeout'] <= 0) { |
||||
184 | throw new \UnexpectedValueException('The timeout must be an integer with a value greater than 0'); |
||||
185 | } |
||||
186 | |||||
187 | if (!is_bool($opts['async'])) { |
||||
188 | throw new \UnexpectedValueException('The async option must be boolean'); |
||||
189 | } |
||||
190 | |||||
191 | return $opts; |
||||
192 | } |
||||
193 | |||||
194 | /** |
||||
195 | * Creates an analytics response object. |
||||
196 | * |
||||
197 | * @param RequestInterface $request |
||||
198 | * @param ResponseInterface|PromiseInterface $response |
||||
0 ignored issues
–
show
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. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
199 | * @return AnalyticsResponse |
||||
200 | */ |
||||
201 | protected function getAnalyticsResponse(RequestInterface $request, $response) |
||||
202 | { |
||||
203 | return new AnalyticsResponse($request, $response); |
||||
204 | } |
||||
205 | } |
||||
206 |