Github::readData()   B
last analyzed

Complexity

Conditions 11
Paths 32

Size

Total Lines 51
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 39
nc 32
nop 1
dl 0
loc 51
rs 7.3166
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
 * Analytics
4
 *
5
 * SPDX-FileCopyrightText: 2019-2022 Marcel Scherello
6
 * SPDX-License-Identifier: AGPL-3.0-or-later
7
 */
8
9
namespace OCA\Analytics\Datasource;
10
11
use OCP\IL10N;
0 ignored issues
show
Bug introduced by
The type OCP\IL10N 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...
12
use Psr\Log\LoggerInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Log\LoggerInterface 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...
13
14
class Github implements IDatasource
15
{
16
    private LoggerInterface $logger;
17
    private IL10N $l10n;
18
19
    public function __construct(
20
        IL10N $l10n,
21
        LoggerInterface $logger
22
    )
23
    {
24
        $this->l10n = $l10n;
25
        $this->logger = $logger;
26
    }
27
28
    /**
29
     * @return string Display Name of the datasource
30
     */
31
    public function getName(): string
32
    {
33
        return 'GitHub';
34
    }
35
36
    /**
37
     * @return int digit unique datasource id
38
     */
39
    public function getId(): int
40
    {
41
        return 3;
42
    }
43
44
    /**
45
     * @return array available options of the datasoure
46
     */
47
    public function getTemplate(): array
48
    {
49
        $template = array();
50
        $template[] = ['id' => 'user', 'name' => 'GitHub Username', 'placeholder' => 'GitHub user'];
51
        $template[] = ['id' => 'repository', 'name' => 'Repository', 'placeholder' => 'GitHub repository'];
52
        $template[] = ['id' => 'limit', 'name' => $this->l10n->t('Limit'), 'placeholder' => $this->l10n->t('Number of rows'), 'type' => 'number'];
53
        $template[] = ['id' => 'timestamp', 'name' => $this->l10n->t('Timestamp of data load'), 'placeholder' => 'false-' . $this->l10n->t('No').'/true-'.$this->l10n->t('Yes'), 'type' => 'tf'];
54
        return $template;
55
    }
56
57
    /**
58
     * Read the Data
59
     * @param $option
60
     * @return array available options of the data source
61
     */
62
    public function readData($option): array
63
    {
64
        $http_code = '';
65
        if (isset($option['link'])) $string = 'https://api.github.com/repos/' . $option['link'] . '/releases';
66
        else $string = 'https://api.github.com/repos/' . $option['user'] . '/' . $option['repository'] . '/releases';
67
68
        $ch = curl_init();
69
        if ($ch !== false) {
70
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
71
            curl_setopt($ch, CURLOPT_HEADER, false);
72
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
73
            curl_setopt($ch, CURLOPT_URL, $string);
74
            curl_setopt($ch, CURLOPT_REFERER, $string);
75
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
76
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
77
            $curlResult = curl_exec($ch);
78
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
79
            curl_close($ch);
80
        } else {
81
            $curlResult = '';
82
        }
83
84
        $json = json_decode($curlResult, true);
0 ignored issues
show
Bug introduced by
It seems like $curlResult can also be of type true; however, parameter $json of json_decode() does only seem to accept string, 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

84
        $json = json_decode(/** @scrutinizer ignore-type */ $curlResult, true);
Loading history...
85
        $i = 0;
86
        $data = array();
87
        foreach ($json as $item) {
88
            if (isset($option['limit']) and $option['limit'] !== '') {
89
                if ($i === (int)$option['limit']) break;
90
            }
91
            $nc_value = 0;
92
            foreach ($item['assets'] as $asset) {
93
                if (str_ends_with($asset['name'], 'gz')) $nc_value = $asset['download_count'];
94
            }
95
            $data[] = [$item['tag_name'], $this->floatvalue($nc_value)];
96
            $i++;
97
        }
98
99
        $header = array();
100
        $header[0] = $this->l10n->t('Version');
101
        $header[1] = $this->l10n->t('Download count');
102
103
        usort($data, function ($a, $b) {
104
            return strnatcmp($a[0], $b[0]);
105
        });
106
107
        return [
108
            'header' => $header,
109
            'dimensions' => array_slice($header, 0, count($header) - 1),
110
            'data' => $data,
111
            'rawdata' => $curlResult,
112
            'error' => ($http_code>=200 && $http_code<300) ? 0 : 'HTTP response code: '.$http_code,
113
        ];
114
    }
115
116
    private function floatvalue($val)
117
    {
118
        $val = str_replace(",", ".", $val);
119
        $val = preg_replace('/\.(?=.*\.)/', '', $val);
120
        $val = preg_replace('/[^0-9-.]+/', '', $val);
121
        if (is_numeric($val)) {
122
            return floatval($val);
123
        } else {
124
            return false;
125
        }
126
    }
127
}