Passed
Push — master ( 4c4336...d024b0 )
by Marcel
02:33 queued 11s
created

File::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
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\Files\IRootFolder;
15
use OCP\Files\NotFoundException;
16
use OCP\IL10N;
17
use Psr\Log\LoggerInterface;
18
19
class File implements IDatasource
20
{
21
    private $logger;
22
    private $rootFolder;
23
    private $userId;
24
    private $l10n;
25
26
    public function __construct(
27
        $userId,
28
        IL10N $l10n,
29
        LoggerInterface $logger,
30
        IRootFolder $rootFolder
31
    )
32
    {
33
        $this->userId = $userId;
34
        $this->l10n = $l10n;
35
        $this->logger = $logger;
36
        $this->rootFolder = $rootFolder;
37
    }
38
39
    /**
40
     * @return string Display Name of the datasource
41
     */
42
    public function getName(): string
43
    {
44
        return $this->l10n->t('Local file') . ': csv';
45
    }
46
47
    /**
48
     * @return int digit unique datasource id
49
     */
50
    public function getId(): int
51
    {
52
        return 1;
53
    }
54
55
    /**
56
     * @return array available options of the datasoure
57
     */
58
    public function getTemplate(): array
59
    {
60
        $template = array();
61
        array_push($template, ['id' => 'link', 'name' => $this->l10n->t('File'), 'placeholder' => $this->l10n->t('File')]);
62
        array_push($template, ['id' => 'offset', 'name' => $this->l10n->t('Ignore leading rows'), 'placeholder' => $this->l10n->t('Number of rows')]);
63
        array_push($template, ['id' => 'columns', 'name' => $this->l10n->t('Select columns'), 'placeholder' => $this->l10n->t('e.g. 1,2,4 or leave empty')]);
64
        return $template;
65
    }
66
67
    /**
68
     * Read the Data
69
     * @param $option
70
     * @return array available options of the datasoure
71
     * @throws NotFoundException
72
     * @throws \OCP\Files\NotPermittedException
73
     */
74
    public function readData($option): array
75
    {
76
        $data = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
77
        $header = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $header is dead and can be removed.
Loading history...
78
        $headerrow = $errorMessage = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $headerrow is dead and can be removed.
Loading history...
79
        $selectedColumns = array();
80
81
        $file = $this->rootFolder->getUserFolder($option['user_id'])->get($option['link']);
82
        $rows = str_getcsv($file->getContent(), "\n");
0 ignored issues
show
Bug introduced by
The method getContent() does not exist on OCP\Files\Node. It seems like you code against a sub-type of OCP\Files\Node such as OCP\Files\File. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

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