Passed
Push — master ( c753a2...d7ee80 )
by Goffy
03:06
created

GithubClient::getRepositoryContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
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, true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_get($url, true) could also return false which is incompatible with the documented return type array|string. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
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, true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_get($url, true) could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
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 content of repository
198
     *
199
     * @param  $username
200
     * @param  $repository
201
     * @return array
202
     */
203
    public function getRepositoryContent($username, $repository)
204
    {
205
        $url = static::BASE_URL . 'repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents';
206
207
        return $this->_get($url);
208
    }
209
210
    /**
211
     * Get github content
212
     *
213
     * @param      $url
214
     * @param bool $skipError
215
     * @return array|bool
216
     */
217
    public function _get($url, $skipError = false)
218
    {
219
        $error = false;
220
        $errMsg = '';
221
222
        $logsHandler = $this->helper->getHandler('Logs');
223
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'START');
224
        $api = new Github\Api;
225
        $token = new Github\OAuth\Token($this->tokenAuth, 'bearer', ['repo', 'user', 'public_repo']);
226
        $api->setToken($token);
227
        $response = $api->get($url);
228
        $code = $response->getCode();
229
        if (\in_array($code, [200, 201], true)) {
230
            $logsHandler->updateTableLogs(Constants::LOG_TYPE_REQUEST, $url, 'OK');
231
        } else {
232
            if ($skipError) {
233
                $logsHandler->updateTableLogs(Constants::LOG_TYPE_ERROR, $errMsg, 'Skipped');
234
                return false;
235
            } else {
236
                $error = true;
237
                $errMsg = $response->getContent();
238
                $logsHandler->updateTableLogs(Constants::LOG_TYPE_ERROR, $errMsg, 'ERROR ' . $code);
239
            }
240
        }
241
        if ($error) {
242
            //catch common errors
243
            switch ($code) {
244
                case 401:
245
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_401 . '"');
246
                    break;
247
                case 403:
248
                    /*
249
                    if (\strpos($errMsg, 'API rate limit exceeded') > 0) {
250
                        $GLOBALS['xoopsTpl']->assign('apiexceed', true);
251
                    }
252
                    */
253
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_403 . '"');
254
                    break;
255
                case 404:
256
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_404 . '"');
257
                    break;
258
                case 405:
259
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API_405 . '"');
260
                    break;
261
                case 0:
262
                default:
263
                    throw new \RuntimeException('"' . \_MA_WGGITHUB_READGH_ERROR_API . $errMsg . '"');
264
                    break;
265
            }
266
        }
267
        $data = (array)$api->decode($response);
268
269
        return $data;
270
    }
271
272
    /**
273
     * Execute update of repositories and all related tables
274
     * @param string $dirName
275
     * @return bool
276
     */
277
    public function executeUpdate($dirName = '')
278
    {
279
        $helper = Helper::getInstance();
280
        $directoriesHandler = $helper->getHandler('Directories');
281
        $repositoriesHandler = $helper->getHandler('Repositories');
282
        $releasesHandler = $helper->getHandler('Releases');
283
        $readmesHandler = $helper->getHandler('Readmes');
284
        $logsHandler = $helper->getHandler('Logs');
285
286
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_UPDATE_START, '', 'OK');
287
        $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...
288
        if ('' !== $dirName) {
289
            $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...
290
        } else {
291
            $crDirectories->add(new \Criteria('dir_autoupdate', 1));
292
        }
293
        $crDirectories->add(new \Criteria('dir_online', 1));
294
        $directoriesAll = $directoriesHandler->getAll($crDirectories);
295
        // Get All Directories
296
        $directories = [];
297
        foreach (\array_keys($directoriesAll) as $i) {
298
            $directories[$i] = $directoriesAll[$i]->getValuesDirectories();
299
            $dirName = $directoriesAll[$i]->getVar('dir_name');
300
            $dirContent = $directoriesAll[$i]->getVar('dir_content');
301
            $repos = [];
302
            for ($j = 1; $j <= 9; $j++) {
303
                $repos[$j] = [];
304
                if (Constants::DIRECTORY_TYPE_ORG == $directoriesAll[$i]->getVar('dir_type')) {
305
                    $repos = $this->getOrgRepositories($dirName, 100, $j);
306
                } else {
307
                    $repos = $this->getUserRepositories($dirName, 100, $j);
308
                }
309
                if (false === $repos) {
310
                    return false;
311
                    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...
312
                }
313
                if (count($repos) > 0) {
314
                    $repositoriesHandler->updateTableRepositories($dirName, $repos, true, $dirContent);
315
                } else {
316
                    break 1;
317
                }
318
                if (count($repos) < 100) {
319
                    break 1;
320
                }
321
            }
322
        }
323
        unset($directories);
324
325
        $releasesHandler->updateRepoReleases();
326
        $readmesHandler->updateRepoReadme();
327
328
        $logsHandler->updateTableLogs(Constants::LOG_TYPE_UPDATE_END, '', 'OK');
329
330
        return true;
331
    }
332
333
    /**
334
     * Get primary setting
335
     *
336
     * @return bool|array
337
     */
338
    private function getSetting()
339
    {
340
        $settingsHandler = $this->helper->getHandler('Settings');
341
        $setting = $settingsHandler->getPrimarySetting();
342
343
        if (0 == \count($setting)) {
344
            \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

344
            /** @scrutinizer ignore-call */ 
345
            \redirect_header(\XOOPS_URL . '/index.php', 3, \_AM_WGGITHUB_THEREARENT_SETTINGS);
Loading history...
345
        }
346
        //$this->userAuth = $setting['user'];
347
        $this->tokenAuth = $setting['token'];
348
349
        return true;
350
    }
351
}
352