Passed
Push — master ( 853447...550809 )
by Marcel
02:40 queued 12s
created

OutputController::getData()   B

Complexity

Conditions 7
Paths 48

Size

Total Lines 38
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 27
nc 48
nop 1
dl 0
loc 38
rs 8.5546
c 0
b 0
f 0
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\Controller;
13
14
use OCA\Analytics\DataSession;
15
use OCA\Analytics\Service\ReportService;
16
use OCA\Analytics\Service\ShareService;
17
use OCA\Analytics\Service\ThresholdService;
18
use OCA\Analytics\Service\StorageService;
19
use OCA\Analytics\Service\VariableService;
20
use OCP\AppFramework\Controller;
21
use OCP\AppFramework\Http;
22
use OCP\AppFramework\Http\DataResponse;
23
use OCP\AppFramework\Http\NotFoundResponse;
24
use OCP\Constants;
25
use OCP\DB\Exception;
26
use OCP\Files\NotFoundException;
27
use OCP\IRequest;
28
use Psr\Log\LoggerInterface;
29
30
class OutputController extends Controller
31
{
32
    private $logger;
33
    private $ReportService;
34
    private $DataSession;
35
    private $ShareService;
36
    private $DatasourceController;
37
    private $StorageService;
38
    private $ThresholdService;
39
    private $VariableService;
40
41
    public function __construct(
42
        string $AppName,
43
        IRequest $request,
44
        LoggerInterface $logger,
45
        ReportService $ReportService,
46
        ShareService $ShareService,
47
        DataSession $DataSession,
48
        DatasourceController $DatasourceController,
49
        StorageService $StorageService,
50
        ThresholdService $ThresholdService,
51
        VariableService $VariableService
52
    )
53
    {
54
        parent::__construct($AppName, $request);
55
        $this->logger = $logger;
56
        $this->ReportService = $ReportService;
57
        $this->DataSession = $DataSession;
58
        $this->ShareService = $ShareService;
59
        $this->DatasourceController = $DatasourceController;
60
        $this->StorageService = $StorageService;
61
        $this->ThresholdService = $ThresholdService;
62
        $this->VariableService = $VariableService;
63
    }
64
65
    /**
66
     * get the data when requested from internal page
67
     *
68
     * @NoAdminRequired
69
     * @param int $reportId
70
     * @param $filteroptions
71
     * @param $dataoptions
72
     * @param $chartoptions
73
     * @return DataResponse|NotFoundResponse
74
     * @throws Exception
75
     */
76
    public function read(int $reportId, $filteroptions, $dataoptions, $chartoptions)
77
    {
78
        $reportMetadata = $this->ReportService->read($reportId);
79
        if (empty($reportMetadata)) $reportMetadata = $this->ShareService->getSharedReport($reportId);
80
81
        if (!empty($reportMetadata)) {
82
            $reportMetadata = $this->evaluateCanFilter($reportMetadata, $filteroptions, $dataoptions, $chartoptions);
83
            $result = $this->getData($reportMetadata);
84
            return new DataResponse($result, HTTP::STATUS_OK);
85
        } else {
86
            return new NotFoundResponse();
87
        }
88
    }
89
90
    /**
91
     * Get the data from backend;
92
     * pre-evaluation of valid datasetId within read & readPublic is trusted here
93
     *
94
     * @NoAdminRequired
95
     * @param $reportMetadata
96
     * @return array
97
     * @throws Exception
98
     */
99
    public function getData($reportMetadata)
100
    {
101
        $datasource = (int)$reportMetadata['type'];
102
        $datasetId = (int)$reportMetadata['dataset'];
103
104
        $filterWithVariables = $reportMetadata['filteroptions']; // need to remember the filter with original text variables
105
        $reportMetadata = $this->VariableService->replaceFilterVariables($reportMetadata); // replace %xx% dynamic variables
106
107
        if ($datasource === DatasourceController::DATASET_TYPE_INTERNAL_DB) {
108
            // Internal data
109
            if ($datasetId !== 0) {
110
                $result = $this->StorageService->read($datasetId, $reportMetadata);
111
            } else {
112
                $result['error'] = 'inconsistent report';
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...
113
            }
114
        } else {
115
            // Realtime data
116
            $result = $this->DatasourceController->read($datasource, $reportMetadata);
117
        }
118
119
        unset($reportMetadata['parent']
120
            , $reportMetadata['user_id']
121
            , $reportMetadata['link']
122
            , $reportMetadata['dimension1']
123
            , $reportMetadata['dimension2']
124
            , $reportMetadata['dimension3']
125
            , $reportMetadata['value']
126
            , $reportMetadata['password']
127
            , $reportMetadata['dataset']
128
        );
129
        $result['filterApplied'] = $reportMetadata['filteroptions'];
130
        $reportMetadata['filteroptions'] = $filterWithVariables; // keep the original filters
131
        // there can be different values for no options. null during creation; empty after removal; => harmonize them
132
        $reportMetadata['chartoptions'] = ($reportMetadata['chartoptions'] === '' || $reportMetadata['chartoptions'] === 'null') ? null : $reportMetadata['chartoptions'];
133
        $reportMetadata['dataoptions'] = ($reportMetadata['dataoptions'] === '' || $reportMetadata['dataoptions'] === 'null') ? null : $reportMetadata['dataoptions'];
134
        $result['options'] = $reportMetadata;
135
        $result['thresholds'] = $this->ThresholdService->read($reportMetadata['id']);
136
        return $result;
137
    }
138
139
    /**
140
     * get the data when requested from public page
141
     *
142
     * @NoAdminRequired
143
     * @PublicPage
144
     * @UseSession
145
     * @param $token
146
     * @param $filteroptions
147
     * @param $dataoptions
148
     * @param $chartoptions
149
     * @return DataResponse|NotFoundResponse
150
     * @throws Exception
151
     */
152
    public function readPublic($token, $filteroptions, $dataoptions, $chartoptions)
153
    {
154
        $share = $this->ShareService->getReportByToken($token);
155
        if (empty($share)) {
156
            // Dataset not shared or wrong token
157
            return new NotFoundResponse();
158
        } else {
159
            if ($share['password'] !== null) {
160
                $password = $this->DataSession->getPasswordForShare($token);
161
                $passwordVerification = $this->ShareService->verifyPassword($password, $share['password']);
162
                if ($passwordVerification === false) {
163
                    return new NotFoundResponse();
164
                }
165
            }
166
            $share = $this->evaluateCanFilter($share, $filteroptions, $dataoptions, $chartoptions);
167
            $result = $this->getData($share);
168
            return new DataResponse($result, HTTP::STATUS_OK);
169
        }
170
    }
171
172
    /**
173
     * evaluate if the user did filter in the report and if he is allowed to filter (shared reports)
174
     *
175
     * @param $metadata
176
     * @param $filteroptions
177
     * @param $dataoptions
178
     * @param $chartoptions
179
     * @return mixed
180
     */
181
    private function evaluateCanFilter($metadata, $filteroptions, $dataoptions, $chartoptions)
182
    {
183
        // send current user filter options to the data request
184
        // only if the report has update-permissions
185
        // if nothing is changed by the user, the filter which is stored for the report, will be used
186
        if ($filteroptions and $filteroptions !== '' and (int)$metadata['permissions'] === Constants::PERMISSION_UPDATE) {
187
            $metadata['filteroptions'] = $filteroptions;
188
            $metadata['dataoptions'] = $dataoptions;
189
            $metadata['chartoptions'] = $chartoptions;
190
        }
191
        return $metadata;
192
    }
193
}