Completed
Push — develop ( e75c9e...43e4be )
by
unknown
11s
created

Client::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Spinen\QuickBooks;
4
5
use Exception;
6
use QuickBooksOnline\API\DataService\DataService;
7
use QuickBooksOnline\API\ReportService\ReportService;
8
9
/**
10
 * Class Client
11
 *
12
 * @package Spinen\QuickBooks
13
 */
14
class Client
15
{
16
    /**
17
     * The configs to set up a DataService
18
     *
19
     * @var array
20
     */
21
    protected $configs;
22
23
    /**
24
     * The DataService instance
25
     *
26
     * @var DataService
27
     */
28
    protected $data_service;
29
30
    /**
31
     * The ReportService instance
32
     *
33
     * @var ReportService
34
     */
35
    protected $report_service;
36
37
    /**
38
     * The Token instance
39
     *
40
     * @var Token
41
     */
42
    protected $token;
43
44
    /**
45
     * Client constructor.
46
     *
47
     * @param array $configs
48
     * @param Token $token
49
     */
50
    public function __construct(array $configs, Token $token)
51
    {
52
        $this->configs = $configs;
53
54
        $this->setToken($token);
55
    }
56
57
    /**
58
     * Build URI to request authorization
59
     *
60
     * @return String
61
     * @throws \QuickBooksOnline\API\Exception\SdkException
62
     * @throws \QuickBooksOnline\API\Exception\ServiceException
63
     */
64
    public function authorizationUri()
65
    {
66
        return $this->getDataservice()
67
                    ->getOAuth2LoginHelper()
68
                    ->getAuthorizationCodeURL();
69
    }
70
71
    /**
72
     *
73
     */
74
    public function configureLogging()
75
    {
76
        // In case any of the keys are not in the configs, just disable logging
77
        try {
78
            if ($this->configs['logging']['enabled'] && dir($this->configs['logging']['location'])) {
79
                $this->data_service->setLogLocation($this->configs['logging']['location'] . '/quickbooks.log');
80
81
                return;
82
            }
83
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
84
        }
85
86
        $this->data_service->disableLog();
87
    }
88
89
    /**
90
     * Delete the token
91
     *
92
     * @return $this
93
     * @throws Exception
94
     */
95
    public function deleteToken()
96
    {
97
        $this->setToken($this->token->remove());
98
99
        return $this;
100
    }
101
102
    /**
103
     * Convert code to an access token
104
     *
105
     * Upon the user allowing access to their account, there is a code sent to
106
     * over that needs to be converted to an OAuth token.
107
     *
108
     * @param string $code
109
     * @param integer $realm_id
110
     *
111
     * @return $this
112
     * @throws \QuickBooksOnline\API\Exception\SdkException
113
     * @throws \QuickBooksOnline\API\Exception\ServiceException
114
     */
115
    public function exchangeCodeForToken($code, $realm_id)
116
    {
117
        $oauth_token = $this->getDataService()
118
                            ->getOAuth2LoginHelper()
119
                            ->exchangeAuthorizationCodeForToken($code, $realm_id);
120
121
        $this->getDataService()
122
             ->updateOAuth2Token($oauth_token);
123
124
        $this->token->parseOauthToken($oauth_token)
125
                    ->save();
126
127
        return $this;
128
    }
129
130
    /**
131
     * Getter for the DataService
132
     *
133
     * Makes sure that it is setup & ready to be used.
134
     *
135
     * @return DataService
136
     * @throws \QuickBooksOnline\API\Exception\SdkException
137
     * @throws \QuickBooksOnline\API\Exception\ServiceException
138
     */
139
    public function getDataService()
140
    {
141
        if (!isset($this->data_service)) {
142
            $this->data_service = $this->makeDataService();
143
144
            $this->configureLogging();
145
        }
146
147
        return $this->data_service;
148
    }
149
150
    /**
151
     * Getter for the ReportService
152
     *
153
     * Makes sure that it is setup & ready to be used.
154
     *
155
     * @return ReportService
156
     * @throws \QuickBooksOnline\API\Exception\SdkException
157
     * @throws \QuickBooksOnline\API\Exception\ServiceException
158
     */
159
    public function getReportService()
160
    {
161
        if (!isset($this->report_service)) {
162
            $this->report_service = new ReportService($this->getDataService()
163
                                                           ->getServiceContext());
164
        }
165
166
        return $this->report_service;
167
    }
168
169
    /**
170
     * Check to see if the token has a valid access token
171
     *
172
     * @return boolean
173
     */
174
    public function hasValidAccessToken()
175
    {
176
        return $this->token->hasValidAccessToken;
177
    }
178
179
    /**
180
     * Check to see if the token has a valid refresh token
181
     *
182
     * @return boolean
183
     */
184
    public function hasValidRefreshToken()
185
    {
186
        return $this->token->hasValidRefreshToken;
187
    }
188
189
    /**
190
     * Factory to make DataService
191
     *
192
     * There are 3 use cases for making a DataService....
193
     *
194
     *      1) Have valid access token, so ready to be used
195
     *      2) Have valid refresh token, so renew access token & then use
196
     *      3) No existing token, so need to link account
197
     *
198
     * @return DataService
199
     * @throws \QuickBooksOnline\API\Exception\SdkException
200
     * @throws \QuickBooksOnline\API\Exception\ServiceException
201
     */
202
    protected function makeDataService()
203
    {
204
        // Associative array to use to filter out only the needed config keys when using existing token
205
        $existing_keys = [
206
            'auth_mode'    => null,
207
            'baseUrl'      => null,
208
            'ClientID'     => null,
209
            'ClientSecret' => null,
210
        ];
211
212
        // Have good access & refresh, so allow app to run
213
        if ($this->hasValidAccessToken()) {
214
            // Pull in the configs from the token into needed keys from the configs
215
            return DataService::Configure(array_merge(array_intersect_key($this->parseDataConfigs(), $existing_keys), [
216
                'accessTokenKey'  => $this->token->access_token,
217
                'QBORealmID'      => $this->token->realm_id,
218
                'refreshTokenKey' => $this->token->refresh_token,
219
            ]));
220
        }
221
222
        // Have refresh, so update access & allow app to run
223
        if ($this->hasValidRefreshToken()) {
224
            // Pull in the configs from the token into needed keys from the configs
225
            $data_service = DataService::Configure(array_merge(array_intersect_key($this->parseDataConfigs(), $existing_keys), [
226
                'QBORealmID'      => $this->token->realm_id,
227
                'refreshTokenKey' => $this->token->refresh_token,
228
            ]));
229
230
            $oauth_token = $data_service->getOAuth2LoginHelper()
231
                                        ->refreshToken();
232
233
            $data_service->updateOAuth2Token($oauth_token);
234
235
            $this->token->parseOauthToken($oauth_token)
236
                        ->save();
237
238
            return $data_service;
239
        }
240
241
        // Create new...
242
        return DataService::Configure($this->parseDataConfigs());
243
    }
244
245
    /**
246
     * QuickBooks is not consistent on their naming of variables, so map them
247
     */
248
    protected function parseDataConfigs()
249
    {
250
        return [
251
            'auth_mode'    => $this->configs['data_service']['auth_mode'],
252
            'baseUrl'      => $this->configs['data_service']['base_url'],
253
            'ClientID'     => $this->configs['data_service']['client_id'],
254
            'ClientSecret' => $this->configs['data_service']['client_secret'],
255
            'RedirectURI'  => route('quickbooks.token'),
256
            'scope'        => $this->configs['data_service']['scope'],
257
        ];
258
    }
259
260
    /**
261
     * Allow setting a token to switch "user"
262
     *
263
     * @param Token $token
264
     *
265
     * @return $this
266
     */
267
    public function setToken(Token $token)
268
    {
269
        $this->token = $token;
270
271
        // The DataService is tied to a specific token, so remove it when using a new one
272
        unset($this->data_service);
273
274
        return $this;
275
    }
276
}
277