Test Failed
Branch master (901d12)
by Robert
06:03
created

LiveEngageLaravel   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 317
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 51
dl 0
loc 317
rs 8.3206
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __get() 0 3 1
A __construct() 0 5 2
A skills() 0 5 1
A get() 0 3 1
A retry() 0 5 1
A limit() 0 5 1
A nonInteractive() 0 4 1
D history() 0 40 9
A domain() 0 9 2
B request() 0 49 6
B retrieveMsgHistory() 0 26 4
A agentStatus() 0 9 2
A key() 0 5 1
D messagingHistory() 0 37 9
A __set() 0 3 1
A account() 0 5 1
A visitor() 0 14 3
A active() 0 4 1
B retrieveHistory() 0 26 4

How to fix   Complexity   

Complex Class

Complex classes like LiveEngageLaravel often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LiveEngageLaravel, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace LivePersonInc\LiveEngageLaravel;
4
5
use Carbon\Carbon;
6
use GuzzleHttp\Client;
7
use GuzzleHttp\HandlerStack;
8
use GuzzleHttp\Subscriber\Oauth\Oauth1;
9
use LivePersonInc\LiveEngageLaravel\Models\Info;
10
use LivePersonInc\LiveEngageLaravel\Models\Payload;
11
use LivePersonInc\LiveEngageLaravel\Models\Visitor;
12
use LivePersonInc\LiveEngageLaravel\Models\Campaign;
13
use LivePersonInc\LiveEngageLaravel\Models\Engagement;
14
use LivePersonInc\LiveEngageLaravel\Models\Conversation;
15
use LivePersonInc\LiveEngageLaravel\Collections\EngagementHistory;
16
use LivePersonInc\LiveEngageLaravel\Exceptions\LiveEngageException;
17
use LivePersonInc\LiveEngageLaravel\Collections\ConversationHistory;
18
19
class LiveEngageLaravel
20
{
21
    private $account = false;
22
    private $results = [];
23
    private $skills = [];
24
    private $next = false;
25
    private $prev = false;
26
    private $start;
27
    private $end;
28
    private $config = 'services.liveperson.default';
29
    private $version = '1.0';
30
    private $history_limit = 50;
31
    private $history = false;
32
    private $context = 'interactionHistoryRecords';
33
    private $interactive = true;
34
    private $ended = true;
35
36
    private $domain = false;
37
38
    private $retry_limit = 5;
39
    private $retry_counter = 0;
40
41
    public function __get($attribute)
42
    {
43
        return $this->$attribute;
44
    }
45
46
    public function __set($attribute, $value)
47
    {
48
        return $this->$attribute = $value;
49
    }
50
51
    public function __construct()
52
    {
53
        $this->account = config("{$this->config}.account");
54
        $this->domain = config("{$this->config}.domain");
55
        $this->version = config("{$this->config}.version") ?: $this->version;
56
    }
57
58
    public function key($key = 'default')
59
    {
60
        $this->config = "services.liveperson.$key";
61
62
        return $this;
63
    }
64
    
65
    public function nonInteractive()
66
    {
67
	    $this->interactive = false;
68
	    return $this;
69
    }
70
    
71
    public function active()
72
    {
73
	    $this->ended = false;
74
	    return $this;
75
    }
76
77
    public function limit($limit)
78
    {
79
        $this->history_limit = $limit;
80
81
        return $this;
82
    }
83
84
    public function skills($skills)
85
    {
86
        $this->skills = $skills;
87
88
        return $this;
89
    }
90
91
    public function retry($limit)
92
    {
93
        $this->retry_limit = $limit;
94
95
        return $this;
96
    }
97
98
    public function get()
99
    {
100
        return $this->results;
101
    }
102
103
    public function account($accountid)
104
    {
105
        $this->account = $accountid;
106
107
        return $this;
108
    }
109
110
    public function domain($service)
111
    {
112
        $response = $this->request("https://api.liveperson.net/api/account/{$this->account}/service/{$service}/baseURI.json?version={$this->version}", 'GET');
113
        if (is_a($response, 'Exception')) {
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type mixed; however, parameter $object of is_a() does only seem to accept object|string, maybe add an additional type check? ( Ignorable by Annotation )

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

113
        if (is_a(/** @scrutinizer ignore-type */ $response, 'Exception')) {
Loading history...
114
            throw new \Exception('Unable to get LivePerson account domain', 101);
115
        } else {
116
            $this->domain = $response->baseURI;
117
118
            return $this;
119
        }
120
    }
121
122
    public function visitor($visitorID, $sessionID, $setData = false)
123
    {
124
        if (! $this->domain) {
125
            $this->domain('smt');
126
        }
127
128
        if ($setData) {
129
            $url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/events?v=1&sid={$sessionID}";
130
131
            return $this->request($url, 'POST', $setData);
132
        } else {
133
            $url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/state?v=1&sid={$sessionID}";
134
135
            return $this->request($url, 'GET');
136
        }
137
    }
138
139
    public function agentStatus()
140
    {
141
        if (! $this->domain) {
142
            $this->domain('msgHist');
143
        }
144
145
        $url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/agent-view/status";
146
147
        return $this->request($url, 'POST', new Payload(['skillIds' => $this->skills]));
148
    }
149
150
    final public function retrieveHistory(Carbon $start, Carbon $end, $url = false)
151
    {
152
        if (! $this->domain) {
153
            $this->domain('engHistDomain');
154
        }
155
156
        $url = $url ?: "https://{$this->domain}/interaction_history/api/account/{$this->account}/interactions/search?limit={$this->history_limit}&offset=0";
157
158
        $start_str = $start->toW3cString();
159
        $end_str = $end->toW3cString();
160
161
        $data = [
162
            'interactive' => $this->interactive,
163
            'ended' => $this->ended,
164
            'start' => [
165
                'from' => strtotime($start_str).'000',
166
                'to' => strtotime($end_str).'000',
167
            ],
168
        ];
169
        if (count($this->skills)) {
170
            $data['skillIds'] = $this->skills;
171
        }
172
173
        $data = new Payload($data);
174
175
        return $this->request($url, 'POST', $data);
176
    }
177
178
    final public function retrieveMsgHistory(Carbon $start, Carbon $end, $url = false)
179
    {
180
        if (! $this->domain) {
181
            $this->domain('msgHist');
182
        }
183
184
        $url = $url ?: "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/search?limit={$this->history_limit}&offset=0";
185
186
        $start_str = $start->toW3cString();
187
        $end_str = $end->toW3cString();
188
189
        $data = [
190
            'interactive' => $this->interactive,
191
            'ended' => $this->ended,
192
            'start' => [
193
                'from' => strtotime($start_str).'000',
194
                'to' => strtotime($end_str).'000',
195
            ],
196
        ];
197
        if (count($this->skills)) {
198
            $data['skillIds'] = $this->skills;
199
        }
200
201
        $data = new Payload($data);
202
203
        return $this->request($url, 'POST', $data);
204
    }
205
206
    public function messagingHistory(Carbon $start = null, Carbon $end = null)
207
    {
208
        $this->retry_counter = 0;
209
210
        $start = $start ?: (new Carbon())->today();
211
        $end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
212
213
        $this->start = $start;
214
        $this->end = $end;
215
216
        $results_object = $this->retrieveMsgHistory($start, $end);
217
        $results = $results_object->conversationHistoryRecords;
0 ignored issues
show
Bug introduced by
The property conversationHistoryRecords does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
218
        if (property_exists($results_object->_metadata, 'next')) {
0 ignored issues
show
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
219
            $this->next = $results_object->_metadata->next->href;
220
        }
221
        if (property_exists($results_object->_metadata, 'prev')) {
222
            $this->prev = $results_object->_metadata->prev->href;
223
        }
224
225
        $history = [];
226
        foreach ($results as $item) {
227
            if (property_exists($item, 'info')) {
228
                $item->info = new Info((array) $item->info);
229
            }
230
231
            if (property_exists($item, 'visitorInfo')) {
232
                $item->visitorInfo = new Visitor((array) $item->visitorInfo);
233
            }
234
235
            if (property_exists($item, 'campaign')) {
236
                $item->campaign = new Campaign((array) $item->campaign);
237
            }
238
239
            $history[] = new Conversation((array) $item);
240
        }
241
242
        return new ConversationHistory($history, $this);
243
    }
244
245
    public function history(Carbon $start = null, Carbon $end = null)
246
    {
247
        $this->retry_counter = 0;
248
249
        $start = $start ?: (new Carbon())->today();
250
        $end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
251
252
        $this->start = $start;
253
        $this->end = $end;
254
255
        $results_object = $this->retrieveHistory($start, $end);
256
        $results = $results_object->interactionHistoryRecords;
0 ignored issues
show
Bug introduced by
The property interactionHistoryRecords does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
257
        if (property_exists($results_object->_metadata, 'next')) {
0 ignored issues
show
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
258
            $this->next = $results_object->_metadata->next->href;
259
        }
260
        if (property_exists($results_object->_metadata, 'prev')) {
261
            $this->prev = $results_object->_metadata->prev->href;
262
        }
263
264
        $history = [];
265
        foreach ($results as $item) {
266
            if (property_exists($item, 'info')) {
267
                $item->info = new Info((array) $item->info);
268
            }
269
270
            if (property_exists($item, 'visitorInfo')) {
271
                $item->visitorInfo = new Visitor((array) $item->visitorInfo);
272
            }
273
274
            if (property_exists($item, 'campaign')) {
275
                $item->campaign = new Campaign((array) $item->campaign);
276
            }
277
278
            $history[] = new Engagement((array) $item);
279
        }
280
        
281
        $collection = new EngagementHistory($history, $this);
282
        $collection->metaData = $results_object->_metadata;
0 ignored issues
show
Bug introduced by
The property metaData does not seem to exist on LivePersonInc\LiveEngage...tions\EngagementHistory.
Loading history...
283
        
284
        return $collection;
285
    }
286
287
    private function request($url, $method, $payload = false)
288
    {
289
        $consumer_key = config("{$this->config}.key");
290
        $consumer_secret = config("{$this->config}.secret");
291
        $token = config("{$this->config}.token");
292
        $secret = config("{$this->config}.token_secret");
293
294
        $stack = HandlerStack::create();
295
        $auth = new Oauth1([
296
            'consumer_key'    => $consumer_key,
297
            'consumer_secret' => $consumer_secret,
298
            'token'           => $token,
299
            'token_secret'    => $secret,
300
            'signature_method'=> Oauth1::SIGNATURE_METHOD_HMAC,
301
        ]);
302
        $stack->push($auth);
303
304
        $client = new Client([
305
            'handler' => $stack,
306
        ]);
307
308
        $args = [
309
            'auth' => 'oauth',
310
            'headers' => [
311
                'content-type' => 'application/json',
312
            ],
313
        ];
314
315
        if ($payload !== false) {
316
            $args['body'] = json_encode($payload);
317
        }
318
319
        try {
320
            $res = $client->request($method, $url, $args);
321
322
            $response = json_decode($res->getBody());
323
        } catch (\GuzzleHttp\Exception\ConnectException $connection) {
324
            return $connection;
325
        } catch (\Exception $e) {
326
            if ($this->retry_counter < $this->retry_limit || $this->retry_limit == -1) {
327
                usleep(1500);
328
                $this->retry_counter++;
329
                $response = $this->request($url, $payload);
330
            } else {
331
                throw $e; //new LiveEngageException("Retry limit has been exceeded ($this->retry_limit)", 100);
332
            }
333
        }
334
335
        return $response;
336
    }
337
}
338