Test Failed
Branch development (1f4e65)
by Robert
11:57
created

LiveEngageLaravel::getSettings()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 14
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * Root class file for all api wrappers.
4
 *
5
 * @package LivePersonInc\LiveEngageLaravel
6
 *
7
 */
8
9
namespace LivePersonInc\LiveEngageLaravel;
10
11
use Carbon\Carbon;
12
use GuzzleHttp\Client;
13
use GuzzleHttp\HandlerStack;
14
use GuzzleHttp\Subscriber\Oauth\Oauth1;
15
use LivePersonInc\LiveEngageLaravel\Models\Info;
16
use LivePersonInc\LiveEngageLaravel\Models\MetaData;
17
use LivePersonInc\LiveEngageLaravel\Models\AccountStatus;
18
use LivePersonInc\LiveEngageLaravel\Models\MessagingInfo;
19
use LivePersonInc\LiveEngageLaravel\Models\Payload;
20
use LivePersonInc\LiveEngageLaravel\Models\Visitor;
21
use LivePersonInc\LiveEngageLaravel\Models\Agent;
22
use LivePersonInc\LiveEngageLaravel\Models\Skill;
23
use LivePersonInc\LiveEngageLaravel\Models\Campaign;
24
use LivePersonInc\LiveEngageLaravel\Models\Engagement;
25
use LivePersonInc\LiveEngageLaravel\Models\Conversation;
26
use LivePersonInc\LiveEngageLaravel\Models\Message;
27
use LivePersonInc\LiveEngageLaravel\Collections\EngagementHistory;
28
use LivePersonInc\LiveEngageLaravel\Collections\Skills;
29
use LivePersonInc\LiveEngageLaravel\Collections\AgentParticipants;
30
use LivePersonInc\LiveEngageLaravel\Exceptions\LiveEngageException;
31
use LivePersonInc\LiveEngageLaravel\Collections\ConversationHistory;
32
33
/**
34
 * LiveEngageLaravel class holds all of the root package functions.
35
 *
36
 * All "setting" functions will return `$this` so method can be chained. Most methods will return a class object or Laravel collection.
37
 */
38
class LiveEngageLaravel
39
{
40
	/**
41
	 * account - LiveEngage account number, usually set by configuration
42
	 *
43
	 * (default value: false)
44
	 *
45
	 * @var long
0 ignored issues
show
Bug introduced by
The type LivePersonInc\LiveEngageLaravel\long was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
46
	 * @access private
47
	 */
48
	private $account = false;
49
	/**
50
	 * skills - holds the skills for history retrieval
51
	 *
52
	 * (default value: [])
53
	 *
54
	 * @var array
55
	 * @access private
56
	 */
57
	private $skills = [];
58
	/**
59
	 * config - holds the configuration key where keyset is stored in config/services.php
60
	 *
61
	 * (default value: 'services.liveperson.default')
62
	 *
63
	 * @var string
64
	 * @access private
65
	 */
66
	private $config = 'services.liveperson.default';
67
	/**
68
	 * version - api version
69
	 *
70
	 * (default value: '1.0')
71
	 *
72
	 * @var string
73
	 * @access private
74
	 */
75
	private $version = '1.0';
76
	/**
77
	 * history_limit - stores the history page limit
78
	 *
79
	 * (default value: 50)
80
	 *
81
	 * @var int
82
	 * @access private
83
	 */
84
	private $history_limit = 50;
85
	private $interactive = true;
86
	private $ended = true;
87
	/**
88
	 * bearer - bearer token for V2 authentication
89
	 *
90
	 * (default value: false)
91
	 *
92
	 * @var string
93
	 * @access private
94
	 */
95
	private $bearer = false;
96
	/**
97
	 * revision
98
	 *
99
	 * (default value: 0)
100
	 *
101
	 * @var int
102
	 * @access private
103
	 */
104
	private $revision = 0;
105
106
	/**
107
	 * domain - api domain storage
108
	 *
109
	 * (default value: false)
110
	 *
111
	 * @var bool
112
	 * @access private
113
	 */
114
	private $domain = false;
115
116
	/**
117
	 * retry_limit - number of times the request will attempt before it throws the exception.
118
	 *
119
	 * (default value: 5)
120
	 *
121
	 * @var int
122
	 * @access private
123
	 */
124
	private $retry_limit = 5;
125
	/**
126
	 * retry_counter - stores current count of retries.
127
	 *
128
	 * (default value: 0)
129
	 *
130
	 * @var int
131
	 * @access private
132
	 */
133
	private $retry_counter = 0;
134
135
	private $request_version = 'V1';
136
137
	/**
138
	 * __get magic function to retrieve private properties of the class.
139
	 *
140
	 * @access public
141
	 * @param mixed $attribute
142 5
	 * @return mixed
143
	 */
144 5
	public function __get($attribute)
145
	{
146
		return $this->$attribute;
147
	}
148
149
	private $request;
150
151
	/**
152
	 * __construct function.
153 8
	 *
154
	 * @access public
155 8
	 * @return void
156
	 */
157 8
	public function __construct()
158 8
	{
159
		$this->account = config("{$this->config}.account");
160
		$this->version = config("{$this->config}.version") ?: $this->version;
161
		$this->request = new LiveEngageRequest($this->config);
162
	}
163
164
	/**
165
	 * key function sets the keyset the class should use. Setting this once will be stored for script execution, but not for the session.
166
	 *
167 1
	 * @access public
168
	 * @param string $key (default: 'default')
169 1
	 * @return this
170 1
	 */
171
	public function key($key = 'default')
172 1
	{
173
		$this->config = "services.liveperson.$key";
174
		$this->__construct();
175
176
		return $this;
177
	}
178
179
	/**
180
	 * version function.
181 1
	 *
182
	 * @access public
183 1
	 * @param string $version (default: 'V1')
184 1
	 * @return void
185
	 */
186
	public function version($version = 'V1') {
0 ignored issues
show
Unused Code introduced by
The parameter $version is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

186
	public function version(/** @scrutinizer ignore-unused */ $version = 'V1') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
187
		$this->request_version = 'V2';
188
189
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LivePersonInc\LiveEngageLaravel\LiveEngageLaravel which is incompatible with the documented return type void.
Loading history...
190
	}
191
192
	/**
193 1
	 * nonInteractive function.
194
	 *
195 1
	 * @access public
196 1
	 * @return void
197
	 */
198
	public function nonInteractive()
199
	{
200
		$this->interactive = false;
201
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LivePersonInc\LiveEngageLaravel\LiveEngageLaravel which is incompatible with the documented return type void.
Loading history...
202
	}
203
204
	/**
205
	 * active function.
206 1
	 *
207
	 * @access public
208 1
	 * @return void
209
	 */
210 1
	public function active()
211
	{
212
		$this->ended = false;
213
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LivePersonInc\LiveEngageLaravel\LiveEngageLaravel which is incompatible with the documented return type void.
Loading history...
214
	}
215
216
	/**
217
	 * limit function.
218
	 *
219
	 * @access public
220 1
	 * @param mixed $limit
221
	 * @return void
222 1
	 */
223
	public function limit($limit)
224 1
	{
225
		$this->history_limit = $limit;
226
227
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LivePersonInc\LiveEngageLaravel\LiveEngageLaravel which is incompatible with the documented return type void.
Loading history...
228
	}
229
230
	/**
231
	 * retry function.
232
	 *
233
	 * @access public
234 1
	 * @param mixed $limit
235
	 * @return void
236 1
	 */
237
	public function retry($limit)
238 1
	{
239
		$this->retry_limit = $limit;
240
241
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LivePersonInc\LiveEngageLaravel\LiveEngageLaravel which is incompatible with the documented return type void.
Loading history...
242
	}
243
244
	/**
245
	 * account function.
246
	 *
247
	 * @access public
248 1
	 * @param mixed $accountid
249
	 * @return void
250 1
	 */
251
	public function account($accountid)
252 1
	{
253
		$this->account = $accountid;
254 1
255
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LivePersonInc\LiveEngageLaravel\LiveEngageLaravel which is incompatible with the documented return type void.
Loading history...
256
	}
257
258
	/**
259
	 * domain function sets the LivePerson domain for the secified service. Like `key` it is set for the execution script, but not session. It must be run each time.
260
	 *
261
	 * @access public
262
	 * @param mixed $service
263
	 * @return this
264
	 */
265
	public function domain($service)
266
	{
267
		$response = $this->request->get('V1', "https://api.liveperson.net/api/account/{$this->account}/service/{$service}/baseURI.json?version={$this->version}", 'GET');
268
269
		$this->domain = $response->body->baseURI;
270
271
		return $this;
272
	}
273
274
	/**
275
	 * visitor function gets or sets visitor attribute information - this only works for CHAT, not messaging.
276
	 *
277
	 * @access public
278
	 * @param string $visitorID
279
	 * @param string $sessionID
280
	 * @param mixed $setData (default: false)
281
	 * @return mixed
282
	 * @codeCoverageIgnore
283
	 */
284
	public function visitor($visitorID, $sessionID, $setData = false)
285
	{
286
		$this->domain('smt');
287
288
		if ($setData) {
289
			$url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/events?v=1&sid={$sessionID}";
290
291
			return $this->request->get($this->request_version, $url, 'POST', $setData)->body;
292
		} else {
293
			$url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/state?v=1&sid={$sessionID}";
294
295
			return $this->request->get($this->request_version, $url, 'GET')->body;
296
		}
297
	}
298
299
	/**
300
	 * chat function
301
	 *
302
     * @codeCoverageIgnore
303
     *
304
     * @todo connect this to the server chat api - this function currently does nothing.
305
     */
306
	public function chat()
307
	{
308
		$this->domain('conversationVep');
309
310
		$url = "https://{$this->domain}/api/account/{$this->account}/chat/request?v=1&NC=true";
311
312
		$args = [
313
314
		];
315 1
		$payload = new Payload($args);
316
317 1
		$response = $this->request->get($this->request_version, $url, 'POST', $payload)->body;
318
319 1
		return $response;
320
	}
321 1
322 1
	/**
323
	 * retrieveHistory function.
324 1
	 *
325 1
	 * @access public
326 1
	 * @final
327
	 * @param Carbon $start
328 1
	 * @param Carbon $end
329 1
	 * @param string $url (default: false)
330
	 * @return mixed
331 1
	 */
332
	final public function retrieveHistory(Carbon $start, Carbon $end, $url = false)
333
	{
334 1
		$this->domain('engHistDomain');
335 1
336 1
		$url = $url ?: "https://{$this->domain}/interaction_history/api/account/{$this->account}/interactions/search?limit={$this->history_limit}&offset=0";
337
338 1
		$start_str = $start->toW3cString();
339
		$end_str = $end->toW3cString();
340
341
		$data = new Payload([
342
			'interactive' => $this->interactive,
343
			'ended' => $this->ended,
344
			'start' => [
345
				'from' => strtotime($start_str) . '000',
346
				'to' => strtotime($end_str) . '000',
347
			],
348
			'skillIds' => $this->skills
349
		]);
350
351 1
		$result = $this->request->get($this->request_version, $url, 'POST', $data)->body;
352
		$result->records = $result->interactionHistoryRecords;
353 1
		$result->interactionHistoryRecords = null;
354
355 1
		return $result;
356
	}
357 1
358 1
	/**
359
	 * retrieveMsgHistory function.
360 1
	 *
361 1
	 * @access public
362
	 * @final
363 1
	 * @param Carbon $start
364 1
	 * @param Carbon $end
365
	 * @param string $url (default: false)
366 1
	 * @return mixed
367
	 */
368
	final public function retrieveMsgHistory(Carbon $start, Carbon $end, $url = false, $parameters = [])
369 1
	{
370 1
		$this->domain('msgHist');
371 1
		$version = $this->request_version;
372
373 1
		$url = $url ?: "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/search?limit={$this->history_limit}&offset=0&sort=start:desc";
374
375
		$start_str = $start->toW3cString();
376
		$end_str = $end->toW3cString();
377
378
		$data = new Payload(array_merge([
379
			'status' => $this->ended ? ['CLOSE'] : ['OPEN', 'CLOSE'],
380
			'start' => [
381
				'from' => strtotime($start_str) . '000',
382 1
				'to' => strtotime($end_str) . '000',
383
			],
384 1
			'skillIds' => $this->skills
385
		], $parameters));
386 1
387
		$result = $this->request->get($version, $url, 'POST', $data)->body;
388 1
389
		$result->records = $result->conversationHistoryRecords;
390
		$result->conversationHistoryRecords = null;
391
392
		return $result;
393
	}
394
395
	/**
396
	 * skills function gets collection of skills associated with the account.
397
	 *
398 1
	 * @access public
399
	 * @return Collections\Skills
400 1
	 */
401
	public function skills()
402 1
	{
403
		$this->domain('accountConfigReadOnly');
404 1
405
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/skills?v=4.0";
406
407
		return new Skills($this->request->get($this->request_version, $url, 'GET')->body);
408
	}
409
410
	/**
411
	 * getSkill function gets skill object based on ID.
412
	 *
413
	 * @access public
414 1
	 * @param int $skillId
415
	 * @return Models\Skill
416 1
	 */
417
	public function getSkill($skillId)
418 1
	{
419
		$this->domain('accountConfigReadOnly');
420 1
421
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/skills/{$skillId}?v=4.0";
422
423
		return new Skill((array) $this->request->get($this->request_version, $url, 'GET')->body);
424
	}
425
426
	/**
427
	 * getAgent function gets agent object based on ID.
428
	 *
429
	 * @access public
430
	 * @param int $userId
431
	 * @return Models\Agent
432
	 */
433
	public function getAgent($userId)
434
	{
435
		$this->domain('accountConfigReadOnly');
436
437
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/users/{$userId}?v=4.0";
438
439
		$content = $this->request->get($this->request_version, $url, 'GET');
440
441
		$agent = new Agent((array) $content->body);
442
		$agent->revision = $content->headers['ac-revision'];
0 ignored issues
show
Bug introduced by
The property revision does not seem to exist on LivePersonInc\LiveEngageLaravel\Models\Agent. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
443
444
		return $agent;
445
	}
446
447
	public function getSettings($filters = [])
448
	{
449
		$url = "https://z1-a.houston.int.liveperson.net/a/{$this->account}/module/sitesettings/doc/siteSettingsDictionary.json";
450
451
		$content = $this->request->get('V2', $url, 'GET');
452
453 1
		$settings = collect($content->body);
454
		foreach ($filters as $filter => $value) {
455 1
			$settings = $settings->filter(function($item, $key) use ($filter, $value) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

455
			$settings = $settings->filter(function($item, /** @scrutinizer ignore-unused */ $key) use ($filter, $value) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
456
				return str_contains($item->$filter, $value);
457 1
			});
458 1
		}
459
460
		return $settings;
461
	}
462
463
	/**
464
	 * updateAgent function.
465
	 *
466
	 * @access public
467
	 * @param mixed $userId
468
	 * @param mixed $properties
469
	 * @return void
470
	 * @codeCoverageIgnore
471
	 */
472
	public function updateAgent($userId, $properties)
473
	{
474
		$agent = $this->getAgent($userId);
475
476
		$this->domain('accountConfigReadWrite');
477
478
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/users/{$userId}?v=4.0";
479
		$headers = [
480
			'X-HTTP-Method-Override' => 'PUT',
481
			'If-Match' => $agent->revision
0 ignored issues
show
Bug introduced by
The property revision does not seem to exist on LivePersonInc\LiveEngageLaravel\Models\Agent. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
482
		];
483
484
		$content = $this->request->get($this->request_version, $url, 'PUT', $properties, $headers);
485
486 1
		return new Agent((array) $content->body);
0 ignored issues
show
Bug Best Practice introduced by
The expression return new LivePersonInc...((array)$content->body) returns the type LivePersonInc\LiveEngageLaravel\Models\Agent which is incompatible with the documented return type void.
Loading history...
487
	}
488 1
489
	/**
490
	 * agents function gets collection of agents from account.
491
	 *
492
	 * @access public
493
	 * @return Collections\AgentParticipants
494
	 */
495
	public function agents()
496
	{
497
		$this->domain('accountConfigReadOnly');
498 1
499
		$select = implode(',', [
500 1
			'id',
501
			'pid',
502 1
			'deleted',
503
			'loginName',
504 1
			'skills',
505
			'nickname',
506 1
			'dateCreated',
507
			'userTypeId',
508 1
			'isApiUser',
509 1
			'profileIds',
510 1
			'permissionGroups',
511
			'allowedAppKeys',
512 1
			'changePwdNextLogin',
513
			'maxChats',
514
			'skillIds',
515
			'lpaCreatedUser',
516
			'email',
517
			'lobs',
518
			'profiles',
519
			'fullName',
520
			'employeeId',
521
			'managedAgentGroups',
522
			'dateUpdated',
523
			'isEnabled',
524
			'lastPwdChangeDate',
525 1
			'pictureUrl'
526
		]);
527 1
528 1
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/users?v=4.0&select=$select";
529
530 1
		return new AgentParticipants((array) $this->request->get('V2', $url, 'GET')->body);
531 1
	}
532
533 1
	/**
534
	 * getAgentStatus function gets status of agents based on provided Skill IDs.
535 1
	 *
536 1
	 * @access public
537
	 * @param int/array $skills
0 ignored issues
show
Documentation Bug introduced by
The doc comment int/array at position 0 could not be parsed: Unknown type name 'int/array' at position 0 in int/array.
Loading history...
538 1
	 * @return Collections\AgentParticipants
539
	 */
540 1
	public function getAgentStatus($skills)
541 1
	{
542
		$skills = is_array($skills) ? $skills : [$skills];
543 1
544
		$this->domain('msgHist');
545
546
		$url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/agent-view/status";
547
548
		$data = ['skillIds' => $skills];
549
550
		$response = $this->request->get($this->request_version, $url, 'POST', $data)->body;
551
		$collection = new AgentParticipants($response->agentStatusRecords);
552
		$collection->metaData = new MetaData((array) $response->_metadata);
553
554 1
		return $collection;
555
556 1
	}
557
558 1
	/**
559
	 * conversationHistory function.
560 1
	 *
561 1
	 * @access public
562
	 * @param Carbon $start (default: null)
563
	 * @param Carbon $end (default: null)
564 1
	 * @param int/array $skills (default: [])
0 ignored issues
show
Documentation Bug introduced by
The doc comment int/array at position 0 could not be parsed: Unknown type name 'int/array' at position 0 in int/array.
Loading history...
565 1
	 * @return Collections\ConversationHistory
566
	 */
567
	public function conversationHistory(Carbon $start = null, Carbon $end = null, $skills = [], $parameters = [])
568
	{
569 1
		$this->retry_counter = 0;
570
		$this->skills = $skills;
571
572
		$start = $start ?: (new Carbon())->today();
573
		$end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
574
575
		$results_object = $this->retrieveMsgHistory($start, $end, false, $parameters);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $url of LivePersonInc\LiveEngage...l::retrieveMsgHistory(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

575
		$results_object = $this->retrieveMsgHistory($start, $end, /** @scrutinizer ignore-type */ false, $parameters);
Loading history...
576
577
		$results_object->_metadata->start = $start;
578
		$results_object->_metadata->end = $end;
579
580
		$meta = new MetaData((array) $results_object->_metadata);
581 1
582
		$collection = new ConversationHistory($results_object->records);
583 1
		$collection->metaData = $meta;
584 1
585
		return $collection;
586 1
587 1
	}
588
589 1
	/**
590
	 * getConversation function.
591 1
	 *
592 1
	 * @access public
593
	 * @param mixed $conversationId
594 1
	 * @return Models\Conversation
595
	 */
596 1
	public function getConversation($conversationId)
597 1
	{
598
		$this->domain('msgHist');
599 1
600
		$url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/conversation/search";
601
602
		$data = new Payload([
603
			'conversationId' => $conversationId
604
		]);
605
606
		$result = $this->request->get($this->request_version, $url, 'POST', $data)->body;
607
		if (!count($result->conversationHistoryRecords)) {
608
			return null; // @codeCoverageIgnore
609 1
		}
610
611 1
		return new Conversation((array) $result->conversationHistoryRecords[0]);
612
	}
613 1
614
	/**
615 1
	 * engagementHistory function.
616
	 *
617
	 * @access public
618
	 * @param Carbon $start (default: null)
619
	 * @param Carbon $end (default: null)
620
	 * @param int/array $skills (default: [])
0 ignored issues
show
Documentation Bug introduced by
The doc comment int/array at position 0 could not be parsed: Unknown type name 'int/array' at position 0 in int/array.
Loading history...
621
	 * @return Collections\EngagementHistory
622
	 */
623
	public function engagementHistory(Carbon $start = null, Carbon $end = null, $skills = [])
624 1
	{
625
		$this->retry_counter = 0;
626 1
		$this->skills = $skills;
627
628 1
		$start = $start ?: (new Carbon())->today();
629 1
		$end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
630 1
631 1
		$results_object = $this->retrieveHistory($start, $end);
632 1
633
		$results_object->_metadata->start = $start;
634
		$results_object->_metadata->end = $end;
635 1
636 1
		$meta = new MetaData((array) $results_object->_metadata);
637 1
638 1
		$collection = new EngagementHistory($results_object->records);
639 1
		$collection->metaData = $meta;
640
641
		return $collection;
642 1
643
	}
644 1
645
	/**
646 1
	 * status function gets status of the account.
647
	 *
648 1
	 * @access public
649
	 * @return Models\AccountStatus
650
	 */
651
	public function status()
652
	{
653
		$url = "https://status.liveperson.com/json?site={$this->account}";
654
655
		$response = $this->request->get('V1', $url, 'GET')->body;
656
657
		return new AccountStatus((array) $response);
658
	}
659
}
660