Completed
Pull Request — master (#15)
by Mischa
02:29
created

RequestParameters::validateDate()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 14
rs 8.8571
cc 5
eloc 8
nc 4
nop 1
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\Request;
16
17
use Superdesk\ContentApiSdk\Exception\InvalidArgumentException;
18
use DateTime;
19
20
/**
21
 * Request parameter class.
22
 */
23
class RequestParameters
24
{
25
    const DEFAULT_PAGE = 1;
26
    const DEFAULT_MAX_RESULTS = 25;
27
28
    /**
29
     * Start date.
30
     *
31
     * @var DateTime|null
32
     */
33
    protected $startDate;
34
35
    /**
36
     * End date.
37
     *
38
     * @var DateTime|null
39
     */
40
    protected $endDate;
41
42
    /**
43
     * Query for text search.
44
     *
45
     * @var string|null
46
     */
47
    protected $query;
48
49
    /**
50
     * Page.
51
     *
52
     * @var int
53
     */
54
    protected $page = self::DEFAULT_PAGE;
55
56
    /**
57
     * Max results per page.
58
     *
59
     * @var int
60
     */
61
    protected $maxResults = self::DEFAULT_MAX_RESULTS;
62
63
    /**
64
     * Include fields list. These fields will be set in your packages or items.
65
     *
66
     * @var array|null
67
     */
68
    protected $includeFields;
69
70
    /**
71
     * Exclude fields lists. These fields won't be set in your packages or items.
72
     *
73
     * @var array|null
74
     */
75
    protected $excludeFields;
76
77
    /**
78
     * Mapping array, which links correct parameter name for API with proper
79
     * method.
80
     *
81
     * @var string[]
82
     */
83
    protected $propertyMapping = array(
84
        'start_date' => 'getStartDate',
85
        'end_date' => 'getEndDate',
86
        'q' => 'getQuery',
87
        'page' => 'getPage',
88
        'max_results' => 'getMaxResults',
89
        'include_fields' => 'getIncludeFields',
90
        'exclude_fields' => 'getExcludeFields',
91
    );
92
93
    /**
94
     * Returns start date.
95
     *
96
     * @return DateTime|null
97
     */
98
    public function getStartDate()
99
    {
100
        return $this->startDate;
101
    }
102
103
    /**
104
     * Sets start date. Will accept a string formatted 'yyyy-mm-dd' or DateTime
105
     * object.
106
     *
107
     * @param string|DateTime|null $startDate
108
     *
109
     * @return self
110
     */
111
    public function setStartDate($startDate)
112
    {
113
        $this->setProperty('startDate', $startDate, 'validateDate');
0 ignored issues
show
Bug introduced by
It seems like $startDate defined by parameter $startDate on line 111 can also be of type null or object<DateTime>; however, Superdesk\ContentApiSdk\...rameters::setProperty() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
114
115
        return $this;
116
    }
117
118
    /**
119
     * Returns end date.
120
     *
121
     * @return DateTime|null
122
     */
123
    public function getEndDate()
124
    {
125
        return $this->endDate;
126
    }
127
128
    /**
129
     * Sets end date. Will accept string formatted 'yyyy-mm-dd' or DateTIme
130
     * object.
131
     *
132
     * @param string|DateTime|null $endDate
133
     *
134
     * @return self
135
     */
136
    public function setEndDate($endDate)
137
    {
138
        $this->setProperty('endDate', $endDate, 'validateDate');
0 ignored issues
show
Bug introduced by
It seems like $endDate defined by parameter $endDate on line 136 can also be of type null or object<DateTime>; however, Superdesk\ContentApiSdk\...rameters::setProperty() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
139
140
        return $this;
141
    }
142
143
    /**
144
     * Returns text query.
145
     *
146
     * @return string
147
     */
148
    public function getQuery()
149
    {
150
        return $this->query;
151
    }
152
153
    /**
154
     * Sets query parameters.
155
     *
156
     * @param string|null $query
157
     *
158
     * @return self
159
     */
160
    public function setQuery($query)
161
    {
162
        if (!is_string($query) && $query !== null) {
163
            throw new InvalidArgumentException('Parameter query should be of type string or null.');
164
        }
165
166
        $this->query = $query;
167
168
        return $this;
169
    }
170
171
    /**
172
     * Returns page number.
173
     *
174
     * @return int
175
     */
176
    public function getPage()
177
    {
178
        return $this->page;
179
    }
180
181
    /**
182
     * Sets page number. If null is supplied, resets to class default.
183
     *
184
     * @param int|null $page
185
     *
186
     * @return self
187
     */
188
    public function setPage($page)
189
    {
190
        if ($page === null) {
191
            $page = self::DEFAULT_PAGE;
192
        }
193
194
        $this->setProperty('page', $page, 'validateNumeric');
195
196
        return $this;
197
    }
198
199
    /**
200
     * Returns maximum results per page.
201
     *
202
     * @return int
203
     */
204
    public function getMaxResults()
205
    {
206
        return $this->maxResults;
207
    }
208
209
    /**
210
     * Sets maximum results per page. If null is supplied, resets to class
211
     * default.
212
     *
213
     * @param int|nul $maxResults
214
     *
215
     * @return self
216
     */
217
    public function setMaxResults($maxResults)
218
    {
219
        if ($maxResults === null) {
220
            $maxResults = self::DEFAULT_MAX_RESULTS;
221
        }
222
223
        $this->setProperty('maxResults', $maxResults, 'validateNumeric');
0 ignored issues
show
Bug introduced by
It seems like $maxResults can also be of type integer; however, Superdesk\ContentApiSdk\...rameters::setProperty() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
224
225
        return $this;
226
    }
227
228
    /**
229
     * Returns include fields.
230
     *
231
     * @return array
232
     */
233
    public function getIncludeFields()
234
    {
235
        return $this->includeFields;
236
    }
237
238
    /**
239
     * Sets include fields.
240
     *
241
     * @param array|null $includeFields
242
     *
243
     * @return self
244
     */
245
    public function setIncludeFields($includeFields)
246
    {
247
        $this->setProperty('includeFields', $includeFields, 'validateStringOrArray');
0 ignored issues
show
Documentation introduced by
$includeFields is of type array|null, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
248
249
        return $this;
250
    }
251
252
    /**
253
     * Gets exclude fields.
254
     *
255
     * @return array
256
     */
257
    public function getExcludeFields()
258
    {
259
        return $this->excludeFields;
260
    }
261
262
    /**
263
     * Sets exclude fields
264
     *
265
     * @param array|null
266
     *
267
     * @return self
268
     */
269
    public function setExcludeFields($excludeFields)
270
    {
271
        $this->setProperty('excludeFields', $excludeFields, 'validateStringOrArray');
272
273
        return $this;
274
    }
275
276
    /**
277
     * Validate date parameter input and converts to DateTime.
278
     *
279
     * @param  string|DateTime $date When string format yyyy-mm-dd should be used
280
     *
281
     * @return DateTime
282
     * @throws InvalidArgumentException
283
     */
284
    private function validateDate($date)
285
    {
286
        if (!is_string($date) && !($date instanceof \DateTime)) {
287
            throw new InvalidArgumentException('Parameter should be of type string or DateTime.');
288
        } elseif (is_string($date)) {
289
            if (!preg_match('/\d\d\d\d\-\d\d\-\d\d/', $date)) {
290
                throw new InvalidArgumentException('Parameter %s has invalid format, please use yyyy-mm-dd.');
291
            }
292
293
            $date = new DateTime($date);
294
        }
295
296
        return $date;
297
    }
298
299
    /**
300
     * Arguments of type string and array are valid. String will be split on ,
301
     * and converted to an array.
302
     *
303
     * @param  string|array $value
304
     *
305
     * @return array
306
     * @throws InvalidArgumentException
307
     */
308
    private function validateStringOrArray($value)
309
    {
310
        if (!is_string($value) && !is_array($value)) {
311
            throw new InvalidArgumentException('Parameter should be of type string or array.');
312
        } elseif (is_string($value)) {
313
            $value = array_map('trim', explode(',', $value));
314
        }
315
316
        return $value;
317
    }
318
319
    /**
320
     * Validates if value is numeric.
321
     *
322
     * @param  string|int $value
323
     *
324
     * @return int
325
     * @throws InvalidArgumentException
326
     */
327
    private function validateNumeric($value)
328
    {
329
        if (!is_int($value) && !ctype_digit($value)) {
330
            throw new InvalidArgumentException('Parameter should be of type integer.');
331
        } elseif (!is_int($value)) {
332
            $value = (int) $value;
333
        }
334
335
        return $value;
336
    }
337
338
    /**
339
     * Helper function for setting a property. Sets a proprety to a value, by
340
     * pulling it through a validator function. If null is specified as value
341
     * then property will be set to null as well..
342
     *
343
     * @param string $property Property name
344
     * @param string $value Value of the property
345
     * @param string $validator Name of the validator method
346
     *
347
     * @throws InvalidArgumentException
348
     */
349
    private function setProperty($property, $value, $validator)
350
    {
351
        if ($value !== null) {
352
            try {
353
                $this->$property = $this->$validator($value);
354
            } catch (InvalidArgumentException $e) {
355
                throw new InvalidArgumentException(sprintf('Invalid value for %s parameter.', $property), $e->getCode(), $e);
356
            }
357
        } else {
358
            $this->$property = null;
359
        }
360
    }
361
362
    /**
363
     * Returns all properties either as an array or http query string.
364
     *
365
     * @param  boolean $buildHttpQuery Build query from array
366
     *
367
     * @return mixed[]|string
368
     */
369
    public function getAllParameters($buildHttpQuery = false)
370
    {
371
        $httpQuery = array();
372
373
        foreach ($this->propertyMapping as $uriParameter => $method) {
374
375
            $value = $this->$method();
376
377
            if ($value instanceof DateTIme) {
378
                $value = $value->format('Y-m-d');
379
            }
380
381
            $httpQuery[$uriParameter] = $value;
382
        }
383
384
        return ($buildHttpQuery) ? http_build_query($httpQuery) : $httpQuery;
385
    }
386
}
387