1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace AdrianMejias\FactomApi; |
4
|
|
|
|
5
|
|
|
class FactomConnector |
6
|
|
|
{ |
7
|
|
|
/** |
8
|
|
|
* The JSON RPC spec that the API uses. |
9
|
|
|
*/ |
10
|
|
|
const JSON_RPC = '2.0'; |
11
|
|
|
/** |
12
|
|
|
* The "ID" param provided in all requests to the API. |
13
|
|
|
*/ |
14
|
|
|
const REQUEST_ID = 0; |
15
|
|
|
/** |
16
|
|
|
* The header content type in all requests to the API. |
17
|
|
|
*/ |
18
|
|
|
const HEADER_CONTENT_TYPE = 'text/plain'; |
19
|
|
|
/** |
20
|
|
|
* The generic error if cannot load server properly. |
21
|
|
|
*/ |
22
|
|
|
const BLANK_PAGE_ERROR = 'Page not found'; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* The URL for all API requests. |
26
|
|
|
* |
27
|
|
|
* @var null|string |
28
|
|
|
*/ |
29
|
|
|
protected $url; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Make secure URL requests. |
33
|
|
|
* |
34
|
|
|
* @var null|bool |
35
|
|
|
*/ |
36
|
|
|
protected $ssl; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Path to the certificate file for using factomd over TLS. |
40
|
|
|
* |
41
|
|
|
* @var null |
42
|
|
|
*/ |
43
|
|
|
protected $certifcate; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* The provided username for interacting with factomd |
47
|
|
|
* Optional. |
48
|
|
|
* |
49
|
|
|
* @var null |
50
|
|
|
*/ |
51
|
|
|
protected $username; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* The provided password for interacting with factomd |
55
|
|
|
* Optional. |
56
|
|
|
* |
57
|
|
|
* @var null |
58
|
|
|
*/ |
59
|
|
|
protected $password; |
60
|
|
|
|
61
|
|
|
public function __construct(string $url, bool $ssl = false, string $certificate = null, string $username = null, string $password = null) |
62
|
|
|
{ |
63
|
|
|
$this->url = $url; |
64
|
|
|
$this->ssl = $ssl; |
65
|
|
|
$this->certificate = $certificate; |
|
|
|
|
66
|
|
|
$this->username = $username; |
|
|
|
|
67
|
|
|
$this->password = $password; |
|
|
|
|
68
|
|
|
|
69
|
|
|
if (! function_exists('curl_init')) { |
70
|
|
|
throw InvalidFactomApiConfig::noCurlFound(); |
71
|
|
|
} elseif (empty($this->url)) { |
72
|
|
|
throw InvalidFactomApiConfig::noUrlDefined(); |
73
|
|
|
} elseif (empty($this->certificate) && $this->ssl) { |
|
|
|
|
74
|
|
|
throw InvalidFactomApiConfig::noCertificateDefined(); |
75
|
|
|
} elseif (! empty($this->certificate) && $this->ssl) { |
|
|
|
|
76
|
|
|
if (preg_match('/^(https:\/\/)/i', $this->url)) { |
77
|
|
|
throw InvalidFactomApiConfig::noSecureUrlDefined(); |
78
|
|
|
} elseif (! file_exists($this->certificate)) { |
|
|
|
|
79
|
|
|
throw InvalidFactomApiConfig::noCertificateExists(); |
80
|
|
|
} |
81
|
|
|
} elseif (! empty($this->username) && empty($this->password)) { |
82
|
|
|
throw InvalidFactomApiConfig::noUsernameDefined(); |
83
|
|
|
} elseif (empty($this->username) && ! empty($this->password)) { |
84
|
|
|
throw InvalidFactomApiConfig::noPasswordDefined(); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
if (! $this->ssl) { |
88
|
|
|
$this->certificate = null; |
|
|
|
|
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Initialize the cURL request with all requested params. |
94
|
|
|
* |
95
|
|
|
* @param string $actionName |
96
|
|
|
* @param string $method |
97
|
|
|
* @param array $binaryDataParams |
98
|
|
|
* @param array $customOptions |
99
|
|
|
* @return array |
100
|
|
|
* @throws Exception - ensures we are passing in viable methods |
101
|
|
|
*/ |
102
|
|
|
private function gatherCurlOptions(string $actionName, string $method, array $binaryDataParams = [], array $customOptions = []) |
103
|
|
|
{ |
104
|
|
|
if (! in_array(strtoupper($method), ['GET', 'POST'])) { |
105
|
|
|
throw InvalidFactomApiConfig::invalidMethodCalled(); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
$options = [ |
109
|
|
|
CURLOPT_HTTPHEADER => [ |
110
|
|
|
'Content-Type: '.self::HEADER_CONTENT_TYPE, |
111
|
|
|
], |
112
|
|
|
CURLOPT_HEADER => false, |
113
|
|
|
CURLOPT_POSTFIELDS => json_encode([ |
114
|
|
|
'jsonrpc' => self::JSON_RPC, |
115
|
|
|
'id' => self::REQUEST_ID, |
116
|
|
|
'method' => $actionName, |
117
|
|
|
'params' => $binaryDataParams, |
118
|
|
|
]), |
119
|
|
|
CURLOPT_SSL_VERIFYHOST => 0, |
120
|
|
|
CURLOPT_SSL_VERIFYPEER => 0, |
121
|
|
|
// CURLOPT_URL => $this->url, |
|
|
|
|
122
|
|
|
CURLOPT_POST => strtoupper($method) == 'POST' ? 1 : 0, |
123
|
|
|
CURLOPT_RETURNTRANSFER => true, |
124
|
|
|
CURLOPT_TIMEOUT => 10, |
125
|
|
|
/* |
126
|
|
|
* Auth related cURL params |
127
|
|
|
*/ |
128
|
|
|
CURLOPT_USERPWD => ! empty($this->username) && ! empty($this->password) ? $this->username.':'.$this->password : false, |
129
|
|
|
CURLOPT_HTTPAUTH => ! empty($this->username) && ! empty($this->password) ? CURLAUTH_ANY : false, |
130
|
|
|
/* |
131
|
|
|
* Cert / SSL related cURL params |
132
|
|
|
*/ |
133
|
|
|
CURLOPT_SSL_VERIFYPEER => false, |
134
|
|
|
] + $customOptions; |
135
|
|
|
|
136
|
|
|
// return Result |
137
|
|
|
return $options; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Call the requested endpoint. |
142
|
|
|
* |
143
|
|
|
* @param string $actionName |
144
|
|
|
* @param array $binaryDataParams |
145
|
|
|
* @param array $curlOptions |
146
|
|
|
* |
147
|
|
|
* @return object|string |
148
|
|
|
* |
149
|
|
|
* @throws Exception When a cURL error occurs |
150
|
|
|
*/ |
151
|
|
|
public function callEndpoint(string $actionName, string $method, array $binaryDataParams = [], array $curlOptions = []) |
152
|
|
|
{ |
153
|
|
|
$curlOptions = $this->gatherCurlOptions($actionName, $method, $binaryDataParams, $curlOptions); |
154
|
|
|
|
155
|
|
|
$ch = curl_init($this->url); |
156
|
|
|
curl_setopt_array($ch, $curlOptions); |
157
|
|
|
$result = curl_exec($ch); |
158
|
|
|
$error = curl_error($ch); |
159
|
|
|
$info = curl_getinfo($ch); |
|
|
|
|
160
|
|
|
curl_close($ch); |
161
|
|
|
|
162
|
|
|
if (! $error && strtoupper($result) == strtoupper(self::BLANK_PAGE_ERROR)) { |
163
|
|
|
$error = self::BLANK_PAGE_ERROR; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
if ($error) { |
167
|
|
|
throw InvalidFactomApiConfig::invalidApiResponse($error, $actionName); |
168
|
|
|
} elseif (! $result) { |
169
|
|
|
throw InvalidFactomApiConfig::emptyApiResponse($actionName); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
$response = json_decode($result); |
173
|
|
|
|
174
|
|
|
if (is_object($response) && ! empty($response->result)) { |
175
|
|
|
return $response->result; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
if (is_object($response) && ! empty($response->error)) { |
179
|
|
|
return $response->error; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
// return Result |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
|
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.