Passed
Push — master ( d9cbe6...e3b2f0 )
by Radu
01:21
created

CurlBrowser::setMethod()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace WebServCo\Framework\Libraries;
3
4
use WebServCo\Framework\Http;
5
use WebServCo\Framework\Exceptions\ApplicationException;
6
use WebServCo\Framework\Interfaces\LoggerInterface;
7
8
final class CurlBrowser extends \WebServCo\Framework\AbstractLibrary implements
9
    \WebServCo\Framework\Interfaces\HttpBrowserInterface
10
{
11
    protected $method;
12
13
    protected $curl;
14
    protected $debugStderr;
15
    protected $debugOutput;
16
    protected $debugInfo;
17
    protected $response;
18
19
    protected $loggerInterface;
20
21
    public function setLogger(LoggerInterface $loggerInterface)
22
    {
23
        $this->loggerInterface = $loggerInterface;
24
    }
25
26
    public function get($url)
27
    {
28
        $this->setMethod(Http::METHOD_GET);
29
        return $this->retrieve($url);
30
    }
31
32
    public function post($url, $data = [])
33
    {
34
        $this->setMethod(Http::METHOD_POST);
35
        $this->setData('post', $data);
36
        return $this->retrieve($url);
37
    }
38
39
    protected function setMethod($method)
40
    {
41
        if (!in_array($method, Http::getMethods())) {
42
            throw new ApplicationException('Unsupported method');
43
        }
44
        $this->method = $method;
45
        return true;
46
    }
47
48
    protected function debugInit()
49
    {
50
        if ($this->setting('debug', true)) {
51
            ob_start();
52
            $this->debugStderr = fopen('php://output', 'w');
53
            return true;
54
        }
55
        return false;
56
    }
57
58
    protected function debugDo()
59
    {
60
        if ($this->setting('debug', true)) {
61
            //curl_setopt($this->curl, CURLINFO_HEADER_OUT, 1); /* verbose not working if this is enabled */
62
            curl_setopt($this->curl, CURLOPT_VERBOSE, 1);
63
            curl_setopt($this->curl, CURLOPT_STDERR, $this->debugStderr);
64
            return false;
65
        }
66
        return false;
67
    }
68
69
    protected function debugFinish()
70
    {
71
        if ($this->setting('debug', true)) {
72
            fclose($this->debugStderr);
73
            $this->debugOutput = ob_get_clean();
74
75
            if (!($this->loggerInterface instanceof LoggerInterface)) {
76
                throw new ApplicationException('No LoggerInterface specified');
77
            }
78
79
            $this->loggerInterface->debug('CURL INFO:', $this->debugInfo);
80
            $this->loggerInterface->debug('CURL VERBOSE:', $this->debugOutput);
81
            $this->loggerInterface->debug('CURL RESPONSE:', $this->response);
82
83
            return true;
84
        }
85
        return false;
86
    }
87
88
    protected function getHttpCode()
89
    {
90
        return isset($this->debugInfo['http_code']) ? $this->debugInfo['http_code']: false;
91
    }
92
93
    protected function parseResponseHeaders($headerString)
94
    {
95
        $headers = [];
96
        $lines = explode("\r\n", $headerString);
97
        foreach ($lines as $index => $line) {
98
            if (0 === $index) {
99
                continue; /* we'll get the status code elsewhere */
100
            }
101
            list($key, $value) = explode(': ', $line);
102
            $headers[$key] = $value;
103
        }
104
        return $headers;
105
    }
106
107
    protected function parseRequestHeaders($headers)
108
    {
109
        $data = [];
110
        foreach ($headers as $k => $v) {
111
            $data[] = sprintf('%s: %s', $k, $v);
112
        }
113
        return $data;
114
    }
115
116
    protected function retrieve($url)
117
    {
118
        $this->debugInit();
119
120
        $this->curl = curl_init();
121
        curl_setopt_array(
122
            $this->curl,
123
            [
124
                CURLOPT_RETURNTRANSFER => true, /* return instead of outputting */
125
                CURLOPT_URL => $url,
126
                CURLOPT_HEADER => true, /* include the header in the output */
127
                CURLOPT_FOLLOWLOCATION => true /* follow redirects */
128
            ]
129
        );
130
        if ($this->setting('headers', false)) {
131
            curl_setopt(
132
                $this->curl,
133
                CURLOPT_HTTPHEADER,
134
                $this->parseRequestHeaders($this->setting('headers'))
135
            );
136
        }
137
138
        $this->debugDo();
139
140
        if ($this->method == Http::METHOD_POST) {
141
            curl_setopt($this->curl, CURLOPT_POST, true);
142
            if ($this->data('post', [])) {
143
                curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->data('post', []));
144
            }
145
        }
146
147
        $this->response = curl_exec($this->curl);
148
        if (false === $this->response) {
149
            throw new ApplicationException(curl_error($this->curl));
150
        }
151
152
        $this->debugInfo = curl_getinfo($this->curl);
153
154
        $httpCode = $this->getHttpCode();
155
156
        curl_close($this->curl);
157
158
        list($headerString, $body) = explode("\r\n\r\n", $this->response, 2);
159
160
        $body = trim($body);
161
        $headers = $this->parseResponseHeaders($headerString);
162
163
        $this->debugFinish();
164
165
        return new \WebServCo\Framework\HttpResponse(
166
            $body,
167
            $httpCode,
168
            $headers
169
        );
170
    }
171
}
172