Passed
Push — master ( 9e5f06...f158b8 )
by Marcel
03:58 queued 13s
created

OutputController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
c 0
b 0
f 0
nc 1
nop 10
dl 0
loc 22
rs 9.9666

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
 * 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
     * Preview the data
92
     *
93
     * @NoAdminRequired
94
     * @param $type
95
     * @param $options
96
     * @return DataResponse|NotFoundResponse
97
     * @throws Exception
98
     */
99
    public function readPreview ($type, $options)
100
    {
101
        $reportMetadata = [];
102
         $array = json_decode($options, true);
103
        foreach ($array as $key => $value) {
104
            $array[$key] = htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8');
105
        }
106
        $reportMetadata['link'] = json_encode($array);
107
        $reportMetadata['type'] = $type;
108
        $reportMetadata['dataset'] = 0;
109
        $reportMetadata['filteroptions'] = '';
110
        $reportMetadata['user_id'] = 'admin';
111
        $reportMetadata['id'] = 0;
112
113
        $result = $this->getData($reportMetadata);
114
        unset($result['options']
115
            , $result['dimensions']
116
            , $result['filterApplied']
117
            , $result['thresholds']
118
        );
119
        $result['data'] = array_slice($result['data'], 0, 1);
120
121
        return new DataResponse($result, HTTP::STATUS_OK);
122
    }
123
124
125
    /**
126
     * Get the data from backend;
127
     * pre-evaluation of valid datasetId within read & readPublic is trusted here
128
     *
129
     * @NoAdminRequired
130
     * @param $reportMetadata
131
     * @return array
132
     * @throws Exception
133
     */
134
    private function getData($reportMetadata)
135
    {
136
        $datasource = (int)$reportMetadata['type'];
137
        $datasetId = (int)$reportMetadata['dataset'];
138
139
        $filterWithVariables = $reportMetadata['filteroptions']; // need to remember the filter with original text variables
140
        $reportMetadata = $this->VariableService->replaceFilterVariables($reportMetadata); // replace %xx% dynamic variables
141
142
        if ($datasource === DatasourceController::DATASET_TYPE_INTERNAL_DB) {
143
            // Internal data
144
            if ($datasetId !== 0) {
145
                $result = $this->StorageService->read($datasetId, $reportMetadata);
146
            } else {
147
                $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...
148
            }
149
        } else {
150
            // Realtime data
151
            $result = $this->DatasourceController->read($datasource, $reportMetadata);
152
        }
153
154
        unset($reportMetadata['parent']
155
            , $reportMetadata['user_id']
156
            , $reportMetadata['link']
157
            , $reportMetadata['dimension1']
158
            , $reportMetadata['dimension2']
159
            , $reportMetadata['dimension3']
160
            , $reportMetadata['value']
161
            , $reportMetadata['password']
162
            , $reportMetadata['dataset']
163
        );
164
        $result['filterApplied'] = $reportMetadata['filteroptions'];
165
        $reportMetadata['filteroptions'] = $filterWithVariables; // keep the original filters
166
        // there can be different values for no options. null during creation; empty after removal; => harmonize them
167
        $reportMetadata['chartoptions'] = ($reportMetadata['chartoptions'] === '' || $reportMetadata['chartoptions'] === 'null') ? null : $reportMetadata['chartoptions'];
168
        $reportMetadata['dataoptions'] = ($reportMetadata['dataoptions'] === '' || $reportMetadata['dataoptions'] === 'null') ? null : $reportMetadata['dataoptions'];
169
        $result['options'] = $reportMetadata;
170
        $result['thresholds'] = $this->ThresholdService->read($reportMetadata['id']);
171
        return $result;
172
    }
173
174
    /**
175
     * get the data when requested from public page
176
     *
177
     * @NoAdminRequired
178
     * @PublicPage
179
     * @UseSession
180
     * @param $token
181
     * @param $filteroptions
182
     * @param $dataoptions
183
     * @param $chartoptions
184
     * @return DataResponse|NotFoundResponse
185
     * @throws Exception
186
     */
187
    public function readPublic($token, $filteroptions, $dataoptions, $chartoptions)
188
    {
189
        $share = $this->ShareService->getReportByToken($token);
190
        if (empty($share)) {
191
            // Dataset not shared or wrong token
192
            return new NotFoundResponse();
193
        } else {
194
            if ($share['password'] !== null) {
195
                $password = $this->DataSession->getPasswordForShare($token);
196
                $passwordVerification = $this->ShareService->verifyPassword($password, $share['password']);
197
                if ($passwordVerification === false) {
198
                    return new NotFoundResponse();
199
                }
200
            }
201
            $share = $this->evaluateCanFilter($share, $filteroptions, $dataoptions, $chartoptions);
202
            $result = $this->getData($share);
203
            return new DataResponse($result, HTTP::STATUS_OK);
204
        }
205
    }
206
207
    /**
208
     * evaluate if the user did filter in the report and if he is allowed to filter (shared reports)
209
     *
210
     * @param $metadata
211
     * @param $filteroptions
212
     * @param $dataoptions
213
     * @param $chartoptions
214
     * @return mixed
215
     */
216
    private function evaluateCanFilter($metadata, $filteroptions, $dataoptions, $chartoptions)
217
    {
218
        // send current user filter options to the data request
219
        // only if the report has update-permissions
220
        // if nothing is changed by the user, the filter which is stored for the report, will be used
221
        if ($filteroptions and $filteroptions !== '' and (int)$metadata['permissions'] === Constants::PERMISSION_UPDATE) {
222
            $metadata['filteroptions'] = $filteroptions;
223
            $metadata['dataoptions'] = $dataoptions;
224
            $metadata['chartoptions'] = $chartoptions;
225
        }
226
        return $metadata;
227
    }
228
}