Client::makeDataService()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 51
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 3.054

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 25
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 51
rs 9.52
ccs 18
cts 22
cp 0.8182
crap 3.054

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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