Api   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 301
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 19

Importance

Changes 0
Metric Value
wmc 17
lcom 2
cbo 19
dl 0
loc 301
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
B request() 0 45 6
A performRequest() 0 19 6
A validateConstructorArgs() 0 10 3
A setupResources() 0 25 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: Matt
5
 * Date: 20/04/2016
6
 * Time: 2:32 PM
7
 */
8
9
namespace Freshdesk;
10
11
use Freshdesk\Exceptions\AccessDeniedException;
12
use Freshdesk\Exceptions\ApiException;
13
use Freshdesk\Exceptions\AuthenticationException;
14
use Freshdesk\Exceptions\ConflictingStateException;
15
use Freshdesk\Exceptions\RateLimitExceededException;
16
use Freshdesk\Exceptions\UnsupportedContentTypeException;
17
use Freshdesk\Resources\Agent;
18
use Freshdesk\Resources\BusinessHour;
19
use Freshdesk\Resources\Category;
20
use Freshdesk\Resources\Comment;
21
use Freshdesk\Resources\Company;
22
use Freshdesk\Resources\Contact;
23
use Freshdesk\Resources\Conversation;
24
use Freshdesk\Resources\EmailConfig;
25
use Freshdesk\Resources\Forum;
26
use Freshdesk\Resources\Group;
27
use Freshdesk\Resources\Product;
28
use Freshdesk\Resources\SLAPolicy;
29
use Freshdesk\Resources\Ticket;
30
use Freshdesk\Resources\TimeEntry;
31
use Freshdesk\Resources\Topic;
32
use GuzzleHttp\Client;
33
use GuzzleHttp\Exception\RequestException;
34
35
/**
36
 * Class for interacting with the Freshdesk Api
37
 *
38
 * This is the only class that should be instantiated directly. All API resources are available
39
 * via the relevant public properties
40
 *
41
 * @package Api
42
 * @author Matthew Clarkson <[email protected]>
43
 */
44
class Api
45
{
46
    /**
47
     * Agent resources
48
     *
49
     * @api
50
     * @var Agent
51
     */
52
    public $agents;
53
54
    /**
55
     * Company resources
56
     *
57
     * @api
58
     * @var Company
59
     */
60
    public $companies;
61
62
    /**
63
     * Contact resources
64
     *
65
     * @api
66
     * @var Contact
67
     */
68
    public $contacts;
69
70
    /**
71
     * Group resources
72
     *
73
     * @api
74
     * @var Group
75
     */
76
    public $groups;
77
78
    /**
79
     * Ticket resources
80
     *
81
     * @api
82
     * @var Ticket
83
     */
84
    public $tickets;
85
86
    /**
87
     * TimeEntry resources
88
     *
89
     * @api
90
     * @var TimeEntry
91
     */
92
    public $timeEntries;
93
94
    /**
95
     * Conversation resources
96
     *
97
     * @api
98
     * @var Conversation
99
     */
100
    public $conversations;
101
102
    /**
103
     * Category resources
104
     *
105
     * @api
106
     * @var Category
107
     */
108
    public $categories;
109
110
    /**
111
     * Forum resources
112
     *
113
     * @api
114
     * @var Forum
115
     */
116
    public $forums;
117
118
    /**
119
     * Topic resources
120
     *
121
     * @api
122
     * @var Topic
123
     */
124
    public $topics;
125
126
    /**
127
     * Comment resources
128
     *
129
     * @api
130
     * @var Comment
131
     */
132
    public $comments;
133
134
    //Admin
135
136
    /**
137
     * Email Config resources
138
     *
139
     * @api
140
     * @var EmailConfig
141
     */
142
    public $emailConfigs;
143
144
    /**
145
     * Access Product resources
146
     *
147
     * @api
148
     * @var Product
149
     */
150
    public $products;
151
152
    /**
153
     * Business Hours resources
154
     *
155
     * @api
156
     * @var BusinessHour
157
     */
158
    public $businessHours;
159
160
    /**
161
     * SLA Policy resources
162
     *
163
     * @api
164
     * @var SLAPolicy
165
     */
166
    public $slaPolicies;
167
168
    /**
169
     * @internal
170
     * @var Client
171
     */
172
    protected $client;
173
174
    /**
175
     * @internal
176
     * @var string
177
     */
178
    private $baseUrl;
179
180
    /**
181
     * Constructs a new api instance
182
     *
183
     * @api
184
     * @param string $apiKey
185
     * @param string $domain
186
     * @throws Exceptions\InvalidConfigurationException
187
     */
188
    public function __construct($apiKey, $domain)
189
    {
190
        $this->validateConstructorArgs($apiKey, $domain);
191
192
        $this->baseUrl = sprintf('https://%s.freshdesk.com/api/v2', $domain);
193
194
        $this->client = new Client([
195
                'auth' => [$apiKey, 'X']
196
            ]
197
        );
198
199
        $this->setupResources();
200
    }
201
202
203
    /**
204
     * Internal method for handling requests
205
     *
206
     * @internal
207
     * @param $method
208
     * @param $endpoint
209
     * @param array|null $data
210
     * @param array|null $query
211
     * @return mixed|null
212
     * @throws ApiException
213
     * @throws ConflictingStateException
214
     * @throws RateLimitExceededException
215
     * @throws UnsupportedContentTypeException
216
     */
217
    public function request($method, $endpoint, array $data = null, array $query = null)
218
    {
219
220
		if (isset($data['attachments'])) {
221
			// Has file attachments, so we can't use the json property.
222
			// Instead, we have to use the "multipart" property
223
			$attachments = $data['attachments'];
224
			unset($data['attachments']);
225
226
			if (!is_array($attachments)) {
227
				$attachments = [$attachments];
228
			}
229
230
			$multiparts = [];
231
			foreach($attachments as $attachment) {
232
				$multiparts[] = [
233
					'name' => 'attachments[]',
234
					'contents' => $attachment, // $attachment is a resource from fopen('/path/to/file', 'r')
235
				];
236
			}
237
			foreach($data as $key => $value) {
238
				$multiparts[] = [
239
					'name' => $key,
240
					'contents' => $value,
241
				];
242
			}
243
244
			$options = [
245
				'multipart' => $multiparts,
246
			];
247
		} else {
248
			// normal method
249
			$options = [
250
				'json' => $data,
251
			];
252
		}
253
254
        if (isset($query)) {
255
            $options['query'] = $query;
256
        }
257
258
        $url = $this->baseUrl . $endpoint;
259
260
        return $this->performRequest($method, $url, $options);
261
    }
262
263
    /**
264
     * Performs the request
265
     *
266
     * @internal
267
     *
268
     * @param $method
269
     * @param $url
270
     * @param $options
271
     * @return mixed|null
272
     * @throws AccessDeniedException
273
     * @throws ApiException
274
     * @throws AuthenticationException
275
     * @throws ConflictingStateException
276
     */
277
    private function performRequest($method, $url, $options) {
278
279
        try {
280
            switch ($method) {
281
                case 'GET':
282
                    return json_decode($this->client->get($url, $options)->getBody(), true);
283
                case 'POST':
284
                    return json_decode($this->client->post($url, $options)->getBody(), true);
285
                case 'PUT':
286
                    return json_decode($this->client->put($url, $options)->getBody(), true);
287
                case 'DELETE':
288
                    return json_decode($this->client->delete($url, $options)->getBody(), true);
289
                default:
290
                    return null;
291
            }
292
        } catch (RequestException $e) {
293
            throw ApiException::create($e);
294
        }
295
    }
296
297
298
    /**
299
     * @param $apiKey
300
     * @param $domain
301
     * @throws Exceptions\InvalidConfigurationException
302
     * @internal
303
     *
304
     */
305
    private function validateConstructorArgs($apiKey, $domain)
306
    {
307
        if (!isset($apiKey)) {
308
            throw new Exceptions\InvalidConfigurationException("API key is empty.");
309
        }
310
311
        if (!isset($domain)) {
312
            throw new Exceptions\InvalidConfigurationException("Domain is empty.");
313
        }
314
    }
315
316
    /**
317
     * @internal
318
     */
319
    private function setupResources()
320
    {
321
        //People
322
        $this->agents = new Agent($this);
323
        $this->companies = new Company($this);
324
        $this->contacts = new Contact($this);
325
        $this->groups = new Group($this);
326
327
        //Tickets
328
        $this->tickets = new Ticket($this);
329
        $this->timeEntries = new TimeEntry($this);
330
        $this->conversations = new Conversation($this);
331
332
        //Discussions
333
        $this->categories = new Category($this);
334
        $this->forums = new Forum($this);
335
        $this->topics = new Topic($this);
336
        $this->comments = new Comment($this);
337
338
        //Admin
339
        $this->products = new Product($this);
340
        $this->emailConfigs = new EmailConfig($this);
341
        $this->slaPolicies = new SLAPolicy($this);
342
        $this->businessHours = new BusinessHour($this);
343
    }
344
}
345