ReportService::create()   B
last analyzed

Complexity

Conditions 8
Paths 16

Size

Total Lines 35
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 14
nc 16
nop 12
dl 0
loc 35
rs 8.4444
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * Analytics
4
 *
5
 * SPDX-FileCopyrightText: 2019-2022 Marcel Scherello
6
 * SPDX-License-Identifier: AGPL-3.0-or-later
7
 */
8
9
namespace OCA\Analytics\Service;
10
11
use OCA\Analytics\Activity\ActivityManager;
12
use OCA\Analytics\Controller\DatasourceController;
13
use OCA\Analytics\Db\DataloadMapper;
14
use OCA\Analytics\Db\ReportMapper;
15
use OCA\Analytics\Db\StorageMapper;
16
use OCA\Analytics\Db\ThresholdMapper;
17
use OCP\AppFramework\Http\DataDownloadResponse;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http\DataDownloadResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use OCP\DB\Exception;
0 ignored issues
show
Bug introduced by
The type OCP\DB\Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use OCP\Files\IRootFolder;
0 ignored issues
show
Bug introduced by
The type OCP\Files\IRootFolder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use OCP\ITagManager;
0 ignored issues
show
Bug introduced by
The type OCP\ITagManager was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use OCP\IConfig;
0 ignored issues
show
Bug introduced by
The type OCP\IConfig was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use OCP\PreConditionNotMetException;
0 ignored issues
show
Bug introduced by
The type OCP\PreConditionNotMetException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Psr\Log\LoggerInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Log\LoggerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use OCP\IL10N;
0 ignored issues
show
Bug introduced by
The type OCP\IL10N was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
26
class ReportService {
27
	/** @var IConfig */
28
	protected $config;
29
	private $userId;
30
	private $logger;
31
	private $tagManager;
32
	private $ShareService;
33
	private $DatasetService;
34
	private $StorageMapper;
35
	private $ReportMapper;
36
	private $ThresholdMapper;
37
	private $DataloadMapper;
38
	private $ActivityManager;
39
	private $rootFolder;
40
	private $VariableService;
41
	private $l10n;
42
43
	const REPORT_TYPE_GROUP = 0;
44
45
	public function __construct(
46
		$userId,
47
		IL10N $l10n,
48
		LoggerInterface $logger,
49
		ITagManager $tagManager,
50
		ShareService $ShareService,
51
		DatasetService $DatasetService,
52
		StorageMapper $StorageMapper,
53
		ReportMapper $ReportMapper,
54
		ThresholdMapper $ThresholdMapper,
55
		DataloadMapper $DataloadMapper,
56
		ActivityManager $ActivityManager,
57
		IRootFolder $rootFolder,
58
		IConfig $config,
59
		VariableService $VariableService
60
	) {
61
		$this->userId = $userId;
62
		$this->logger = $logger;
63
		$this->tagManager = $tagManager;
64
		$this->ShareService = $ShareService;
65
		$this->DatasetService = $DatasetService;
66
		$this->ThresholdMapper = $ThresholdMapper;
67
		$this->StorageMapper = $StorageMapper;
68
		$this->ReportMapper = $ReportMapper;
69
		$this->DataloadMapper = $DataloadMapper;
70
		$this->ActivityManager = $ActivityManager;
71
		$this->rootFolder = $rootFolder;
72
		$this->VariableService = $VariableService;
73
		$this->config = $config;
74
		$this->l10n = $l10n;
75
	}
76
77
	/**
78
	 * get all reports
79
	 *
80
	 * @return array
81
	 * @throws PreConditionNotMetException
82
	 */
83
	public function index(): array {
84
		$ownReports = $this->ReportMapper->index();
85
		$sharedReports = $this->ShareService->getSharedItems(ShareService::SHARE_ITEM_TYPE_REPORT);
86
		$keysToKeep = array('id', 'name', 'dataset', 'favorite', 'parent', 'type', 'isShare', 'shareId');
87
88
		// get shared reports and remove duplicates
89
		foreach ($sharedReports as $sharedReport) {
90
			if (!array_search($sharedReport['id'], array_column($ownReports, 'id'))) {
91
				// just keep the necessary fields
92
				$ownReports[] = array_intersect_key($sharedReport, array_flip($keysToKeep));;
93
			}
94
		}
95
		if (count($ownReports) === 0) return $ownReports;
96
97
		// get data load indicators for icons shown in the advanced screen
98
		$dataloads = $this->DataloadMapper->getAllDataloadMetadata();
99
		foreach ($dataloads as $dataload) {
100
			$key = array_search($dataload['dataset'], array_column($ownReports, 'dataset'));
101
			if ($key !== '') {
102
				if ($dataload['schedules'] !== '' and $dataload['schedules'] !== null) {
103
					$dataload['schedules'] = 1;
104
				} else {
105
					$dataload['schedules'] = 0;
106
				}
107
				$ownReports[$key]['dataloads'] = $dataload['dataloads'];
108
				$ownReports[$key]['schedules'] = $dataload['schedules'];
109
			}
110
		}
111
112
		$favorites = $this->tagManager->load('analytics')->getFavorites();
113
		foreach ($ownReports as &$ownReport) {
114
			$hasTag = 0;
115
			if (is_array($favorites) and in_array($ownReport['id'], $favorites)) {
116
				$hasTag = 1;
117
			}
118
			$ownReport['favorite'] = $hasTag;
119
			$ownReport['item_type'] = ShareService::SHARE_ITEM_TYPE_REPORT;
120
			$ownReport = $this->VariableService->replaceTextVariables($ownReport);
121
		}
122
123
		return $ownReports;
124
	}
125
126
	/**
127
	 * get own report details
128
	 *
129
	 * @param int $reportId
130
	 * @return array
131
	 * @throws Exception
132
	 */
133
	public function read(int $reportId, $replace = true) {
134
		$ownReport = $this->ReportMapper->readOwn($reportId);
135
		if (!empty($ownReport)) {
136
			$ownReport['permissions'] = \OCP\Constants::PERMISSION_UPDATE;
0 ignored issues
show
Bug introduced by
The type OCP\Constants was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
137
			if ($replace) $ownReport = $this->VariableService->replaceTextVariables($ownReport);
138
139
			if ($ownReport['type'] === DatasourceController::DATASET_TYPE_INTERNAL_DB && $ownReport['dataset'] !== 0) {
140
				$dataset = $this->DatasetService->readOwn($ownReport['dataset']);
141
				$ownReport['dimension1'] = $dataset['dimension1'];
142
				$ownReport['dimension2'] = $dataset['dimension2'];
143
				$ownReport['value'] = $dataset['value'];
144
			}
145
146
		}
147
		return $ownReport;
148
	}
149
150
	/**
151
	 * check if own report
152
	 *
153
	 * @param int $reportId
154
	 * @return bool
155
	 */
156
	public function isOwn(int $reportId) {
157
		$ownReport = $this->ReportMapper->readOwn($reportId);
158
		if (!empty($ownReport)) {
159
			return true;
160
		} else {
161
			return false;
162
		}
163
	}
164
165
	/**
166
	 * create new blank report
167
	 *
168
	 * @return int
169
	 * @throws Exception
170
	 */
171
	public function create(
172
		$name,
173
		$subheader,
174
		$parent,
175
		$type,
176
		int $dataset,
177
		$link,
178
		$visualization,
179
		$chart,
180
		$dimension1,
181
		$dimension2,
182
		$value,
183
		$addReport = null
184
	): int {
185
		$array = json_decode($link, true);
186
		if (is_array($array)) {
187
			foreach ($array as $key => $value) {
0 ignored issues
show
introduced by
$value is overwriting one of the parameters of this function.
Loading history...
188
				$array[$key] = htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8');
189
			}
190
		}
191
		$link = json_encode($array);
192
193
		if ($type === DatasourceController::DATASET_TYPE_GROUP) {
194
			$parent = 0;
195
		}
196
		if ($type === DatasourceController::DATASET_TYPE_INTERNAL_DB && $dataset === 0) { // New dataset
197
			$dataset = $this->DatasetService->create($name, $dimension1, $dimension2, $value);
198
		}
199
		$reportId = $this->ReportMapper->create($name, $subheader, $parent, $type, $dataset, $link, $visualization, $chart, $dimension1, $dimension2, $value);
200
		$this->ActivityManager->triggerEvent($reportId, ActivityManager::OBJECT_REPORT, ActivityManager::SUBJECT_REPORT_ADD);
201
202
		if ($addReport !== null && $addReport !== '') {
203
			$this->updateGroup($addReport, $reportId);
204
		}
205
		return $reportId;
206
	}
207
208
	/**
209
	 * copy an existing report with the current navigation status
210
	 *
211
	 * @NoAdminRequired
212
	 * @param int $reportId
213
	 * @param $chartoptions
214
	 * @param $dataoptions
215
	 * @param $filteroptions
216
	 * @return int
217
	 * @throws Exception
218
	 */
219
	public function createCopy(int $reportId, $chartoptions, $dataoptions, $filteroptions, $tableoptions) {
220
221
		$template = $this->ReportMapper->readOwn($reportId);
222
		$newId = $this->ReportMapper->create(// TRANSLATORS Noun
223
			$template['name'] . ' - ' . $this->l10n->t('copy'), $template['subheader'], $template['parent'], $template['type'], $template['dataset'], $template['link'], $template['visualization'], $template['chart'], $template['dimension1'], $template['dimension2'], $template['value']);
224
		$this->ReportMapper->updateOptions($newId, $chartoptions, $dataoptions, $filteroptions, $tableoptions);
225
		return $newId;
226
	}
227
228
	/**
229
	 * create new report
230
	 *
231
	 * @param string $file
232
	 * @return int
233
	 */
234
	public function createFromDataFile($file = '') {
235
		$this->ActivityManager->triggerEvent(0, ActivityManager::OBJECT_REPORT, ActivityManager::SUBJECT_REPORT_ADD);
236
237
		if ($file !== '') {
238
			$name = explode('.', end(explode('/', $file)))[0];
239
			$subheader = $file;
240
			$parent = 0;
241
			$dataset = 0;
242
			$type = DatasourceController::DATASET_TYPE_FILE;
243
			$link = $file;
244
			$visualization = 'table';
245
			$chart = 'line';
246
			$reportId = $this->ReportMapper->create($name, $subheader, $parent, $type, $dataset, $link, $visualization, $chart, '', '', '');
247
		}
248
		return $reportId;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $reportId does not seem to be defined for all execution paths leading up to this point.
Loading history...
249
	}
250
251
	/**
252
	 * update report details
253
	 *
254
	 * @param int $reportId
255
	 * @param $name
256
	 * @param $subheader
257
	 * @param int $parent
258
	 * @param $options
259
	 * @param $visualization
260
	 * @param $chart
261
	 * @param $chartoptions
262
	 * @param $dataoptions
263
	 * @param $dimension1
264
	 * @param $dimension2
265
	 * @param $value
266
	 * @return bool
267
	 */
268
	public function update(
269
		int $reportId,
270
			$name,
271
			$subheader,
272
		int $parent,
273
			$options,
274
			$visualization,
275
			$chart,
276
			$chartoptions,
277
			$dataoptions,
278
			$dimension1 = null,
279
			$dimension2 = null,
280
			$value = null
281
	) {
282
		$array = json_decode($options, true);
283
		foreach ($array as $key => $value) {
284
			$array[$key] = htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8');
285
		}
286
		$options = json_encode($array);
287
288
		return $this->ReportMapper->update($reportId, $name, $subheader, $parent, $options, $visualization, $chart, $chartoptions, $dataoptions, $dimension1, $dimension2, $value);
289
	}
290
291
	/**
292
	 * Delete Dataset and all depending objects
293
	 *
294
	 * @param int $reportId
295
	 * @return string
296
	 * @throws Exception
297
	 */
298
	public function delete(int $reportId) {
299
		$metadata = $this->ReportMapper->readOwn($reportId);
300
		$this->ActivityManager->triggerEvent($reportId, ActivityManager::OBJECT_REPORT, ActivityManager::SUBJECT_REPORT_DELETE);
301
		$this->ShareService->deleteSharesByItem(ShareService::SHARE_ITEM_TYPE_REPORT, $reportId);
302
		$this->ThresholdMapper->deleteThresholdByReport($reportId);
303
		$this->setFavorite($reportId, 'false');
304
		$this->ReportMapper->delete($reportId);
305
306
		$report = $this->reportsForDataset((int)$metadata['dataset']);
307
		if (empty($report) && (int)$metadata['type'] === DatasourceController::DATASET_TYPE_INTERNAL_DB) {
308
			return $metadata['dataset'];
309
		} else {
310
			return 'true';
311
		}
312
	}
313
314
	/**
315
	 * get dataset by user
316
	 *
317
	 * @param string $userId
318
	 * @return array|bool
319
	 * @throws Exception
320
	 */
321
	public function deleteByUser(string $userId) {
322
		$reports = $this->ReportMapper->indexByUser($userId);
323
		foreach ($reports as $report) {
324
			$this->ShareService->deleteSharesByItem(ShareService::SHARE_ITEM_TYPE_REPORT, $report['id']);
325
			$this->ThresholdMapper->deleteThresholdByReport($report['id']);
326
			$this->setFavorite($report['id'], 'false');
327
			$this->ReportMapper->delete($report['id']);
328
		}
329
		return true;
330
	}
331
332
	/**
333
	 * get own reports which are marked as favorites
334
	 *
335
	 * @return array|bool
336
	 * @throws Exception
337
	 */
338
	public function getOwnFavoriteReports() {
339
		$ownReports = $this->ReportMapper->index();
340
		$sharedReports = $this->ShareService->getSharedItems(ShareService::SHARE_ITEM_TYPE_REPORT);
341
		$favorites = $this->tagManager->load('analytics')->getFavorites();
342
343
		// remove the favorite if the report is not existing anymore
344
		foreach ($favorites as $favorite) {
345
			if (!in_array($favorite, array_column($ownReports, 'id')) && !in_array($favorite, array_column($sharedReports, 'id'))) {
346
				unset($favorites[$favorite]);
347
				$this->tagManager->load('analytics')->removeFromFavorites($favorite);
348
			}
349
		}
350
351
		return $favorites;
352
	}
353
354
	/**
355
	 * set/remove the favorite flag for a report
356
	 *
357
	 * @param int $reportId
358
	 * @param string $favorite
359
	 * @return bool
360
	 */
361
	public function setFavorite(int $reportId, string $favorite) {
362
		if ($favorite === 'true') {
363
			$return = $this->tagManager->load('analytics')->addToFavorites($reportId);
364
		} else {
365
			$return = $this->tagManager->load('analytics')->removeFromFavorites($reportId);
366
		}
367
		return $return;
368
	}
369
370
	/**
371
	 * Import Report from File
372
	 *
373
	 * @param string|null $path
374
	 * @param string|null $raw
375
	 * @return int
376
	 * @throws \OCP\Files\NotFoundException
377
	 * @throws \OCP\Files\NotPermittedException
378
	 */
379
	public function import(string $path = null, string $raw = null) {
380
		if ($path !== '' and $path !== null) {
381
			$file = $this->rootFolder->getUserFolder($this->userId)->get($path);
382
			$data = $file->getContent();
383
		} else if ($raw !== null) {
384
			$data = $raw;
385
		} else {
386
			return 0;
387
		}
388
		$data = json_decode($data, true);
389
390
		$report = $data['report'];
391
		isset($report['name']) ? $name = $report['name'] : $name = '';
392
		isset($report['subheader']) ? $subheader = $report['subheader'] : $subheader = '';
393
		$parent = 0;
394
		$dataset = 0;
395
		isset($report['type']) ? $type = (int)$report['type'] : $type = null;
396
		isset($report['link']) ? $link = $report['link'] : $link = null;
397
		isset($report['visualization']) ? $visualization = $report['visualization'] : $visualization = null;
398
		isset($report['chart']) ? $chart = $report['chart'] : $chart = null;
399
		isset($report['chartoptions']) ? $chartoptions = $report['chartoptions'] : $chartoptions = null;
400
		isset($report['dataoptions']) ? $dataoptions = $report['dataoptions'] : $dataoptions = null;
401
		isset($report['filteroptions']) ? $filteroptions = $report['filteroptions'] : $filteroptions = null;
402
		isset($report['tableoptions']) ? $tableoptions = $report['tableoptions'] : $tableoptions = null;
403
		isset($report['dimension1']) ? $dimension1 = $report['dimension1'] : $dimension1 = null;
404
		isset($report['dimension2']) ? $dimension2 = $report['dimension2'] : $dimension2 = null;
405
		isset($report['value']) ? $value = $report['value'] : $value = null;
406
407
		if ($type === DatasourceController::DATASET_TYPE_INTERNAL_DB) { // New dataset
408
			$dataset = $this->DatasetService->create($name, $dimension1, $dimension2, $value);
409
		}
410
		$reportId = $this->create($name, $subheader, $parent, $type, $dataset, $link, $visualization, $chart, $dimension1, $dimension2, $value);
411
		$this->updateOptions($reportId, $chartoptions, $dataoptions, $filteroptions, $tableoptions);
412
		$report = $this->ReportMapper->readOwn($reportId);
413
		$datasetId = $report['dataset'];
414
415
		$this->DataloadMapper->beginTransaction();
416
417
		foreach ($data['dataload'] as $dataload) {
418
			isset($dataload['datasource']) ? $datasource = $dataload['datasource'] : $datasource = null;
419
			isset($dataload['name']) ? $name = $dataload['name'] : $name = null;
420
			isset($dataload['option']) ? $option = $dataload['option'] : $option = null;
421
			$schedule = null;
422
423
			$dataloadId = $this->DataloadMapper->create($datasetId, $datasource);
424
			$this->DataloadMapper->update($dataloadId, $name, $option, $schedule);
425
		}
426
427
		foreach ($data['threshold'] as $threshold) {
428
			isset($threshold['dimension1']) ? $dimension1 = $threshold['dimension1'] : $dimension1 = null;
429
			isset($threshold['value']) ? $value = $threshold['value'] : $value = null;
430
			isset($threshold['option']) ? $option = $threshold['option'] : $option = null;
431
			isset($threshold['severity']) ? $severity = $threshold['severity'] : $severity = null;
432
			$value = $this->floatvalue($value);
433
			$this->ThresholdMapper->create($reportId, $dimension1, $value, $option, $severity);
434
		}
435
436
		foreach ($data['data'] as $dData) {
437
			isset($dData[0]) ? $dimension1 = $dData[0] : $dimension1 = null;
438
			isset($dData[1]) ? $dimension2 = $dData[1] : $dimension2 = null;
439
			isset($dData[2]) ? $value = $dData[2] : $value = null;
440
			$this->StorageMapper->create($datasetId, $dimension1, $dimension2, $value);
441
		}
442
443
		$this->DataloadMapper->commit();
444
445
		if (isset($data['favorite'])) {
446
			$this->setFavorite($reportId, $data['favorite']);
447
		}
448
449
		return $reportId;
450
	}
451
452
	/**
453
	 * Export Report
454
	 *
455
	 * @param int $reportId
456
	 * @return DataDownloadResponse
457
	 */
458
	public function export(int $reportId) {
459
		$result = array();
460
		$result['report'] = $this->ReportMapper->readOwn($reportId);
461
		$datasetId = $result['report']['dataset'];
462
		$result['dataload'] = $this->DataloadMapper->read($datasetId);
463
		$result['threshold'] = $this->ThresholdMapper->getThresholdsByReport($reportId);
464
		$result['favorite'] = '';
465
466
		if ($result['report']['type'] === DatasourceController::DATASET_TYPE_INTERNAL_DB) {
467
			$result['data'] = $this->StorageMapper->read($datasetId);
468
		}
469
470
		unset($result['report']['id'], $result['report']['user_id'], $result['report']['user_id'], $result['report']['parent'], $result['report']['dataset']);
471
		$data = json_encode($result);
472
		return new DataDownloadResponse($data, $result['report']['name'] . '.export.txt', 'text/plain; charset=utf-8');
473
	}
474
475
	/**
476
	 * Update report options
477
	 *
478
	 * @param int $reportId
479
	 * @param $chartoptions
480
	 * @param $dataoptions
481
	 * @param $filteroptions
482
	 * @param $tableoptions
483
	 * @return bool
484
	 * @throws Exception
485
	 */
486
	public function updateOptions(int $reportId, $chartoptions, $dataoptions, $filteroptions, $tableoptions) {
487
		return $this->ReportMapper->updateOptions($reportId, $chartoptions, $dataoptions, $filteroptions, $tableoptions);
488
	}
489
490
	/**
491
	 * get report refresh options
492
	 *
493
	 * @NoAdminRequired
494
	 * @param int $reportId
495
	 * @param $refresh
496
	 * @return bool
497
	 */
498
	public function updateRefresh(int $reportId, $refresh) {
499
		return $this->ReportMapper->updateRefresh($reportId, $refresh);
500
	}
501
502
	/**
503
	 * update report group assignment (from drag & drop)
504
	 *
505
	 * @NoAdminRequired
506
	 * @param int $reportId
507
	 * @param $groupId
508
	 * @return bool
509
	 */
510
	public function updateGroup(int $reportId, $groupId) {
511
		return $this->ReportMapper->updateGroup($reportId, $groupId);
512
	}
513
514
	/**
515
	 * search for reports
516
	 *
517
	 * @param string $searchString
518
	 * @return array
519
	 */
520
	public function search(string $searchString) {
521
		return $this->ReportMapper->search($searchString);
522
	}
523
524
	/**
525
	 * @throws Exception
526
	 */
527
	public function reportsForDataset($datasetId) {
528
		return $this->ReportMapper->reportsForDataset($datasetId);
529
	}
530
531
	private function floatvalue($val) {
532
		// if value is a 3 digit comma number with one leading zero like 0,111, it should not go through the 1000 separator removal
533
		if (preg_match('/(?<=\b0)\,(?=\d{3}\b)/', $val) === 0 && preg_match('/(?<=\b0)\.(?=\d{3}\b)/', $val) === 0) {
534
			// remove , as 1000 separator
535
			$val = preg_replace('/(?<=\d)\,(?=\d{3}\b)/', '', $val);
536
			// remove . as 1000 separator
537
			$val = preg_replace('/(?<=\d)\.(?=\d{3}\b)/', '', $val);
538
		}
539
		// convert remaining comma to decimal point
540
		$val = str_replace(",", ".", $val);
541
		if (is_numeric($val)) {
542
			return number_format(floatval($val), 2, '.', '');
543
		} else {
544
			return false;
545
		}
546
	}
547
548
}
549