Passed
Push — master ( 1bf514...8085c4 )
by Goffy
04:05
created

GithubClient   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 297
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 119
dl 0
loc 297
rs 9.92
c 0
b 0
f 0
wmc 31

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getUserRepositories() 0 5 1
A testMilo() 0 6 1
A getLatestRelease() 0 18 4
A testMilo2() 0 18 1
A getOrgRepositories() 0 5 1
A getReleases() 0 5 1
A __construct() 0 4 1
A getInstance() 0 8 2
A getReadme() 0 5 1
B _get() 0 49 8
A getSetting() 0 12 2
B executeUpdate() 0 53 8
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
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 testMilo($url) {
83
        $api = new Github\Api;
84
        $response = $api->get(static::BASE_URL . $url);
85
        $data = $api->decode($response);
86
        
87
        return $data;
88
    }
89
90
    public function testMilo2($url) {
91
        $api = new Github\Api;
92
93
        $token = new Github\OAuth\Token('{myKey}', 'bearer', ['repo', 'user', 'public_repo']);
94
        $api->setToken($token);
95
        $response = $api->get(static::BASE_URL . $url);
96
97
        $data = $api->decode($response);
98
99
        /*
100
        $api = new Github\Api;
101
102
        $request = $api->createRequest('GET', $url, [], [], '');
103
        $response = $api->request($request);
104
        $data = (array)$api->decode($response);
105
        */
106
107
        return $data;
108
    }
109
110
    /**
111
     * Get repositories of given user
112
     *
113
     * @param     $username
114
     * @param int $per_page
115
     * @param int $page
116
     * @return array
117
     */
118
    public function getUserRepositories($username, $per_page = 100, $page = 1)
119
    {
120
        $url = static::BASE_URL . 'users/' . \rawurlencode($username) . '/repos?per_page=' . $per_page . '&page=' . $page;
121
122
        return $this->_get($url);
123
    }
124
125
    /**
126
     * Get repositories of given organisation
127
     *
128
     * @param     $org
129
     * @param int $per_page
130
     * @param int $page
131
     * @return array
132
     */
133
    public function getOrgRepositories($org, $per_page = 100, $page = 1)
134
    {
135
        $url = static::BASE_URL . 'orgs/' . \rawurlencode($org) . '/repos?per_page=' . $per_page . '&page=' . $page;
136
137
        return $this->_get($url);
138
    }
139
140
    /**
141
     * Get the readme content for a repository by its username and repository name.
142
     *
143
     * @param string $username   the user who owns the repository
144
     * @param string $repository the name of the repository
145
     * @return string|array the readme content
146
     */
147
    public function getReadme($username, $repository)
148
    {
149
        $url = static::BASE_URL . 'repos/' . \rawurlencode($username) . '/' . \rawurlencode($repository) . '/readme';
150
151
        return $this->_get($url);
152
    }
153
154
    /**
155
     * Get all releases
156
     *
157
     * @param string $username   the user who owns the repository
158
     * @param string $repository the name of the repository
159
     * @return array
160
     */
161
    public function getReleases($username, $repository)
162
    {
163
        $url = static::BASE_URL . 'repos/' . $username . '/' . $repository . '/releases';
164
165
        return $this->_get($url);
166
    }
167
168
    /**
169
     * Get latest release
170
     *
171
     * @param string $username   the user who owns the repository
172
     * @param string $repository the name of the repository
173
     * @param bool   $prerelease
174
     * @return array
175
     */
176
    public function getLatestRelease($username, $repository, $prerelease = false)
177
    {
178
        if ($prerelease) {
179
            $url = static::BASE_URL . 'repos/' . $username . '/' . $repository . '/releases';
180
        } else {
181
            $url = static::BASE_URL . 'repos/' . $username . '/' . $repository . '/releases/latest';
182
        }
183
        $result = $this->_get($url);
184
185
        if ($prerelease) {
186
            if (\is_array($result)) {
0 ignored issues
show
introduced by
The condition is_array($result) is always true.
Loading history...
187
                return $result[0];
188
            } else {
189
                return [];
190
            }
191
        }
192
193
        return $result;
194
    }
195
196
    /**
197
     * Get github content
198
     *
199
     * @param $url
200
     * @return array
201
     */
202
    public function _get($url)
203
    {
204
        $error = false;
205
        $errMsg = '';
206
207
        $logsHandler = $this->helper->getHandler('Logs');
208
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'START');
209
210
        $api = new Github\Api;
211
        $token = new Github\OAuth\Token($this->tokenAuth, 'bearer', ['repo', 'user', 'public_repo']);
212
        $api->setToken($token);
213
        $response = $api->get($url);
214
        $code = $response->getCode();
215
        if (\in_array($code, [200, 201], true)) {
216
            $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'OK');
217
        } else {
218
            $error = true;
219
            $errMsg = $response->getContent();
220
            $logsHandler->updateTableLogs(Constants::LOG_TYPE_ERROR, $errMsg, 'ERROR ' . $code);
221
        }
222
        if ($error) {
223
            //catch common errors
224
            switch ($code) {
225
                case 401:
226
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_401 . '"');
227
                    break;
228
                case 403:
229
                    /*
230
                    if (\strpos($errMsg, 'API rate limit exceeded') > 0) {
231
                        $GLOBALS['xoopsTpl']->assign('apiexceed', true);
232
                    }
233
                    */
234
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_403 . '"');
235
                    break;
236
                case 404:
237
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_404 . '"');
238
                    break;
239
                case 405:
240
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_405 . '"');
241
                    break;
242
                case 0:
243
                default:
244
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API . $errMsg . '"');
245
                    break;
246
            }
247
        }
248
        $data = (array)$api->decode($response);
249
250
        return $data;
251
    }
252
253
    /**
254
     * Execute update of repositories and all related tables
255
     * @param string $dirName
256
     * @return bool
257
     */
258
    public function executeUpdate($dirName = '')
259
    {
260
        $helper = Helper::getInstance();
261
        $directoriesHandler = $helper->getHandler('Directories');
262
        $repositoriesHandler = $helper->getHandler('Repositories');
263
        $releasesHandler = $helper->getHandler('Releases');
264
        $readmesHandler = $helper->getHandler('Readmes');
265
        $logsHandler = $helper->getHandler('Logs');
266
267
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_UPDATE_START, '', 'OK');
268
        $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...
269
        if ('' !== $dirName) {
270
            $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...
271
        } else {
272
            $crDirectories->add(new \Criteria('dir_autoupdate', 1));
273
        }
274
        $crDirectories->add(new \Criteria('dir_online', 1));
275
        $directoriesAll = $directoriesHandler->getAll($crDirectories);
276
        // Get All Directories
277
        $directories = [];
278
        foreach (\array_keys($directoriesAll) as $i) {
279
            $directories[$i] = $directoriesAll[$i]->getValuesDirectories();
280
            $dirName = $directoriesAll[$i]->getVar('dir_name');
281
            $repos = [];
282
            for ($j = 1; $j <= 9; $j++) {
283
                $repos[$j] = [];
284
                if (Constants::DIRECTORY_TYPE_ORG == $directoriesAll[$i]->getVar('dir_type')) {
285
                    $repos = $this->getOrgRepositories($dirName, 100, $j);
286
                } else {
287
                    $repos = $this->getUserRepositories($dirName, 100, $j);
288
                }
289
                if (false === $repos) {
290
                    return false;
291
                    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...
292
                }
293
                if (count($repos) > 0) {
294
                    $repositoriesHandler->updateTableRepositories($dirName, $repos, true);
295
                } else {
296
                    break 1;
297
                }
298
                if (count($repos) < 100) {
299
                    break 1;
300
                }
301
            }
302
        }
303
        unset($directories);
304
305
        $releasesHandler->updateRepoReleases();
306
        $readmesHandler->updateRepoReadme();
307
308
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_UPDATE_END, '', 'OK');
309
310
        return true;
311
    }
312
313
    /**
314
     * Get primary setting
315
     *
316
     * @return bool|array
317
     */
318
    private function getSetting()
319
    {
320
        $settingsHandler = $this->helper->getHandler('Settings');
321
        $setting = $settingsHandler->getPrimarySetting();
322
323
        if (0 == \count($setting)) {
324
            \redirect_header(\XOOPS_URL . '/index.php', 3, \_AM_WGGITHUB_THEREARENT_SETTINGS);
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

324
            /** @scrutinizer ignore-call */ 
325
            \redirect_header(\XOOPS_URL . '/index.php', 3, \_AM_WGGITHUB_THEREARENT_SETTINGS);
Loading history...
Bug introduced by
The constant XOOPS_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
325
        }
326
        //$this->userAuth = $setting['user'];
327
        $this->tokenAuth = $setting['token'];
328
329
        return true;
330
    }
331
}
332