Passed
Pull Request — develop (#24)
by Stephen
02:42
created

Client::makeDataService()   A

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) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
88
        }
89
90 3
        return $this->data_service->disableLog();
91
    }
92
93
    /**
94
     * Delete the token
95
     *
96
     * @return $this
97
     * @throws Exception
98
     */
99 1
    public function deleteToken()
100
    {
101 1
        $this->setToken($this->token->remove());
102
103 1
        return $this;
104
    }
105
106
    /**
107
     * Convert code to an access token
108
     *
109
     * Upon the user allowing access to their account, there is a code sent to
110
     * over that needs to be converted to an OAuth token.
111
     *
112
     * @param string $code
113
     * @param integer $realm_id
114
     *
115
     * @return $this
116
     * @throws SdkException
117
     * @throws ServiceException
118
     */
119
    public function exchangeCodeForToken($code, $realm_id)
120
    {
121
        $oauth_token = $this->getDataService()
122
                            ->getOAuth2LoginHelper()
123
                            ->exchangeAuthorizationCodeForToken($code, $realm_id);
124
125
        $this->getDataService()
126
             ->updateOAuth2Token($oauth_token);
127
128
        $this->token->parseOauthToken($oauth_token)
129
                    ->save();
130
131
        return $this;
132
    }
133
134
    /**
135
     * Getter for the DataService
136
     *
137
     * Makes sure that it is setup & ready to be used.
138
     *
139
     * @return DataService
140
     * @throws SdkException
141
     * @throws ServiceException
142
     */
143 4
    public function getDataService()
144
    {
145 4
        if (!$this->hasValidAccessToken() || !isset($this->data_service)) {
146 4
            $this->data_service = $this->makeDataService();
147
148 3
            $this->configureLogging();
149
        }
150
151 3
        return $this->data_service;
152
    }
153
154
    /**
155
     * Getter for the ReportService
156
     *
157
     * Makes sure that it is setup & ready to be used.
158
     *
159
     * @return ReportService
160
     * @throws SdkException
161
     * @throws ServiceException
162
     */
163
    public function getReportService()
164
    {
165
        if (!$this->hasValidAccessToken() || !isset($this->report_service)) {
166
            $this->report_service = new ReportService(
167
                $this->getDataService()
168
                     ->getServiceContext()
169
            );
170
        }
171
172
        return $this->report_service;
173
    }
174
175
    /**
176
     * Check to see if the token has a valid access token
177
     *
178
     * @return boolean
179
     */
180 4
    public function hasValidAccessToken()
181
    {
182 4
        return $this->token->hasValidAccessToken;
183
    }
184
185
    /**
186
     * Check to see if the token has a valid refresh token
187
     *
188
     * @return boolean
189
     */
190 3
    public function hasValidRefreshToken()
191
    {
192 3
        return $this->token->hasValidRefreshToken;
193
    }
194
195
    /**
196
     * Factory to make DataService
197
     *
198
     * There are 3 use cases for making a DataService....
199
     *
200
     *      1) Have valid access token, so ready to be used
201
     *      2) Have valid refresh token, so renew access token & then use
202
     *      3) No existing token, so need to link account
203
     *
204
     * @return DataService
205
     * @throws SdkException
206
     * @throws ServiceException
207
     */
208 4
    protected function makeDataService()
209
    {
210
        // Associative array to use to filter out only the needed config keys when using existing token
211
        $existing_keys = [
212 4
            'auth_mode'    => null,
213
            'baseUrl'      => null,
214
            'ClientID'     => null,
215
            'ClientSecret' => null,
216
        ];
217
218
        // Have good access & refresh, so allow app to run
219 4
        if ($this->hasValidAccessToken()) {
220
            // Pull in the configs from the token into needed keys from the configs
221 1
            return DataService::Configure(
222 1
                array_merge(
223 1
                    array_intersect_key($this->parseDataConfigs(), $existing_keys),
224
                    [
225 1
                        'accessTokenKey'  => $this->token->access_token,
226 1
                        'QBORealmID'      => $this->token->realm_id,
227 1
                        'refreshTokenKey' => $this->token->refresh_token,
228
                    ]
229
                )
230
            );
231
        }
232
233
        // Have refresh, so update access & allow app to run
234 3
        if ($this->hasValidRefreshToken()) {
235
            // Pull in the configs from the token into needed keys from the configs
236 1
            $data_service = DataService::Configure(
237 1
                array_merge(
238 1
                    array_intersect_key($this->parseDataConfigs(), $existing_keys),
239
                    [
240 1
                        'QBORealmID'      => $this->token->realm_id,
241 1
                        'refreshTokenKey' => $this->token->refresh_token,
242
                    ]
243
                )
244
            );
245
246 1
            $oauth_token = $data_service->getOAuth2LoginHelper()
247 1
                                        ->refreshToken();
248
249
            $data_service->updateOAuth2Token($oauth_token);
250
251
            $this->token->parseOauthToken($oauth_token)
252
                        ->save();
253
254
            return $data_service;
255
        }
256
257
        // Create new...
258 2
        return DataService::Configure($this->parseDataConfigs());
259
    }
260
261
    /**
262
     * QuickBooks is not consistent on their naming of variables, so map them
263
     */
264 4
    protected function parseDataConfigs()
265
    {
266
        return [
267 4
            'auth_mode'    => $this->configs['data_service']['auth_mode'],
268 4
            'baseUrl'      => $this->configs['data_service']['base_url'],
269 4
            'ClientID'     => $this->configs['data_service']['client_id'],
270 4
            'ClientSecret' => $this->configs['data_service']['client_secret'],
271 4
            'RedirectURI'  => route('quickbooks.token'),
272 4
            'scope'        => $this->configs['data_service']['scope'],
273
        ];
274
    }
275
276
    /**
277
     * Allow setting a token to switch "user"
278
     *
279
     * @param Token $token
280
     *
281
     * @return $this
282
     */
283 6
    public function setToken(Token $token)
284
    {
285 6
        $this->token = $token;
286
287
        // The DataService is tied to a specific token, so remove it when using a new one
288 6
        unset($this->data_service);
289
290 6
        return $this;
291
    }
292
}
293