Failed Conditions
Pull Request — master (#316)
by
unknown
08:27
created

CurlAdapter::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 2
crap 2
1
<?php
2
/**
3
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 *
23
 */
24
25
namespace FacebookAds\Http\Adapter;
26
27
use FacebookAds\Exception\Exception;
28
use FacebookAds\Http\Adapter\Curl\AbstractCurl;
29
use FacebookAds\Http\Adapter\Curl\Curl;
30
use FacebookAds\Http\Adapter\Curl\CurlInterface;
31
use FacebookAds\Http\Client;
32
use FacebookAds\Http\Headers;
33
use FacebookAds\Http\RequestInterface;
34
use FacebookAds\Http\ResponseInterface;
35
36
class CurlAdapter extends AbstractAdapter {
37
38
  /**
39
   * @var CurlInterface
40
   */
41
  protected $curl;
42
43
  /**
44
   * @var \ArrayObject
45
   */
46
  protected $opts;
47
48
  /**
49
   * @param Client $client
50
   * @param CurlInterface $curl
51
   */
52 4
  public function __construct(Client $client, CurlInterface $curl = null) {
53 4
    parent::__construct($client);
54 4
    $this->curl = $curl ?: AbstractCurl::createOptimalVersion();
55 4
    $this->curl->init();
56 4
  }
57
58
  /**
59
   * @return Curl
60
   */
61 2
  public function getCurl() {
62 2
    return $this->curl;
63
  }
64
65
  /**
66
   * @return \ArrayObject
67
   */
68 2
  public function getOpts() {
69 2
    if ($this->opts === null) {
70 2
      $this->opts = new \ArrayObject(array(
71 2
        CURLOPT_CONNECTTIMEOUT => 10,
72 2
        CURLOPT_TIMEOUT => 60,
73 2
        CURLOPT_RETURNTRANSFER => true,
74 2
        CURLOPT_HEADER => true,
75 2
        CURLOPT_CAINFO => $this->getCaBundlePath(),
76
      ));
77
    }
78
79 2
    return $this->opts;
80
  }
81
82
  /**
83
   * @param \ArrayObject $opts
84
   */
85 1
  public function setOpts(\ArrayObject $opts) {
86 1
    $this->opts = $opts;
87 1
  }
88
89
  /**
90
   * @return int
91
   */
92 1
  protected function getheaderSize() {
93 1
    return $this->getCurl()->getInfo(CURLINFO_HEADER_SIZE);
94
  }
95
96
  /**
97
   * Extracts the headers and the body into a two-part array
98
   * @param string $raw_response
99
   * @return array
100
   */
101 1
  protected function extractResponseHeadersAndBody($raw_response) {
102 1
    $header_size = $this->getheaderSize();
103
104 1
    $raw_headers = mb_substr($raw_response, 0, $header_size);
105 1
    $raw_body = mb_substr($raw_response, $header_size);
106
107 1
    return array(trim($raw_headers), trim($raw_body));
108
  }
109
110
  /**
111
   * @param Headers $headers
112
   * @param string $raw_headers
113
   */
114 1
  protected function parseHeaders(Headers $headers, $raw_headers) {
115 1
    $raw_headers = str_replace("\r\n", "\n", $raw_headers);
116
117
    // There will be multiple headers if a 301 was followed
118
    // or a proxy was followed, etc
119 1
    $header_collection = explode("\n\n", trim($raw_headers));
120
    // We just want the last response (at the end)
121 1
    $raw_headers = array_pop($header_collection);
122
123 1
    $header_components = explode("\n", $raw_headers);
124 1
    foreach ($header_components as $line) {
125 1
      if (($delimeterPos = strpos($line, ': ')) === false) {
0 ignored issues
show
Coding Style introduced by
$delimeterPos does not seem to conform to the naming convention (^[a-z][a-z0-9]*(_[a-z0-9]+)*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
126 1
        $headers['http_code'] = $line;
127
      } else {
128 1
        $key = substr($line, 0, $delimeterPos);
0 ignored issues
show
Coding Style introduced by
$delimeterPos does not seem to conform to the naming convention (^[a-z][a-z0-9]*(_[a-z0-9]+)*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
129 1
        $value = substr($line, $delimeterPos + 1, strlen($line));
0 ignored issues
show
Coding Style introduced by
$delimeterPos does not seem to conform to the naming convention (^[a-z][a-z0-9]*(_[a-z0-9]+)*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
130 1
        $headers[$key] = trim($value);
131
      }
132
    }
133 1
  }
134
135
  /**
136
   * @param RequestInterface $request
137
   * @return ResponseInterface
138
   * @throws Exception
139
   */
140 1
  public function sendRequest(RequestInterface $request) {
141 1
    $response = $this->getClient()->createResponse();
142 1
    $this->getCurl()->reset();
143
    $curlopts = array(
144 1
      CURLOPT_URL => $request->getUrl(),
145
    );
146
147 1
    $method = $request->getMethod();
148 1
    if ($method !== RequestInterface::METHOD_GET
149 1
      && $method !== RequestInterface::METHOD_POST) {
150 1
      $curlopts[CURLOPT_CUSTOMREQUEST] = $method;
151
    }
152
153 1
    $curlopts = $this->getOpts()->getArrayCopy() + $curlopts;
154
155 1
    if ($request->getHeaders()->count()) {
156 1
      $headers = array();
157 1
      foreach ($request->getHeaders() as $header => $value) {
158 1
        $headers[] = "{$header}: {$value}";
159
      }
160 1
      $curlopts[CURLOPT_HTTPHEADER] = $headers;
161
    }
162
163 1
    $postfields = array();
164 1
    if ($method === RequestInterface::METHOD_POST
165 1
      && $request->getFileParams()->count()
166
    ) {
167 1
      $postfields = array_merge(
168
        $postfields,
169 1
        array_map(
170 1
          array($this->getCurl(), 'preparePostFileField'),
171 1
          $request->getFileParams()->getArrayCopy()));
172
    }
173 1
    if ($method !== RequestInterface::METHOD_GET
174 1
      && $request->getBodyParams()->count()) {
175
      $postfields
176 1
        = array_merge($postfields, $request->getBodyParams()->export());
177
    }
178
179 1
    if (!empty($postfields)) {
180 1
      $curlopts[CURLOPT_POSTFIELDS] = $postfields;
181
    }
182
183 1
    $this->getCurl()->setoptArray($curlopts);
184 1
    $raw_response = $this->getCurl()->exec();
185
186 1
    $status_code = $this->getCurl()->getInfo(CURLINFO_HTTP_CODE);
187 1
    $curl_errno = $this->getCurl()->errno();
188 1
    $curl_error = $curl_errno ? $this->getCurl()->error() : null;
189
190 1
    $response_parts = $this->extractResponseHeadersAndBody($raw_response);
191
192 1
    $response->setStatusCode($status_code);
193 1
    $this->parseHeaders($response->getHeaders(), $response_parts[0]);
194 1
    $response->setBody($response_parts[1]);
195
196 1
    if ($curl_errno) {
197 1
      throw new Exception($curl_error, $curl_errno);
198
    }
199
200 1
    return $response;
201
  }
202
}
203