Browse code

removed Telnyx Plivo Twilio Flowroute appinfo/info.xml appinfo/signature.json README.md lib/Controller/AuthorApiController.php

DoubleBastionAdmin authored on 20/08/2022 16:26:33
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,523 +0,0 @@
1
-<?php
2
-
3
-namespace Telnyx;
4
-
5
-/**
6
- * Class TelnyxObject
7
- *
8
- * @package Telnyx
9
- */
10
-class TelnyxObject implements \ArrayAccess, \Countable, \JsonSerializable
11
-{
12
-    protected $_opts;
13
-    protected $_originalValues;
14
-    protected $_values;
15
-    protected $_unsavedValues;
16
-    protected $_transientValues;
17
-    protected $_retrieveOptions;
18
-    protected $_lastResponse;
19
-
20
-    /**
21
-     * @return Util\Set Attributes that should not be sent to the API because
22
-     *    they're not updatable (e.g. ID).
23
-     */
24
-    public static function getPermanentAttributes()
25
-    {
26
-        static $permanentAttributes = null;
27
-        if ($permanentAttributes === null) {
28
-            $permanentAttributes = new Util\Set([
29
-                'id',
30
-            ]);
31
-        }
32
-        return $permanentAttributes;
33
-    }
34
-
35
-    /**
36
-     * Additive objects are subobjects in the API that don't have the same
37
-     * semantics as most subobjects, which are fully replaced when they're set.
38
-     * This is best illustrated by example. The `source` parameter sent when
39
-     * updating a subscription is *not* additive; if we set it:
40
-     *
41
-     *     source[object]=card&source[number]=123
42
-     *
43
-     * We expect the old `source` object to have been overwritten completely. If
44
-     * the previous source had an `address_state` key associated with it and we
45
-     * didn't send one this time, that value of `address_state` is gone.
46
-     *
47
-     * By contrast, additive objects are those that will have new data added to
48
-     * them while keeping any existing data in place. The only known case of its
49
-     * use is for `metadata`, but it could in theory be more general. As an
50
-     * example, say we have a `metadata` object that looks like this on the
51
-     * server side:
52
-     *
53
-     *     metadata = ["old" => "old_value"]
54
-     *
55
-     * If we update the object with `metadata[new]=new_value`, the server side
56
-     * object now has *both* fields:
57
-     *
58
-     *     metadata = ["old" => "old_value", "new" => "new_value"]
59
-     *
60
-     * This is okay in itself because usually users will want to treat it as
61
-     * additive:
62
-     *
63
-     *     $obj->metadata["new"] = "new_value";
64
-     *     $obj->save();
65
-     *
66
-     * However, in other cases, they may want to replace the entire existing
67
-     * contents:
68
-     *
69
-     *     $obj->metadata = ["new" => "new_value"];
70
-     *     $obj->save();
71
-     *
72
-     * This is where things get a little bit tricky because in order to clear
73
-     * any old keys that may have existed, we actually have to send an explicit
74
-     * empty string to the server. So the operation above would have to send
75
-     * this form to get the intended behavior:
76
-     *
77
-     *     metadata[old]=&metadata[new]=new_value
78
-     *
79
-     * This method allows us to track which parameters are considered additive,
80
-     * and lets us behave correctly where appropriate when serializing
81
-     * parameters to be sent.
82
-     *
83
-     * @return Util\Set Set of additive parameters
84
-     */
85
-    public static function getAdditiveParams()
86
-    {
87
-        static $additiveParams = null;
88
-        if ($additiveParams === null) {
89
-            // Set `metadata` as additive so that when it's set directly we remember
90
-            // to clear keys that may have been previously set by sending empty
91
-            // values for them.
92
-            //
93
-            // It's possible that not every object has `metadata`, but having this
94
-            // option set when there is no `metadata` field is not harmful.
95
-            $additiveParams = new Util\Set([
96
-                'metadata',
97
-            ]);
98
-        }
99
-        return $additiveParams;
100
-    }
101
-
102
-    public function __construct($id = null, $opts = null)
103
-    {
104
-        list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id);
105
-        $this->_opts = Util\RequestOptions::parse($opts);
106
-        $this->_originalValues = [];
107
-        $this->_values = [];
108
-        $this->_unsavedValues = new Util\Set();
109
-        $this->_transientValues = new Util\Set();
110
-        if ($id !== null) {
111
-            $this->_values['id'] = $id;
112
-        }
113
-    }
114
-
115
-    // Standard accessor magic methods
116
-    public function __set($k, $v)
117
-    {
118
-        if (static::getPermanentAttributes()->includes($k)) {
119
-            throw new \InvalidArgumentException(
120
-                "Cannot set $k on this object. HINT: you can't set: " .
121
-                join(', ', static::getPermanentAttributes()->toArray())
122
-            );
123
-        }
124
-
125
-        if ($v === "") {
126
-            throw new \InvalidArgumentException(
127
-                'You cannot set \''.$k.'\'to an empty string. '
128
-                .'We interpret empty strings as NULL in requests. '
129
-                .'You may set obj->'.$k.' = NULL to delete the property'
130
-            );
131
-        }
132
-
133
-        $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $this->_opts);
134
-        $this->dirtyValue($this->_values[$k]);
135
-        $this->_unsavedValues->add($k);
136
-    }
137
-
138
-    public function __isset($k)
139
-    {
140
-        return isset($this->_values[$k]);
141
-    }
142
-
143
-    public function __unset($k)
144
-    {
145
-        unset($this->_values[$k]);
146
-        $this->_transientValues->add($k);
147
-        $this->_unsavedValues->discard($k);
148
-    }
149
-
150
-    public function &__get($k)
151
-    {
152
-        // function should return a reference, using $nullval to return a reference to null
153
-        $nullval = null;
154
-        if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
155
-            return $this->_values[$k];
156
-        } elseif (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
157
-            $class = get_class($this);
158
-            $attrs = join(', ', array_keys($this->_values));
159
-            $message = "Telnyx Notice: Undefined property of $class instance: $k. "
160
-                    . "HINT: The $k attribute was set in the past, however. "
161
-                    . "It was then wiped when refreshing the object "
162
-                    . "with the result returned by Telnyx's API, "
163
-                    . "probably as a result of a save(). The attributes currently "
164
-                    . "available on this object are: $attrs";
165
-            Telnyx::getLogger()->error($message);
166
-            return $nullval;
167
-        } else {
168
-            $class = get_class($this);
169
-            Telnyx::getLogger()->error("Telnyx Notice: Undefined property of $class instance: $k");
170
-            return $nullval;
171
-        }
172
-    }
173
-
174
-    // Magic method for var_dump output. Only works with PHP >= 5.6
175
-    public function __debugInfo()
176
-    {
177
-        return $this->_values;
178
-    }
179
-
180
-    // ArrayAccess methods
181
-    public function offsetSet($k, $v)
182
-    {
183
-        $this->$k = $v;
184
-    }
185
-
186
-    public function offsetExists($k)
187
-    {
188
-        return array_key_exists($k, $this->_values);
189
-    }
190
-
191
-    public function offsetUnset($k)
192
-    {
193
-        unset($this->$k);
194
-    }
195
-
196
-    public function offsetGet($k)
197
-    {
198
-        return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
199
-    }
200
-
201
-    // Countable method
202
-    public function count()
203
-    {
204
-        return count($this->_values);
205
-    }
206
-
207
-    public function keys()
208
-    {
209
-        return array_keys($this->_values);
210
-    }
211
-
212
-    public function values()
213
-    {
214
-        return array_values($this->_values);
215
-    }
216
-
217
-    /**
218
-     * This unfortunately needs to be public to be used in Util\Util
219
-     *
220
-     * @param array $values
221
-     * @param null|string|array|Util\RequestOptions $opts
222
-     *
223
-     * @return static The object constructed from the given values.
224
-     */
225
-    public static function constructFrom($values, $opts = null)
226
-    {
227
-        $obj = new static(isset($values['id']) ? $values['id'] : null);
228
-        $obj->refreshFrom($values, $opts);
229
-        return $obj;
230
-    }
231
-
232
-    /**
233
-     * Refreshes this object using the provided values.
234
-     *
235
-     * @param array $values
236
-     * @param null|string|array|Util\RequestOptions $opts
237
-     * @param boolean $partial Defaults to false.
238
-     */
239
-    public function refreshFrom($values, $opts, $partial = false)
240
-    {
241
-        $this->_opts = Util\RequestOptions::parse($opts);
242
-
243
-        $this->_originalValues = self::deepCopy($values);
244
-
245
-        if ($values instanceof TelnyxObject) {
246
-            $values = $values->__toArray(true);
247
-        }
248
-
249
-        // Wipe old state before setting new.  This is useful for e.g. updating a
250
-        // customer, where there is no persistent card parameter.  Mark those values
251
-        // which don't persist as transient
252
-        if ($partial) {
253
-            $removed = new Util\Set();
254
-        } else {
255
-            $removed = new Util\Set(array_diff(array_keys($this->_values), array_keys($values)));
256
-        }
257
-
258
-        foreach ($removed->toArray() as $k) {
259
-            unset($this->$k);
260
-        }
261
-
262
-        $this->updateAttributes($values, $opts, false);
263
-        foreach ($values as $k => $v) {
264
-            $this->_transientValues->discard($k);
265
-            $this->_unsavedValues->discard($k);
266
-        }
267
-    }
268
-
269
-    /**
270
-     * Mass assigns attributes on the model.
271
-     *
272
-     * @param array $values
273
-     * @param null|string|array|Util\RequestOptions $opts
274
-     * @param boolean $dirty Defaults to true.
275
-     */
276
-    public function updateAttributes($values, $opts = null, $dirty = true)
277
-    {
278
-        foreach ($values as $k => $v) {
279
-            // Special-case metadata to always be cast as a TelnyxObject
280
-            // This is necessary in case metadata is empty, as PHP arrays do
281
-            // not differentiate between lists and hashes, and we consider
282
-            // empty arrays to be lists.
283
-            if (($k === "metadata") && (is_array($v))) {
284
-                $this->_values[$k] = TelnyxObject::constructFrom($v, $opts);
285
-            } else {
286
-                $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $opts);
287
-            }
288
-            if ($dirty) {
289
-                $this->dirtyValue($this->_values[$k]);
290
-            }
291
-            $this->_unsavedValues->add($k);
292
-        }
293
-    }
294
-
295
-    /**
296
-     * @return array A recursive mapping of attributes to values for this object,
297
-     *    including the proper value for deleted attributes.
298
-     */
299
-    public function serializeParameters($force = false)
300
-    {
301
-        $updateParams = [];
302
-
303
-        foreach ($this->_values as $k => $v) {
304
-            // There are a few reasons that we may want to add in a parameter for
305
-            // update:
306
-            //
307
-            //   1. The `$force` option has been set.
308
-            //   2. We know that it was modified.
309
-            //   3. Its value is a TelnyxObject. A TelnyxObject may contain modified
310
-            //      values within in that its parent TelnyxObject doesn't know about.
311
-            //
312
-            $original = array_key_exists($k, $this->_originalValues) ? $this->_originalValues[$k] : null;
313
-            $unsaved = $this->_unsavedValues->includes($k);
314
-            if ($force || $unsaved || $v instanceof TelnyxObject) {
315
-                $updateParams[$k] = $this->serializeParamsValue(
316
-                    $this->_values[$k],
317
-                    $original,
318
-                    $unsaved,
319
-                    $force,
320
-                    $k
321
-                );
322
-            }
323
-        }
324
-
325
-        // a `null` that makes it out of `serializeParamsValue` signals an empty
326
-        // value that we shouldn't appear in the serialized form of the object
327
-        $updateParams = array_filter(
328
-            $updateParams,
329
-            function ($v) {
330
-                return $v !== null;
331
-            }
332
-        );
333
-
334
-        return $updateParams;
335
-    }
336
-
337
-
338
-    public function serializeParamsValue($value, $original, $unsaved, $force, $key = null)
339
-    {
340
-        // The logic here is that essentially any object embedded in another
341
-        // object that had a `type` is actually an API resource of a different
342
-        // type that's been included in the response. These other resources must
343
-        // be updated from their proper endpoints, and therefore they are not
344
-        // included when serializing even if they've been modified.
345
-        //
346
-        // There are _some_ known exceptions though.
347
-        //
348
-        // For example, if the value is unsaved (meaning the user has set it), and
349
-        // it looks like the API resource is persisted with an ID, then we include
350
-        // the object so that parameters are serialized with a reference to its
351
-        // ID.
352
-        //
353
-        // Another example is that on save API calls it's sometimes desirable to
354
-        // update a customer's default source by setting a new card (or other)
355
-        // object with `->source=` and then saving the customer. The
356
-        // `saveWithParent` flag to override the default behavior allows us to
357
-        // handle these exceptions.
358
-        //
359
-        // We throw an error if a property was set explicitly but we can't do
360
-        // anything with it because the integration is probably not working as the
361
-        // user intended it to.
362
-        if ($value === null) {
363
-            return "";
364
-        } elseif (($value instanceof APIResource) && (!$value->saveWithParent)) {
365
-            if (!$unsaved) {
366
-                return null;
367
-            } elseif (isset($value->id)) {
368
-                return $value;
369
-            } else {
370
-                throw new \InvalidArgumentException(
371
-                    "Cannot save property `$key` containing an API resource of type " .
372
-                    get_class($value) . ". It doesn't appear to be persisted and is " .
373
-                    "not marked as `saveWithParent`."
374
-                );
375
-            }
376
-        } elseif (is_array($value)) {
377
-            if (Util\Util::isList($value)) {
378
-                // Sequential array, i.e. a list
379
-                $update = [];
380
-                foreach ($value as $v) {
381
-                    array_push($update, $this->serializeParamsValue($v, null, true, $force));
382
-                }
383
-                // This prevents an array that's unchanged from being resent.
384
-                if ($update !== $this->serializeParamsValue($original, null, true, $force, $key)) {
385
-                    return $update;
386
-                }
387
-            } else {
388
-                // Associative array, i.e. a map
389
-                return Util\Util::convertToTelnyxObject($value, $this->_opts)->serializeParameters();
390
-            }
391
-        } elseif ($value instanceof TelnyxObject) {
392
-            $update = $value->serializeParameters($force);
393
-            if ($original && $unsaved && $key && static::getAdditiveParams()->includes($key)) {
394
-                $update = array_merge(self::emptyValues($original), $update);
395
-            }
396
-            return $update;
397
-        } else {
398
-            return $value;
399
-        }
400
-    }
401
-
402
-    public function jsonSerialize()
403
-    {
404
-        return $this->__toArray(true);
405
-    }
406
-
407
-    public function __toJSON()
408
-    {
409
-        return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
410
-    }
411
-
412
-    public function __toString()
413
-    {
414
-        $class = get_class($this);
415
-        return $class . ' JSON: ' . $this->__toJSON();
416
-    }
417
-
418
-    public function __toArray($recursive = false)
419
-    {
420
-        if ($recursive) {
421
-            return Util\Util::convertTelnyxObjectToArray($this->_values);
422
-        } else {
423
-            return $this->_values;
424
-        }
425
-    }
426
-
427
-    /**
428
-     * Sets all keys within the TelnyxObject as unsaved so that they will be
429
-     * included with an update when `serializeParameters` is called. This
430
-     * method is also recursive, so any TelnyxObjects contained as values or
431
-     * which are values in a tenant array are also marked as dirty.
432
-     */
433
-    public function dirty()
434
-    {
435
-        $this->_unsavedValues = new Util\Set(array_keys($this->_values));
436
-        foreach ($this->_values as $k => $v) {
437
-            $this->dirtyValue($v);
438
-        }
439
-    }
440
-
441
-    protected function dirtyValue($value)
442
-    {
443
-        if (is_array($value)) {
444
-            foreach ($value as $v) {
445
-                $this->dirtyValue($v);
446
-            }
447
-        } elseif ($value instanceof TelnyxObject) {
448
-            $value->dirty();
449
-        }
450
-    }
451
-
452
-    /**
453
-     * Produces a deep copy of the given object including support for arrays
454
-     * and TelnyxObjects.
455
-     */
456
-    protected static function deepCopy($obj)
457
-    {
458
-        if (is_array($obj)) {
459
-            $copy = [];
460
-            foreach ($obj as $k => $v) {
461
-                $copy[$k] = self::deepCopy($v);
462
-            }
463
-            return $copy;
464
-        } elseif ($obj instanceof TelnyxObject) {
465
-            return $obj::constructFrom(
466
-                self::deepCopy($obj->_values),
467
-                clone $obj->_opts
468
-            );
469
-        } else {
470
-            return $obj;
471
-        }
472
-    }
473
-
474
-    /**
475
-     * Returns a hash of empty values for all the values that are in the given
476
-     * TelnyxObject.
477
-     */
478
-    public static function emptyValues($obj)
479
-    {
480
-        if (is_array($obj)) {
481
-            $values = $obj;
482
-        } elseif ($obj instanceof TelnyxObject) {
483
-            $values = $obj->_values;
484
-        } else {
485
-            throw new \InvalidArgumentException(
486
-                "empty_values got got unexpected object type: " . get_class($obj)
487
-            );
488
-        }
489
-        $update = array_fill_keys(array_keys($values), "");
490
-        return $update;
491
-    }
492
-
493
-    /**
494
-     * @return object The last response from the Telnyx API
495
-     */
496
-    public function getLastResponse()
497
-    {
498
-        return $this->_lastResponse;
499
-    }
500
-
501
-    /**
502
-     * Sets the last response from the Telnyx API
503
-     *
504
-     * @param ApiResponse $resp
505
-     * @return void
506
-     */
507
-    public function setLastResponse($resp)
508
-    {
509
-        $this->_lastResponse = $resp;
510
-    }
511
-
512
-    /**
513
-     * Indicates whether or not the resource has been deleted on the server.
514
-     * Note that some, but not all, resources can indicate whether they have
515
-     * been deleted.
516
-     *
517
-     * @return bool Whether the resource is deleted.
518
-     */
519
-    public function isDeleted()
520
-    {
521
-        return isset($this->_values['deleted']) ? $this->_values['deleted'] : false;
522
-    }
523
-}
Browse code

added appinfo/signature.json Telnyx Twilio Flowroute

DoubleBastionAdmin authored on 19/08/2022 13:10:24
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,523 @@
1
+<?php
2
+
3
+namespace Telnyx;
4
+
5
+/**
6
+ * Class TelnyxObject
7
+ *
8
+ * @package Telnyx
9
+ */
10
+class TelnyxObject implements \ArrayAccess, \Countable, \JsonSerializable
11
+{
12
+    protected $_opts;
13
+    protected $_originalValues;
14
+    protected $_values;
15
+    protected $_unsavedValues;
16
+    protected $_transientValues;
17
+    protected $_retrieveOptions;
18
+    protected $_lastResponse;
19
+
20
+    /**
21
+     * @return Util\Set Attributes that should not be sent to the API because
22
+     *    they're not updatable (e.g. ID).
23
+     */
24
+    public static function getPermanentAttributes()
25
+    {
26
+        static $permanentAttributes = null;
27
+        if ($permanentAttributes === null) {
28
+            $permanentAttributes = new Util\Set([
29
+                'id',
30
+            ]);
31
+        }
32
+        return $permanentAttributes;
33
+    }
34
+
35
+    /**
36
+     * Additive objects are subobjects in the API that don't have the same
37
+     * semantics as most subobjects, which are fully replaced when they're set.
38
+     * This is best illustrated by example. The `source` parameter sent when
39
+     * updating a subscription is *not* additive; if we set it:
40
+     *
41
+     *     source[object]=card&source[number]=123
42
+     *
43
+     * We expect the old `source` object to have been overwritten completely. If
44
+     * the previous source had an `address_state` key associated with it and we
45
+     * didn't send one this time, that value of `address_state` is gone.
46
+     *
47
+     * By contrast, additive objects are those that will have new data added to
48
+     * them while keeping any existing data in place. The only known case of its
49
+     * use is for `metadata`, but it could in theory be more general. As an
50
+     * example, say we have a `metadata` object that looks like this on the
51
+     * server side:
52
+     *
53
+     *     metadata = ["old" => "old_value"]
54
+     *
55
+     * If we update the object with `metadata[new]=new_value`, the server side
56
+     * object now has *both* fields:
57
+     *
58
+     *     metadata = ["old" => "old_value", "new" => "new_value"]
59
+     *
60
+     * This is okay in itself because usually users will want to treat it as
61
+     * additive:
62
+     *
63
+     *     $obj->metadata["new"] = "new_value";
64
+     *     $obj->save();
65
+     *
66
+     * However, in other cases, they may want to replace the entire existing
67
+     * contents:
68
+     *
69
+     *     $obj->metadata = ["new" => "new_value"];
70
+     *     $obj->save();
71
+     *
72
+     * This is where things get a little bit tricky because in order to clear
73
+     * any old keys that may have existed, we actually have to send an explicit
74
+     * empty string to the server. So the operation above would have to send
75
+     * this form to get the intended behavior:
76
+     *
77
+     *     metadata[old]=&metadata[new]=new_value
78
+     *
79
+     * This method allows us to track which parameters are considered additive,
80
+     * and lets us behave correctly where appropriate when serializing
81
+     * parameters to be sent.
82
+     *
83
+     * @return Util\Set Set of additive parameters
84
+     */
85
+    public static function getAdditiveParams()
86
+    {
87
+        static $additiveParams = null;
88
+        if ($additiveParams === null) {
89
+            // Set `metadata` as additive so that when it's set directly we remember
90
+            // to clear keys that may have been previously set by sending empty
91
+            // values for them.
92
+            //
93
+            // It's possible that not every object has `metadata`, but having this
94
+            // option set when there is no `metadata` field is not harmful.
95
+            $additiveParams = new Util\Set([
96
+                'metadata',
97
+            ]);
98
+        }
99
+        return $additiveParams;
100
+    }
101
+
102
+    public function __construct($id = null, $opts = null)
103
+    {
104
+        list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id);
105
+        $this->_opts = Util\RequestOptions::parse($opts);
106
+        $this->_originalValues = [];
107
+        $this->_values = [];
108
+        $this->_unsavedValues = new Util\Set();
109
+        $this->_transientValues = new Util\Set();
110
+        if ($id !== null) {
111
+            $this->_values['id'] = $id;
112
+        }
113
+    }
114
+
115
+    // Standard accessor magic methods
116
+    public function __set($k, $v)
117
+    {
118
+        if (static::getPermanentAttributes()->includes($k)) {
119
+            throw new \InvalidArgumentException(
120
+                "Cannot set $k on this object. HINT: you can't set: " .
121
+                join(', ', static::getPermanentAttributes()->toArray())
122
+            );
123
+        }
124
+
125
+        if ($v === "") {
126
+            throw new \InvalidArgumentException(
127
+                'You cannot set \''.$k.'\'to an empty string. '
128
+                .'We interpret empty strings as NULL in requests. '
129
+                .'You may set obj->'.$k.' = NULL to delete the property'
130
+            );
131
+        }
132
+
133
+        $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $this->_opts);
134
+        $this->dirtyValue($this->_values[$k]);
135
+        $this->_unsavedValues->add($k);
136
+    }
137
+
138
+    public function __isset($k)
139
+    {
140
+        return isset($this->_values[$k]);
141
+    }
142
+
143
+    public function __unset($k)
144
+    {
145
+        unset($this->_values[$k]);
146
+        $this->_transientValues->add($k);
147
+        $this->_unsavedValues->discard($k);
148
+    }
149
+
150
+    public function &__get($k)
151
+    {
152
+        // function should return a reference, using $nullval to return a reference to null
153
+        $nullval = null;
154
+        if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
155
+            return $this->_values[$k];
156
+        } elseif (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
157
+            $class = get_class($this);
158
+            $attrs = join(', ', array_keys($this->_values));
159
+            $message = "Telnyx Notice: Undefined property of $class instance: $k. "
160
+                    . "HINT: The $k attribute was set in the past, however. "
161
+                    . "It was then wiped when refreshing the object "
162
+                    . "with the result returned by Telnyx's API, "
163
+                    . "probably as a result of a save(). The attributes currently "
164
+                    . "available on this object are: $attrs";
165
+            Telnyx::getLogger()->error($message);
166
+            return $nullval;
167
+        } else {
168
+            $class = get_class($this);
169
+            Telnyx::getLogger()->error("Telnyx Notice: Undefined property of $class instance: $k");
170
+            return $nullval;
171
+        }
172
+    }
173
+
174
+    // Magic method for var_dump output. Only works with PHP >= 5.6
175
+    public function __debugInfo()
176
+    {
177
+        return $this->_values;
178
+    }
179
+
180
+    // ArrayAccess methods
181
+    public function offsetSet($k, $v)
182
+    {
183
+        $this->$k = $v;
184
+    }
185
+
186
+    public function offsetExists($k)
187
+    {
188
+        return array_key_exists($k, $this->_values);
189
+    }
190
+
191
+    public function offsetUnset($k)
192
+    {
193
+        unset($this->$k);
194
+    }
195
+
196
+    public function offsetGet($k)
197
+    {
198
+        return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
199
+    }
200
+
201
+    // Countable method
202
+    public function count()
203
+    {
204
+        return count($this->_values);
205
+    }
206
+
207
+    public function keys()
208
+    {
209
+        return array_keys($this->_values);
210
+    }
211
+
212
+    public function values()
213
+    {
214
+        return array_values($this->_values);
215
+    }
216
+
217
+    /**
218
+     * This unfortunately needs to be public to be used in Util\Util
219
+     *
220
+     * @param array $values
221
+     * @param null|string|array|Util\RequestOptions $opts
222
+     *
223
+     * @return static The object constructed from the given values.
224
+     */
225
+    public static function constructFrom($values, $opts = null)
226
+    {
227
+        $obj = new static(isset($values['id']) ? $values['id'] : null);
228
+        $obj->refreshFrom($values, $opts);
229
+        return $obj;
230
+    }
231
+
232
+    /**
233
+     * Refreshes this object using the provided values.
234
+     *
235
+     * @param array $values
236
+     * @param null|string|array|Util\RequestOptions $opts
237
+     * @param boolean $partial Defaults to false.
238
+     */
239
+    public function refreshFrom($values, $opts, $partial = false)
240
+    {
241
+        $this->_opts = Util\RequestOptions::parse($opts);
242
+
243
+        $this->_originalValues = self::deepCopy($values);
244
+
245
+        if ($values instanceof TelnyxObject) {
246
+            $values = $values->__toArray(true);
247
+        }
248
+
249
+        // Wipe old state before setting new.  This is useful for e.g. updating a
250
+        // customer, where there is no persistent card parameter.  Mark those values
251
+        // which don't persist as transient
252
+        if ($partial) {
253
+            $removed = new Util\Set();
254
+        } else {
255
+            $removed = new Util\Set(array_diff(array_keys($this->_values), array_keys($values)));
256
+        }
257
+
258
+        foreach ($removed->toArray() as $k) {
259
+            unset($this->$k);
260
+        }
261
+
262
+        $this->updateAttributes($values, $opts, false);
263
+        foreach ($values as $k => $v) {
264
+            $this->_transientValues->discard($k);
265
+            $this->_unsavedValues->discard($k);
266
+        }
267
+    }
268
+
269
+    /**
270
+     * Mass assigns attributes on the model.
271
+     *
272
+     * @param array $values
273
+     * @param null|string|array|Util\RequestOptions $opts
274
+     * @param boolean $dirty Defaults to true.
275
+     */
276
+    public function updateAttributes($values, $opts = null, $dirty = true)
277
+    {
278
+        foreach ($values as $k => $v) {
279
+            // Special-case metadata to always be cast as a TelnyxObject
280
+            // This is necessary in case metadata is empty, as PHP arrays do
281
+            // not differentiate between lists and hashes, and we consider
282
+            // empty arrays to be lists.
283
+            if (($k === "metadata") && (is_array($v))) {
284
+                $this->_values[$k] = TelnyxObject::constructFrom($v, $opts);
285
+            } else {
286
+                $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $opts);
287
+            }
288
+            if ($dirty) {
289
+                $this->dirtyValue($this->_values[$k]);
290
+            }
291
+            $this->_unsavedValues->add($k);
292
+        }
293
+    }
294
+
295
+    /**
296
+     * @return array A recursive mapping of attributes to values for this object,
297
+     *    including the proper value for deleted attributes.
298
+     */
299
+    public function serializeParameters($force = false)
300
+    {
301
+        $updateParams = [];
302
+
303
+        foreach ($this->_values as $k => $v) {
304
+            // There are a few reasons that we may want to add in a parameter for
305
+            // update:
306
+            //
307
+            //   1. The `$force` option has been set.
308
+            //   2. We know that it was modified.
309
+            //   3. Its value is a TelnyxObject. A TelnyxObject may contain modified
310
+            //      values within in that its parent TelnyxObject doesn't know about.
311
+            //
312
+            $original = array_key_exists($k, $this->_originalValues) ? $this->_originalValues[$k] : null;
313
+            $unsaved = $this->_unsavedValues->includes($k);
314
+            if ($force || $unsaved || $v instanceof TelnyxObject) {
315
+                $updateParams[$k] = $this->serializeParamsValue(
316
+                    $this->_values[$k],
317
+                    $original,
318
+                    $unsaved,
319
+                    $force,
320
+                    $k
321
+                );
322
+            }
323
+        }
324
+
325
+        // a `null` that makes it out of `serializeParamsValue` signals an empty
326
+        // value that we shouldn't appear in the serialized form of the object
327
+        $updateParams = array_filter(
328
+            $updateParams,
329
+            function ($v) {
330
+                return $v !== null;
331
+            }
332
+        );
333
+
334
+        return $updateParams;
335
+    }
336
+
337
+
338
+    public function serializeParamsValue($value, $original, $unsaved, $force, $key = null)
339
+    {
340
+        // The logic here is that essentially any object embedded in another
341
+        // object that had a `type` is actually an API resource of a different
342
+        // type that's been included in the response. These other resources must
343
+        // be updated from their proper endpoints, and therefore they are not
344
+        // included when serializing even if they've been modified.
345
+        //
346
+        // There are _some_ known exceptions though.
347
+        //
348
+        // For example, if the value is unsaved (meaning the user has set it), and
349
+        // it looks like the API resource is persisted with an ID, then we include
350
+        // the object so that parameters are serialized with a reference to its
351
+        // ID.
352
+        //
353
+        // Another example is that on save API calls it's sometimes desirable to
354
+        // update a customer's default source by setting a new card (or other)
355
+        // object with `->source=` and then saving the customer. The
356
+        // `saveWithParent` flag to override the default behavior allows us to
357
+        // handle these exceptions.
358
+        //
359
+        // We throw an error if a property was set explicitly but we can't do
360
+        // anything with it because the integration is probably not working as the
361
+        // user intended it to.
362
+        if ($value === null) {
363
+            return "";
364
+        } elseif (($value instanceof APIResource) && (!$value->saveWithParent)) {
365
+            if (!$unsaved) {
366
+                return null;
367
+            } elseif (isset($value->id)) {
368
+                return $value;
369
+            } else {
370
+                throw new \InvalidArgumentException(
371
+                    "Cannot save property `$key` containing an API resource of type " .
372
+                    get_class($value) . ". It doesn't appear to be persisted and is " .
373
+                    "not marked as `saveWithParent`."
374
+                );
375
+            }
376
+        } elseif (is_array($value)) {
377
+            if (Util\Util::isList($value)) {
378
+                // Sequential array, i.e. a list
379
+                $update = [];
380
+                foreach ($value as $v) {
381
+                    array_push($update, $this->serializeParamsValue($v, null, true, $force));
382
+                }
383
+                // This prevents an array that's unchanged from being resent.
384
+                if ($update !== $this->serializeParamsValue($original, null, true, $force, $key)) {
385
+                    return $update;
386
+                }
387
+            } else {
388
+                // Associative array, i.e. a map
389
+                return Util\Util::convertToTelnyxObject($value, $this->_opts)->serializeParameters();
390
+            }
391
+        } elseif ($value instanceof TelnyxObject) {
392
+            $update = $value->serializeParameters($force);
393
+            if ($original && $unsaved && $key && static::getAdditiveParams()->includes($key)) {
394
+                $update = array_merge(self::emptyValues($original), $update);
395
+            }
396
+            return $update;
397
+        } else {
398
+            return $value;
399
+        }
400
+    }
401
+
402
+    public function jsonSerialize()
403
+    {
404
+        return $this->__toArray(true);
405
+    }
406
+
407
+    public function __toJSON()
408
+    {
409
+        return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
410
+    }
411
+
412
+    public function __toString()
413
+    {
414
+        $class = get_class($this);
415
+        return $class . ' JSON: ' . $this->__toJSON();
416
+    }
417
+
418
+    public function __toArray($recursive = false)
419
+    {
420
+        if ($recursive) {
421
+            return Util\Util::convertTelnyxObjectToArray($this->_values);
422
+        } else {
423
+            return $this->_values;
424
+        }
425
+    }
426
+
427
+    /**
428
+     * Sets all keys within the TelnyxObject as unsaved so that they will be
429
+     * included with an update when `serializeParameters` is called. This
430
+     * method is also recursive, so any TelnyxObjects contained as values or
431
+     * which are values in a tenant array are also marked as dirty.
432
+     */
433
+    public function dirty()
434
+    {
435
+        $this->_unsavedValues = new Util\Set(array_keys($this->_values));
436
+        foreach ($this->_values as $k => $v) {
437
+            $this->dirtyValue($v);
438
+        }
439
+    }
440
+
441
+    protected function dirtyValue($value)
442
+    {
443
+        if (is_array($value)) {
444
+            foreach ($value as $v) {
445
+                $this->dirtyValue($v);
446
+            }
447
+        } elseif ($value instanceof TelnyxObject) {
448
+            $value->dirty();
449
+        }
450
+    }
451
+
452
+    /**
453
+     * Produces a deep copy of the given object including support for arrays
454
+     * and TelnyxObjects.
455
+     */
456
+    protected static function deepCopy($obj)
457
+    {
458
+        if (is_array($obj)) {
459
+            $copy = [];
460
+            foreach ($obj as $k => $v) {
461
+                $copy[$k] = self::deepCopy($v);
462
+            }
463
+            return $copy;
464
+        } elseif ($obj instanceof TelnyxObject) {
465
+            return $obj::constructFrom(
466
+                self::deepCopy($obj->_values),
467
+                clone $obj->_opts
468
+            );
469
+        } else {
470
+            return $obj;
471
+        }
472
+    }
473
+
474
+    /**
475
+     * Returns a hash of empty values for all the values that are in the given
476
+     * TelnyxObject.
477
+     */
478
+    public static function emptyValues($obj)
479
+    {
480
+        if (is_array($obj)) {
481
+            $values = $obj;
482
+        } elseif ($obj instanceof TelnyxObject) {
483
+            $values = $obj->_values;
484
+        } else {
485
+            throw new \InvalidArgumentException(
486
+                "empty_values got got unexpected object type: " . get_class($obj)
487
+            );
488
+        }
489
+        $update = array_fill_keys(array_keys($values), "");
490
+        return $update;
491
+    }
492
+
493
+    /**
494
+     * @return object The last response from the Telnyx API
495
+     */
496
+    public function getLastResponse()
497
+    {
498
+        return $this->_lastResponse;
499
+    }
500
+
501
+    /**
502
+     * Sets the last response from the Telnyx API
503
+     *
504
+     * @param ApiResponse $resp
505
+     * @return void
506
+     */
507
+    public function setLastResponse($resp)
508
+    {
509
+        $this->_lastResponse = $resp;
510
+    }
511
+
512
+    /**
513
+     * Indicates whether or not the resource has been deleted on the server.
514
+     * Note that some, but not all, resources can indicate whether they have
515
+     * been deleted.
516
+     *
517
+     * @return bool Whether the resource is deleted.
518
+     */
519
+    public function isDeleted()
520
+    {
521
+        return isset($this->_values['deleted']) ? $this->_values['deleted'] : false;
522
+    }
523
+}
Browse code

removed appinfo/signature.json and Telnyx

DoubleBastionAdmin authored on 19/08/2022 12:45:59
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,523 +0,0 @@
1
-<?php
2
-
3
-namespace Telnyx;
4
-
5
-/**
6
- * Class TelnyxObject
7
- *
8
- * @package Telnyx
9
- */
10
-class TelnyxObject implements \ArrayAccess, \Countable, \JsonSerializable
11
-{
12
-    protected $_opts;
13
-    protected $_originalValues;
14
-    protected $_values;
15
-    protected $_unsavedValues;
16
-    protected $_transientValues;
17
-    protected $_retrieveOptions;
18
-    protected $_lastResponse;
19
-
20
-    /**
21
-     * @return Util\Set Attributes that should not be sent to the API because
22
-     *    they're not updatable (e.g. ID).
23
-     */
24
-    public static function getPermanentAttributes()
25
-    {
26
-        static $permanentAttributes = null;
27
-        if ($permanentAttributes === null) {
28
-            $permanentAttributes = new Util\Set([
29
-                'id',
30
-            ]);
31
-        }
32
-        return $permanentAttributes;
33
-    }
34
-
35
-    /**
36
-     * Additive objects are subobjects in the API that don't have the same
37
-     * semantics as most subobjects, which are fully replaced when they're set.
38
-     * This is best illustrated by example. The `source` parameter sent when
39
-     * updating a subscription is *not* additive; if we set it:
40
-     *
41
-     *     source[object]=card&source[number]=123
42
-     *
43
-     * We expect the old `source` object to have been overwritten completely. If
44
-     * the previous source had an `address_state` key associated with it and we
45
-     * didn't send one this time, that value of `address_state` is gone.
46
-     *
47
-     * By contrast, additive objects are those that will have new data added to
48
-     * them while keeping any existing data in place. The only known case of its
49
-     * use is for `metadata`, but it could in theory be more general. As an
50
-     * example, say we have a `metadata` object that looks like this on the
51
-     * server side:
52
-     *
53
-     *     metadata = ["old" => "old_value"]
54
-     *
55
-     * If we update the object with `metadata[new]=new_value`, the server side
56
-     * object now has *both* fields:
57
-     *
58
-     *     metadata = ["old" => "old_value", "new" => "new_value"]
59
-     *
60
-     * This is okay in itself because usually users will want to treat it as
61
-     * additive:
62
-     *
63
-     *     $obj->metadata["new"] = "new_value";
64
-     *     $obj->save();
65
-     *
66
-     * However, in other cases, they may want to replace the entire existing
67
-     * contents:
68
-     *
69
-     *     $obj->metadata = ["new" => "new_value"];
70
-     *     $obj->save();
71
-     *
72
-     * This is where things get a little bit tricky because in order to clear
73
-     * any old keys that may have existed, we actually have to send an explicit
74
-     * empty string to the server. So the operation above would have to send
75
-     * this form to get the intended behavior:
76
-     *
77
-     *     metadata[old]=&metadata[new]=new_value
78
-     *
79
-     * This method allows us to track which parameters are considered additive,
80
-     * and lets us behave correctly where appropriate when serializing
81
-     * parameters to be sent.
82
-     *
83
-     * @return Util\Set Set of additive parameters
84
-     */
85
-    public static function getAdditiveParams()
86
-    {
87
-        static $additiveParams = null;
88
-        if ($additiveParams === null) {
89
-            // Set `metadata` as additive so that when it's set directly we remember
90
-            // to clear keys that may have been previously set by sending empty
91
-            // values for them.
92
-            //
93
-            // It's possible that not every object has `metadata`, but having this
94
-            // option set when there is no `metadata` field is not harmful.
95
-            $additiveParams = new Util\Set([
96
-                'metadata',
97
-            ]);
98
-        }
99
-        return $additiveParams;
100
-    }
101
-
102
-    public function __construct($id = null, $opts = null)
103
-    {
104
-        list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id);
105
-        $this->_opts = Util\RequestOptions::parse($opts);
106
-        $this->_originalValues = [];
107
-        $this->_values = [];
108
-        $this->_unsavedValues = new Util\Set();
109
-        $this->_transientValues = new Util\Set();
110
-        if ($id !== null) {
111
-            $this->_values['id'] = $id;
112
-        }
113
-    }
114
-
115
-    // Standard accessor magic methods
116
-    public function __set($k, $v)
117
-    {
118
-        if (static::getPermanentAttributes()->includes($k)) {
119
-            throw new \InvalidArgumentException(
120
-                "Cannot set $k on this object. HINT: you can't set: " .
121
-                join(', ', static::getPermanentAttributes()->toArray())
122
-            );
123
-        }
124
-
125
-        if ($v === "") {
126
-            throw new \InvalidArgumentException(
127
-                'You cannot set \''.$k.'\'to an empty string. '
128
-                .'We interpret empty strings as NULL in requests. '
129
-                .'You may set obj->'.$k.' = NULL to delete the property'
130
-            );
131
-        }
132
-
133
-        $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $this->_opts);
134
-        $this->dirtyValue($this->_values[$k]);
135
-        $this->_unsavedValues->add($k);
136
-    }
137
-
138
-    public function __isset($k)
139
-    {
140
-        return isset($this->_values[$k]);
141
-    }
142
-
143
-    public function __unset($k)
144
-    {
145
-        unset($this->_values[$k]);
146
-        $this->_transientValues->add($k);
147
-        $this->_unsavedValues->discard($k);
148
-    }
149
-
150
-    public function &__get($k)
151
-    {
152
-        // function should return a reference, using $nullval to return a reference to null
153
-        $nullval = null;
154
-        if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
155
-            return $this->_values[$k];
156
-        } elseif (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
157
-            $class = get_class($this);
158
-            $attrs = join(', ', array_keys($this->_values));
159
-            $message = "Telnyx Notice: Undefined property of $class instance: $k. "
160
-                    . "HINT: The $k attribute was set in the past, however. "
161
-                    . "It was then wiped when refreshing the object "
162
-                    . "with the result returned by Telnyx's API, "
163
-                    . "probably as a result of a save(). The attributes currently "
164
-                    . "available on this object are: $attrs";
165
-            Telnyx::getLogger()->error($message);
166
-            return $nullval;
167
-        } else {
168
-            $class = get_class($this);
169
-            Telnyx::getLogger()->error("Telnyx Notice: Undefined property of $class instance: $k");
170
-            return $nullval;
171
-        }
172
-    }
173
-
174
-    // Magic method for var_dump output. Only works with PHP >= 5.6
175
-    public function __debugInfo()
176
-    {
177
-        return $this->_values;
178
-    }
179
-
180
-    // ArrayAccess methods
181
-    public function offsetSet($k, $v)
182
-    {
183
-        $this->$k = $v;
184
-    }
185
-
186
-    public function offsetExists($k)
187
-    {
188
-        return array_key_exists($k, $this->_values);
189
-    }
190
-
191
-    public function offsetUnset($k)
192
-    {
193
-        unset($this->$k);
194
-    }
195
-
196
-    public function offsetGet($k)
197
-    {
198
-        return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
199
-    }
200
-
201
-    // Countable method
202
-    public function count()
203
-    {
204
-        return count($this->_values);
205
-    }
206
-
207
-    public function keys()
208
-    {
209
-        return array_keys($this->_values);
210
-    }
211
-
212
-    public function values()
213
-    {
214
-        return array_values($this->_values);
215
-    }
216
-
217
-    /**
218
-     * This unfortunately needs to be public to be used in Util\Util
219
-     *
220
-     * @param array $values
221
-     * @param null|string|array|Util\RequestOptions $opts
222
-     *
223
-     * @return static The object constructed from the given values.
224
-     */
225
-    public static function constructFrom($values, $opts = null)
226
-    {
227
-        $obj = new static(isset($values['id']) ? $values['id'] : null);
228
-        $obj->refreshFrom($values, $opts);
229
-        return $obj;
230
-    }
231
-
232
-    /**
233
-     * Refreshes this object using the provided values.
234
-     *
235
-     * @param array $values
236
-     * @param null|string|array|Util\RequestOptions $opts
237
-     * @param boolean $partial Defaults to false.
238
-     */
239
-    public function refreshFrom($values, $opts, $partial = false)
240
-    {
241
-        $this->_opts = Util\RequestOptions::parse($opts);
242
-
243
-        $this->_originalValues = self::deepCopy($values);
244
-
245
-        if ($values instanceof TelnyxObject) {
246
-            $values = $values->__toArray(true);
247
-        }
248
-
249
-        // Wipe old state before setting new.  This is useful for e.g. updating a
250
-        // customer, where there is no persistent card parameter.  Mark those values
251
-        // which don't persist as transient
252
-        if ($partial) {
253
-            $removed = new Util\Set();
254
-        } else {
255
-            $removed = new Util\Set(array_diff(array_keys($this->_values), array_keys($values)));
256
-        }
257
-
258
-        foreach ($removed->toArray() as $k) {
259
-            unset($this->$k);
260
-        }
261
-
262
-        $this->updateAttributes($values, $opts, false);
263
-        foreach ($values as $k => $v) {
264
-            $this->_transientValues->discard($k);
265
-            $this->_unsavedValues->discard($k);
266
-        }
267
-    }
268
-
269
-    /**
270
-     * Mass assigns attributes on the model.
271
-     *
272
-     * @param array $values
273
-     * @param null|string|array|Util\RequestOptions $opts
274
-     * @param boolean $dirty Defaults to true.
275
-     */
276
-    public function updateAttributes($values, $opts = null, $dirty = true)
277
-    {
278
-        foreach ($values as $k => $v) {
279
-            // Special-case metadata to always be cast as a TelnyxObject
280
-            // This is necessary in case metadata is empty, as PHP arrays do
281
-            // not differentiate between lists and hashes, and we consider
282
-            // empty arrays to be lists.
283
-            if (($k === "metadata") && (is_array($v))) {
284
-                $this->_values[$k] = TelnyxObject::constructFrom($v, $opts);
285
-            } else {
286
-                $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $opts);
287
-            }
288
-            if ($dirty) {
289
-                $this->dirtyValue($this->_values[$k]);
290
-            }
291
-            $this->_unsavedValues->add($k);
292
-        }
293
-    }
294
-
295
-    /**
296
-     * @return array A recursive mapping of attributes to values for this object,
297
-     *    including the proper value for deleted attributes.
298
-     */
299
-    public function serializeParameters($force = false)
300
-    {
301
-        $updateParams = [];
302
-
303
-        foreach ($this->_values as $k => $v) {
304
-            // There are a few reasons that we may want to add in a parameter for
305
-            // update:
306
-            //
307
-            //   1. The `$force` option has been set.
308
-            //   2. We know that it was modified.
309
-            //   3. Its value is a TelnyxObject. A TelnyxObject may contain modified
310
-            //      values within in that its parent TelnyxObject doesn't know about.
311
-            //
312
-            $original = array_key_exists($k, $this->_originalValues) ? $this->_originalValues[$k] : null;
313
-            $unsaved = $this->_unsavedValues->includes($k);
314
-            if ($force || $unsaved || $v instanceof TelnyxObject) {
315
-                $updateParams[$k] = $this->serializeParamsValue(
316
-                    $this->_values[$k],
317
-                    $original,
318
-                    $unsaved,
319
-                    $force,
320
-                    $k
321
-                );
322
-            }
323
-        }
324
-
325
-        // a `null` that makes it out of `serializeParamsValue` signals an empty
326
-        // value that we shouldn't appear in the serialized form of the object
327
-        $updateParams = array_filter(
328
-            $updateParams,
329
-            function ($v) {
330
-                return $v !== null;
331
-            }
332
-        );
333
-
334
-        return $updateParams;
335
-    }
336
-
337
-
338
-    public function serializeParamsValue($value, $original, $unsaved, $force, $key = null)
339
-    {
340
-        // The logic here is that essentially any object embedded in another
341
-        // object that had a `type` is actually an API resource of a different
342
-        // type that's been included in the response. These other resources must
343
-        // be updated from their proper endpoints, and therefore they are not
344
-        // included when serializing even if they've been modified.
345
-        //
346
-        // There are _some_ known exceptions though.
347
-        //
348
-        // For example, if the value is unsaved (meaning the user has set it), and
349
-        // it looks like the API resource is persisted with an ID, then we include
350
-        // the object so that parameters are serialized with a reference to its
351
-        // ID.
352
-        //
353
-        // Another example is that on save API calls it's sometimes desirable to
354
-        // update a customer's default source by setting a new card (or other)
355
-        // object with `->source=` and then saving the customer. The
356
-        // `saveWithParent` flag to override the default behavior allows us to
357
-        // handle these exceptions.
358
-        //
359
-        // We throw an error if a property was set explicitly but we can't do
360
-        // anything with it because the integration is probably not working as the
361
-        // user intended it to.
362
-        if ($value === null) {
363
-            return "";
364
-        } elseif (($value instanceof APIResource) && (!$value->saveWithParent)) {
365
-            if (!$unsaved) {
366
-                return null;
367
-            } elseif (isset($value->id)) {
368
-                return $value;
369
-            } else {
370
-                throw new \InvalidArgumentException(
371
-                    "Cannot save property `$key` containing an API resource of type " .
372
-                    get_class($value) . ". It doesn't appear to be persisted and is " .
373
-                    "not marked as `saveWithParent`."
374
-                );
375
-            }
376
-        } elseif (is_array($value)) {
377
-            if (Util\Util::isList($value)) {
378
-                // Sequential array, i.e. a list
379
-                $update = [];
380
-                foreach ($value as $v) {
381
-                    array_push($update, $this->serializeParamsValue($v, null, true, $force));
382
-                }
383
-                // This prevents an array that's unchanged from being resent.
384
-                if ($update !== $this->serializeParamsValue($original, null, true, $force, $key)) {
385
-                    return $update;
386
-                }
387
-            } else {
388
-                // Associative array, i.e. a map
389
-                return Util\Util::convertToTelnyxObject($value, $this->_opts)->serializeParameters();
390
-            }
391
-        } elseif ($value instanceof TelnyxObject) {
392
-            $update = $value->serializeParameters($force);
393
-            if ($original && $unsaved && $key && static::getAdditiveParams()->includes($key)) {
394
-                $update = array_merge(self::emptyValues($original), $update);
395
-            }
396
-            return $update;
397
-        } else {
398
-            return $value;
399
-        }
400
-    }
401
-
402
-    public function jsonSerialize()
403
-    {
404
-        return $this->__toArray(true);
405
-    }
406
-
407
-    public function __toJSON()
408
-    {
409
-        return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
410
-    }
411
-
412
-    public function __toString()
413
-    {
414
-        $class = get_class($this);
415
-        return $class . ' JSON: ' . $this->__toJSON();
416
-    }
417
-
418
-    public function __toArray($recursive = false)
419
-    {
420
-        if ($recursive) {
421
-            return Util\Util::convertTelnyxObjectToArray($this->_values);
422
-        } else {
423
-            return $this->_values;
424
-        }
425
-    }
426
-
427
-    /**
428
-     * Sets all keys within the TelnyxObject as unsaved so that they will be
429
-     * included with an update when `serializeParameters` is called. This
430
-     * method is also recursive, so any TelnyxObjects contained as values or
431
-     * which are values in a tenant array are also marked as dirty.
432
-     */
433
-    public function dirty()
434
-    {
435
-        $this->_unsavedValues = new Util\Set(array_keys($this->_values));
436
-        foreach ($this->_values as $k => $v) {
437
-            $this->dirtyValue($v);
438
-        }
439
-    }
440
-
441
-    protected function dirtyValue($value)
442
-    {
443
-        if (is_array($value)) {
444
-            foreach ($value as $v) {
445
-                $this->dirtyValue($v);
446
-            }
447
-        } elseif ($value instanceof TelnyxObject) {
448
-            $value->dirty();
449
-        }
450
-    }
451
-
452
-    /**
453
-     * Produces a deep copy of the given object including support for arrays
454
-     * and TelnyxObjects.
455
-     */
456
-    protected static function deepCopy($obj)
457
-    {
458
-        if (is_array($obj)) {
459
-            $copy = [];
460
-            foreach ($obj as $k => $v) {
461
-                $copy[$k] = self::deepCopy($v);
462
-            }
463
-            return $copy;
464
-        } elseif ($obj instanceof TelnyxObject) {
465
-            return $obj::constructFrom(
466
-                self::deepCopy($obj->_values),
467
-                clone $obj->_opts
468
-            );
469
-        } else {
470
-            return $obj;
471
-        }
472
-    }
473
-
474
-    /**
475
-     * Returns a hash of empty values for all the values that are in the given
476
-     * TelnyxObject.
477
-     */
478
-    public static function emptyValues($obj)
479
-    {
480
-        if (is_array($obj)) {
481
-            $values = $obj;
482
-        } elseif ($obj instanceof TelnyxObject) {
483
-            $values = $obj->_values;
484
-        } else {
485
-            throw new \InvalidArgumentException(
486
-                "empty_values got got unexpected object type: " . get_class($obj)
487
-            );
488
-        }
489
-        $update = array_fill_keys(array_keys($values), "");
490
-        return $update;
491
-    }
492
-
493
-    /**
494
-     * @return object The last response from the Telnyx API
495
-     */
496
-    public function getLastResponse()
497
-    {
498
-        return $this->_lastResponse;
499
-    }
500
-
501
-    /**
502
-     * Sets the last response from the Telnyx API
503
-     *
504
-     * @param ApiResponse $resp
505
-     * @return void
506
-     */
507
-    public function setLastResponse($resp)
508
-    {
509
-        $this->_lastResponse = $resp;
510
-    }
511
-
512
-    /**
513
-     * Indicates whether or not the resource has been deleted on the server.
514
-     * Note that some, but not all, resources can indicate whether they have
515
-     * been deleted.
516
-     *
517
-     * @return bool Whether the resource is deleted.
518
-     */
519
-    public function isDeleted()
520
-    {
521
-        return isset($this->_values['deleted']) ? $this->_values['deleted'] : false;
522
-    }
523
-}
Browse code

added appinfo/signature.json and Telnyx directory

DoubleBastionAdmin authored on 19/08/2022 11:38:54
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,523 @@
1
+<?php
2
+
3
+namespace Telnyx;
4
+
5
+/**
6
+ * Class TelnyxObject
7
+ *
8
+ * @package Telnyx
9
+ */
10
+class TelnyxObject implements \ArrayAccess, \Countable, \JsonSerializable
11
+{
12
+    protected $_opts;
13
+    protected $_originalValues;
14
+    protected $_values;
15
+    protected $_unsavedValues;
16
+    protected $_transientValues;
17
+    protected $_retrieveOptions;
18
+    protected $_lastResponse;
19
+
20
+    /**
21
+     * @return Util\Set Attributes that should not be sent to the API because
22
+     *    they're not updatable (e.g. ID).
23
+     */
24
+    public static function getPermanentAttributes()
25
+    {
26
+        static $permanentAttributes = null;
27
+        if ($permanentAttributes === null) {
28
+            $permanentAttributes = new Util\Set([
29
+                'id',
30
+            ]);
31
+        }
32
+        return $permanentAttributes;
33
+    }
34
+
35
+    /**
36
+     * Additive objects are subobjects in the API that don't have the same
37
+     * semantics as most subobjects, which are fully replaced when they're set.
38
+     * This is best illustrated by example. The `source` parameter sent when
39
+     * updating a subscription is *not* additive; if we set it:
40
+     *
41
+     *     source[object]=card&source[number]=123
42
+     *
43
+     * We expect the old `source` object to have been overwritten completely. If
44
+     * the previous source had an `address_state` key associated with it and we
45
+     * didn't send one this time, that value of `address_state` is gone.
46
+     *
47
+     * By contrast, additive objects are those that will have new data added to
48
+     * them while keeping any existing data in place. The only known case of its
49
+     * use is for `metadata`, but it could in theory be more general. As an
50
+     * example, say we have a `metadata` object that looks like this on the
51
+     * server side:
52
+     *
53
+     *     metadata = ["old" => "old_value"]
54
+     *
55
+     * If we update the object with `metadata[new]=new_value`, the server side
56
+     * object now has *both* fields:
57
+     *
58
+     *     metadata = ["old" => "old_value", "new" => "new_value"]
59
+     *
60
+     * This is okay in itself because usually users will want to treat it as
61
+     * additive:
62
+     *
63
+     *     $obj->metadata["new"] = "new_value";
64
+     *     $obj->save();
65
+     *
66
+     * However, in other cases, they may want to replace the entire existing
67
+     * contents:
68
+     *
69
+     *     $obj->metadata = ["new" => "new_value"];
70
+     *     $obj->save();
71
+     *
72
+     * This is where things get a little bit tricky because in order to clear
73
+     * any old keys that may have existed, we actually have to send an explicit
74
+     * empty string to the server. So the operation above would have to send
75
+     * this form to get the intended behavior:
76
+     *
77
+     *     metadata[old]=&metadata[new]=new_value
78
+     *
79
+     * This method allows us to track which parameters are considered additive,
80
+     * and lets us behave correctly where appropriate when serializing
81
+     * parameters to be sent.
82
+     *
83
+     * @return Util\Set Set of additive parameters
84
+     */
85
+    public static function getAdditiveParams()
86
+    {
87
+        static $additiveParams = null;
88
+        if ($additiveParams === null) {
89
+            // Set `metadata` as additive so that when it's set directly we remember
90
+            // to clear keys that may have been previously set by sending empty
91
+            // values for them.
92
+            //
93
+            // It's possible that not every object has `metadata`, but having this
94
+            // option set when there is no `metadata` field is not harmful.
95
+            $additiveParams = new Util\Set([
96
+                'metadata',
97
+            ]);
98
+        }
99
+        return $additiveParams;
100
+    }
101
+
102
+    public function __construct($id = null, $opts = null)
103
+    {
104
+        list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id);
105
+        $this->_opts = Util\RequestOptions::parse($opts);
106
+        $this->_originalValues = [];
107
+        $this->_values = [];
108
+        $this->_unsavedValues = new Util\Set();
109
+        $this->_transientValues = new Util\Set();
110
+        if ($id !== null) {
111
+            $this->_values['id'] = $id;
112
+        }
113
+    }
114
+
115
+    // Standard accessor magic methods
116
+    public function __set($k, $v)
117
+    {
118
+        if (static::getPermanentAttributes()->includes($k)) {
119
+            throw new \InvalidArgumentException(
120
+                "Cannot set $k on this object. HINT: you can't set: " .
121
+                join(', ', static::getPermanentAttributes()->toArray())
122
+            );
123
+        }
124
+
125
+        if ($v === "") {
126
+            throw new \InvalidArgumentException(
127
+                'You cannot set \''.$k.'\'to an empty string. '
128
+                .'We interpret empty strings as NULL in requests. '
129
+                .'You may set obj->'.$k.' = NULL to delete the property'
130
+            );
131
+        }
132
+
133
+        $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $this->_opts);
134
+        $this->dirtyValue($this->_values[$k]);
135
+        $this->_unsavedValues->add($k);
136
+    }
137
+
138
+    public function __isset($k)
139
+    {
140
+        return isset($this->_values[$k]);
141
+    }
142
+
143
+    public function __unset($k)
144
+    {
145
+        unset($this->_values[$k]);
146
+        $this->_transientValues->add($k);
147
+        $this->_unsavedValues->discard($k);
148
+    }
149
+
150
+    public function &__get($k)
151
+    {
152
+        // function should return a reference, using $nullval to return a reference to null
153
+        $nullval = null;
154
+        if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
155
+            return $this->_values[$k];
156
+        } elseif (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
157
+            $class = get_class($this);
158
+            $attrs = join(', ', array_keys($this->_values));
159
+            $message = "Telnyx Notice: Undefined property of $class instance: $k. "
160
+                    . "HINT: The $k attribute was set in the past, however. "
161
+                    . "It was then wiped when refreshing the object "
162
+                    . "with the result returned by Telnyx's API, "
163
+                    . "probably as a result of a save(). The attributes currently "
164
+                    . "available on this object are: $attrs";
165
+            Telnyx::getLogger()->error($message);
166
+            return $nullval;
167
+        } else {
168
+            $class = get_class($this);
169
+            Telnyx::getLogger()->error("Telnyx Notice: Undefined property of $class instance: $k");
170
+            return $nullval;
171
+        }
172
+    }
173
+
174
+    // Magic method for var_dump output. Only works with PHP >= 5.6
175
+    public function __debugInfo()
176
+    {
177
+        return $this->_values;
178
+    }
179
+
180
+    // ArrayAccess methods
181
+    public function offsetSet($k, $v)
182
+    {
183
+        $this->$k = $v;
184
+    }
185
+
186
+    public function offsetExists($k)
187
+    {
188
+        return array_key_exists($k, $this->_values);
189
+    }
190
+
191
+    public function offsetUnset($k)
192
+    {
193
+        unset($this->$k);
194
+    }
195
+
196
+    public function offsetGet($k)
197
+    {
198
+        return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
199
+    }
200
+
201
+    // Countable method
202
+    public function count()
203
+    {
204
+        return count($this->_values);
205
+    }
206
+
207
+    public function keys()
208
+    {
209
+        return array_keys($this->_values);
210
+    }
211
+
212
+    public function values()
213
+    {
214
+        return array_values($this->_values);
215
+    }
216
+
217
+    /**
218
+     * This unfortunately needs to be public to be used in Util\Util
219
+     *
220
+     * @param array $values
221
+     * @param null|string|array|Util\RequestOptions $opts
222
+     *
223
+     * @return static The object constructed from the given values.
224
+     */
225
+    public static function constructFrom($values, $opts = null)
226
+    {
227
+        $obj = new static(isset($values['id']) ? $values['id'] : null);
228
+        $obj->refreshFrom($values, $opts);
229
+        return $obj;
230
+    }
231
+
232
+    /**
233
+     * Refreshes this object using the provided values.
234
+     *
235
+     * @param array $values
236
+     * @param null|string|array|Util\RequestOptions $opts
237
+     * @param boolean $partial Defaults to false.
238
+     */
239
+    public function refreshFrom($values, $opts, $partial = false)
240
+    {
241
+        $this->_opts = Util\RequestOptions::parse($opts);
242
+
243
+        $this->_originalValues = self::deepCopy($values);
244
+
245
+        if ($values instanceof TelnyxObject) {
246
+            $values = $values->__toArray(true);
247
+        }
248
+
249
+        // Wipe old state before setting new.  This is useful for e.g. updating a
250
+        // customer, where there is no persistent card parameter.  Mark those values
251
+        // which don't persist as transient
252
+        if ($partial) {
253
+            $removed = new Util\Set();
254
+        } else {
255
+            $removed = new Util\Set(array_diff(array_keys($this->_values), array_keys($values)));
256
+        }
257
+
258
+        foreach ($removed->toArray() as $k) {
259
+            unset($this->$k);
260
+        }
261
+
262
+        $this->updateAttributes($values, $opts, false);
263
+        foreach ($values as $k => $v) {
264
+            $this->_transientValues->discard($k);
265
+            $this->_unsavedValues->discard($k);
266
+        }
267
+    }
268
+
269
+    /**
270
+     * Mass assigns attributes on the model.
271
+     *
272
+     * @param array $values
273
+     * @param null|string|array|Util\RequestOptions $opts
274
+     * @param boolean $dirty Defaults to true.
275
+     */
276
+    public function updateAttributes($values, $opts = null, $dirty = true)
277
+    {
278
+        foreach ($values as $k => $v) {
279
+            // Special-case metadata to always be cast as a TelnyxObject
280
+            // This is necessary in case metadata is empty, as PHP arrays do
281
+            // not differentiate between lists and hashes, and we consider
282
+            // empty arrays to be lists.
283
+            if (($k === "metadata") && (is_array($v))) {
284
+                $this->_values[$k] = TelnyxObject::constructFrom($v, $opts);
285
+            } else {
286
+                $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $opts);
287
+            }
288
+            if ($dirty) {
289
+                $this->dirtyValue($this->_values[$k]);
290
+            }
291
+            $this->_unsavedValues->add($k);
292
+        }
293
+    }
294
+
295
+    /**
296
+     * @return array A recursive mapping of attributes to values for this object,
297
+     *    including the proper value for deleted attributes.
298
+     */
299
+    public function serializeParameters($force = false)
300
+    {
301
+        $updateParams = [];
302
+
303
+        foreach ($this->_values as $k => $v) {
304
+            // There are a few reasons that we may want to add in a parameter for
305
+            // update:
306
+            //
307
+            //   1. The `$force` option has been set.
308
+            //   2. We know that it was modified.
309
+            //   3. Its value is a TelnyxObject. A TelnyxObject may contain modified
310
+            //      values within in that its parent TelnyxObject doesn't know about.
311
+            //
312
+            $original = array_key_exists($k, $this->_originalValues) ? $this->_originalValues[$k] : null;
313
+            $unsaved = $this->_unsavedValues->includes($k);
314
+            if ($force || $unsaved || $v instanceof TelnyxObject) {
315
+                $updateParams[$k] = $this->serializeParamsValue(
316
+                    $this->_values[$k],
317
+                    $original,
318
+                    $unsaved,
319
+                    $force,
320
+                    $k
321
+                );
322
+            }
323
+        }
324
+
325
+        // a `null` that makes it out of `serializeParamsValue` signals an empty
326
+        // value that we shouldn't appear in the serialized form of the object
327
+        $updateParams = array_filter(
328
+            $updateParams,
329
+            function ($v) {
330
+                return $v !== null;
331
+            }
332
+        );
333
+
334
+        return $updateParams;
335
+    }
336
+
337
+
338
+    public function serializeParamsValue($value, $original, $unsaved, $force, $key = null)
339
+    {
340
+        // The logic here is that essentially any object embedded in another
341
+        // object that had a `type` is actually an API resource of a different
342
+        // type that's been included in the response. These other resources must
343
+        // be updated from their proper endpoints, and therefore they are not
344
+        // included when serializing even if they've been modified.
345
+        //
346
+        // There are _some_ known exceptions though.
347
+        //
348
+        // For example, if the value is unsaved (meaning the user has set it), and
349
+        // it looks like the API resource is persisted with an ID, then we include
350
+        // the object so that parameters are serialized with a reference to its
351
+        // ID.
352
+        //
353
+        // Another example is that on save API calls it's sometimes desirable to
354
+        // update a customer's default source by setting a new card (or other)
355
+        // object with `->source=` and then saving the customer. The
356
+        // `saveWithParent` flag to override the default behavior allows us to
357
+        // handle these exceptions.
358
+        //
359
+        // We throw an error if a property was set explicitly but we can't do
360
+        // anything with it because the integration is probably not working as the
361
+        // user intended it to.
362
+        if ($value === null) {
363
+            return "";
364
+        } elseif (($value instanceof APIResource) && (!$value->saveWithParent)) {
365
+            if (!$unsaved) {
366
+                return null;
367
+            } elseif (isset($value->id)) {
368
+                return $value;
369
+            } else {
370
+                throw new \InvalidArgumentException(
371
+                    "Cannot save property `$key` containing an API resource of type " .
372
+                    get_class($value) . ". It doesn't appear to be persisted and is " .
373
+                    "not marked as `saveWithParent`."
374
+                );
375
+            }
376
+        } elseif (is_array($value)) {
377
+            if (Util\Util::isList($value)) {
378
+                // Sequential array, i.e. a list
379
+                $update = [];
380
+                foreach ($value as $v) {
381
+                    array_push($update, $this->serializeParamsValue($v, null, true, $force));
382
+                }
383
+                // This prevents an array that's unchanged from being resent.
384
+                if ($update !== $this->serializeParamsValue($original, null, true, $force, $key)) {
385
+                    return $update;
386
+                }
387
+            } else {
388
+                // Associative array, i.e. a map
389
+                return Util\Util::convertToTelnyxObject($value, $this->_opts)->serializeParameters();
390
+            }
391
+        } elseif ($value instanceof TelnyxObject) {
392
+            $update = $value->serializeParameters($force);
393
+            if ($original && $unsaved && $key && static::getAdditiveParams()->includes($key)) {
394
+                $update = array_merge(self::emptyValues($original), $update);
395
+            }
396
+            return $update;
397
+        } else {
398
+            return $value;
399
+        }
400
+    }
401
+
402
+    public function jsonSerialize()
403
+    {
404
+        return $this->__toArray(true);
405
+    }
406
+
407
+    public function __toJSON()
408
+    {
409
+        return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
410
+    }
411
+
412
+    public function __toString()
413
+    {
414
+        $class = get_class($this);
415
+        return $class . ' JSON: ' . $this->__toJSON();
416
+    }
417
+
418
+    public function __toArray($recursive = false)
419
+    {
420
+        if ($recursive) {
421
+            return Util\Util::convertTelnyxObjectToArray($this->_values);
422
+        } else {
423
+            return $this->_values;
424
+        }
425
+    }
426
+
427
+    /**
428
+     * Sets all keys within the TelnyxObject as unsaved so that they will be
429
+     * included with an update when `serializeParameters` is called. This
430
+     * method is also recursive, so any TelnyxObjects contained as values or
431
+     * which are values in a tenant array are also marked as dirty.
432
+     */
433
+    public function dirty()
434
+    {
435
+        $this->_unsavedValues = new Util\Set(array_keys($this->_values));
436
+        foreach ($this->_values as $k => $v) {
437
+            $this->dirtyValue($v);
438
+        }
439
+    }
440
+
441
+    protected function dirtyValue($value)
442
+    {
443
+        if (is_array($value)) {
444
+            foreach ($value as $v) {
445
+                $this->dirtyValue($v);
446
+            }
447
+        } elseif ($value instanceof TelnyxObject) {
448
+            $value->dirty();
449
+        }
450
+    }
451
+
452
+    /**
453
+     * Produces a deep copy of the given object including support for arrays
454
+     * and TelnyxObjects.
455
+     */
456
+    protected static function deepCopy($obj)
457
+    {
458
+        if (is_array($obj)) {
459
+            $copy = [];
460
+            foreach ($obj as $k => $v) {
461
+                $copy[$k] = self::deepCopy($v);
462
+            }
463
+            return $copy;
464
+        } elseif ($obj instanceof TelnyxObject) {
465
+            return $obj::constructFrom(
466
+                self::deepCopy($obj->_values),
467
+                clone $obj->_opts
468
+            );
469
+        } else {
470
+            return $obj;
471
+        }
472
+    }
473
+
474
+    /**
475
+     * Returns a hash of empty values for all the values that are in the given
476
+     * TelnyxObject.
477
+     */
478
+    public static function emptyValues($obj)
479
+    {
480
+        if (is_array($obj)) {
481
+            $values = $obj;
482
+        } elseif ($obj instanceof TelnyxObject) {
483
+            $values = $obj->_values;
484
+        } else {
485
+            throw new \InvalidArgumentException(
486
+                "empty_values got got unexpected object type: " . get_class($obj)
487
+            );
488
+        }
489
+        $update = array_fill_keys(array_keys($values), "");
490
+        return $update;
491
+    }
492
+
493
+    /**
494
+     * @return object The last response from the Telnyx API
495
+     */
496
+    public function getLastResponse()
497
+    {
498
+        return $this->_lastResponse;
499
+    }
500
+
501
+    /**
502
+     * Sets the last response from the Telnyx API
503
+     *
504
+     * @param ApiResponse $resp
505
+     * @return void
506
+     */
507
+    public function setLastResponse($resp)
508
+    {
509
+        $this->_lastResponse = $resp;
510
+    }
511
+
512
+    /**
513
+     * Indicates whether or not the resource has been deleted on the server.
514
+     * Note that some, but not all, resources can indicate whether they have
515
+     * been deleted.
516
+     *
517
+     * @return bool Whether the resource is deleted.
518
+     */
519
+    public function isDeleted()
520
+    {
521
+        return isset($this->_values['deleted']) ? $this->_values['deleted'] : false;
522
+    }
523
+}
Browse code

removed Telnyx directory

DoubleBastionAdmin authored on 19/08/2022 11:12:03
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,523 +0,0 @@
1
-<?php
2
-
3
-namespace Telnyx;
4
-
5
-/**
6
- * Class TelnyxObject
7
- *
8
- * @package Telnyx
9
- */
10
-class TelnyxObject implements \ArrayAccess, \Countable, \JsonSerializable
11
-{
12
-    protected $_opts;
13
-    protected $_originalValues;
14
-    protected $_values;
15
-    protected $_unsavedValues;
16
-    protected $_transientValues;
17
-    protected $_retrieveOptions;
18
-    protected $_lastResponse;
19
-
20
-    /**
21
-     * @return Util\Set Attributes that should not be sent to the API because
22
-     *    they're not updatable (e.g. ID).
23
-     */
24
-    public static function getPermanentAttributes()
25
-    {
26
-        static $permanentAttributes = null;
27
-        if ($permanentAttributes === null) {
28
-            $permanentAttributes = new Util\Set([
29
-                'id',
30
-            ]);
31
-        }
32
-        return $permanentAttributes;
33
-    }
34
-
35
-    /**
36
-     * Additive objects are subobjects in the API that don't have the same
37
-     * semantics as most subobjects, which are fully replaced when they're set.
38
-     * This is best illustrated by example. The `source` parameter sent when
39
-     * updating a subscription is *not* additive; if we set it:
40
-     *
41
-     *     source[object]=card&source[number]=123
42
-     *
43
-     * We expect the old `source` object to have been overwritten completely. If
44
-     * the previous source had an `address_state` key associated with it and we
45
-     * didn't send one this time, that value of `address_state` is gone.
46
-     *
47
-     * By contrast, additive objects are those that will have new data added to
48
-     * them while keeping any existing data in place. The only known case of its
49
-     * use is for `metadata`, but it could in theory be more general. As an
50
-     * example, say we have a `metadata` object that looks like this on the
51
-     * server side:
52
-     *
53
-     *     metadata = ["old" => "old_value"]
54
-     *
55
-     * If we update the object with `metadata[new]=new_value`, the server side
56
-     * object now has *both* fields:
57
-     *
58
-     *     metadata = ["old" => "old_value", "new" => "new_value"]
59
-     *
60
-     * This is okay in itself because usually users will want to treat it as
61
-     * additive:
62
-     *
63
-     *     $obj->metadata["new"] = "new_value";
64
-     *     $obj->save();
65
-     *
66
-     * However, in other cases, they may want to replace the entire existing
67
-     * contents:
68
-     *
69
-     *     $obj->metadata = ["new" => "new_value"];
70
-     *     $obj->save();
71
-     *
72
-     * This is where things get a little bit tricky because in order to clear
73
-     * any old keys that may have existed, we actually have to send an explicit
74
-     * empty string to the server. So the operation above would have to send
75
-     * this form to get the intended behavior:
76
-     *
77
-     *     metadata[old]=&metadata[new]=new_value
78
-     *
79
-     * This method allows us to track which parameters are considered additive,
80
-     * and lets us behave correctly where appropriate when serializing
81
-     * parameters to be sent.
82
-     *
83
-     * @return Util\Set Set of additive parameters
84
-     */
85
-    public static function getAdditiveParams()
86
-    {
87
-        static $additiveParams = null;
88
-        if ($additiveParams === null) {
89
-            // Set `metadata` as additive so that when it's set directly we remember
90
-            // to clear keys that may have been previously set by sending empty
91
-            // values for them.
92
-            //
93
-            // It's possible that not every object has `metadata`, but having this
94
-            // option set when there is no `metadata` field is not harmful.
95
-            $additiveParams = new Util\Set([
96
-                'metadata',
97
-            ]);
98
-        }
99
-        return $additiveParams;
100
-    }
101
-
102
-    public function __construct($id = null, $opts = null)
103
-    {
104
-        list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id);
105
-        $this->_opts = Util\RequestOptions::parse($opts);
106
-        $this->_originalValues = [];
107
-        $this->_values = [];
108
-        $this->_unsavedValues = new Util\Set();
109
-        $this->_transientValues = new Util\Set();
110
-        if ($id !== null) {
111
-            $this->_values['id'] = $id;
112
-        }
113
-    }
114
-
115
-    // Standard accessor magic methods
116
-    public function __set($k, $v)
117
-    {
118
-        if (static::getPermanentAttributes()->includes($k)) {
119
-            throw new \InvalidArgumentException(
120
-                "Cannot set $k on this object. HINT: you can't set: " .
121
-                join(', ', static::getPermanentAttributes()->toArray())
122
-            );
123
-        }
124
-
125
-        if ($v === "") {
126
-            throw new \InvalidArgumentException(
127
-                'You cannot set \''.$k.'\'to an empty string. '
128
-                .'We interpret empty strings as NULL in requests. '
129
-                .'You may set obj->'.$k.' = NULL to delete the property'
130
-            );
131
-        }
132
-
133
-        $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $this->_opts);
134
-        $this->dirtyValue($this->_values[$k]);
135
-        $this->_unsavedValues->add($k);
136
-    }
137
-
138
-    public function __isset($k)
139
-    {
140
-        return isset($this->_values[$k]);
141
-    }
142
-
143
-    public function __unset($k)
144
-    {
145
-        unset($this->_values[$k]);
146
-        $this->_transientValues->add($k);
147
-        $this->_unsavedValues->discard($k);
148
-    }
149
-
150
-    public function &__get($k)
151
-    {
152
-        // function should return a reference, using $nullval to return a reference to null
153
-        $nullval = null;
154
-        if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
155
-            return $this->_values[$k];
156
-        } elseif (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
157
-            $class = get_class($this);
158
-            $attrs = join(', ', array_keys($this->_values));
159
-            $message = "Telnyx Notice: Undefined property of $class instance: $k. "
160
-                    . "HINT: The $k attribute was set in the past, however. "
161
-                    . "It was then wiped when refreshing the object "
162
-                    . "with the result returned by Telnyx's API, "
163
-                    . "probably as a result of a save(). The attributes currently "
164
-                    . "available on this object are: $attrs";
165
-            Telnyx::getLogger()->error($message);
166
-            return $nullval;
167
-        } else {
168
-            $class = get_class($this);
169
-            Telnyx::getLogger()->error("Telnyx Notice: Undefined property of $class instance: $k");
170
-            return $nullval;
171
-        }
172
-    }
173
-
174
-    // Magic method for var_dump output. Only works with PHP >= 5.6
175
-    public function __debugInfo()
176
-    {
177
-        return $this->_values;
178
-    }
179
-
180
-    // ArrayAccess methods
181
-    public function offsetSet($k, $v)
182
-    {
183
-        $this->$k = $v;
184
-    }
185
-
186
-    public function offsetExists($k)
187
-    {
188
-        return array_key_exists($k, $this->_values);
189
-    }
190
-
191
-    public function offsetUnset($k)
192
-    {
193
-        unset($this->$k);
194
-    }
195
-
196
-    public function offsetGet($k)
197
-    {
198
-        return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
199
-    }
200
-
201
-    // Countable method
202
-    public function count()
203
-    {
204
-        return count($this->_values);
205
-    }
206
-
207
-    public function keys()
208
-    {
209
-        return array_keys($this->_values);
210
-    }
211
-
212
-    public function values()
213
-    {
214
-        return array_values($this->_values);
215
-    }
216
-
217
-    /**
218
-     * This unfortunately needs to be public to be used in Util\Util
219
-     *
220
-     * @param array $values
221
-     * @param null|string|array|Util\RequestOptions $opts
222
-     *
223
-     * @return static The object constructed from the given values.
224
-     */
225
-    public static function constructFrom($values, $opts = null)
226
-    {
227
-        $obj = new static(isset($values['id']) ? $values['id'] : null);
228
-        $obj->refreshFrom($values, $opts);
229
-        return $obj;
230
-    }
231
-
232
-    /**
233
-     * Refreshes this object using the provided values.
234
-     *
235
-     * @param array $values
236
-     * @param null|string|array|Util\RequestOptions $opts
237
-     * @param boolean $partial Defaults to false.
238
-     */
239
-    public function refreshFrom($values, $opts, $partial = false)
240
-    {
241
-        $this->_opts = Util\RequestOptions::parse($opts);
242
-
243
-        $this->_originalValues = self::deepCopy($values);
244
-
245
-        if ($values instanceof TelnyxObject) {
246
-            $values = $values->__toArray(true);
247
-        }
248
-
249
-        // Wipe old state before setting new.  This is useful for e.g. updating a
250
-        // customer, where there is no persistent card parameter.  Mark those values
251
-        // which don't persist as transient
252
-        if ($partial) {
253
-            $removed = new Util\Set();
254
-        } else {
255
-            $removed = new Util\Set(array_diff(array_keys($this->_values), array_keys($values)));
256
-        }
257
-
258
-        foreach ($removed->toArray() as $k) {
259
-            unset($this->$k);
260
-        }
261
-
262
-        $this->updateAttributes($values, $opts, false);
263
-        foreach ($values as $k => $v) {
264
-            $this->_transientValues->discard($k);
265
-            $this->_unsavedValues->discard($k);
266
-        }
267
-    }
268
-
269
-    /**
270
-     * Mass assigns attributes on the model.
271
-     *
272
-     * @param array $values
273
-     * @param null|string|array|Util\RequestOptions $opts
274
-     * @param boolean $dirty Defaults to true.
275
-     */
276
-    public function updateAttributes($values, $opts = null, $dirty = true)
277
-    {
278
-        foreach ($values as $k => $v) {
279
-            // Special-case metadata to always be cast as a TelnyxObject
280
-            // This is necessary in case metadata is empty, as PHP arrays do
281
-            // not differentiate between lists and hashes, and we consider
282
-            // empty arrays to be lists.
283
-            if (($k === "metadata") && (is_array($v))) {
284
-                $this->_values[$k] = TelnyxObject::constructFrom($v, $opts);
285
-            } else {
286
-                $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $opts);
287
-            }
288
-            if ($dirty) {
289
-                $this->dirtyValue($this->_values[$k]);
290
-            }
291
-            $this->_unsavedValues->add($k);
292
-        }
293
-    }
294
-
295
-    /**
296
-     * @return array A recursive mapping of attributes to values for this object,
297
-     *    including the proper value for deleted attributes.
298
-     */
299
-    public function serializeParameters($force = false)
300
-    {
301
-        $updateParams = [];
302
-
303
-        foreach ($this->_values as $k => $v) {
304
-            // There are a few reasons that we may want to add in a parameter for
305
-            // update:
306
-            //
307
-            //   1. The `$force` option has been set.
308
-            //   2. We know that it was modified.
309
-            //   3. Its value is a TelnyxObject. A TelnyxObject may contain modified
310
-            //      values within in that its parent TelnyxObject doesn't know about.
311
-            //
312
-            $original = array_key_exists($k, $this->_originalValues) ? $this->_originalValues[$k] : null;
313
-            $unsaved = $this->_unsavedValues->includes($k);
314
-            if ($force || $unsaved || $v instanceof TelnyxObject) {
315
-                $updateParams[$k] = $this->serializeParamsValue(
316
-                    $this->_values[$k],
317
-                    $original,
318
-                    $unsaved,
319
-                    $force,
320
-                    $k
321
-                );
322
-            }
323
-        }
324
-
325
-        // a `null` that makes it out of `serializeParamsValue` signals an empty
326
-        // value that we shouldn't appear in the serialized form of the object
327
-        $updateParams = array_filter(
328
-            $updateParams,
329
-            function ($v) {
330
-                return $v !== null;
331
-            }
332
-        );
333
-
334
-        return $updateParams;
335
-    }
336
-
337
-
338
-    public function serializeParamsValue($value, $original, $unsaved, $force, $key = null)
339
-    {
340
-        // The logic here is that essentially any object embedded in another
341
-        // object that had a `type` is actually an API resource of a different
342
-        // type that's been included in the response. These other resources must
343
-        // be updated from their proper endpoints, and therefore they are not
344
-        // included when serializing even if they've been modified.
345
-        //
346
-        // There are _some_ known exceptions though.
347
-        //
348
-        // For example, if the value is unsaved (meaning the user has set it), and
349
-        // it looks like the API resource is persisted with an ID, then we include
350
-        // the object so that parameters are serialized with a reference to its
351
-        // ID.
352
-        //
353
-        // Another example is that on save API calls it's sometimes desirable to
354
-        // update a customer's default source by setting a new card (or other)
355
-        // object with `->source=` and then saving the customer. The
356
-        // `saveWithParent` flag to override the default behavior allows us to
357
-        // handle these exceptions.
358
-        //
359
-        // We throw an error if a property was set explicitly but we can't do
360
-        // anything with it because the integration is probably not working as the
361
-        // user intended it to.
362
-        if ($value === null) {
363
-            return "";
364
-        } elseif (($value instanceof APIResource) && (!$value->saveWithParent)) {
365
-            if (!$unsaved) {
366
-                return null;
367
-            } elseif (isset($value->id)) {
368
-                return $value;
369
-            } else {
370
-                throw new \InvalidArgumentException(
371
-                    "Cannot save property `$key` containing an API resource of type " .
372
-                    get_class($value) . ". It doesn't appear to be persisted and is " .
373
-                    "not marked as `saveWithParent`."
374
-                );
375
-            }
376
-        } elseif (is_array($value)) {
377
-            if (Util\Util::isList($value)) {
378
-                // Sequential array, i.e. a list
379
-                $update = [];
380
-                foreach ($value as $v) {
381
-                    array_push($update, $this->serializeParamsValue($v, null, true, $force));
382
-                }
383
-                // This prevents an array that's unchanged from being resent.
384
-                if ($update !== $this->serializeParamsValue($original, null, true, $force, $key)) {
385
-                    return $update;
386
-                }
387
-            } else {
388
-                // Associative array, i.e. a map
389
-                return Util\Util::convertToTelnyxObject($value, $this->_opts)->serializeParameters();
390
-            }
391
-        } elseif ($value instanceof TelnyxObject) {
392
-            $update = $value->serializeParameters($force);
393
-            if ($original && $unsaved && $key && static::getAdditiveParams()->includes($key)) {
394
-                $update = array_merge(self::emptyValues($original), $update);
395
-            }
396
-            return $update;
397
-        } else {
398
-            return $value;
399
-        }
400
-    }
401
-
402
-    public function jsonSerialize()
403
-    {
404
-        return $this->__toArray(true);
405
-    }
406
-
407
-    public function __toJSON()
408
-    {
409
-        return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
410
-    }
411
-
412
-    public function __toString()
413
-    {
414
-        $class = get_class($this);
415
-        return $class . ' JSON: ' . $this->__toJSON();
416
-    }
417
-
418
-    public function __toArray($recursive = false)
419
-    {
420
-        if ($recursive) {
421
-            return Util\Util::convertTelnyxObjectToArray($this->_values);
422
-        } else {
423
-            return $this->_values;
424
-        }
425
-    }
426
-
427
-    /**
428
-     * Sets all keys within the TelnyxObject as unsaved so that they will be
429
-     * included with an update when `serializeParameters` is called. This
430
-     * method is also recursive, so any TelnyxObjects contained as values or
431
-     * which are values in a tenant array are also marked as dirty.
432
-     */
433
-    public function dirty()
434
-    {
435
-        $this->_unsavedValues = new Util\Set(array_keys($this->_values));
436
-        foreach ($this->_values as $k => $v) {
437
-            $this->dirtyValue($v);
438
-        }
439
-    }
440
-
441
-    protected function dirtyValue($value)
442
-    {
443
-        if (is_array($value)) {
444
-            foreach ($value as $v) {
445
-                $this->dirtyValue($v);
446
-            }
447
-        } elseif ($value instanceof TelnyxObject) {
448
-            $value->dirty();
449
-        }
450
-    }
451
-
452
-    /**
453
-     * Produces a deep copy of the given object including support for arrays
454
-     * and TelnyxObjects.
455
-     */
456
-    protected static function deepCopy($obj)
457
-    {
458
-        if (is_array($obj)) {
459
-            $copy = [];
460
-            foreach ($obj as $k => $v) {
461
-                $copy[$k] = self::deepCopy($v);
462
-            }
463
-            return $copy;
464
-        } elseif ($obj instanceof TelnyxObject) {
465
-            return $obj::constructFrom(
466
-                self::deepCopy($obj->_values),
467
-                clone $obj->_opts
468
-            );
469
-        } else {
470
-            return $obj;
471
-        }
472
-    }
473
-
474
-    /**
475
-     * Returns a hash of empty values for all the values that are in the given
476
-     * TelnyxObject.
477
-     */
478
-    public static function emptyValues($obj)
479
-    {
480
-        if (is_array($obj)) {
481
-            $values = $obj;
482
-        } elseif ($obj instanceof TelnyxObject) {
483
-            $values = $obj->_values;
484
-        } else {
485
-            throw new \InvalidArgumentException(
486
-                "empty_values got got unexpected object type: " . get_class($obj)
487
-            );
488
-        }
489
-        $update = array_fill_keys(array_keys($values), "");
490
-        return $update;
491
-    }
492
-
493
-    /**
494
-     * @return object The last response from the Telnyx API
495
-     */
496
-    public function getLastResponse()
497
-    {
498
-        return $this->_lastResponse;
499
-    }
500
-
501
-    /**
502
-     * Sets the last response from the Telnyx API
503
-     *
504
-     * @param ApiResponse $resp
505
-     * @return void
506
-     */
507
-    public function setLastResponse($resp)
508
-    {
509
-        $this->_lastResponse = $resp;
510
-    }
511
-
512
-    /**
513
-     * Indicates whether or not the resource has been deleted on the server.
514
-     * Note that some, but not all, resources can indicate whether they have
515
-     * been deleted.
516
-     *
517
-     * @return bool Whether the resource is deleted.
518
-     */
519
-    public function isDeleted()
520
-    {
521
-        return isset($this->_values['deleted']) ? $this->_values['deleted'] : false;
522
-    }
523
-}
Browse code

Created repository.

DoubleBastionAdmin authored on 01/03/2022 23:47:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,523 @@
1
+<?php
2
+
3
+namespace Telnyx;
4
+
5
+/**
6
+ * Class TelnyxObject
7
+ *
8
+ * @package Telnyx
9
+ */
10
+class TelnyxObject implements \ArrayAccess, \Countable, \JsonSerializable
11
+{
12
+    protected $_opts;
13
+    protected $_originalValues;
14
+    protected $_values;
15
+    protected $_unsavedValues;
16
+    protected $_transientValues;
17
+    protected $_retrieveOptions;
18
+    protected $_lastResponse;
19
+
20
+    /**
21
+     * @return Util\Set Attributes that should not be sent to the API because
22
+     *    they're not updatable (e.g. ID).
23
+     */
24
+    public static function getPermanentAttributes()
25
+    {
26
+        static $permanentAttributes = null;
27
+        if ($permanentAttributes === null) {
28
+            $permanentAttributes = new Util\Set([
29
+                'id',
30
+            ]);
31
+        }
32
+        return $permanentAttributes;
33
+    }
34
+
35
+    /**
36
+     * Additive objects are subobjects in the API that don't have the same
37
+     * semantics as most subobjects, which are fully replaced when they're set.
38
+     * This is best illustrated by example. The `source` parameter sent when
39
+     * updating a subscription is *not* additive; if we set it:
40
+     *
41
+     *     source[object]=card&source[number]=123
42
+     *
43
+     * We expect the old `source` object to have been overwritten completely. If
44
+     * the previous source had an `address_state` key associated with it and we
45
+     * didn't send one this time, that value of `address_state` is gone.
46
+     *
47
+     * By contrast, additive objects are those that will have new data added to
48
+     * them while keeping any existing data in place. The only known case of its
49
+     * use is for `metadata`, but it could in theory be more general. As an
50
+     * example, say we have a `metadata` object that looks like this on the
51
+     * server side:
52
+     *
53
+     *     metadata = ["old" => "old_value"]
54
+     *
55
+     * If we update the object with `metadata[new]=new_value`, the server side
56
+     * object now has *both* fields:
57
+     *
58
+     *     metadata = ["old" => "old_value", "new" => "new_value"]
59
+     *
60
+     * This is okay in itself because usually users will want to treat it as
61
+     * additive:
62
+     *
63
+     *     $obj->metadata["new"] = "new_value";
64
+     *     $obj->save();
65
+     *
66
+     * However, in other cases, they may want to replace the entire existing
67
+     * contents:
68
+     *
69
+     *     $obj->metadata = ["new" => "new_value"];
70
+     *     $obj->save();
71
+     *
72
+     * This is where things get a little bit tricky because in order to clear
73
+     * any old keys that may have existed, we actually have to send an explicit
74
+     * empty string to the server. So the operation above would have to send
75
+     * this form to get the intended behavior:
76
+     *
77
+     *     metadata[old]=&metadata[new]=new_value
78
+     *
79
+     * This method allows us to track which parameters are considered additive,
80
+     * and lets us behave correctly where appropriate when serializing
81
+     * parameters to be sent.
82
+     *
83
+     * @return Util\Set Set of additive parameters
84
+     */
85
+    public static function getAdditiveParams()
86
+    {
87
+        static $additiveParams = null;
88
+        if ($additiveParams === null) {
89
+            // Set `metadata` as additive so that when it's set directly we remember
90
+            // to clear keys that may have been previously set by sending empty
91
+            // values for them.
92
+            //
93
+            // It's possible that not every object has `metadata`, but having this
94
+            // option set when there is no `metadata` field is not harmful.
95
+            $additiveParams = new Util\Set([
96
+                'metadata',
97
+            ]);
98
+        }
99
+        return $additiveParams;
100
+    }
101
+
102
+    public function __construct($id = null, $opts = null)
103
+    {
104
+        list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id);
105
+        $this->_opts = Util\RequestOptions::parse($opts);
106
+        $this->_originalValues = [];
107
+        $this->_values = [];
108
+        $this->_unsavedValues = new Util\Set();
109
+        $this->_transientValues = new Util\Set();
110
+        if ($id !== null) {
111
+            $this->_values['id'] = $id;
112
+        }
113
+    }
114
+
115
+    // Standard accessor magic methods
116
+    public function __set($k, $v)
117
+    {
118
+        if (static::getPermanentAttributes()->includes($k)) {
119
+            throw new \InvalidArgumentException(
120
+                "Cannot set $k on this object. HINT: you can't set: " .
121
+                join(', ', static::getPermanentAttributes()->toArray())
122
+            );
123
+        }
124
+
125
+        if ($v === "") {
126
+            throw new \InvalidArgumentException(
127
+                'You cannot set \''.$k.'\'to an empty string. '
128
+                .'We interpret empty strings as NULL in requests. '
129
+                .'You may set obj->'.$k.' = NULL to delete the property'
130
+            );
131
+        }
132
+
133
+        $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $this->_opts);
134
+        $this->dirtyValue($this->_values[$k]);
135
+        $this->_unsavedValues->add($k);
136
+    }
137
+
138
+    public function __isset($k)
139
+    {
140
+        return isset($this->_values[$k]);
141
+    }
142
+
143
+    public function __unset($k)
144
+    {
145
+        unset($this->_values[$k]);
146
+        $this->_transientValues->add($k);
147
+        $this->_unsavedValues->discard($k);
148
+    }
149
+
150
+    public function &__get($k)
151
+    {
152
+        // function should return a reference, using $nullval to return a reference to null
153
+        $nullval = null;
154
+        if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
155
+            return $this->_values[$k];
156
+        } elseif (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
157
+            $class = get_class($this);
158
+            $attrs = join(', ', array_keys($this->_values));
159
+            $message = "Telnyx Notice: Undefined property of $class instance: $k. "
160
+                    . "HINT: The $k attribute was set in the past, however. "
161
+                    . "It was then wiped when refreshing the object "
162
+                    . "with the result returned by Telnyx's API, "
163
+                    . "probably as a result of a save(). The attributes currently "
164
+                    . "available on this object are: $attrs";
165
+            Telnyx::getLogger()->error($message);
166
+            return $nullval;
167
+        } else {
168
+            $class = get_class($this);
169
+            Telnyx::getLogger()->error("Telnyx Notice: Undefined property of $class instance: $k");
170
+            return $nullval;
171
+        }
172
+    }
173
+
174
+    // Magic method for var_dump output. Only works with PHP >= 5.6
175
+    public function __debugInfo()
176
+    {
177
+        return $this->_values;
178
+    }
179
+
180
+    // ArrayAccess methods
181
+    public function offsetSet($k, $v)
182
+    {
183
+        $this->$k = $v;
184
+    }
185
+
186
+    public function offsetExists($k)
187
+    {
188
+        return array_key_exists($k, $this->_values);
189
+    }
190
+
191
+    public function offsetUnset($k)
192
+    {
193
+        unset($this->$k);
194
+    }
195
+
196
+    public function offsetGet($k)
197
+    {
198
+        return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
199
+    }
200
+
201
+    // Countable method
202
+    public function count()
203
+    {
204
+        return count($this->_values);
205
+    }
206
+
207
+    public function keys()
208
+    {
209
+        return array_keys($this->_values);
210
+    }
211
+
212
+    public function values()
213
+    {
214
+        return array_values($this->_values);
215
+    }
216
+
217
+    /**
218
+     * This unfortunately needs to be public to be used in Util\Util
219
+     *
220
+     * @param array $values
221
+     * @param null|string|array|Util\RequestOptions $opts
222
+     *
223
+     * @return static The object constructed from the given values.
224
+     */
225
+    public static function constructFrom($values, $opts = null)
226
+    {
227
+        $obj = new static(isset($values['id']) ? $values['id'] : null);
228
+        $obj->refreshFrom($values, $opts);
229
+        return $obj;
230
+    }
231
+
232
+    /**
233
+     * Refreshes this object using the provided values.
234
+     *
235
+     * @param array $values
236
+     * @param null|string|array|Util\RequestOptions $opts
237
+     * @param boolean $partial Defaults to false.
238
+     */
239
+    public function refreshFrom($values, $opts, $partial = false)
240
+    {
241
+        $this->_opts = Util\RequestOptions::parse($opts);
242
+
243
+        $this->_originalValues = self::deepCopy($values);
244
+
245
+        if ($values instanceof TelnyxObject) {
246
+            $values = $values->__toArray(true);
247
+        }
248
+
249
+        // Wipe old state before setting new.  This is useful for e.g. updating a
250
+        // customer, where there is no persistent card parameter.  Mark those values
251
+        // which don't persist as transient
252
+        if ($partial) {
253
+            $removed = new Util\Set();
254
+        } else {
255
+            $removed = new Util\Set(array_diff(array_keys($this->_values), array_keys($values)));
256
+        }
257
+
258
+        foreach ($removed->toArray() as $k) {
259
+            unset($this->$k);
260
+        }
261
+
262
+        $this->updateAttributes($values, $opts, false);
263
+        foreach ($values as $k => $v) {
264
+            $this->_transientValues->discard($k);
265
+            $this->_unsavedValues->discard($k);
266
+        }
267
+    }
268
+
269
+    /**
270
+     * Mass assigns attributes on the model.
271
+     *
272
+     * @param array $values
273
+     * @param null|string|array|Util\RequestOptions $opts
274
+     * @param boolean $dirty Defaults to true.
275
+     */
276
+    public function updateAttributes($values, $opts = null, $dirty = true)
277
+    {
278
+        foreach ($values as $k => $v) {
279
+            // Special-case metadata to always be cast as a TelnyxObject
280
+            // This is necessary in case metadata is empty, as PHP arrays do
281
+            // not differentiate between lists and hashes, and we consider
282
+            // empty arrays to be lists.
283
+            if (($k === "metadata") && (is_array($v))) {
284
+                $this->_values[$k] = TelnyxObject::constructFrom($v, $opts);
285
+            } else {
286
+                $this->_values[$k] = Util\Util::convertToTelnyxObject($v, $opts);
287
+            }
288
+            if ($dirty) {
289
+                $this->dirtyValue($this->_values[$k]);
290
+            }
291
+            $this->_unsavedValues->add($k);
292
+        }
293
+    }
294
+
295
+    /**
296
+     * @return array A recursive mapping of attributes to values for this object,
297
+     *    including the proper value for deleted attributes.
298
+     */
299
+    public function serializeParameters($force = false)
300
+    {
301
+        $updateParams = [];
302
+
303
+        foreach ($this->_values as $k => $v) {
304
+            // There are a few reasons that we may want to add in a parameter for
305
+            // update:
306
+            //
307
+            //   1. The `$force` option has been set.
308
+            //   2. We know that it was modified.
309
+            //   3. Its value is a TelnyxObject. A TelnyxObject may contain modified
310
+            //      values within in that its parent TelnyxObject doesn't know about.
311
+            //
312
+            $original = array_key_exists($k, $this->_originalValues) ? $this->_originalValues[$k] : null;
313
+            $unsaved = $this->_unsavedValues->includes($k);
314
+            if ($force || $unsaved || $v instanceof TelnyxObject) {
315
+                $updateParams[$k] = $this->serializeParamsValue(
316
+                    $this->_values[$k],
317
+                    $original,
318
+                    $unsaved,
319
+                    $force,
320
+                    $k
321
+                );
322
+            }
323
+        }
324
+
325
+        // a `null` that makes it out of `serializeParamsValue` signals an empty
326
+        // value that we shouldn't appear in the serialized form of the object
327
+        $updateParams = array_filter(
328
+            $updateParams,
329
+            function ($v) {
330
+                return $v !== null;
331
+            }
332
+        );
333
+
334
+        return $updateParams;
335
+    }
336
+
337
+
338
+    public function serializeParamsValue($value, $original, $unsaved, $force, $key = null)
339
+    {
340
+        // The logic here is that essentially any object embedded in another
341
+        // object that had a `type` is actually an API resource of a different
342
+        // type that's been included in the response. These other resources must
343
+        // be updated from their proper endpoints, and therefore they are not
344
+        // included when serializing even if they've been modified.
345
+        //
346
+        // There are _some_ known exceptions though.
347
+        //
348
+        // For example, if the value is unsaved (meaning the user has set it), and
349
+        // it looks like the API resource is persisted with an ID, then we include
350
+        // the object so that parameters are serialized with a reference to its
351
+        // ID.
352
+        //
353
+        // Another example is that on save API calls it's sometimes desirable to
354
+        // update a customer's default source by setting a new card (or other)
355
+        // object with `->source=` and then saving the customer. The
356
+        // `saveWithParent` flag to override the default behavior allows us to
357
+        // handle these exceptions.
358
+        //
359
+        // We throw an error if a property was set explicitly but we can't do
360
+        // anything with it because the integration is probably not working as the
361
+        // user intended it to.
362
+        if ($value === null) {
363
+            return "";
364
+        } elseif (($value instanceof APIResource) && (!$value->saveWithParent)) {
365
+            if (!$unsaved) {
366
+                return null;
367
+            } elseif (isset($value->id)) {
368
+                return $value;
369
+            } else {
370
+                throw new \InvalidArgumentException(
371
+                    "Cannot save property `$key` containing an API resource of type " .
372
+                    get_class($value) . ". It doesn't appear to be persisted and is " .
373
+                    "not marked as `saveWithParent`."
374
+                );
375
+            }
376
+        } elseif (is_array($value)) {
377
+            if (Util\Util::isList($value)) {
378
+                // Sequential array, i.e. a list
379
+                $update = [];
380
+                foreach ($value as $v) {
381
+                    array_push($update, $this->serializeParamsValue($v, null, true, $force));
382
+                }
383
+                // This prevents an array that's unchanged from being resent.
384
+                if ($update !== $this->serializeParamsValue($original, null, true, $force, $key)) {
385
+                    return $update;
386
+                }
387
+            } else {
388
+                // Associative array, i.e. a map
389
+                return Util\Util::convertToTelnyxObject($value, $this->_opts)->serializeParameters();
390
+            }
391
+        } elseif ($value instanceof TelnyxObject) {
392
+            $update = $value->serializeParameters($force);
393
+            if ($original && $unsaved && $key && static::getAdditiveParams()->includes($key)) {
394
+                $update = array_merge(self::emptyValues($original), $update);
395
+            }
396
+            return $update;
397
+        } else {
398
+            return $value;
399
+        }
400
+    }
401
+
402
+    public function jsonSerialize()
403
+    {
404
+        return $this->__toArray(true);
405
+    }
406
+
407
+    public function __toJSON()
408
+    {
409
+        return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
410
+    }
411
+
412
+    public function __toString()
413
+    {
414
+        $class = get_class($this);
415
+        return $class . ' JSON: ' . $this->__toJSON();
416
+    }
417
+
418
+    public function __toArray($recursive = false)
419
+    {
420
+        if ($recursive) {
421
+            return Util\Util::convertTelnyxObjectToArray($this->_values);
422
+        } else {
423
+            return $this->_values;
424
+        }
425
+    }
426
+
427
+    /**
428
+     * Sets all keys within the TelnyxObject as unsaved so that they will be
429
+     * included with an update when `serializeParameters` is called. This
430
+     * method is also recursive, so any TelnyxObjects contained as values or
431
+     * which are values in a tenant array are also marked as dirty.
432
+     */
433
+    public function dirty()
434
+    {
435
+        $this->_unsavedValues = new Util\Set(array_keys($this->_values));
436
+        foreach ($this->_values as $k => $v) {
437
+            $this->dirtyValue($v);
438
+        }
439
+    }
440
+
441
+    protected function dirtyValue($value)
442
+    {
443
+        if (is_array($value)) {
444
+            foreach ($value as $v) {
445
+                $this->dirtyValue($v);
446
+            }
447
+        } elseif ($value instanceof TelnyxObject) {
448
+            $value->dirty();
449
+        }
450
+    }
451
+
452
+    /**
453
+     * Produces a deep copy of the given object including support for arrays
454
+     * and TelnyxObjects.
455
+     */
456
+    protected static function deepCopy($obj)
457
+    {
458
+        if (is_array($obj)) {
459
+            $copy = [];
460
+            foreach ($obj as $k => $v) {
461
+                $copy[$k] = self::deepCopy($v);
462
+            }
463
+            return $copy;
464
+        } elseif ($obj instanceof TelnyxObject) {
465
+            return $obj::constructFrom(
466
+                self::deepCopy($obj->_values),
467
+                clone $obj->_opts
468
+            );
469
+        } else {
470
+            return $obj;
471
+        }
472
+    }
473
+
474
+    /**
475
+     * Returns a hash of empty values for all the values that are in the given
476
+     * TelnyxObject.
477
+     */
478
+    public static function emptyValues($obj)
479
+    {
480
+        if (is_array($obj)) {
481
+            $values = $obj;
482
+        } elseif ($obj instanceof TelnyxObject) {
483
+            $values = $obj->_values;
484
+        } else {
485
+            throw new \InvalidArgumentException(
486
+                "empty_values got got unexpected object type: " . get_class($obj)
487
+            );
488
+        }
489
+        $update = array_fill_keys(array_keys($values), "");
490
+        return $update;
491
+    }
492
+
493
+    /**
494
+     * @return object The last response from the Telnyx API
495
+     */
496
+    public function getLastResponse()
497
+    {
498
+        return $this->_lastResponse;
499
+    }
500
+
501
+    /**
502
+     * Sets the last response from the Telnyx API
503
+     *
504
+     * @param ApiResponse $resp
505
+     * @return void
506
+     */
507
+    public function setLastResponse($resp)
508
+    {
509
+        $this->_lastResponse = $resp;
510
+    }
511
+
512
+    /**
513
+     * Indicates whether or not the resource has been deleted on the server.
514
+     * Note that some, but not all, resources can indicate whether they have
515
+     * been deleted.
516
+     *
517
+     * @return bool Whether the resource is deleted.
518
+     */
519
+    public function isDeleted()
520
+    {
521
+        return isset($this->_values['deleted']) ? $this->_values['deleted'] : false;
522
+    }
523
+}