Passed
Push — master ( c1235b...0945e8 )
by Marcel
02:27
created

Json::readData()   F

Complexity

Conditions 17
Paths 288

Size

Total Lines 76
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 17
eloc 56
nc 288
nop 1
dl 0
loc 76
rs 3.2833
c 4
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
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the LICENSE.md file.
7
 *
8
 * @author Marcel Scherello <[email protected]>
9
 * @copyright 2021 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Datasource;
13
14
use OCP\IL10N;
15
use Psr\Log\LoggerInterface;
16
17
class Json implements IDatasource
18
{
19
    private $logger;
20
    private $l10n;
21
22
    public function __construct(
23
        IL10N $l10n,
24
        LoggerInterface $logger
25
    )
26
    {
27
        $this->l10n = $l10n;
28
        $this->logger = $logger;
29
    }
30
31
    /**
32
     * @return string Display Name of the datasource
33
     */
34
    public function getName(): string
35
    {
36
        return $this->l10n->t('JSON');
37
    }
38
39
    /**
40
     * @return int digit unique datasource id
41
     */
42
    public function getId(): int
43
    {
44
        return 6;
45
    }
46
47
    /**
48
     * @return array available options of the datasoure
49
     */
50
    public function getTemplate(): array
51
    {
52
        $template = array();
53
        array_push($template, ['id' => 'url', 'name' => 'URL', 'placeholder' => 'url']);
54
        array_push($template, ['id' => 'auth', 'name' => $this->l10n->t('Authentication'), 'placeholder' => 'User:Password']);
55
        array_push($template, ['id' => 'path', 'name' => $this->l10n->t('Object path'), 'placeholder' => 'x/y/z']);
56
        array_push($template, ['id' => 'method', 'name' => $this->l10n->t('HTTP method'), 'placeholder' => 'GET/POST', 'type' => 'tf']);
57
        array_push($template, ['id' => 'body', 'name' => $this->l10n->t('Request body'), 'placeholder' => '']);
58
        array_push($template, ['id' => 'content-type', 'name' => $this->l10n->t('Header Content-Type'), 'placeholder' => 'application/json']);
59
        array_push($template, ['id' => 'timestamp', 'name' => $this->l10n->t('Timestamp of dataload'), 'placeholder' => $this->l10n->t('true/false'), 'type' => 'tf']);
60
        return $template;
61
    }
62
63
    /**
64
     * Read the Data
65
     * @param $option
66
     * @return array available options of the datasoure
67
     */
68
    public function readData($option): array
69
    {
70
        $string = $option['url'];
71
        $path = $option['path'];
72
        $auth = $option['auth'];
73
        $post = ($option['method'] === 'POST') ? true : false;
74
        $contentType = ($option['content-type'] && $option['content-type'] !== '') ? $option['content-type'] : 'application/json';
75
        $data = array();
76
77
        $ch = curl_init();
78
        if ($ch !== false) {
79
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
80
            curl_setopt($ch, CURLOPT_URL, $string);
81
            curl_setopt($ch, CURLOPT_POST, $post);
82
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
83
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
84
                'OCS-APIRequest: true',
85
                'Content-Type: ' . $contentType
86
            ));
87
            curl_setopt($ch, CURLOPT_USERPWD, $auth);
88
            curl_setopt($ch, CURLOPT_VERBOSE, true);
89
            if ($option['body'] && $option['body'] !== '') {
90
                curl_setopt($ch, CURLOPT_POSTFIELDS, $option['body']);
91
            }
92
            $curlResult = curl_exec($ch);
93
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
94
            curl_close($ch);
95
        } else {
96
            $curlResult = '';
97
        }
98
99
        $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

99
        $json = json_decode(/** @scrutinizer ignore-type */ $curlResult, true);
Loading history...
100
101
        // check if an array of values should be extracted
102
        preg_match_all("/(?<={).*(?=})/", $path, $matches);
103
        if (count($matches[0]) > 0) {
104
            // array extraction
105
            $paths = explode(',', $matches[0][0]);
106
            foreach ($json as $rowArray) {
107
                $dim1 = $rowArray[$paths[0]] ?: $paths[0];
108
                $dim2 = $rowArray[$paths[1]] ?: $paths[1];
109
                $val = $rowArray[$paths[2]] ?: $paths[2];
110
                array_push($data, [$dim1, $dim2, $val]);
111
            }
112
        } else {
113
            // single value extraction
114
            $paths = explode(',', $path);
115
            foreach ($paths as $singlePath) {
116
                $array = $this->get_nested_array_value($json, $singlePath);
117
118
                if (is_array($array)) {
119
                    foreach ($array as $key => $value) {
120
                        $pathArray = explode('/', $singlePath);
121
                        $group = end($pathArray);
122
                        array_push($data, [$group, $key, $value]);
123
                    }
124
                } else {
125
                    $pathArray = explode('/', $singlePath);
126
                    $key = end($pathArray);
127
                    array_push($data, ['', $key, $array]);
128
                }
129
            }
130
        }
131
132
133
        $header = array();
134
        $header[0] = '';
135
        $header[1] = 'Key';
136
        $header[2] = 'Value';
137
138
        return [
139
            'header' => $header,
140
            'dimensions' => array_slice($header, 0, count($header) - 1),
141
            'data' => $data,
142
            'rawdata' => $curlResult,
143
            'error' => ($http_code>=200 && $http_code<300) ? 0 : 'HTTP response code: '.$http_code,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $http_code does not seem to be defined for all execution paths leading up to this point.
Loading history...
144
        ];
145
    }
146
147
    /**
148
     * get array object from string
149
     *
150
     * @NoAdminRequired
151
     * @param $array
152
     * @param $path
153
     * @param string $delimiter
154
     * @return array|string
155
     */
156
    private function get_nested_array_value(&$array, $path, $delimiter = '/')
157
    {
158
        $pathParts = explode($delimiter, $path);
159
        $current = &$array;
160
        foreach ($pathParts as $key) {
161
            $current = &$current[$key];
162
        }
163
        return $current;
164
    }
165
}