GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 0c2a79...0011c3 )
by ignace
23:46
created

JSend::__set_state()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

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 2
nc 1
nop 1
1
<?php
2
3
namespace Carpediem\JSend;
4
5
use InvalidArgumentException;
6
use JsonSerializable;
7
use UnexpectedValueException;
8
9
/**
10
 * A Immutable Value Object Class to represent a JSend object
11
 */
12
class JSend implements JsonSerializable
13
{
14
    const STATUS_SUCCESS = 'success';
15
16
    const STATUS_ERROR = 'error';
17
18
    const STATUS_FAIL = 'fail';
19
20
    /**
21
     * JSend status
22
     *
23
     * @var string
24
     */
25
    protected $status;
26
27
    /**
28
     * JSend Data
29
     *
30
     * @var array
31
     */
32
    protected $data = [];
33
34
    /**
35
     * JSend Error Message
36
     *
37
     * @var string
38
     */
39
    protected $errorMessage = '';
40
41
    /**
42
     * JSend Error Code
43
     * @var int|null
44
     */
45
    protected $errorCode;
46
47
    /**
48
     * New Instance
49
     *
50
     * @param string $status
51
     * @param array  $data
52
     * @param string $errorMessage
53
     * @param int    $errorCode
54
     */
55
    public function __construct($status, array $data = null, $errorMessage = null, $errorCode = null)
56
    {
57
        $this->status = $this->filterStatus($status);
58
        $this->data = $data ?: [];
59
        $this->filterError($errorMessage, $errorCode);
60
    }
61
62
    /**
63
     * Filter and Validate the JSend Status
64
     *
65
     * @param string $status
66
     *
67
     * @throws UnexpectedValueException If the status value does not conform to JSend Spec.
68
     *
69
     * @return string
70
     */
71
    protected function filterStatus($status)
72
    {
73
        $res = [self::STATUS_SUCCESS => 1, self::STATUS_ERROR => 1, self::STATUS_FAIL => 1];
74
        if (isset($res[$status])) {
75
            return $status;
76
        }
77
78
        throw new UnexpectedValueException('The given status does not conform to Jsend specification');
79
    }
80
81
    /**
82
     * Filter and Validate the JSend Error properties
83
     *
84
     * @param string $errorMessage
85
     * @param int    $errorCode
86
     */
87
    protected function filterError($errorMessage, $errorCode)
88
    {
89
        if (self::STATUS_ERROR != $this->status) {
90
            return;
91
        }
92
93
        $this->errorMessage = $this->validateType('string', 'is_string', $errorMessage);
94
        if (!is_null($errorCode)) {
95
            $this->errorCode = $this->validateType('numeric', 'is_numeric', $errorCode);
96
        }
97
    }
98
99
    /**
100
     * Validate a Type
101
     *
102
     * @param string   $type
103
     * @param callable $func
104
     * @param mixed    $str
105
     *
106
     * @throws UnexpectedValueException If the data value does not conform to the specified type
107
     *
108
     * @return mixed
109
     */
110
    protected function validateType($type, callable $func, $str)
111
    {
112
        if ($func($str)) {
113
            return $str;
114
        }
115
116
        throw new UnexpectedValueException(sprintf(
117
            'Expected data to be a %s; received "%s"',
118
            $type,
119
            (is_object($str) ? get_class($str) : gettype($str))
120
        ));
121
    }
122
123
    /**
124
     * Returns the JSend status
125
     *
126
     * @return string
127
     */
128
    public function getStatus()
129
    {
130
        return $this->status;
131
    }
132
133
    /**
134
     * Returns the JSend data
135
     *
136
     * @return array
137
     */
138
    public function getData()
139
    {
140
        return $this->data;
141
    }
142
143
    /**
144
     * Returns the JSend error message
145
     *
146
     * @return string
147
     */
148
    public function getErrorMessage()
149
    {
150
        return $this->errorMessage;
151
    }
152
153
    /**
154
     * Returns the JSend error code
155
     *
156
     * @return int|null
157
     */
158
    public function getErrorCode()
159
    {
160
        return $this->errorCode;
161
    }
162
163
    /**
164
     * Returns true if the status is success
165
     *
166
     * @return bool
167
     */
168
    public function isSuccess()
169
    {
170
        return self::STATUS_SUCCESS === $this->status;
171
    }
172
173
    /**
174
     * Returns true if the status is fail
175
     *
176
     * @return bool
177
     */
178
    public function isFail()
179
    {
180
        return self::STATUS_FAIL === $this->status;
181
    }
182
183
    /**
184
     * Returns true if the status is error
185
     *
186
     * @return bool
187
     */
188
    public function isError()
189
    {
190
        return self::STATUS_ERROR === $this->status;
191
    }
192
193
    /**
194
     * @inheritdoc
195
     */
196
    public function __toString()
197
    {
198
        return json_encode($this, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
199
    }
200
201
    /**
202
     * @inheritdoc
203
     */
204
    public function jsonSerialize()
205
    {
206
        return $this->toArray();
207
    }
208
209
    /**
210
     * Transcode the JSend object into an array
211
     *
212
     * @return array
213
     */
214
    public function toArray()
215
    {
216
        $arr = ['status' => $this->status, 'data' => $this->data ?: null];
217
        if (self::STATUS_ERROR !== $this->status) {
218
            return $arr;
219
        }
220
221
        $arr['message'] = $this->errorMessage;
222
        if (!is_null($this->errorCode)) {
223
            $arr['code'] = $this->errorCode;
224
        }
225
226
        if (is_null($arr['data'])) {
227
            unset($arr['data']);
228
        }
229
230
        return $arr;
231
    }
232
233
    /**
234
     * @inheritdoc
235
     */
236
    public function __debugInfo()
237
    {
238
        return $this->toArray();
239
    }
240
241
    /**
242
     * Encode and Send the JSend object as an HTTP Response
243
     *
244
     * @param array $headers Optional headers to add to the response
245
     *
246
     * @return string
247
     */
248
    public function send(array $headers = [])
249
    {
250
        $headers = $this->filterHeaders($headers);
251
        $headers[] = 'Content-Type: application/json;charset=utf-8';
252
        foreach ($headers as $header) {
253
            header($header);
254
        }
255
        echo $this;
256
    }
257
258
    /**
259
     * Filter Submitted Headers
260
     *
261
     * @param array $headers a Collection of key/value headers
262
     *
263
     * @return array
264
     */
265
    protected function filterHeaders(array $headers)
266
    {
267
        $formattedHeaders = [];
268
        foreach ($headers as $name => $value) {
269
            $formattedHeaders[] = $this->validateHeaderName($name).': '.$this->validateHeaderValue($value);
270
        }
271
272
        return $formattedHeaders;
273
    }
274
275
    /**
276
     * Validate Header name
277
     *
278
     * @param string $name
279
     *
280
     * @throws InvalidArgumentException if the header name is invalid
281
     *
282
     * @return string
283
     */
284
    protected function validateHeaderName($name)
285
    {
286
        if (!preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $name)) {
287
            throw new InvalidArgumentException('Invalid header name');
288
        }
289
290
        return $name;
291
    }
292
293
    /**
294
     * Validate Header value
295
     *
296
     * @param string $value
297
     *
298
     * @throws InvalidArgumentException if the header value is invalid
299
     *
300
     * @return string
301
     */
302
    protected function validateHeaderValue($value)
303
    {
304
        if (preg_match("#(?:(?:(?<!\r)\n)|(?:\r(?!\n))|(?:\r\n(?![ \t])))#", $value)
305
            || preg_match('/[^\x09\x0a\x0d\x20-\x7E\x80-\xFE]/', $value)
306
        ) {
307
            throw new InvalidArgumentException('Invalid header value');
308
        }
309
310
        return $value;
311
    }
312
313
    /**
314
     * Returns an instance with the specified status.
315
     *
316
     * This method MUST retain the state of the current instance, and return
317
     * an instance that contains the specified status.
318
     *
319
     * @param string $status The status to use with the new instance.
320
     *
321
     * @return static A new instance with the specified status.
322
     */
323
    public function withStatus($status)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
324
    {
325
        if ($status === $this->status) {
326
            return $this;
327
        }
328
329
        return new static($status, $this->data, $this->errorMessage, $this->errorCode);
330
    }
331
332
    /**
333
     * Returns an instance with the specified data.
334
     *
335
     * This method MUST retain the state of the current instance, and return
336
     * an instance that contains the specified data.
337
     *
338
     * @param array $data The data to use with the new instance.
339
     *
340
     * @return static A new instance with the specified data.
341
     */
342
    public function withData(array $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
343
    {
344
        if ($data === $this->data) {
345
            return $this;
346
        }
347
348
        return new static($this->status, $data, $this->errorMessage, $this->errorCode);
349
    }
350
351
    /**
352
     * Returns an instance with the specified error message and error code.
353
     *
354
     * This method MUST retain the state of the current instance, and return
355
     * an instance that contains the specified error message and error code.
356
     *
357
     * @param string   $errorMessage The error message to use with the new instance.
358
     * @param int|null $errorCode    The error code to use with the new instance.
359
     *
360
     * @return static A new instance with the specified status.
361
     */
362
    public function withError($errorMessage, $errorCode = null)
363
    {
364
        if ($errorMessage == $this->errorMessage && $errorCode == $this->errorCode) {
365
            return $this;
366
        }
367
368
        return new static($this->status, $this->data, $errorMessage, $errorCode);
369
    }
370
371
    /**
372
     * Returns a successful JSend object with the specified data
373
     *
374
     * @param array $data The data to use with the new instance.
375
     *
376
     * @return static A new succesful instance with the specified data.
377
     */
378
    public static function success(array $data = [])
379
    {
380
        return new static(static::STATUS_SUCCESS, $data);
381
    }
382
383
    /**
384
     * Returns a failed JSend object with the specified data
385
     *
386
     * @param array $data The data to use with the new instance.
387
     *
388
     * @return static A new failed instance with the specified data.
389
     */
390
    public static function fail(array $data = [])
391
    {
392
        return new static(static::STATUS_FAIL, $data);
393
    }
394
395
    /**
396
     * Returns a error JSend object with the specified error message and error code.
397
     *
398
     * @param string   $errorMessage The error message to use with the new instance.
399
     * @param int|null $errorCode    The error code to use with the new instance.
400
     * @param array    $data         The optional data to use with the new instance.
401
     *
402
     * @return static A new failed instance with the specified data.
403
     */
404
    public static function error($errorMessage, $errorCode = null, $data = null)
405
    {
406
        return new static(static::STATUS_ERROR, $data, $errorMessage, $errorCode);
407
    }
408
409
    /**
410
     * Returns a new instance from a JSON string
411
     *
412
     * @param string $json    The string being decoded
413
     * @param int    $depth   User specified recursion depth.
414
     * @param int    $options Bitmask of JSON decode options
415
     *
416
     * @throws InvalidArgumentException If the string can not be decode
417
     *
418
     * @return static
419
     */
420
    public static function createFromString($json, $depth = 512, $options = 0)
421
    {
422
        $raw = json_decode($json, true, $depth, $options);
423
        if (JSON_ERROR_NONE !== json_last_error()) {
424
            throw new InvalidArgumentException(sprintf(
425
                'Unable to decode JSON to array in %s: %s',
426
                __CLASS__,
427
                json_last_error_msg()
428
            ));
429
        }
430
431
        return static::createFromArray($raw);
432
    }
433
434
    /**
435
     * @inheritdoc
436
     */
437
    public static function __set_state(array $properties)
438
    {
439
        return static::createFromArray($properties);
440
    }
441
442
    /**
443
     * Returns a new instance from an array
444
     *
445
     * @param array $arr The array to build a new JSend object with
446
     *
447
     * @return static
448
     */
449
    public static function createFromArray(array $arr)
450
    {
451
        $defaultValues = ['status' => null, 'data' => null, 'message' => null, 'code' => null];
452
        $arr = array_replace($defaultValues, array_intersect_key($arr, $defaultValues));
453
454
        return new static($arr['status'], $arr['data'], $arr['message'], $arr['code']);
455
    }
456
}
457