|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace SugarAPI\SDK\Request\Abstracts; |
|
4
|
|
|
|
|
5
|
|
|
use SugarAPI\SDK\Request\Interfaces\RequestInterface; |
|
6
|
|
|
|
|
7
|
|
|
abstract class AbstractRequest implements RequestInterface { |
|
8
|
|
|
|
|
9
|
|
|
const STATUS_INIT = 'initialized'; |
|
10
|
|
|
const STATUS_SENT = 'sent'; |
|
11
|
|
|
const STATUS_CLOSED = 'closed'; |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* The HTTP Request Type |
|
15
|
|
|
* @var string |
|
16
|
|
|
*/ |
|
17
|
|
|
protected static $_TYPE = ''; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* The Default Curl Options |
|
21
|
|
|
* @var array |
|
22
|
|
|
*/ |
|
23
|
|
|
protected static $_DEFAULT_OPTIONS = array( |
|
24
|
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0, |
|
25
|
|
|
CURLOPT_HEADER => TRUE, |
|
26
|
|
|
CURLOPT_SSL_VERIFYPEER => 0, |
|
27
|
|
|
CURLOPT_RETURNTRANSFER => 1, |
|
28
|
|
|
CURLOPT_FOLLOWLOCATION => 0, |
|
29
|
|
|
CURLOPT_USERAGENT => 'SugarAPI-SDK-PHP' |
|
30
|
|
|
); |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* The default HTTP Headers to be added to Curl Request |
|
34
|
|
|
* @var array |
|
35
|
|
|
*/ |
|
36
|
|
|
protected static $_DEFAULT_HEADERS = array(); |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* The Curl Resource used to actually send data to Sugar API |
|
40
|
|
|
* @var - Curl Resource |
|
41
|
|
|
*/ |
|
42
|
|
|
protected $CurlResponse; |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* The raw response from curl_exec |
|
46
|
|
|
* @var - Curl Response |
|
47
|
|
|
*/ |
|
48
|
|
|
protected $CurlRequest; |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* List of Headers for Request |
|
52
|
|
|
* @var array |
|
53
|
|
|
*/ |
|
54
|
|
|
protected $headers = array(); |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* The body of the request or payload. JSON Encoded |
|
58
|
|
|
* @var string |
|
59
|
|
|
*/ |
|
60
|
|
|
protected $body = ''; |
|
61
|
|
|
|
|
62
|
|
|
/** |
|
63
|
|
|
* The URL the Request is sent to |
|
64
|
|
|
* @var string |
|
65
|
|
|
*/ |
|
66
|
|
|
protected $url = ''; |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* @var null |
|
70
|
|
|
*/ |
|
71
|
|
|
protected $status = NULL; |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* The Request Type |
|
75
|
|
|
* @var |
|
76
|
|
|
*/ |
|
77
|
|
|
protected $type; |
|
78
|
|
|
|
|
79
|
|
|
public function __construct($url = NULL){ |
|
80
|
|
|
$this->start(); |
|
81
|
|
|
if (!empty($url)){ |
|
82
|
|
|
$this->setURL($url); |
|
83
|
|
|
} |
|
84
|
|
|
$this->setType(); |
|
85
|
|
|
foreach (static::$_DEFAULT_OPTIONS as $option => $value){ |
|
86
|
|
|
$this->setOption($option, $value); |
|
87
|
|
|
} |
|
88
|
|
|
} |
|
89
|
|
|
|
|
90
|
|
|
/** |
|
91
|
|
|
* Always make sure to destroy Curl Resource |
|
92
|
|
|
*/ |
|
93
|
|
|
public function __destruct() { |
|
94
|
|
|
if ($this->status!==self::STATUS_CLOSED){ |
|
95
|
|
|
curl_close($this->CurlRequest); |
|
96
|
|
|
} |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
/** |
|
100
|
|
|
* @inheritdoc |
|
101
|
|
|
*/ |
|
102
|
|
|
public function setURL($url){ |
|
103
|
|
|
$this->url = $url; |
|
104
|
|
|
$this->setOption(CURLOPT_URL, $this->url); |
|
105
|
|
|
return $this; |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* @inheritdoc |
|
110
|
|
|
*/ |
|
111
|
|
|
public function getURL(){ |
|
112
|
|
|
return $this->url; |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* @inheritdoc |
|
117
|
|
|
*/ |
|
118
|
|
|
public function addHeader($name, $value){ |
|
119
|
|
|
$token = $name.": ".$value; |
|
120
|
|
|
$this->headers[] = $token; |
|
121
|
|
|
return $this; |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
/** |
|
125
|
|
|
* @inheritdoc |
|
126
|
|
|
*/ |
|
127
|
|
|
public function setHeaders(array $array = array()){ |
|
128
|
|
|
if (count($array)>0){ |
|
129
|
|
|
foreach ($array as $key => $value){ |
|
130
|
|
|
$this->addHeader($key, $value); |
|
131
|
|
|
} |
|
132
|
|
|
} |
|
133
|
|
|
$this->setOption(CURLOPT_HTTPHEADER, $this->headers); |
|
134
|
|
|
return $this; |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
/** |
|
138
|
|
|
* @inheritdoc |
|
139
|
|
|
*/ |
|
140
|
|
|
public function getHeaders(){ |
|
141
|
|
|
return $this->headers; |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
/** |
|
145
|
|
|
* @inheritdoc |
|
146
|
|
|
*/ |
|
147
|
|
|
public function setBody($body){ |
|
148
|
|
|
$this->body = $body; |
|
149
|
|
|
$this->setOption(CURLOPT_POSTFIELDS, $this->body); |
|
150
|
|
|
return $this; |
|
151
|
|
|
} |
|
152
|
|
|
|
|
153
|
|
|
/** |
|
154
|
|
|
* @inheritdoc |
|
155
|
|
|
*/ |
|
156
|
|
|
public function getBody(){ |
|
157
|
|
|
return $this->body; |
|
|
|
|
|
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
/** |
|
161
|
|
|
* @inheritdoc |
|
162
|
|
|
*/ |
|
163
|
|
|
public function getCurlObject(){ |
|
164
|
|
|
return $this->CurlRequest; |
|
|
|
|
|
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
/** |
|
168
|
|
|
* @inheritdoc |
|
169
|
|
|
*/ |
|
170
|
|
|
public function setOption($option, $value){ |
|
171
|
|
|
curl_setopt($this->CurlRequest, $option, $value); |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
/** |
|
175
|
|
|
* @inheritdoc |
|
176
|
|
|
*/ |
|
177
|
|
|
public function send(){ |
|
178
|
|
|
$this->setHeaders(); |
|
179
|
|
|
$this->CurlResponse = curl_exec($this->CurlRequest); |
|
180
|
|
|
$this->status = self::STATUS_SENT; |
|
|
|
|
|
|
181
|
|
|
return $this; |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
/** |
|
185
|
|
|
* @inheritdoc |
|
186
|
|
|
*/ |
|
187
|
|
|
public function getResponse(){ |
|
188
|
|
|
return $this->CurlResponse; |
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
/** |
|
192
|
|
|
* Set the Type on the Request |
|
193
|
|
|
*/ |
|
194
|
|
|
protected function setType(){ |
|
195
|
|
|
$this->type = static::$_TYPE; |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
/** |
|
199
|
|
|
* @inheritdoc |
|
200
|
|
|
*/ |
|
201
|
|
|
public function getType(){ |
|
202
|
|
|
return $this->type; |
|
203
|
|
|
} |
|
204
|
|
|
|
|
205
|
|
|
/** |
|
206
|
|
|
* @inheritdoc |
|
207
|
|
|
*/ |
|
208
|
|
|
public function reset(){ |
|
209
|
|
|
if (is_object($this->CurlRequest)){ |
|
210
|
|
|
$this->close(); |
|
211
|
|
|
} |
|
212
|
|
|
$this->start(); |
|
213
|
|
|
return $this; |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
/** |
|
217
|
|
|
* @inheritdoc |
|
218
|
|
|
*/ |
|
219
|
|
|
public function start(){ |
|
220
|
|
|
$this->CurlRequest = curl_init(); |
|
221
|
|
|
$this->status = self::STATUS_INIT; |
|
|
|
|
|
|
222
|
|
|
return $this; |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
/** |
|
226
|
|
|
* @inheritdoc |
|
227
|
|
|
*/ |
|
228
|
|
|
public function close(){ |
|
229
|
|
|
curl_close($this->CurlRequest); |
|
230
|
|
|
unset($this->CurlRequest); |
|
231
|
|
|
$this->status = self::STATUS_CLOSED; |
|
|
|
|
|
|
232
|
|
|
return $this; |
|
233
|
|
|
} |
|
234
|
|
|
|
|
235
|
|
|
/** |
|
236
|
|
|
* @inheritdoc |
|
237
|
|
|
*/ |
|
238
|
|
|
public function getCurlStatus(){ |
|
239
|
|
|
return $this->status; |
|
240
|
|
|
} |
|
241
|
|
|
} |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.