• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlocati / PayWay / 5275990353

pending completion
5275990353

Pull #5

github

web-flow
Merge 189882e26 into 75d4050c4
Pull Request #5: Use separate method to build cURL options

35 of 35 new or added lines in 1 file covered. (100.0%)

1603 of 2139 relevant lines covered (74.94%)

1.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Http/Driver/Curl.php
1
<?php
2

3
namespace MLocati\PayWay\Http\Driver;
4

5
use MLocati\PayWay\Exception\NetworkUnavailable;
6
use MLocati\PayWay\Http\Driver;
7
use MLocati\PayWay\Http\Response;
8

9
class Curl implements Driver
10
{
11
    /**
12
     * {@inheritdoc}
13
     *
14
     * @see \MLocati\PayWay\Http\Driver::send()
15
     */
16
    public function send($url, $method, array $headers, $body = '')
17
    {
18
        $ch = function_exists('curl_init') ? curl_init() : '';
×
19
        if (!$ch) {
×
20
            throw new NetworkUnavailable('curl_init() failed');
×
21
        }
22
        try {
23
            $responseHeaders = [];
×
24
            $options = $this->buildCurlOptions(
×
25
                (string) $url,
×
26
                strtoupper($method),
×
27
                $this->serializeRequestHeaders($headers),
×
28
                (string) $body,
×
29
                $responseHeaders
×
30
            );
×
31
            if (!curl_setopt_array($ch, $options)) {
×
32
                throw new NetworkUnavailable($this->describeCurlError($ch, 'curl_setopt_array() failed: %s'));
×
33
            }
34
            $responseBody = curl_exec($ch);
×
35
            if ($responseBody === false) {
×
36
                throw new NetworkUnavailable($this->describeCurlError($ch, 'curl_exec() failed: %s'));
×
37
            }
38
            $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
×
39
        } finally {
40
            curl_close($ch);
×
41
        }
42

43
        return new Response($responseCode, $responseHeaders, $responseBody);
×
44
    }
45

46
    /**
47
     * @param string $url
48
     * @param string $method
49
     * @param string[] $requestHeaders
50
     * @param string $body
51
     *
52
     * @return array
53
     */
54
    protected function buildCurlOptions($url, $method, array $requestHeaders, $body, array &$responseHeaders)
55
    {
56
        $options = [
×
57
            CURLOPT_URL => $url,
×
58
            CURLOPT_FOLLOWLOCATION => true,
×
59
            CURLOPT_RETURNTRANSFER => true,
×
60
            CURLOPT_HEADERFUNCTION => function ($ch, $header) use (&$responseHeaders) {
×
61
                $this->collectResponseHeader($header, $responseHeaders);
×
62

63
                return strlen($header);
×
64
            },
×
65
        ];
×
66
        switch ($method) {
67
            case 'GET':
×
68
                $options[CURLOPT_HTTPGET] = true;
×
69
                break;
×
70
            case 'POST':
×
71
                $options[CURLOPT_POST] = true;
×
72
                break;
×
73
            case 'PUT':
×
74
                $options[CURLOPT_PUT] = true;
×
75
                break;
×
76
            case 'HEAD':
×
77
                $options[CURLOPT_NOBODY] = true;
×
78
                break;
×
79
            default:
80
                $options[CURLOPT_CUSTOMREQUEST] = $method;
×
81
                break;
×
82
        }
83
        if ($body !== '') {
×
84
            $options[CURLOPT_POSTFIELDS] = $body;
×
85
        }
86
        if ($requestHeaders !== []) {
×
87
            $options[CURLOPT_HTTPHEADER] = $requestHeaders;
×
88
        }
89

90
        return $options;
×
91
    }
92

93
    /**
94
     * @return string[]
95
     */
96
    protected function serializeRequestHeaders(array $headers)
97
    {
98
        $result = [];
×
99
        foreach ($headers as $key => $value) {
×
100
            if (is_array($value)) {
×
101
                foreach ($value as $item) {
×
102
                    $result[] = "{$key}: {$item}";
×
103
                }
104
            } else {
105
                $result[] = "{$key}: {$value}";
×
106
            }
107
        }
108

109
        return $result;
×
110
    }
111

112
    /**
113
     * @param string $header
114
     */
115
    protected function collectResponseHeader($header, array &$responseHeaders)
116
    {
117
        $match = null;
×
118
        $header = trim($header);
×
119
        if ($header === '') {
×
120
            return;
×
121
        }
122
        if (preg_match('/^(?<name>[^:]*?)\s*:\s*(?<value>.*)$/', $header, $match)) {
×
123
            $name = $match['name'];
×
124
            $value = $match['value'];
×
125
        } else {
126
            $name = $header;
×
127
            $value = '';
×
128
        }
129
        foreach (array_keys($responseHeaders) as $alreadyName) {
×
130
            if (strcasecmp($alreadyName, $name) === 0) {
×
131
                if (is_string($responseHeaders[$alreadyName])) {
×
132
                    $responseHeaders[$alreadyName] = [$responseHeaders[$alreadyName], $value];
×
133
                } else {
134
                    $responseHeaders[$alreadyName][] = $value;
×
135
                }
136
                break;
×
137
            }
138
        }
139
        $responseHeaders[$name] = $value;
×
140
    }
141

142
    /**
143
     * @param resource|\CurlHandle $ch
144
     * @param string $messagePattern
145
     *
146
     * @return string
147
     */
148
    protected function describeCurlError($ch, $messagePattern)
149
    {
150
        $errorMessage = curl_error($ch);
×
151
        $errorMessage = is_string($errorMessage) ? trim($errorMessage) : '';
×
152
        if ($errorMessage === '') {
×
153
            $errorCode = curl_errno($ch);
×
154
            if (!empty($errorCode)) {
×
155
                $errorMessage = "cURL error #{$errorCode}";
×
156
            }
157
        }
158
        if ($errorMessage === '') {
×
159
            $errorMessage = 'unknows error';
×
160
        }
161

162
        return sprintf($messagePattern, $errorMessage);
×
163
    }
164
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc