Completed
Pull Request — master (#15)
by Mischa
11:40 queued 04:07
created

Request::enableParameterValidation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
/**
4
 * This file is part of the PHP SDK library for the Superdesk Content API.
5
 *
6
 * Copyright 2015 Sourcefabric z.u. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2015 Sourcefabric z.ú.
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace Superdesk\ContentApiSdk\API;
16
17
use Superdesk\ContentApiSdk\API\Request\RequestInterface;
18
use Superdesk\ContentApiSdk\ContentApiSdk;
19
use Superdesk\ContentApiSdk\Exception\ResponseException;
20
use Superdesk\ContentApiSdk\Exception\RequestException;
21
use Superdesk\ContentApiSdk\Exception\InvalidArgumentException;
22
use Superdesk\ContentApiSdk\Exception\InvalidDataException;
23
24
/**
25
 * API Request object.
26
 */
27
class Request implements RequestInterface
28
{
29
    /**
30
     * Protocol for api request.
31
     *
32
     * @var string
33
     */
34
    protected $protocol = 'https';
35
36
    /**
37
     * Hostname for api request.
38
     *
39
     * @var string
40
     */
41
    protected $host;
42
43
    /**
44
     * Api port.
45
     *
46
     * @var int
47
     */
48
    protected $port = 80;
49
50
    /**
51
     * Request uri.
52
     *
53
     * @var string
54
     */
55
    protected $uri;
56
57
    /**
58
     * Parameters for request.
59
     *
60
     * @var mixed[]
61
     */
62
    protected $parameters = array();
63
64
    /**
65
     * Boolean for status of parameter handling. When set to true invalid
66
     * parameters will be cleaned out before being sent to the API.
67
     *
68
     * @var boolean
69
     */
70
    protected $cleanParameters = true;
71
72
    /**
73
     * A list of parameters the Content API accepts.
74
     *
75
     * For a list of accepted parameters find the variable allowed_params in
76
     * the following file:
77
     * https://github.com/superdesk/superdesk-content-api/blob/master/content_api/items/service.py
78
     *
79
     * @var string[]
80
     */
81
    protected $validParameters = array(
82
        'start_date', 'end_date', 'q', 'max_results', 'page',
83
        'include_fields', 'exclude_fields'
84
    );
85
86
    /**
87
     * Request headers.
88
     *
89
     * @var string[]
90
     */
91
    protected $headers = array();
92
93
    /**
94
     * Request options, usuably in clients, etc.
95
     *
96
     * @var mixed[]
97
     */
98
    protected $options = array();
99
100
    /**
101
     * Construct a request object.
102
     *
103
     * @param string $hostname Host name
104
     * @param string $uri Request uri
105
     * @param mixed[] $parameters Parameters
106
     * @param int $port Port
107
     */
108
    public function __construct($hostname = null, $uri = null, array $parameters = null, $port = null)
109
    {
110
        if (is_string($hostname) && !empty($hostname)) {
111
            $this->setHost($hostname);
112
        }
113
        if (is_string($uri) && !empty($uri)) {
114
            $this->setUri($uri);
115
        }
116
        if (!empty($parameters)) {
117
            $this->setParameters($parameters);
118
        }
119
        if (is_int($port)) {
120
            $this->setPort($port);
121
        }
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function getHost()
128
    {
129
        return $this->host;
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function setHost($host)
136
    {
137
        $this->host = $host;
138
139
        return $this;
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function getPort()
146
    {
147
        return $this->port;
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function setPort($port)
154
    {
155
        $this->port = $port;
156
157
        return $this;
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163
    public function getUri()
164
    {
165
        return $this->uri;
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function setUri($uri)
172
    {
173
        $this->uri = $uri;
174
175
        return $this;
176
    }
177
178
    /**
179
     * {@inheritdoc}
180
     */
181
    public function getParameters()
182
    {
183
        return $this->parameters;
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189
    public function setParameters(array $parameters)
190
    {
191
        try {
192
            $this->parameters = $this->processParameters($parameters, $this->cleanParameters);
193
        } catch (InvalidArgumentException $e) {
194
            throw new RequestException($e->getMessage(), $e->getCode(), $e);
195
        }
196
197
        return $this;
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     */
203
    public function getCleanParameters()
204
    {
205
        return $this->cleanParameters;
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211
    public function enableParameterCleaning()
212
    {
213
        $this->cleanParameters = true;
214
215
        return $this;
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function disableParameterCleaning()
222
    {
223
        $this->cleanParameters = false;
224
225
        return $this;
226
    }
227
228
    /**
229
     * {@inheritdoc}
230
     */
231
    public function getHeaders()
232
    {
233
        return $this->headers;
234
    }
235
236
    /**
237
     * {@inheritdoc}
238
     */
239
    public function setHeaders(array $headers)
240
    {
241
        $this->headers = $headers;
242
243
        return $this;
244
    }
245
246
    /**
247
     * {@inheritdoc}
248
     */
249
    public function getOptions()
250
    {
251
        return $this->options;
252
    }
253
254
    /**
255
     * {@inheritdoc}
256
     */
257
    public function setOptions(array $options)
258
    {
259
        $this->options = $options;
260
261
        return $this;
262
    }
263
264
    /**
265
     * {@inheritdoc}
266
     */
267
    public function getBaseUrl()
268
    {
269
        return sprintf('%s://%s:%s', $this->protocol, $this->host, $this->port);
270
    }
271
272
    /**
273
     * {@inheritdoc}
274
     */
275
    public function getFullUrl()
276
    {
277
        return sprintf('%s/%s?%s', $this->getBaseUrl(), trim($this->uri, '/ '), http_build_query($this->parameters));
278
    }
279
280
    /**
281
     * Type conversion method for parameters accepted by the API. Will
282
     * by default automatically unset invalid parameters, this behaviour can be
283
     * overridden with the second argument.
284
     *
285
     * @param  mixed[] $requestParameters Array of parameters
286
     * @param  boolean $unsetInvalidParameters Boolean to clean out invalid
287
     *                                         parameters
288
     *
289
     * @return mixed[] Returns an array of parameters with API safe types
290
     * @throws InvalidArgumentException When an invalid type is set for a
291
     *                                  valid parameter
292
     */
293
    public function processParameters(
294
        array $requestParameters,
295
        $unsetInvalidParameters = true
296
    ) {
297
        $processedParameters = $requestParameters;
298
299
        foreach ($requestParameters as $name => $value) {
300
301
            if ($unsetInvalidParameters && !in_array($name, $this->validParameters)) {
302
                unset($processedParameters[$name]);
303
                continue;
304
            }
305
306
            switch ($name) {
307
                case 'start_date':
308
                case 'end_date':
309
                        if (!is_string($value) && !($value instanceof \DateTime)) {
310
                            throw new InvalidArgumentException(sprintf('Parameter %s should be of type string or DateTime.', $name));
311
                        } elseif ($value instanceof \DateTime) {
312
                            $value = $value->format('Y-m-d');
313
                        } elseif (!preg_match('/\d\d\d\d\-\d\d\-\d\d/', $value)) {
314
                            throw new InvalidArgumentException(sprintf('Parameter %s has invalid format, please use dddd-dd-dd.', $name));
315
                        }
316
                    break;
317
                case 'q':
318
                        if (!is_string($value)) {
319
                            throw new InvalidArgumentException(sprintf('Parameter %s should be of type string.', $name));
320
                        }
321
                    break;
322
                case 'include_fields':
323
                case 'exclude_fields':
324
                        if (!is_string($value) && !is_array($value)) {
325
                            throw new InvalidArgumentException(sprintf('Parameter %s should be of type string or array.', $name));
326
                        } elseif (is_array($value)) {
327
                            $value = implode(',', $value);
328
                        }
329
                    break;
330
                case 'page':
331
                case 'max_results':
332
                        if (!is_int($value) && !ctype_digit($value)) {
333
                            throw new InvalidArgumentException(sprintf('Parameter %s should be of type integer.', $name));
334
                        } elseif (!is_int($value)) {
335
                            $value = (int) $value;
336
                        }
337
                    break;
338
            }
339
340
            $processedParameters[$name] = $value;
341
        }
342
343
        return $processedParameters;
344
    }
345
}
346