GithubClient::executeUpdate()   B
last analyzed

Complexity

Conditions 8
Paths 20

Size

Total Lines 54
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 8
eloc 40
c 1
b 1
f 0
nc 20
nop 1
dl 0
loc 54
rs 8.0355

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
declare(strict_types=1);
4
5
namespace XoopsModules\Wggithub\Github;
6
7
/*
8
 * You may not change or alter any portion of this comment or credits
9
 * of supporting developers from this source code or any supporting source code
10
 * which is considered copyrighted (c) material of the original comment or credit authors.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
 */
16
/**
17
 * @copyright    XOOPS Project https://xoops.org/
18
 * @license      GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
19
 * @since
20
 * @author       Goffy - XOOPS Development Team
21
 */
22
23
use XoopsModules\Wggithub;
24
use XoopsModules\Wggithub\{
25
    Helper,
26
    Constants,
27
    Github
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsModules\Wggithub\Github\Github. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
28
};
29
30
/**
31
 * Class GithubClient
32
 */
33
class GithubClient extends Api
34
{
35
    /**
36
     * @var string
37
     */
38
    public const BASE_URL = 'https://api.github.com/';
39
40
    /**
41
     * @var string
42
     */
43
    public $userAuth = 'myusername';
44
45
    /**
46
     * @var string
47
     */
48
    public $tokenAuth = 'mytoken';
49
50
    /**
51
     * @var object
52
     */
53
    private $helper = null;
54
55
    /**
56
     * Constructor
57
     *
58
     * @param null
59
     */
60
    public function __construct()
61
    {
62
        $this->helper = \XoopsModules\Wggithub\Helper::getInstance();
63
        $this->getSetting();
64
    }
65
66
    /**
67
     * @static function &getInstance
68
     *
69
     * @param null
70
     * @return GitHubClient of Api
71
     */
72
    public static function getInstance()
73
    {
74
        static $instance = false;
75
        if (!$instance) {
76
            $instance = new self();
77
        }
78
79
        return $instance;
80
    }
81
82
    public function testApi1($url) {
83
84
        $logsHandler = $this->helper->getHandler('Logs');
85
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, '', 'START Test API1');
86
87
        $url = static::BASE_URL . $url;
88
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'URL');
89
        $data = $this->_get($url);
90
91
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'Read data successful');
92
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, '', 'END Test API1');
93
94
        return $data;
95
    }
96
97
    public function testApi2($url) {
98
        $api = new Github\Api;
99
100
        $token = new Github\OAuth\Token('{myKey}', 'bearer', ['repo', 'user', 'public_repo']);
101
        $api->setToken($token);
102
        $response = $api->get(static::BASE_URL . $url);
103
104
        $data = $api->decode($response);
105
106
        /*
107
        $api = new Github\Api;
108
109
        $request = $api->createRequest('GET', $url, [], [], '');
110
        $response = $api->request($request);
111
        $data = (array)$api->decode($response);
112
        */
113
114
        return $data;
115
    }
116
117
    /**
118
     * Get repositories of given user
119
     *
120
     * @return array|bool
121
     */
122
    public function testUserRepositories()
123
    {
124
        $logsHandler = $this->helper->getHandler('Logs');
125
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, '', 'START Test UserRepositories');
126
127
        $url = static::BASE_URL . 'users/' . \rawurlencode($this->userAuth) . '/repos?per_page=1&page=1';
128
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'URL');
129
130
        $data = $this->_get($url);
131
132
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'Read data successful');
133
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, '', 'END Test UserRepositories');
134
135
        return $data;
136
    }
137
138
    /**
139
     * Get repositories of given user
140
     *
141
     * @param     $username
142
     * @param int $per_page
143
     * @param int $page
144
     * @return array|bool
145
     */
146
    public function getUserRepositories($username, $per_page = 100, $page = 1)
147
    {
148
        $url = static::BASE_URL . 'users/' . \rawurlencode($username) . '/repos?per_page=' . $per_page . '&page=' . $page;
149
150
        return $this->_get($url);
151
    }
152
153
    /**
154
     * Get repositories of given organisation
155
     *
156
     * @param     $org
157
     * @param int $per_page
158
     * @param int $page
159
     * @return array|bool
160
     */
161
    public function getOrgRepositories($org, $per_page = 100, $page = 1)
162
    {
163
        $url = static::BASE_URL . 'orgs/' . \rawurlencode($org) . '/repos?per_page=' . $per_page . '&page=' . $page;
164
165
        return $this->_get($url);
166
    }
167
168
    /**
169
     * Get the readme content for a repository by its username and repository name.
170
     *
171
     * @param string $username   the user who owns the repository
172
     * @param string $repository the name of the repository
173
     * @return array|bool
174
     */
175
    public function getReadme($username, $repository)
176
    {
177
        $url = static::BASE_URL . 'repos/' . \rawurlencode($username) . '/' . \rawurlencode($repository) . '/readme';
178
179
        return $this->_get($url, true);
180
    }
181
182
    /**
183
     * Get all releases
184
     *
185
     * @param string $username   the user who owns the repository
186
     * @param string $repository the name of the repository
187
     * @return array|bool
188
     */
189
    public function getReleases($username, $repository)
190
    {
191
        $url = static::BASE_URL . 'repos/' . $username . '/' . $repository . '/releases';
192
193
        return $this->_get($url, true);
194
    }
195
196
    /**
197
     * Get latest release
198
     *
199
     * @param string $username   the user who owns the repository
200
     * @param string $repository the name of the repository
201
     * @param bool   $prerelease
202
     * @return array|bool
203
     */
204
    public function getLatestRelease($username, $repository, $prerelease = false)
205
    {
206
        //function currently not used
207
        if ($prerelease) {
208
            $url = static::BASE_URL . 'repos/' . $username . '/' . $repository . '/releases';
209
        } else {
210
            $url = static::BASE_URL . 'repos/' . $username . '/' . $repository . '/releases/latest';
211
        }
212
        $result = $this->_get($url);
213
214
        if ($prerelease) {
215
            if (\is_array($result)) {
216
                return $result[0];
217
            } else {
218
                return [];
219
            }
220
        }
221
222
        return $result;
223
    }
224
    
225
    /**
226
     * Get content of repository
227
     *
228
     * @param  $username
229
     * @param  $repository
230
     * @return array|bool
231
     */
232
    public function getRepositoryContent($username, $repository)
233
    {
234
        $url = static::BASE_URL . 'repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents';
235
236
        return $this->_get($url);
237
    }
238
239
    /**
240
     * Get github content
241
     *
242
     * @param      $url
243
     * @param bool $skipError
244
     * @return array|bool
245
     */
246
    public function _get($url, $skipError = false)
247
    {
248
        $error = false;
249
        $errMsg = '';
250
251
        $logsHandler = $this->helper->getHandler('Logs');
252
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'START');
253
        $api = new Github\Api;
254
        $token = new Github\OAuth\Token($this->tokenAuth, 'bearer', ['repo', 'user', 'public_repo']);
255
        $api->setToken($token);
256
        $response = $api->get($url);
257
        $code = $response->getCode();
258
        if (\in_array($code, [200, 201], true)) {
259
            $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'OK');
260
        } else {
261
            if ($skipError) {
262
                $logsHandler->updateTableLogs(Constants::LOG_TYPE_ERROR, $errMsg, 'Skipped');
263
                return false;
264
            } else {
265
                $error = true;
266
                $errMsg = $response->getContent();
267
                $logsHandler->updateTableLogs(Constants::LOG_TYPE_ERROR, $errMsg, 'ERROR ' . $code);
268
            }
269
        }
270
        if ($error) {
271
            //catch common errors
272
            switch ($code) {
273
                case 401:
274
                    $message = \_MA_WGGITHUB_READGH_ERROR_API_401;
275
                    break;
276
                case 403:
277
                    /*if (\strpos($errMsg, 'API rate limit exceeded') > 0) {$GLOBALS['xoopsTpl']->assign('apiexceed', true);}*/
278
                    $message = \_MA_WGGITHUB_READGH_ERROR_API_403;
279
                    break;
280
                case 404:
281
                    $message = \_MA_WGGITHUB_READGH_ERROR_API_404;
282
                    break;
283
                case 405:
284
                    $message = \_MA_WGGITHUB_READGH_ERROR_API_405;
285
                    break;
286
                case 0:
287
                default:
288
                    $message = \_MA_WGGITHUB_READGH_ERROR_API . '(' .$code . ' - ' .  $errMsg . ')';
289
                    break;
290
            }
291
            \redirect_header('index.php?op=api_error&amp;message='. $message . '&amp;url='. $url, 5, $message);
0 ignored issues
show
Bug introduced by
The function redirect_header was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

291
            /** @scrutinizer ignore-call */ \redirect_header('index.php?op=api_error&amp;message='. $message . '&amp;url='. $url, 5, $message);
Loading history...
292
            //throw new \RuntimeException('"' . $message . '"');
293
        } else {
294
            $data = (array)$api->decode($response);
295
        }
296
297
        return $data;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $data does not seem to be defined for all execution paths leading up to this point.
Loading history...
298
    }
299
300
    /**
301
     * Execute update of repositories and all related tables
302
     * @param string $dirName
303
     * @return bool
304
     */
305
    public function executeUpdate($dirName = '')
306
    {
307
        $helper = Helper::getInstance();
308
        $directoriesHandler = $helper->getHandler('Directories');
309
        $repositoriesHandler = $helper->getHandler('Repositories');
310
        $releasesHandler = $helper->getHandler('Releases');
311
        $readmesHandler = $helper->getHandler('Readmes');
312
        $logsHandler = $helper->getHandler('Logs');
313
314
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_UPDATE_START, '', 'OK');
315
        $crDirectories = new \CriteriaCompo();
0 ignored issues
show
Bug introduced by
The type CriteriaCompo was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
316
        if ('' !== $dirName) {
317
            $crDirectories->add(new \Criteria('dir_name', $dirName));
0 ignored issues
show
Bug introduced by
The type Criteria was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
318
        } else {
319
            $crDirectories->add(new \Criteria('dir_autoupdate', 1));
320
        }
321
        $crDirectories->add(new \Criteria('dir_online', 1));
322
        $directoriesAll = $directoriesHandler->getAll($crDirectories);
323
        // Get All Directories
324
        $directories = [];
325
        foreach (\array_keys($directoriesAll) as $i) {
326
            $directories[$i] = $directoriesAll[$i]->getValuesDirectories();
327
            $dirName = $directoriesAll[$i]->getVar('dir_name');
328
            $dirContent = $directoriesAll[$i]->getVar('dir_content');
329
            $repos = [];
330
            for ($j = 1; $j <= 9; $j++) {
331
                $repos[$j] = [];
332
                if (Constants::DIRECTORY_TYPE_ORG == $directoriesAll[$i]->getVar('dir_type')) {
333
                    $repos = $this->getOrgRepositories($dirName, 100, $j);
334
                } else {
335
                    $repos = $this->getUserRepositories($dirName, 100, $j);
336
                }
337
                if (false === $repos) {
338
                    return false;
339
                    break 1;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
340
                }
341
                if (\count($repos) > 0) {
0 ignored issues
show
Bug introduced by
It seems like $repos can also be of type true; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

341
                if (\count(/** @scrutinizer ignore-type */ $repos) > 0) {
Loading history...
342
                    $repositoriesHandler->updateTableRepositories($dirName, $repos, true, $dirContent);
343
                } else {
344
                    break 1;
345
                }
346
                if (\count($repos) < 100) {
347
                    break 1;
348
                }
349
            }
350
        }
351
        unset($directories);
352
353
        $releasesHandler->updateRepoReleases();
354
        $readmesHandler->updateRepoReadme();
355
356
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_UPDATE_END, '', 'OK');
357
358
        return true;
359
    }
360
361
    /**
362
     * Get primary setting
363
     *
364
     * @return bool|array
365
     */
366
    private function getSetting()
367
    {
368
        $settingsHandler = $this->helper->getHandler('Settings');
369
        $setting = $settingsHandler->getPrimarySetting();
370
371
        if (0 == \count($setting)) {
372
            \redirect_header(\XOOPS_URL . '/index.php', 3, \_AM_WGGITHUB_THEREARENT_SETTINGS);
0 ignored issues
show
Bug introduced by
The constant XOOPS_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The function redirect_header was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

372
            /** @scrutinizer ignore-call */ \redirect_header(\XOOPS_URL . '/index.php', 3, \_AM_WGGITHUB_THEREARENT_SETTINGS);
Loading history...
373
        }
374
        $this->userAuth = $setting['user'];
375
        $this->tokenAuth = $setting['token'];
376
377
        return true;
378
    }
379
}
380