Passed
Push — master ( 34ef5e...ffe1e4 )
by Marcel
08:33
created

DataLoadController::delete()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 8
rs 10
1
<?php
2
/**
3
 * Data 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 2019 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Controller;
13
14
use OCA\Analytics\Activity\ActivityManager;
15
use OCA\Analytics\Db\DataloadMapper;
16
use OCP\AppFramework\Controller;
17
use OCP\AppFramework\Http\DataResponse;
18
use OCP\AppFramework\Http\NotFoundResponse;
19
use OCP\Files\NotFoundException;
20
use OCP\IL10N;
21
use OCP\ILogger;
22
use OCP\IRequest;
23
24
class DataLoadController extends Controller
25
{
26
    private $logger;
27
    private $StorageController;
28
    private $DataSourceController;
29
    private $userId;
30
    private $ActivityManager;
31
    private $DatasetController;
32
    private $l10n;
33
    private $DataloadMapper;
34
35
    public function __construct(
36
        string $AppName,
37
        IRequest $request,
38
        IL10N $l10n,
39
        $userId,
40
        ILogger $logger,
41
        ActivityManager $ActivityManager,
42
        DataSourceController $DataSourceController,
43
        DatasetController $DatasetController,
44
        StorageController $StorageController,
45
        DataloadMapper $DataloadMapper
46
    )
47
    {
48
        parent::__construct($AppName, $request);
49
        $this->l10n = $l10n;
50
        $this->userId = $userId;
51
        $this->logger = $logger;
52
        $this->StorageController = $StorageController;
53
        $this->ActivityManager = $ActivityManager;
54
        $this->DataSourceController = $DataSourceController;
55
        $this->DatasetController = $DatasetController;
56
        $this->DataloadMapper = $DataloadMapper;
57
    }
58
59
    /**
60
     * load data into dataset from datasource
61
     *
62
     * @NoAdminRequired
63
     * @param int $dataloadId
64
     * @param $path
65
     * @return DataResponse|NotFoundResponse
66
     * @throws NotFoundException
67
     * @throws \Exception
68
     */
69
    public function load(int $dataloadId)
0 ignored issues
show
Unused Code introduced by
The parameter $dataloadId is not used and could be removed. ( Ignorable by Annotation )

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

69
    public function load(/** @scrutinizer ignore-unused */ int $dataloadId)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
70
    {
71
        //$this->logger->error('DataLoadController 71:'.$dataloadId);
72
        $dataloadId = 1;
73
        $dataloadMetadata = $this->DataloadMapper->getDataloadById($dataloadId);
74
        $datasetMetadata = $this->DatasetController->getOwnDataset($dataloadMetadata['dataset']);
75
76
        if (!empty($datasetMetadata)) {
77
            $insert = $update = 0;
78
            $option = json_decode($dataloadMetadata['option'], true);
79
            $option['user_id'] = $this->userId;
80
81
            //$this->logger->debug('DataLoadController 81:'.$dataloadMetadata['option'].'---'.json_encode($option));
82
            $result = $this->DataSourceController->read((int)$dataloadMetadata['datasource'], $option);
83
84
            $row = $result['data'][0];
85
            $row['dimension1'] = $row['dimension2'];
86
            $row['dimension2'] = date("Y-m-d");
87
            $action = $this->StorageController->update($dataloadMetadata['dataset'], $row['dimension1'], $row['dimension2'], $row['dimension3']);
88
            $insert = $insert + $action['insert'];
89
            $update = $update + $action['update'];
90
91
            $result = [
92
                'insert' => $insert,
93
                'update' => $update,
94
                'error' => $result['error'],
95
            ];
96
97
            if ($result['error'] === 0) $this->ActivityManager->triggerEvent($dataloadMetadata['dataset'], ActivityManager::OBJECT_DATA, ActivityManager::SUBJECT_DATA_ADD_IMPORT);
98
            return new DataResponse($result);
99
        } else {
100
            return new NotFoundResponse();
101
        }
102
    }
103
104
105
    /**
106
     * update data from input form
107
     *
108
     * @NoAdminRequired
109
     * @param int $datasetId
110
     * @param $dimension1
111
     * @param $dimension2
112
     * @param $dimension3
113
     * @return DataResponse|NotFoundResponse
114
     * @throws \Exception
115
     */
116
    public function update(int $datasetId, $dimension1, $dimension2, $dimension3)
117
    {
118
        $datasetMetadata = $this->DatasetController->getOwnDataset($datasetId);
119
        if (!empty($datasetMetadata)) {
120
            $insert = $update = $errorMessage = 0;
121
            $action = array();
122
            $dimension3 = $this->floatvalue($dimension3);
123
            if ($dimension3 === false) {
124
                $errorMessage = $this->l10n->t('3rd field must be a valid number');
125
            } else {
126
                $action = $this->StorageController->update($datasetId, $dimension1, $dimension2, $dimension3);
127
                $insert = $insert + $action['insert'];
128
                $update = $update + $action['update'];
129
            }
130
131
            $result = [
132
                'insert' => $insert,
133
                'update' => $update,
134
                'error' => $errorMessage,
135
                'validate' => $action['validate'],
136
            ];
137
138
            //$this->logger->error('DataLoadController 88:'.$errorMessage);
139
            if ($errorMessage === 0) $this->ActivityManager->triggerEvent($datasetId, ActivityManager::OBJECT_DATA, ActivityManager::SUBJECT_DATA_ADD);
140
            return new DataResponse($result);
141
        } else {
142
            return new NotFoundResponse();
143
        }
144
    }
145
146
    /**
147
     * update data from input form
148
     *
149
     * @NoAdminRequired
150
     * @param int $datasetId
151
     * @param $dimension1
152
     * @param $dimension2
153
     * @return DataResponse|NotFoundResponse
154
     */
155
    public function delete(int $datasetId, $dimension1, $dimension2)
156
    {
157
        $datasetMetadata = $this->DatasetController->getOwnDataset($datasetId);
158
        if (!empty($datasetMetadata)) {
159
            $result = $this->StorageController->delete($datasetId, $dimension1, $dimension2);
160
            return new DataResponse($result);
0 ignored issues
show
Bug introduced by
$result of type true is incompatible with the type array|object expected by parameter $data of OCP\AppFramework\Http\DataResponse::__construct(). ( Ignorable by Annotation )

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

160
            return new DataResponse(/** @scrutinizer ignore-type */ $result);
Loading history...
161
        } else {
162
            return new NotFoundResponse();
163
        }
164
    }
165
166
    /**
167
     * Import clipboard data
168
     *
169
     * @NoAdminRequired
170
     * @param int $datasetId
171
     * @param $import
172
     * @return DataResponse|NotFoundResponse
173
     * @throws \Exception
174
     */
175
    public function importClipboard($datasetId, $import)
176
    {
177
        $datasetMetadata = $this->DatasetController->getOwnDataset($datasetId);
178
        if (!empty($datasetMetadata)) {
179
            $insert = $update = $errorMessage = $errorCounter = 0;
180
            $delimiter = $this->detectDelimiter($import);
181
            $rows = str_getcsv($import, "\n");
182
183
            foreach ($rows as &$row) {
184
                $row = str_getcsv($row, $delimiter);
185
                $row[2] = $this->floatvalue($row[2]);
186
                if ($row[2] === false) {
187
                    $errorCounter++;
188
                } else {
189
                    $action = $this->StorageController->update($datasetId, $row[0], $row[1], $row[2]);
190
                    $insert = $insert + $action['insert'];
191
                    $update = $update + $action['update'];
192
                }
193
                if ($errorCounter === 2) {
194
                    // first error is ignored; might be due to header row
195
                    $errorMessage = $this->l10n->t('3rd field must be a valid number');
196
                    break;
197
                }
198
            }
199
200
            $result = [
201
                'insert' => $insert,
202
                'update' => $update,
203
                'delimiter' => $delimiter,
204
                'error' => $errorMessage,
205
            ];
206
207
            if ($errorMessage === 0) $this->ActivityManager->triggerEvent($datasetId, ActivityManager::OBJECT_DATA, ActivityManager::SUBJECT_DATA_ADD_IMPORT);
208
            return new DataResponse($result);
209
        } else {
210
            return new NotFoundResponse();
211
        }
212
    }
213
214
    /**
215
     * Import data into dataset from an internal or external file
216
     *
217
     * @NoAdminRequired
218
     * @param int $datasetId
219
     * @param $path
220
     * @return DataResponse|NotFoundResponse
221
     * @throws NotFoundException
222
     * @throws \Exception
223
     */
224
    public function importFile(int $datasetId, $path)
225
    {
226
        //$this->logger->error('DataLoadController 100:'.$datasetId. $path);
227
        $datasetMetadata = $this->DatasetController->getOwnDataset($datasetId);
228
        if (!empty($datasetMetadata)) {
229
            $insert = $update = 0;
230
            $option['user_id'] = $datasetMetadata['user_id'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$option was never initialized. Although not strictly required by PHP, it is generally a good practice to add $option = array(); before regardless.
Loading history...
231
            $option['path'] = $path;
232
            $option['link'] = $datasetMetadata['link'];
233
            $result = $this->DataSourceController->read(DataSourceController::DATASET_TYPE_INTERNAL_FILE, $option);
234
235
            if ($result['error'] === 0) {
236
                foreach ($result['data'] as &$row) {
237
                    $action = $this->StorageController->update($datasetId, $row['dimension1'], $row['dimension2'], $row['dimension3']);
238
                    $insert = $insert + $action['insert'];
239
                    $update = $update + $action['update'];
240
                }
241
            }
242
243
            $result = [
244
                'insert' => $insert,
245
                'update' => $update,
246
                'error' => $result['error'],
247
            ];
248
249
            if ($result['error'] === 0) $this->ActivityManager->triggerEvent($datasetId, ActivityManager::OBJECT_DATA, ActivityManager::SUBJECT_DATA_ADD_IMPORT);
250
            return new DataResponse($result);
251
        } else {
252
            return new NotFoundResponse();
253
        }
254
    }
255
256
    private function detectDelimiter($data)
257
    {
258
        $delimiters = ["\t", ";", "|", ","];
259
        $data_2 = null;
260
        $delimiter = $delimiters[0];
261
        foreach ($delimiters as $d) {
262
            $firstRow = str_getcsv($data, "\n")[0];
263
            $data_1 = str_getcsv($firstRow, $d);
264
            if (sizeof($data_1) > sizeof($data_2)) {
265
                $delimiter = $d;
266
                $data_2 = $data_1;
267
            }
268
        }
269
        return $delimiter;
270
    }
271
272
    private function floatvalue($val)
273
    {
274
        $val = str_replace(",", ".", $val);
275
        $val = preg_replace('/\.(?=.*\.)/', '', $val);
276
        $val = preg_replace('/[^0-9-.]+/', '', $val);
277
        if (is_numeric($val)) {
278
            return number_format(floatval($val), 2, '.', '');
279
        } else {
280
            return false;
281
        }
282
    }
283
}