Completed
Push — master ( e8e573...d0b5f0 )
by Yassine
11s
created

GraphNode::getNodeMap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright 2017 Facebook, Inc.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 */
23
namespace Facebook\GraphNode;
24
25
/**
26
 * @package Facebook
27
 */
28
class GraphNode extends Collection
29
{
30
    /**
31
     * @var array maps object key names to Graph object types
32
     */
33
    protected static $graphNodeMap = [];
34
35
    /**
36
     * Init this Graph object.
37
     *
38
     * @param array $data
39
     */
40
    public function __construct(array $data = [])
41
    {
42
        parent::__construct($this->castItems($data));
43
    }
44
45
    /**
46
     * Iterates over an array and detects the types each node
47
     * should be cast to and returns all the items as an array.
48
     *
49
     * @TODO Add auto-casting to AccessToken entities.
50
     *
51
     * @param array $data the array to iterate over
52
     *
53
     * @return array
54
     */
55
    public function castItems(array $data)
56
    {
57
        $items = [];
58
59
        foreach ($data as $k => $v) {
60
            if ($this->shouldCastAsDateTime($k)
61
                && (is_numeric($v)
62
                    || $this->isIso8601DateString($v))
63
            ) {
64
                $items[$k] = $this->castToDateTime($v);
65
            } elseif ($k === 'birthday') {
66
                $items[$k] = $this->castToBirthday($v);
67
            } else {
68
                $items[$k] = $v;
69
            }
70
        }
71
72
        return $items;
73
    }
74
75
    /**
76
     * Uncasts any auto-casted datatypes.
77
     * Basically the reverse of castItems().
78
     *
79
     * @return array
80
     */
81
    public function uncastItems()
82
    {
83
        $items = $this->asArray();
84
85
        return array_map(function ($v) {
86
            if ($v instanceof \DateTime) {
87
                return $v->format(\DateTime::ISO8601);
88
            }
89
90
            return $v;
91
        }, $items);
92
    }
93
94
    /**
95
     * Get the collection of items as JSON.
96
     *
97
     * @param int $options
98
     *
99
     * @return string
100
     */
101
    public function asJson($options = 0)
102
    {
103
        return json_encode($this->uncastItems(), $options);
104
    }
105
106
    /**
107
     * Detects an ISO 8601 formatted string.
108
     *
109
     * @param string $string
110
     *
111
     * @return bool
112
     *
113
     * @see https://developers.facebook.com/docs/graph-api/using-graph-api/#readmodifiers
114
     * @see http://www.cl.cam.ac.uk/~mgk25/iso-time.html
115
     * @see http://en.wikipedia.org/wiki/ISO_8601
116
     */
117
    public function isIso8601DateString($string)
118
    {
119
        // This insane regex was yoinked from here:
120
        // http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/
121
        // ...and I'm all like:
122
        // http://thecodinglove.com/post/95378251969/when-code-works-and-i-dont-know-why
123
        $crazyInsaneRegexThatSomehowDetectsIso8601 = '/^([\+-]?\d{4}(?!\d{2}\b))'
124
            . '((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?'
125
            . '|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d'
126
            . '|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])'
127
            . '((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d'
128
            . '([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/';
129
130
        return preg_match($crazyInsaneRegexThatSomehowDetectsIso8601, $string) === 1;
131
    }
132
133
    /**
134
     * Determines if a value from Graph should be cast to DateTime.
135
     *
136
     * @param string $key
137
     *
138
     * @return bool
139
     */
140
    public function shouldCastAsDateTime($key)
141
    {
142
        return in_array($key, [
143
            'created_time',
144
            'updated_time',
145
            'start_time',
146
            'stop_time',
147
            'end_time',
148
            'backdated_time',
149
            'issued_at',
150
            'expires_at',
151
            'publish_time'
152
        ], true);
153
    }
154
155
    /**
156
     * Casts a date value from Graph to DateTime.
157
     *
158
     * @param int|string $value
159
     *
160
     * @return \DateTime
161
     */
162
    public function castToDateTime($value)
163
    {
164
        if (is_int($value)) {
165
            $dt = new \DateTime();
166
            $dt->setTimestamp($value);
167
        } else {
168
            $dt = new \DateTime($value);
169
        }
170
171
        return $dt;
172
    }
173
174
    /**
175
     * Casts a birthday value from Graph to Birthday.
176
     *
177
     * @param string $value
178
     *
179
     * @return Birthday
180
     */
181
    public function castToBirthday($value)
182
    {
183
        return new Birthday($value);
184
    }
185
186
    /**
187
     * Getter for $graphNodeMap.
188
     *
189
     * @return array
190
     */
191
    public static function getNodeMap()
192
    {
193
        return static::$graphNodeMap;
194
    }
195
}
196