Completed
Push — master ( c7c88d...7873ee )
by Mike
02:24
created

AbstractEntryPoint::setResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace SugarAPI\SDK\EntryPoint\Abstracts;
4
5
6
use SugarAPI\SDK\EntryPoint\Interfaces\EPInterface;
7
use SugarAPI\SDK\Exception\EntryPoint\InvalidURLException;
8
use SugarAPI\SDK\Exception\EntryPoint\RequiredDataException;
9
use SugarAPI\SDK\Exception\EntryPoint\RequiredOptionsException;
10
use SugarAPI\SDK\Response\Interfaces\ResponseInterface;
11
use SugarAPI\SDK\Request\Interfaces\RequestInterface;
12
13
abstract class AbstractEntryPoint implements EPInterface {
14
15
    /**
16
     * Whether or not Authentication is Required
17
     * @var bool
18
     */
19
    protected $_AUTH_REQUIRED = true;
20
21
    /**
22
     * The URL for the EntryPoint
23
     * - When configuring URL you define URL Parameters with $variables
24
     *      Examples:
25
     *          - Forecasts/$record_id
26
     * - $module Variable is a keyword to place the Module property into the URL
27
     *      Examples:
28
     *          - $module/$record
29
     * - Options property is used to replace variables in the order in which they are passed
30
     *
31
     * @var string
32
     */
33
    protected $_URL;
34
35
    /**
36
     * An array of Required Data properties that should be passed in the Request
37
     * @var array
38
     */
39
    protected $_REQUIRED_DATA = array();
40
41
    /**
42
     * The required type of Data to be given to the EntryPoint. If none, different types can be passed in.
43
     * @var string
44
     */
45
    protected $_DATA_TYPE;
46
47
    /**
48
     * The configured URL for the EntryPoint
49
     * @var string
50
     */
51
    protected $Url;
52
53
    /**
54
     * The initial URL passed into the EntryPoint
55
     * @var
56
     */
57
    protected $baseUrl;
58
59
    /**
60
     * The configured Module for the EntryPoint
61
     * @var string
62
     */
63
    protected $Module;
64
65
    /**
66
     * The passed in Options for the EntryPoint
67
     * - If $module variable is used in $_URL static property, then 1st option will be used as Module
68
     * @var array
69
     */
70
    protected $Options = array();
71
72
    /**
73
     * The data being passed to the API EntryPoint
74
     * @var mixed - array or Std Object
75
     */
76
    protected $Data;
77
78
    /**
79
     * The Request Object, used by the EntryPoint to submit the data
80
     * @var Object
81
     */
82
    protected $Request;
83
84
    /**
85
     * The Response Object, returned by the Request Object
86
     * @var Object
87
     */
88
    protected $Response;
89
90
    /**
91
     * Access Token for authentication
92
     * @var string
93
     */
94
    protected $accessToken;
95
96
97
    public function __construct($url,$options = array()){
98
        $this->baseUrl = $url;
99
100
        if (!empty($options)) {
101
            $this->setOptions($options);
102
        }elseif(!$this->requiresOptions()){
103
            $this->configureURL();
104
        }
105
    }
106
107
    /**
108
     * @inheritdoc
109
     */
110
    public function setOptions(array $options){
111
        $this->Options = $options;
112
        if ($this->verifyOptions()){
113
            $this->configureURL();
114
        }
115
        return $this;
116
    }
117
118
    /**
119
     * @inheritdoc
120
     * @throws RequiredDataException - When passed in data contains issues
121
     */
122
    public function setData($data){
123
        $this->Data = $data;
124
        if ($this->verifyData()) {
125
            $this->Request->setBody($data);
126
        }
127
        return $this;
128
    }
129
130
    /**
131
     * @inheritdoc
132
     */
133
    public function setAuth($accessToken) {
134
        if ($this->authRequired()){
135
            $this->accessToken = $accessToken;
136
            $this->Request->addHeader('OAuth-Token', $accessToken);
137
        }
138
        return $this;
139
    }
140
141
    /**
142
     * @inheritdoc
143
     * @throws InvalidURLException - When passed in URL contains $variables
144
     */
145
    public function setUrl($url) {
146
        $this->Url = $url;
147
        if ($this->verifyUrl()) {
148
            $this->Request->setURL($this->Url);
149
        }
150
        return $this;
151
    }
152
153
    /**
154
     * @inheritdoc
155
     */
156
    public function setRequest(RequestInterface $Request) {
157
        $this->Request = $Request;
158
        return $this;
159
    }
160
161
    /**
162
     * @inheritdoc
163
     */
164
    public function setResponse(ResponseInterface $Response) {
165
        $this->Response = $Response;
166
        return $this;
167
    }
168
169
    /**
170
     * @inheritdoc
171
     */
172
    public function getModule() {
173
        return $this->Module;
174
    }
175
176
    /**
177
     * @inheritdoc
178
     */
179
    public function getData(){
180
        return $this->Data;
181
    }
182
183
    /**
184
     * @inheritdoc
185
     */
186
    public function getUrl(){
187
        return $this->Url;
188
    }
189
190
    /**
191
     * @inheritdoc
192
     */
193
    public function getResponse(){
194
        return $this->Response;
195
    }
196
197
    /**
198
     * @inheritdoc
199
     */
200
    public function getRequest(){
201
        return $this->Request;
202
    }
203
204
    /**
205
     * @inheritdoc
206
     */
207
    public function execute($data = null){
208
        if ($data!==null){
209
            $this->configureData($data);
210
        }
211
        $this->Request->send();
212
        return $this;
213
    }
214
215
    /**
216
     * @inheritdoc
217
     */
218
    public function authRequired() {
219
        return $this->_AUTH_REQUIRED;
220
    }
221
222
    /**
223
     * Override function for configuring Default Values on some EntryPoints to allow for short hand
224
     */
225
    protected function configureData($data){
226
        if (!empty($this->_REQUIRED_DATA)&&is_array($data)){
227
            foreach($this->_REQUIRED_DATA as $property => $value){
228
                if (!isset($data[$property])){
229
                    $data[$property] = $value;
230
                }
231
            }
232
        }
233
        $this->setData($data);
234
    }
235
236
    /**
237
     * Configures the URL, by updating any variable placeholders in the URL property on the EntryPoint
238
     * - Replaces $module with $this->Module
239
     * - Replaces all other variables starting with $, with options in the order they were given
240
     */
241
    protected function configureURL(){
242
        $url = $this->_URL;
243
        if ($this->requiresOptions()) {
244
            $urlParts = explode("/", $this->_URL);
245
            $o = 0;
246
            foreach ($urlParts as $key => $part) {
247
                if (strpos($part, "$") !== FALSE) {
248
                    if (isset($this->Options[$o])) {
249
                        $urlParts[$key] = $this->Options[$o];
250
                        $o++;
251
                    }
252
                }
253
            }
254
            $url = implode($urlParts,"/");
255
        }
256
        $url = $this->baseUrl.$url;
257
        $this->setUrl($url);
258
    }
259
260
    /**
261
     * Verify if URL is configured properly
262
     * @return bool
263
     * @throws InvalidURLException
264
     */
265
    protected function verifyUrl(){
266
        $UrlArray = explode("?",$this->Url);
267
        if (strpos($UrlArray[0],"$") !== FALSE){
268
            throw new InvalidURLException(get_called_class(),"Configured URL is ".$this->Url);
269
        }
270
        return true;
271
    }
272
273
    /**
274
     * Verify URL variables have been removed, and that valid number of options were passed.
275
     * @return bool
276
     * @throws RequiredOptionsException
277
     */
278
    protected function verifyOptions(){
279
        $urlVarCount = substr_count($this->_URL,"$");
280
        $optionCount = 0;
281
        $optionCount += count($this->Options);
282
        if ($urlVarCount!==$optionCount){
283
            throw new RequiredOptionsException(get_called_class(),"URL requires $urlVarCount options.");
284
        }
285
        return true;
286
    }
287
288
    /**
289
     * Validate Required Data for the Request
290
     * @return bool
291
     * @throws RequiredDataException
292
     */
293
    protected function verifyData(){
294
        if (isset($this->_DATA_TYPE)||!empty($this->_DATA_TYPE)) {
295
            if (gettype($this->Data) !== $this->_DATA_TYPE) {
296
                throw new RequiredDataException(get_called_class(),"Valid DataType is {$this->_DATA_TYPE}");
297
            }
298
        }
299
        if (!empty($this->_REQUIRED_DATA)){
300
            $errors = array();
301
            foreach($this->_REQUIRED_DATA as $property => $defaultValue){
302
                if (!isset($this->Data[$property])){
303
                    $errors[] = $property;
304
                }
305
            }
306
            if (count($errors)>0){
307
                throw new RequiredDataException(get_called_class(),"Missing data for $errors");
308
            }
309
        }
310
        return true;
311
    }
312
313
    /**
314
     * Checks if EntryPoint URL contains requires Options
315
     * @return bool
316
     */
317
    protected function requiresOptions(){
318
        return strpos($this->_URL,"$") !== FALSE?TRUE:FALSE;
319
    }
320
321
}