GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( e6f015...428290 )
by soheil
02:51
created

Connection::setConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 17
rs 9.9332
1
<?php
2
3
namespace Soheilrt\AdobeConnectClient\Client\Connection\Curl;
4
5
use CURLFile;
6
use InvalidArgumentException;
7
use Soheilrt\AdobeConnectClient\Client\Connection\ConnectionInterface;
8
use Soheilrt\AdobeConnectClient\Client\Connection\ResponseInterface;
9
use SplFileInfo;
10
use UnexpectedValueException;
11
12
/**
13
 * Connection using cURL.
14
 */
15
class Connection implements ConnectionInterface
16
{
17
    /**
18
     * @var array Associative array of Options
19
     */
20
    protected $config = [];
21
22
    /**
23
     * @var string The host URL
24
     */
25
    protected $host = '';
26
27
    /**
28
     * @var array [string => string[]] Simplify headers generation in cURL call
29
     */
30
    protected $headers = [];
31
32
    /**
33
     * Create the instance using a host URL and config.
34
     *
35
     * @param string $host   The Host URL
36
     * @param array  $config An array to config cURL. Use CURLOPT_* as index
37
     *
38
     * @throws InvalidArgumentException if $host is not a valid URL with scheme
39
     */
40
    public function __construct($host, array $config = [])
41
    {
42
        $this->setHost($host);
43
        $this->setConfig($config);
44
    }
45
46
    /**
47
     * Set the Host URL.
48
     *
49
     * @param string $host The Host URL
50
     *
51
     * @throws InvalidArgumentException if $host is not a valid URL with scheme
52
     */
53
    public function setHost($host): void
54
    {
55
        $host = filter_var(trim($host, " ?/\n\t"), FILTER_SANITIZE_URL);
56
57
        if (!filter_var($host, FILTER_VALIDATE_URL)) {
58
            throw new InvalidArgumentException('Connection Host must be a valid URL with scheme');
59
        }
60
        $this->host = strpos($host, '/api/xml') === false ? $host . '/api/xml' : $host;
61
    }
62
63
    /**
64
     * Set the cURL config.
65
     *
66
     * @param array $config Associative array. Items as Option => Value
67
     */
68
    protected function setConfig(array $config): void
69
    {
70
        //get default configuration value and merge them with user given values in case that user
71
        //if any of given values are missing from below were absent it'll use default config as given below
72
        $defaults = [
73
            CURLOPT_CONNECTTIMEOUT => 120,
74
            CURLOPT_TIMEOUT        => 120,
75
            CURLOPT_MAXREDIRS      => 10,
76
            CURLOPT_SSL_VERIFYPEER => true,
77
            CURLOPT_SSL_VERIFYHOST => 2,
78
        ];
79
        $this->config = $config + $defaults;
80
81
        // Always need this configurations
82
        $this->config[CURLOPT_RETURNTRANSFER] = true;
83
        $this->config[CURLOPT_FOLLOWLOCATION] = true;
84
        $this->config[CURLOPT_HEADERFUNCTION] = [$this, 'extractHeader'];
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function get(array $queryParams = []): ResponseInterface
91
    {
92
        $curl_resource = $this->prepareCurl($queryParams);
93
        return $this->makeCurlRequest($curl_resource);
94
    }
95
96
    /**
97
     * Reset the temporary headers and prepare the cURL.
98
     *
99
     * @param array $queryParams Associative array to add params in URL
100
     *
101
     * @return resource A cURL resource
102
     */
103
    protected function prepareCurl(array $queryParams = [])
104
    {
105
        $this->headers = [];
106
107
        $ch = curl_init($this->getFullURL($queryParams));
108
        curl_setopt_array($ch, $this->config);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt_array() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

108
        curl_setopt_array(/** @scrutinizer ignore-type */ $ch, $this->config);
Loading history...
109
110
        return $ch;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ch could also return false which is incompatible with the documented return type resource. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
111
    }
112
113
    /**
114
     * Get the full URL with query parameters.
115
     *
116
     * @param array $queryParams Associative array to add params in URL
117
     *
118
     * @return string
119
     */
120
    protected function getFullURL(array $queryParams): string
121
    {
122
        return empty($queryParams)
123
            ? $this->host
124
            : $this->host . '?' . http_build_query($queryParams, '', '&');
125
    }
126
127
    /**
128
     * @param $ch
129
     *
130
     * @return \Soheilrt\AdobeConnectClient\Client\Connection\Curl\Response
131
     */
132
    protected function makeCurlRequest($ch): Response
133
    {
134
        $body = curl_exec($ch);
135
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
136
137
        if ($body === false) {
138
            $exception = new UnexpectedValueException(curl_error($ch), curl_errno($ch));
139
            curl_close($ch);
140
141
            throw $exception;
142
        }
143
        curl_close($ch);
144
145
        return new Response($statusCode, $this->headers, new Stream($body));
0 ignored issues
show
Bug introduced by
It seems like $body can also be of type true; however, parameter $content of Soheilrt\AdobeConnectCli...l\Stream::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

145
        return new Response($statusCode, $this->headers, new Stream(/** @scrutinizer ignore-type */ $body));
Loading history...
146
    }
147
148
    /**
149
     * {@inheritdoc}
150
     */
151
    public function post(array $postParams, array $queryParams = []): ResponseInterface
152
    {
153
        $ch = $this->prepareCurl($queryParams);
154
        curl_setopt($ch, CURLOPT_POST, 1);
155
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->convertFileParams($postParams));
156
        return $this->makeCurlRequest($ch);
157
    }
158
159
    /**
160
     * Convert stream file and SplFileInfo in CURLFile.
161
     *
162
     * @param array $params Associative array of parameters
163
     *
164
     * @return array
165
     */
166
    protected function convertFileParams(array $params): array
167
    {
168
        foreach ($params as $param => $value) {
169
            $fileInfo = $this->fileInfo($value);
170
171
            if (empty($fileInfo)) {
172
                continue;
173
            }
174
            $params[$param] = new CURLFile($fileInfo['path'], $fileInfo['mime']);
175
        }
176
177
        return $params;
178
    }
179
180
    /**
181
     * Get the filepath and mime-type from a file.
182
     *
183
     * If it's a stream file or \SplFileInfo returns an object with path and mime.
184
     *
185
     * @param resource|SplFileInfo $item A stream file or SplFileInfo object
186
     *
187
     * @return array|null Returns null if it's not a valid stream file or SplFileInfo
188
     */
189
    protected function fileInfo($item): ?array
190
    {
191
        if (is_resource($item)) {
192
            $streamMeta = stream_get_meta_data($item);
193
194
            if ($streamMeta['wrapper_type'] !== 'plainfile') {
195
                return null;
196
            }
197
            $path = $streamMeta['uri'];
198
            $mime = mime_content_type($path);
199
        } elseif ($item instanceof SplFileInfo and $item->getType() === 'file') {
200
            $path = $item->getPathname();
201
            $mime = mime_content_type($path);
202
        } else {
203
            return null;
204
        }
205
206
        return [
207
            'path' => $path,
208
            'mime' => $mime,
209
        ];
210
    }
211
212
    /**
213
     * Extract header line and store it to posterior use.
214
     *
215
     * This method is called by option CURLOPT_HEADERFUNCTION.
216
     *
217
     * @param resource $curlResource
218
     * @param string   $headerLine
219
     *
220
     * @return int The size of header line
221
     */
222
    protected function extractHeader($curlResource, $headerLine): int
223
    {
224
        $headerSize = strlen($headerLine);
225
        $headerLine = trim($headerLine, " \t\n");
226
227
        if (empty($headerLine)) {
228
            return $headerSize;
229
        }
230
231
        $pos = strpos($headerLine, ':');
232
233
        if ($pos === false) {
234
            return $headerSize;
235
        }
236
237
        $header = trim(substr($headerLine, 0, $pos));
238
239
        if (!in_array($header, ['Set-Cookie', 'Content-Type'])) {
240
            return $headerSize;
241
        }
242
        $this->headers[$header] = [trim(substr($headerLine, $pos + 1))];
243
244
        return $headerSize;
245
    }
246
}
247