Passed
Push — master ( 5adf78...44ce36 )
by Marcel
02:26 queued 12s
created

ExternalFile::minimizeRow()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 11
rs 10
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 ExternalFile implements IDatasource
18
{
19
    private $logger;
20
    private $userId;
21
    private $l10n;
22
23
    public function __construct(
24
        $userId,
25
        IL10N $l10n,
26
        LoggerInterface $logger
27
    )
28
    {
29
        $this->userId = $userId;
30
        $this->l10n = $l10n;
31
        $this->logger = $logger;
32
    }
33
34
    /**
35
     * @return string Display Name of the datasource
36
     */
37
    public function getName(): string
38
    {
39
        return $this->l10n->t('External file') . ': csv';
40
    }
41
42
    /**
43
     * @return int digit unique datasource id
44
     */
45
    public function getId(): int
46
    {
47
        return 4;
48
    }
49
50
    /**
51
     * @return array available options of the datasoure
52
     */
53
    public function getTemplate(): array
54
    {
55
        $template = array();
56
        array_push($template, ['id' => 'link', 'name' => $this->l10n->t('External URL'), 'placeholder' => 'url']);
57
        array_push($template, ['id' => 'offset', 'name' => $this->l10n->t('Ignore leading rows'), 'placeholder' => $this->l10n->t('Number of rows')]);
58
        array_push($template, ['id' => 'columns', 'name' => $this->l10n->t('Select columns'), 'placeholder' => $this->l10n->t('e.g. 1,2,4 or leave empty')]);
59
        return $template;
60
    }
61
62
    /**
63
     * Read the Data
64
     * @param $option
65
     * @return array available options of the datasoure
66
     */
67
    public function readData($option): array
68
    {
69
        $data = array();
70
        $header = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $header is dead and can be removed.
Loading history...
71
        $headerrow = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $headerrow is dead and can be removed.
Loading history...
72
        $selectedColumns = array();
73
74
        $ch = curl_init();
75
        if ($ch !== false) {
76
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
77
            curl_setopt($ch, CURLOPT_HEADER, false);
78
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
79
            curl_setopt($ch, CURLOPT_URL, $option['link']);
80
            curl_setopt($ch, CURLOPT_REFERER, $option['link']);
81
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
82
            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');
83
            $curlResult = curl_exec($ch);
84
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
85
            curl_close($ch);
86
        } else {
87
            $curlResult = '';
88
        }
89
90
        $rows = str_getcsv($curlResult, "\n");
0 ignored issues
show
Bug introduced by
It seems like $curlResult can also be of type true; however, parameter $string of str_getcsv() 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

90
        $rows = str_getcsv(/** @scrutinizer ignore-type */ $curlResult, "\n");
Loading history...
91
92
        // remove x number of rows from the beginning
93
        if (isset($option['offset']) and is_numeric($option['offset'])) {
94
            $rows = array_slice($rows, $option['offset']);
95
        }
96
97
        if (isset($option['columns']) && strlen($option['columns']) > 0) {
98
            $selectedColumns = str_getcsv($option['columns'], ',');
99
        }
100
        $delimiter = $this->detectDelimiter($rows[0]);
101
102
        $header = str_getcsv($rows[0], $delimiter);
103
        $rows = array_slice($rows, 1);
104
105
        if (count($selectedColumns) !== 0) {
106
            $header = $this->minimizeRow($selectedColumns, $header);
107
108
            foreach ($rows as $row) {
109
                $data[] = $this->minimizeRow($selectedColumns, str_getcsv($row, $delimiter));
110
            }
111
        } else {
112
            foreach ($rows as $row) {
113
                $data[] = str_getcsv($row, $delimiter);
114
            }
115
        }
116
117
        return [
118
            'header' => $header,
119
            'dimensions' => array_slice($header, 0, count($header) - 1),
120
            'data' => $data,
121
            'rawdata' => $curlResult,
122
            '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...
123
        ];
124
    }
125
126
    private function minimizeRow($selectedColumns, $row)
127
    {
128
        $rowMinimized = array();
129
        foreach ($selectedColumns as $selectedColumn) {
130
            if (is_numeric($selectedColumn)) {
131
                $rowMinimized[] = $row[$selectedColumn - 1];
132
            } else {
133
                $rowMinimized[] = $selectedColumn;
134
            }
135
        }
136
        return $rowMinimized;
137
    }
138
139
    private function detectDelimiter($data)
140
    {
141
        $delimiters = ["\t", ";", "|", ","];
142
        $data_2 = array();
143
        $delimiter = $delimiters[0];
144
        foreach ($delimiters as $d) {
145
            //$firstRow = str_getcsv($data, "\n")[0];
146
            $data_1 = str_getcsv($data, $d);
147
            if (sizeof($data_1) > sizeof($data_2)) {
148
                $delimiter = $d;
149
                $data_2 = $data_1;
150
            }
151
        }
152
        return $delimiter;
153
    }
154
}