CurlHTTPClient   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 123
Duplicated Lines 34.15 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 21
lcom 1
cbo 6
dl 42
loc 123
rs 10
c 2
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
D request() 42 94 19

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * This file is part of Communique.
5
 * 
6
 * @author Robert Main
7
 * @package Communique
8
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Communique;
15
16
/**
17
 * CurlHTTP Client
18
 *
19
 * This class is used internally by the main client library for performing HTTP requests using cURl. This
20
 * HTTP client may be swapped out for another by passing a third argument to the library constructor.
21
 */
22
class CurlHTTPClient implements HTTPClient {
23
	/**
24
	 * A reference to the cURL wrapper we're using
25
	 * @var Object
26
	 */
27
	private $curl;
28
29
	/**
30
	 * Constructs the Curl HTTP adapter
31
	 * @param \Communique\Curl $curl A cURL object wrapper
32
	 */
33
	public function __construct(\Communique\Curl $curl = null) {
34
		if ($curl) {
35
			$this->curl = $curl;
36
		} else {
37
			//@codeCoverageIgnoreStart
38
			$this->curl = new \Communique\Curl();
39
			//@codeCoverageIgnoreEnd
40
		}
41
	}
42
43
	/**
44
	 * Make an HTTP request
45
	 * @param  \Communique\RESTClientRequest  $request  Request object
46
	 * @return \Communique\RESTClientResponse $response Response object
47
	 * @throws \Communique\CommuniqueRESTConnectionException This is thrown if cURL is unable to connect (this could be because the server is not available or the DNS record is not resolvable)
48
	 * @throws \Communique\CommuniqueRESTSSLException REST SSL exception. This is thrown for things such as SSL certificate errors or SSL handshake errors.
49
	 */
50
	public function request(\Communique\RESTClientRequest $request) {
51
		$headers = array();
52
		foreach ($request->headers as $header_key => $header_value) {
53
			$headers[] = $header_key . ': ' . $header_value;
54
		}
55
56
		$this->curl->setopt_array(array(
57
			CURLOPT_URL => $request->url,
58
			CURLOPT_RETURNTRANSFER => true,
59
			CURLOPT_HEADER => true,
60
			CURLOPT_HTTPHEADER => $headers
61
		));
62
63
		$this->curl->setopt(CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
64
65
		switch ($request->method) {
66 View Code Duplication
			case 'POST':
67
				$this->curl->setopt_array(
68
					array(
69
						CURLOPT_POST => true,
70
						CURLOPT_POSTFIELDS => $request->payload
71
					)
72
				);
73
			break;
74
75 View Code Duplication
			case 'PUT':
76
				$this->curl->setopt_array(
77
					array(
78
						CURLOPT_PUT => true,
79
						CURLOPT_POSTFIELDS => $request->payload
80
					)
81
				);
82
			break;
83
84 View Code Duplication
			case 'DELETE':
85
				if ($payload = http_build_query($request->payload)) {
86
					$payload = '?' . $payload;
87
				} else {
88
					$payload = '';
89
				}
90
				$this->curl->setopt_array(
91
					array(
92
						CURLOPT_CUSTOMREQUEST => 'DELETE',
93
						CURLOPT_URL => $request->url . $payload
94
					)
95
				);
96
			break;
97
98
			default:
99 View Code Duplication
			case 'GET':
100
				if ($payload = http_build_query($request->payload)) {
101
					$payload = '?' . $payload;
102
				} else {
103
					$payload = '';
104
				}
105
				$this->curl->setopt_array(
106
					array(
107
						CURLOPT_HTTPGET => true,
108
						CURLOPT_URL => $request->url . $payload
109
					)
110
				);
111
			break;
112
		}
113
		
114
		$raw_response = $this->curl->exec();
115
116
		if (!$raw_response) {
117
			$curl_error = $this->curl->errno();
118
			switch ($curl_error) {
119
				case CURLE_SSL_PEER_CERTIFICATE:
120
				case CURLE_SSL_ENGINE_NOTFOUND:
121
				case CURLE_SSL_ENGINE_SETFAILED:
122
				case CURLE_SSL_CERTPROBLEM:
123
				case CURLE_SSL_CIPHER:
124
				case CURLE_SSL_CACERT:
125
				case CURLE_SSL_CONNECT_ERROR:
126
					throw new \Communique\CommuniqueRESTSSLException('cURL SSL Error: ' . $this->curl->error() . ' cURL Error Code: ' . $curl_error);
127
128
				case CURLE_UNSUPPORTED_PROTOCOL:
129
				case CURLE_COULDNT_CONNECT:
130
				case CURLE_COULDNT_RESOLVE_HOST:
131
					throw new \Communique\CommuniqueRESTConnectionException('cURL Error: ' . $this->curl->error() . ' cURL Error Code: ' . $curl_error);
132
133
				default:
134
					throw new \Communique\CommuniqueRESTException('cURL Error: ' . $this->curl->error() . ' cURL Error Code: ' . $curl_error);
135
			}
136
		} else {
137
			return new \Communique\RESTClientResponse(
138
				$raw_response['http_status_code'],
139
				$raw_response['body'],
140
				$raw_response['headers']
141
			);
142
		}
143
	}
144
}