Passed
Push — master ( 3660fa...998d5d )
by Marcel
03:22
created

DatasetService::getOwnDataset()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 6
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 10
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 2020 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Service;
13
14
use OCA\Analytics\Activity\ActivityManager;
15
use OCA\Analytics\Controller\DatasourceController;
16
use OCA\Analytics\Db\DataloadMapper;
17
use OCA\Analytics\Db\DatasetMapper;
18
use OCA\Analytics\Db\StorageMapper;
19
use OCP\AppFramework\Http\DataDownloadResponse;
20
use OCP\AppFramework\Http\DataResponse;
21
use OCP\Files\IRootFolder;
22
use OCP\ILogger;
23
use OCP\ITagManager;
24
25
class DatasetService
26
{
27
    private $userId;
28
    private $logger;
29
    private $tagManager;
30
    private $ShareService;
31
    private $StorageMapper;
32
    private $DatasetMapper;
33
    private $ThresholdService;
34
    private $DataloadMapper;
35
    private $ActivityManager;
36
    private $rootFolder;
37
38
    public function __construct(
39
        $userId,
40
        ILogger $logger,
41
        ITagManager $tagManager,
42
        ShareService $ShareService,
43
        StorageMapper $StorageMapper,
44
        DatasetMapper $DatasetMapper,
45
        ThresholdService $ThresholdService,
46
        DataloadMapper $DataloadMapper,
47
        ActivityManager $ActivityManager,
48
        IRootFolder $rootFolder
49
    )
50
    {
51
        $this->userId = $userId;
52
        $this->logger = $logger;
53
        $this->tagManager = $tagManager;
54
        $this->ShareService = $ShareService;
55
        $this->ThresholdService = $ThresholdService;
56
        $this->StorageMapper = $StorageMapper;
57
        $this->DatasetMapper = $DatasetMapper;
58
        $this->DataloadMapper = $DataloadMapper;
59
        $this->ActivityManager = $ActivityManager;
60
        $this->rootFolder = $rootFolder;
61
    }
62
63
    /**
64
     * get all datasets
65
     *
66
     * @return DataResponse
67
     */
68
    public function index()
69
    {
70
        $ownDatasets = $this->DatasetMapper->getDatasets();
71
72
        // process favorite check only on own datasets - not shared ones
73
        $favorites = $this->tagManager->load('analytics')->getFavorites();
74
        foreach ($ownDatasets as &$ownDataset) {
75
            $hasTag = 0;
76
            if (is_array($favorites) and in_array($ownDataset['id'], $favorites)) {
77
                $hasTag = 1;
78
            }
79
            $ownDataset['favorite'] = $hasTag;
80
        }
81
82
        // get dataload indicators for icons shown in the advanced screen
83
        $dataloads = $this->DataloadMapper->getAllDataloadMetadata();
84
        foreach ($dataloads as $dataload) {
85
            $key = array_search($dataload['dataset'], array_column($ownDatasets, 'id'));
86
            if ($key !== '') {
87
                if ($dataload['schedules'] !== '' and $dataload['schedules'] !== null) {
88
                    $dataload['schedules'] = 1;
89
                } else {
90
                    $dataload['schedules'] = 0;
91
                }
92
                $ownDatasets[$key]['dataloads'] = $dataload['dataloads'];
93
                $ownDatasets[$key]['schedules'] = $dataload['schedules'];
94
            }
95
        }
96
97
        // get shared datasets and remove doublicates
98
        $sharedDatasets = $this->ShareService->getSharedDatasets();
99
        foreach ($sharedDatasets as $sharedDataset) {
100
            if (!array_search($sharedDataset['id'], array_column($ownDatasets, 'id'))) {
101
                array_push($ownDatasets, $sharedDataset);
102
            }
103
        }
104
105
        return new DataResponse($ownDatasets);
106
    }
107
108
    /**
109
     * get own dataset details
110
     *
111
     * @param int $datasetId
112
     * @return array
113
     */
114
    public function read(int $datasetId)
115
    {
116
        return $this->getOwnDataset($datasetId);
117
    }
118
119
    /**
120
     * get own dataset details
121
     *
122
     * @param int $datasetId
123
     * @param string|null $user_id
124
     * @return array
125
     */
126
    public function getOwnDataset(int $datasetId, string $user_id = null)
127
    {
128
        // default permission UPDATE only for internal reports; all others can not change filters
129
        $ownDataset = $this->DatasetMapper->read($datasetId, $user_id);
130
        if (!empty($ownDataset) && (int)$ownDataset['type'] === DatasourceController::DATASET_TYPE_INTERNAL_DB) {
131
            $ownDataset['permissions'] = \OCP\Constants::PERMISSION_UPDATE;
132
        } elseif (!empty($ownDataset)) {
133
            $ownDataset['permissions'] = \OCP\Constants::PERMISSION_READ;
134
        }
135
        return $ownDataset;
136
    }
137
138
    /**
139
     * get own datasets which are marked as favorites
140
     *
141
     * @return array|bool
142
     */
143
    public function getOwnFavoriteDatasets()
144
    {
145
        return $this->tagManager->load('analytics')->getFavorites();
146
    }
147
148
    /**
149
     * create new dataset
150
     *
151
     * @param string $file
152
     * @param string $link
153
     * @return int
154
     */
155
    public function create($file = '', $link = '')
0 ignored issues
show
Unused Code introduced by
The parameter $link 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

155
    public function create($file = '', /** @scrutinizer ignore-unused */ $link = '')

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...
156
    {
157
        //$this->logger->error('datasetcontroller 82: '.$file);
158
        $this->ActivityManager->triggerEvent(0, ActivityManager::OBJECT_DATASET, ActivityManager::SUBJECT_DATASET_ADD);
159
        $datasetId = $this->DatasetMapper->createDataset();
160
161
        if ($file === 'DEMO') {
162
            $name = 'Demo Report';
163
            $subheader = 'CSV Demo Data from GitHub';
164
            $parent = 0;
165
            $type = DatasourceController::DATASET_TYPE_EXTERNAL_FILE;
166
            $link = 'https://raw.githubusercontent.com/Rello/analytics/master/sample_data/sample1.csv';
167
            $visualization = 'ct';
168
            $chart = 'line';
169
            $this->update($datasetId, $name, $subheader, $parent, $type, $link, $visualization, $chart, '', '');
170
            $this->setFavorite($datasetId, 'true');
171
        } elseif ($file !== '') {
172
            $name = explode('.', end(explode('/', $file)))[0];
173
            $subheader = $file;
174
            $parent = 0;
175
            $type = DatasourceController::DATASET_TYPE_INTERNAL_FILE;
176
            $link = $file;
177
            $visualization = 'table';
178
            $chart = 'line';
179
            $this->update($datasetId, $name, $subheader, $parent, $type, $link, $visualization, $chart, '', '');
180
        }
181
        return $datasetId;
182
    }
183
184
    /**
185
     * get dataset details
186
     *
187
     * @param int $datasetId
188
     * @param $name
189
     * @param $subheader
190
     * @param int $parent
191
     * @param int $type
192
     * @param $link
193
     * @param $visualization
194
     * @param $chart
195
     * @param $chartoptions
196
     * @param $dataoptions
197
     * @param $dimension1
198
     * @param $dimension2
199
     * @param $value
200
     * @return bool
201
     */
202
    public function update(int $datasetId, $name, $subheader, int $parent, int $type, $link, $visualization, $chart, $chartoptions, $dataoptions, $dimension1 = null, $dimension2 = null, $value = null)
203
    {
204
        if ($type === DatasourceController::DATASET_TYPE_GROUP) {
205
            $parent = 0;
206
        }
207
        return $this->DatasetMapper->updateDataset($datasetId, $name, $subheader, $parent, $type, $link, $visualization, $chart, $chartoptions, $dataoptions, $dimension1, $dimension2, $value);
208
    }
209
210
    /**
211
     * set/remove the favorite flag for a report
212
     *
213
     * @param int $datasetId
214
     * @param string $favorite
215
     * @return bool
216
     */
217
    public function setFavorite(int $datasetId, string $favorite)
218
    {
219
        if ($favorite === 'true') {
220
            $return = $this->tagManager->load('analytics')->addToFavorites($datasetId);
221
        } else {
222
            $return = $this->tagManager->load('analytics')->removeFromFavorites($datasetId);
223
        }
224
        return $return;
225
    }
226
227
    /**
228
     * Import Dataset from File
229
     *
230
     * @param string $path
231
     * @return int
232
     * @throws \OCP\Files\NotFoundException
233
     * @throws \OCP\Files\NotPermittedException
234
     */
235
    public function import(string $path = '')
236
    {
237
        $file = $this->rootFolder->getUserFolder($this->userId)->get($path);
238
        $data = $file->getContent();
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

238
        /** @scrutinizer ignore-call */ 
239
        $data = $file->getContent();
Loading history...
239
        $data = json_decode($data, true);
240
241
        $dataset = $data['dataset'];
242
        isset($dataset['name']) ? $name = $dataset['name'] : $name = '';
243
        isset($dataset['subheader']) ? $subheader = $dataset['subheader'] : $subheader = '';
244
        $parent = 0;
245
        isset($dataset['type']) ? $type = $dataset['type'] : $type = null;
246
        isset($dataset['link']) ? $link = $dataset['link'] : $link = null;
247
        isset($dataset['visualization']) ? $visualization = $dataset['visualization'] : $visualization = null;
248
        isset($dataset['chart']) ? $chart = $dataset['chart'] : $chart = null;
249
        isset($dataset['chartoptions']) ? $chartoptions = $dataset['chartoptions'] : $chartoptions = null;
250
        isset($dataset['dataoptions']) ? $dataoptions = $dataset['dataoptions'] : $dataoptions = null;
251
        isset($dataset['dimension1']) ? $dimension1 = $dataset['dimension1'] : $dimension1 = null;
252
        isset($dataset['dimension2']) ? $dimension2 = $dataset['dimension2'] : $dimension2 = null;
253
        isset($dataset['value']) ? $value = $dataset['value'] : $value = null;
254
255
        $datasetId = $this->DatasetMapper->createDataset();
256
        $this->DatasetMapper->updateDataset($datasetId, $name, $subheader, $parent, $type, $link, $visualization, $chart, $chartoptions, $dataoptions, $dimension1, $dimension2, $value);
257
258
        foreach ($data['dataload'] as $dataload) {
259
            isset($dataload['datasource']) ? $datasource = $dataload['datasource'] : $datasource = null;
260
            isset($dataload['name']) ? $name = $dataload['name'] : $name = null;
261
            isset($dataload['option']) ? $option = $dataload['option'] : $option = null;
262
            $schedule = null;
263
264
            $dataloadId = $this->DataloadMapper->create($datasetId, $datasource);
265
            $this->DataloadMapper->update($dataloadId, $name, $option, $schedule);
266
        }
267
268
        foreach ($data['threshold'] as $threshold) {
269
            isset($threshold['dimension1']) ? $dimension1 = $threshold['dimension1'] : $dimension1 = null;
270
            isset($threshold['value']) ? $value = $threshold['value'] : $value = null;
271
            isset($threshold['option']) ? $option = $threshold['option'] : $option = null;
272
            isset($threshold['severity']) ? $severity = $threshold['severity'] : $severity = null;
273
            $this->ThresholdService->create($datasetId, $dimension1, $option, $value, $severity);
274
        }
275
276
        foreach ($data['data'] as $dData) {
277
            isset($dData[0]) ? $dimension1 = $dData[0] : $dimension1 = null;
278
            isset($dData[1]) ? $dimension2 = $dData[1] : $dimension2 = null;
279
            isset($dData[2]) ? $value = $dData[2] : $value = null;
280
            $this->logger->error('DatasetService : data:' . $datasetId . $dimension1 . $dimension2 . $value);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\ILogger::error() has been deprecated: 20.0.0 use \Psr\Log\LoggerInterface::error ( Ignorable by Annotation )

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

280
            /** @scrutinizer ignore-deprecated */ $this->logger->error('DatasetService : data:' . $datasetId . $dimension1 . $dimension2 . $value);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
281
282
            $this->StorageMapper->createData($datasetId, $dimension1, $dimension2, $value);
283
        }
284
285
        return $datasetId;
286
    }
287
288
    /**
289
     * Export Dataset
290
     *
291
     * @param int $datasetId
292
     * @return DataDownloadResponse
293
     */
294
    public function export(int $datasetId)
295
    {
296
        $result['dataset'] = $this->DatasetMapper->read($datasetId);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.
Loading history...
297
        $result['dataload'] = $this->DataloadMapper->read($datasetId);
298
        $result['threshold'] = $this->ThresholdService->read($datasetId);
299
300
        if ($result['dataset']['type'] === DatasourceController::DATASET_TYPE_INTERNAL_DB) {
301
            $result['data'] = $this->StorageMapper->getData($datasetId);
302
        }
303
304
        unset($result['dataset']['id'], $result['dataset']['user_id'], $result['dataset']['user_id'], $result['dataset']['parent']);
305
        $data = json_encode($result);
306
        return new DataDownloadResponse($data, $result['dataset']['name'] . '.export.txt', 'text/plain; charset=utf-8');
307
    }
308
309
    /**
310
     * Delete Dataset and all depending objects
311
     *
312
     * @param int $datasetId
313
     * @return bool
314
     */
315
    public function delete(int $datasetId)
316
    {
317
        $this->ShareService->deleteShareByDataset($datasetId);
318
        $this->StorageMapper->deleteDataByDataset($datasetId);
319
        $this->DatasetMapper->deleteDataset($datasetId);
320
        $this->ThresholdService->deleteThresholdByDataset($datasetId);
321
        $this->DataloadMapper->deleteDataloadByDataset($datasetId);
322
        $this->ActivityManager->triggerEvent(0, ActivityManager::OBJECT_DATASET, ActivityManager::SUBJECT_DATASET_DELETE);
323
        $this->setFavorite($datasetId, 'false');
324
        return true;
325
    }
326
327
    /**
328
     * get dataset details
329
     *
330
     * @param int $datasetId
331
     * @param $chartoptions
332
     * @param $dataoptions
333
     * @param $filteroptions
334
     * @return bool
335
     */
336
    public function updateOptions(int $datasetId, $chartoptions, $dataoptions, $filteroptions)
337
    {
338
        return $this->DatasetMapper->updateDatasetOptions($datasetId, $chartoptions, $dataoptions, $filteroptions);
339
    }
340
341
    /**
342
     * search for datasets
343
     *
344
     * @param string $searchString
345
     * @return array
346
     */
347
    public function search(string $searchString)
348
    {
349
        return $this->DatasetMapper->search($searchString);
350
    }
351
352
}