JsonUtility::decodeDates()   B
last analyzed

Complexity

Conditions 7
Paths 4

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 7.0368

Importance

Changes 0
Metric Value
cc 7
eloc 12
nc 4
nop 1
dl 0
loc 17
rs 8.2222
c 0
b 0
f 0
ccs 10
cts 11
cp 0.9091
crap 7.0368
1
<?php
2
3
/**
4
 * apparat/resource
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Resource
8
 * @subpackage  Apparat\Resource\Application
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Apparat\Resource\Application\Service;
38
39
/**
40
 * JsonUtility
41
 *
42
 * @package Apparat\Resource
43
 * @subpackage Apparat\Resource\Application
44
 */
45
class JsonUtility
46
{
47
    /**
48
     * Regular expression for matching ISO 8601 date representations
49
     *
50
     * @var string
51
     */
52
    const ISO_8601_DATE_REGEX = '~^
53
        (?P<year>[0-9][0-9][0-9][0-9])
54
        -(?P<month>[0-9][0-9]?)
55
        -(?P<day>[0-9][0-9]?)
56
        (?:(?:[Tt]|[ \t]+)
57
        (?P<hour>[0-9][0-9]?)
58
        :(?P<minute>[0-9][0-9])
59
        :(?P<second>[0-9][0-9])
60
        (?:\.(?P<fraction>[0-9]*))?
61
        (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
62
        (?::(?P<tz_minute>[0-9][0-9]))?))?)?
63
        $~x';
64
65
    /**
66
     * JSON encode data
67
     *
68
     * @param mixed $data Data
69
     * @return string JSON string
70
     */
71 3
    public static function encode($data)
72
    {
73 3
        return json_encode(self::encodeDates($data), JSON_PRETTY_PRINT);
74
    }
75
76
    /**
77
     * Recursively encode DateTime objects to ISO 8601 date strings
78
     *
79
     * @param mixed $data Data
80
     * @return mixed Data with encoded ISO 8601 dates
81
     */
82 3
    protected static function encodeDates($data)
83
    {
84
        switch (true) {
85 3
            case $data instanceof \DateTimeInterface:
86 1
                return $data->format('c');
87
            case $data instanceof \stdClass:
88 1
                foreach (get_object_vars($data) as $key => $value) {
89 1
                    $data->$key = self::encodeDates($value);
90
                }
91 1
                break;
92 3
            case is_array($data):
93 3
                foreach ($data as $key => $value) {
94 3
                    $data[$key] = self::encodeDates($value);
95
                }
96
        }
97 3
        return $data;
98
    }
99
100
    /**
101
     * JSON decode a string
102
     *
103
     * @param string $str JSON string
104
     * @param bool $assoc Decode objects to associative arrays
105
     * @return mixed Decoded data
106
     */
107 5
    public static function decode($str, $assoc = false)
108
    {
109 5
        return self::decodeDates(json_decode($str, $assoc));
110
    }
111
112
    /**
113
     * Recursively decode ISO 8601 dates to DateTimeImmutable objects
114
     *
115
     * @param mixed $data Data
116
     * @return mixed Data with decoded ISO 8601 dates
117
     */
118 5
    protected static function decodeDates($data)
119
    {
120
        switch (true) {
121 5
            case is_string($data) && preg_match(self::ISO_8601_DATE_REGEX, $data):
122 2
                return new \DateTimeImmutable($data);
123
            case $data instanceof \stdClass:
124 1
                foreach (get_object_vars($data) as $key => $value) {
125 1
                    $data->$key = self::decodeDates($value);
126
                }
127 1
                break;
128 5
            case is_array($data):
129 5
                foreach ($data as $key => $value) {
130 5
                    $data[$key] = self::decodeDates($value);
131
                }
132
        }
133 5
        return $data;
134
    }
135
}
136