Passed
Push — master ( 1876ce...d1e05a )
by Marcel
03:09
created

StorageService   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 230
Duplicated Lines 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
eloc 83
dl 0
loc 230
rs 10
c 4
b 1
f 0
wmc 27

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
B read() 0 39 7
A convertGermanDateFormat() 0 12 4
A deleteSimulate() 0 3 1
A deleteWithFilterSimulate() 0 3 1
B update() 0 40 8
A deleteWithFilter() 0 3 1
A floatvalue() 0 13 2
A delete() 0 3 1
A getRecordCount() 0 3 1
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 2019-2022 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Service;
13
14
use OCA\Analytics\Db\StorageMapper;
15
use OCP\DB\Exception;
16
use OCP\IRequest;
17
use Psr\Log\LoggerInterface;
18
19
class StorageService
20
{
21
    private $logger;
22
    private $StorageMapper;
23
    private $ThresholdService;
24
    private $DatasetService;
25
    private $ReportService;
26
    private $VariableService;
27
28
    public function __construct(
29
        LoggerInterface $logger,
30
        StorageMapper $StorageMapper,
31
        DatasetService $DatasetService,
32
        ThresholdService $ThresholdService,
33
        VariableService $VariableService,
34
        ReportService $ReportService
35
    )
36
    {
37
        $this->logger = $logger;
38
        $this->StorageMapper = $StorageMapper;
39
        $this->DatasetService = $DatasetService;
40
        $this->ThresholdService = $ThresholdService;
41
        $this->VariableService = $VariableService;
42
        $this->ReportService = $ReportService;
43
    }
44
45
    /**
46
     * Get the items for the selected category
47
     *
48
     * @NoAdminRequired
49
     * @param $datasetId
50
     * @param $options
51
     * @return array
52
     * @throws \OCP\DB\Exception
53
     */
54
    public function read($datasetId, $reportMetadata)
55
    {
56
        $availableDimensions = array();
57
        $header = array();
58
        $datasetMetadata = $this->DatasetService->read($datasetId);
59
        if ($reportMetadata['filteroptions'] !== null) {
60
            $options = json_decode($reportMetadata['filteroptions'], true);
61
        } else {
62
            $options = null;
63
        }
64
65
        if (!empty($datasetMetadata)) {
66
            // output the dimensions available for filtering of this dataset
67
            // this needs to map the technical name to its display name in the report
68
            $availableDimensions['dimension1'] = $datasetMetadata['dimension1'];
69
            $availableDimensions['dimension2'] = $datasetMetadata['dimension2'];
70
71
            // return the header texts of the data being transferred according to the current drilldown state selected by user
72
            if (!isset($options['drilldown']['dimension1'])) $header[0] = $datasetMetadata['dimension1'];
73
            if (!isset($options['drilldown']['dimension2'])) $header[1] = $datasetMetadata['dimension2'];
74
            $header[6] = $datasetMetadata['value'];
75
            $header = array_values($header);
76
77
            $data = $this->StorageMapper->read($datasetMetadata['id'], $options);
78
            $data = array_values($data);
79
            foreach ($data as $key => $value) {
80
                $data[$key] = array_values($value);
81
            }
82
        }
83
84
        return empty($data) ? [
85
            'dimensions' => $availableDimensions,
86
            'status' => 'nodata',
87
            'error' => 0
88
        ] : [
89
            'header' => $header,
90
            'dimensions' => $availableDimensions,
91
            'data' => $data,
92
            'error' => 0
93
        ];
94
    }
95
96
    /**
97
     * Get the items for the selected category
98
     *
99
     * @NoAdminRequired
100
     * @param int $datasetId
101
     * @param $dimension1
102
     * @param $dimension2
103
     * @param $value
104
     * @param string|null $user_id
105
     * @param $bulkInsert
106
     * @param $aggregation
107
     * @return array
108
     * @throws Exception
109
     */
110
    public function update(int $datasetId, $dimension1, $dimension2, $value, string $user_id = null, $bulkInsert = null, $aggregation = null)
111
    {
112
        TODO:
113
        //dates in both columns
114
        $dimension2 = $this->convertGermanDateFormat($dimension2);
115
        //convert date into timestamp
116
        //$timestamp = $this->convertGermanDateFormat($timestamp);
117
        $value = $this->floatvalue($value);
118
        $validate = '';
119
        $insert = $update = $error = $action = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $action is dead and can be removed.
Loading history...
120
121
        // replace text variables like %now%
122
        $dimension1 = $this->VariableService->replaceTextVariablesSingle($dimension1);
123
        $dimension2 = $this->VariableService->replaceTextVariablesSingle($dimension2);
124
125
        if ($value !== false) {
126
            try {
127
                $action = $this->StorageMapper->create($datasetId, $dimension1, $dimension2, $value, $user_id, null, $bulkInsert, $aggregation);
128
            } catch (\Exception $e) {
129
                $error = 1;
130
            }
131
            if ($action === 'insert') $insert = 1;
132
            elseif ($action === 'update') $update = 1;
133
        } else {
134
            $error = 1;
135
        }
136
137
        // get all reports for the dataset and evaluate their thresholds for push notifications
138
        if ($error === 0) {
139
            foreach ($this->ReportService->reportsForDataset($datasetId) as $report) {
140
                $validateResult = $this->ThresholdService->validate($report['id'], $dimension1, $dimension2, $value, $insert);
141
                if ($validateResult !== '') $validate = $validateResult;
142
            }
143
        }
144
145
        return [
146
            'insert' => $insert,
147
            'update' => $update,
148
            'error' => $error,
149
            'validate' => $validate
150
        ];
151
    }
152
153
    /**
154
     * delete data
155
     *
156
     * @NoAdminRequired
157
     * @param int $datasetId
158
     * @param $dimension1
159
     * @param $dimension2
160
     * @param string|null $user_id
161
     * @return bool
162
     */
163
    public function delete(int $datasetId, $dimension1, $dimension2, string $user_id = null)
164
    {
165
        return $this->StorageMapper->delete($datasetId, $dimension1, $dimension2, $user_id);
166
    }
167
168
    /**
169
     * Simulate delete data
170
     *
171
     * @NoAdminRequired
172
     * @param int $datasetId
173
     * @param $dimension1
174
     * @param $dimension2
175
     * @return array
176
     * @throws Exception
177
     */
178
    public function deleteSimulate(int $datasetId, $dimension1, $dimension2)
179
    {
180
        return $this->StorageMapper->deleteSimulate($datasetId, $dimension1, $dimension2);
181
    }
182
183
    /**
184
     * Delete data with variables; used for data deletion jobs
185
     *
186
     * @NoAdminRequired
187
     * @param int $datasetId
188
     * @param $filter
189
     * @return bool
190
     * @throws Exception
191
     */
192
    public function deleteWithFilter(int $datasetId, $filter)
193
    {
194
        return $this->StorageMapper->deleteWithFilter($datasetId, $filter);
195
    }
196
197
    /**
198
     * Simulate delete data with variables; used for data deletion jobs
199
     *
200
     * @NoAdminRequired
201
     * @param int $datasetId
202
     * @param $filter
203
     * @return bool
204
     * @throws Exception
205
     */
206
    public function deleteWithFilterSimulate(int $datasetId, $filter)
207
    {
208
        return $this->StorageMapper->deleteWithFilterSimulate($datasetId, $filter);
209
    }
210
211
    /**
212
     * Get the number of records for a dataset
213
     * @param int $datasetId
214
     * @return array
215
     */
216
    public function getRecordCount(int $datasetId)
217
    {
218
        return $this->StorageMapper->getRecordCount($datasetId);
219
    }
220
221
    private function floatvalue($val)
222
    {
223
        // remove thousand separators
224
        $val = preg_replace('/(?<=\d)\,(?=\d{3}\b)/', '', $val);
225
        $val = preg_replace('/(?<=\d)\.(?=\d{3}\b)/', '', $val);
226
        // convert comma to decimal point
227
        $val = str_replace(",", ".", $val);
228
        //$val = preg_replace('/\.(?=.*\.)/', '', $val);
229
        //$val = preg_replace('/[^0-9-.]+/', '', $val);
230
        if (is_numeric($val)) {
231
            return number_format(floatval($val), 2, '.', '');
232
        } else {
233
            return false;
234
        }
235
    }
236
237
    private function convertGermanDateFormat($val)
238
    {
239
        $fullString = explode(' ', $val);
240
        $dateLength = strlen($fullString[0]);
241
        $dateParts = explode('.', $fullString[0]);
242
243
        if ($dateLength >= 6 && $dateLength <= 10 && count($dateParts) === 3) {
244
            // is most likely a german date format 20.02.2020
245
            $fullString[0] = $dateParts[2] . '-' . sprintf('%02d', $dateParts[1]) . '-' . sprintf('%02d', $dateParts[0]);
246
            $val = implode(' ', $fullString);
247
        }
248
        return $val;
249
    }
250
}