Client::getReportService()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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