Rello /
analytics
| 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\Controller; |
||
| 10 | |||
| 11 | use OCA\Analytics\DataSession; |
||
| 12 | use OCA\Analytics\Service\ReportService; |
||
| 13 | use OCA\Analytics\Service\ShareService; |
||
| 14 | use OCA\Analytics\Service\ThresholdService; |
||
| 15 | use OCA\Analytics\Service\StorageService; |
||
| 16 | use OCA\Analytics\Service\VariableService; |
||
| 17 | use OCA\Analytics\Service\PanoramaService; |
||
| 18 | use OCP\AppFramework\Controller; |
||
|
0 ignored issues
–
show
|
|||
| 19 | use OCP\AppFramework\Http; |
||
|
0 ignored issues
–
show
The type
OCP\AppFramework\Http 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. 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\AppFramework\Http\DataResponse; |
||
|
0 ignored issues
–
show
The type
OCP\AppFramework\Http\DataResponse 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. 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\AppFramework\Http\NotFoundResponse; |
||
|
0 ignored issues
–
show
The type
OCP\AppFramework\Http\NotFoundResponse 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. 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\Constants; |
||
|
0 ignored issues
–
show
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. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 23 | use OCP\DB\Exception; |
||
|
0 ignored issues
–
show
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. 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\Files\NotFoundException; |
||
|
0 ignored issues
–
show
The type
OCP\Files\NotFoundException 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. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 25 | use OCP\IRequest; |
||
|
0 ignored issues
–
show
The type
OCP\IRequest 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. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 26 | use Psr\Log\LoggerInterface; |
||
|
0 ignored issues
–
show
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. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 27 | |||
| 28 | class OutputController extends Controller |
||
| 29 | { |
||
| 30 | private $userId; |
||
| 31 | private $logger; |
||
| 32 | private $ReportService; |
||
| 33 | private $DataSession; |
||
| 34 | private $ShareService; |
||
| 35 | private $DatasourceController; |
||
| 36 | private $StorageService; |
||
| 37 | private $ThresholdService; |
||
| 38 | private $VariableService; |
||
| 39 | private $PanoramaService; |
||
| 40 | |||
| 41 | public function __construct( |
||
| 42 | $userId, |
||
| 43 | string $appName, |
||
| 44 | IRequest $request, |
||
| 45 | LoggerInterface $logger, |
||
| 46 | ReportService $ReportService, |
||
| 47 | ShareService $ShareService, |
||
| 48 | DataSession $DataSession, |
||
| 49 | DatasourceController $DatasourceController, |
||
| 50 | StorageService $StorageService, |
||
| 51 | ThresholdService $ThresholdService, |
||
| 52 | VariableService $VariableService, |
||
| 53 | PanoramaService $PanoramaService |
||
| 54 | ) |
||
| 55 | { |
||
| 56 | parent::__construct($appName, $request); |
||
| 57 | $this->userId = $userId; |
||
| 58 | $this->logger = $logger; |
||
| 59 | $this->ReportService = $ReportService; |
||
| 60 | $this->DataSession = $DataSession; |
||
| 61 | $this->ShareService = $ShareService; |
||
| 62 | $this->DatasourceController = $DatasourceController; |
||
| 63 | $this->StorageService = $StorageService; |
||
| 64 | $this->ThresholdService = $ThresholdService; |
||
| 65 | $this->VariableService = $VariableService; |
||
| 66 | $this->PanoramaService = $PanoramaService; |
||
| 67 | } |
||
| 68 | |||
| 69 | /** |
||
| 70 | * get the data when requested from internal page |
||
| 71 | * |
||
| 72 | * @NoAdminRequired |
||
| 73 | * @param int $reportId |
||
| 74 | * @param $filteroptions |
||
| 75 | * @param $dataoptions |
||
| 76 | * @param $chartoptions |
||
| 77 | * @param $tableoptions |
||
| 78 | * @return DataResponse|NotFoundResponse |
||
| 79 | * @throws Exception |
||
| 80 | */ |
||
| 81 | public function read(int $reportId, $filteroptions, $dataoptions, $chartoptions, $tableoptions) |
||
| 82 | { |
||
| 83 | $reportMetadata = $this->ReportService->read($reportId); |
||
| 84 | if (empty($reportMetadata)) $reportMetadata = $this->ShareService->getSharedReport($reportId); |
||
| 85 | |||
| 86 | if (!empty($reportMetadata)) { |
||
| 87 | $reportMetadata = $this->evaluateCanFilter($reportMetadata, $filteroptions, $dataoptions, $chartoptions, $tableoptions); |
||
| 88 | $result = $this->getData($reportMetadata); |
||
| 89 | return new DataResponse($result, HTTP::STATUS_OK); |
||
| 90 | } else { |
||
| 91 | return new NotFoundResponse(); |
||
| 92 | } |
||
| 93 | } |
||
| 94 | |||
| 95 | /** |
||
| 96 | * get the data when requested from a panorama |
||
| 97 | * |
||
| 98 | * @NoAdminRequired |
||
| 99 | * @param int $reportIds |
||
| 100 | * @return DataResponse|NotFoundResponse |
||
| 101 | * @throws Exception |
||
| 102 | */ |
||
| 103 | public function readPanorama(int $reportId) |
||
| 104 | { |
||
| 105 | $reportMetadata = $this->ReportService->read($reportId); |
||
| 106 | if (empty($reportMetadata)) $reportMetadata = $this->ShareService->getSharedPanoramaReport($reportId); |
||
| 107 | |||
| 108 | if (!empty($reportMetadata)) { |
||
| 109 | $result = $this->getData($reportMetadata); |
||
| 110 | return new DataResponse($result, HTTP::STATUS_OK); |
||
| 111 | } else { |
||
| 112 | return new NotFoundResponse(); |
||
| 113 | } |
||
| 114 | } |
||
| 115 | |||
| 116 | /** |
||
| 117 | * Preview the data |
||
| 118 | * |
||
| 119 | * @NoAdminRequired |
||
| 120 | * @param $type |
||
| 121 | * @param $options |
||
| 122 | * @return DataResponse|NotFoundResponse |
||
| 123 | * @throws Exception |
||
| 124 | */ |
||
| 125 | public function readPreview ($type, $options) |
||
| 126 | { |
||
| 127 | $reportMetadata = []; |
||
| 128 | $array = json_decode($options, true); |
||
| 129 | foreach ($array as $key => $value) { |
||
| 130 | $array[$key] = htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8'); |
||
| 131 | } |
||
| 132 | $reportMetadata['link'] = json_encode($array); |
||
| 133 | $reportMetadata['type'] = $type; |
||
| 134 | $reportMetadata['dataset'] = 0; |
||
| 135 | $reportMetadata['filteroptions'] = ''; |
||
| 136 | $reportMetadata['user_id'] = $this->userId; |
||
| 137 | $reportMetadata['id'] = 0; |
||
| 138 | |||
| 139 | $result = $this->getData($reportMetadata); |
||
| 140 | unset($result['options'] |
||
| 141 | , $result['dimensions'] |
||
| 142 | , $result['filterApplied'] |
||
| 143 | , $result['thresholds'] |
||
| 144 | ); |
||
| 145 | $result['data'] = array_slice($result['data'], 0, 1); |
||
| 146 | |||
| 147 | return new DataResponse($result, HTTP::STATUS_OK); |
||
| 148 | } |
||
| 149 | |||
| 150 | |||
| 151 | /** |
||
| 152 | * Get the data from backend; |
||
| 153 | * pre-evaluation of valid datasetId within read & readPublic is trusted here |
||
| 154 | * also used in Pagecontroller-indexPublicMin ToDo: make this private |
||
| 155 | * |
||
| 156 | * @NoAdminRequired |
||
| 157 | * @param $reportMetadata |
||
| 158 | * @return array |
||
| 159 | * @throws Exception |
||
| 160 | */ |
||
| 161 | public function getData($reportMetadata) |
||
| 162 | { |
||
| 163 | $datasource = (int)$reportMetadata['type']; |
||
| 164 | $datasetId = (int)$reportMetadata['dataset']; |
||
| 165 | |||
| 166 | $filterWithVariables = $reportMetadata['filteroptions']; // need to remember the filter with original text variables |
||
| 167 | $reportMetadata = $this->VariableService->replaceFilterVariables($reportMetadata); // replace %xx% dynamic variables |
||
| 168 | |||
| 169 | if ($datasource === DatasourceController::DATASET_TYPE_INTERNAL_DB) { |
||
| 170 | // Internal data |
||
| 171 | if ($datasetId !== 0) { |
||
| 172 | $result = $this->StorageService->read($datasetId, $reportMetadata); |
||
| 173 | } else { |
||
| 174 | $result['error'] = 'inconsistent report'; |
||
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
| 175 | } |
||
| 176 | } else { |
||
| 177 | // Realtime data |
||
| 178 | $result = $this->DatasourceController->read($datasource, $reportMetadata); |
||
| 179 | unset($result['rawdata']); |
||
| 180 | } |
||
| 181 | |||
| 182 | unset($reportMetadata['parent'] |
||
| 183 | , $reportMetadata['user_id'] |
||
| 184 | , $reportMetadata['link'] |
||
| 185 | , $reportMetadata['dimension1'] |
||
| 186 | , $reportMetadata['dimension2'] |
||
| 187 | , $reportMetadata['dimension3'] |
||
| 188 | , $reportMetadata['value'] |
||
| 189 | , $reportMetadata['password'] |
||
| 190 | , $reportMetadata['dataset'] |
||
| 191 | ); |
||
| 192 | |||
| 193 | $result['filterApplied'] = $reportMetadata['filteroptions']; |
||
| 194 | $reportMetadata['filteroptions'] = $filterWithVariables; // keep the original filters |
||
| 195 | // there can be different values for no options. null during creation; empty after removal; => harmonize them |
||
| 196 | if (array_key_exists('chartoptions', $reportMetadata)) { |
||
| 197 | $reportMetadata['chartoptions'] = ($reportMetadata['chartoptions'] === '' || $reportMetadata['chartoptions'] === 'null') ? null : $reportMetadata['chartoptions']; |
||
| 198 | } |
||
| 199 | |||
| 200 | if (array_key_exists('dataoptions', $reportMetadata)) { |
||
| 201 | $reportMetadata['dataoptions'] = ($reportMetadata['dataoptions'] === '' || $reportMetadata['dataoptions'] === 'null') ? null : $reportMetadata['dataoptions']; |
||
| 202 | } |
||
| 203 | $result['options'] = $reportMetadata; |
||
| 204 | $result['thresholds'] = $this->ThresholdService->read($reportMetadata['id']); |
||
| 205 | return $result; |
||
| 206 | } |
||
| 207 | |||
| 208 | /** |
||
| 209 | * get the data when requested from public page |
||
| 210 | * |
||
| 211 | * @NoAdminRequired |
||
| 212 | * @PublicPage |
||
| 213 | * @UseSession |
||
| 214 | * @param $token |
||
| 215 | * @param $filteroptions |
||
| 216 | * @param $dataoptions |
||
| 217 | * @param $chartoptions |
||
| 218 | * @param $tableoptions |
||
| 219 | * @return DataResponse|NotFoundResponse |
||
| 220 | * @throws Exception |
||
| 221 | */ |
||
| 222 | public function readPublic($token, $filteroptions, $dataoptions, $chartoptions, $tableoptions) |
||
| 223 | { |
||
| 224 | $share = $this->ShareService->getReportByToken($token); |
||
| 225 | if (empty($share)) { |
||
| 226 | // Dataset not shared or wrong token |
||
| 227 | return new NotFoundResponse(); |
||
| 228 | } else { |
||
| 229 | if ($share['password'] !== null) { |
||
| 230 | $password = $this->DataSession->getPasswordForShare($token); |
||
| 231 | $passwordVerification = $this->ShareService->verifyPassword($password, $share['password']); |
||
| 232 | if ($passwordVerification === false) { |
||
| 233 | return new NotFoundResponse(); |
||
| 234 | } |
||
| 235 | } |
||
| 236 | $share = $this->evaluateCanFilter($share, $filteroptions, $dataoptions, $chartoptions, $tableoptions); |
||
| 237 | $result = $this->getData($share); |
||
| 238 | return new DataResponse($result, HTTP::STATUS_OK); |
||
| 239 | } |
||
| 240 | } |
||
| 241 | |||
| 242 | /** |
||
| 243 | * evaluate if the user did filter in the report and if he is allowed to filter (shared reports) |
||
| 244 | * |
||
| 245 | * @param $metadata |
||
| 246 | * @param $filteroptions |
||
| 247 | * @param $dataoptions |
||
| 248 | * @param $chartoptions |
||
| 249 | * @param $tableoptions |
||
| 250 | * @return mixed |
||
| 251 | */ |
||
| 252 | private function evaluateCanFilter($metadata, $filteroptions, $dataoptions, $chartoptions, $tableoptions) |
||
| 253 | { |
||
| 254 | // send current user filter options to the data request |
||
| 255 | // only if the report has update-permissions |
||
| 256 | // if nothing is changed by the user, the filter which is stored for the report, will be used |
||
| 257 | if ($filteroptions and $filteroptions !== '' and (int)$metadata['permissions'] === Constants::PERMISSION_UPDATE) { |
||
| 258 | $metadata['filteroptions'] = $filteroptions; |
||
| 259 | $metadata['dataoptions'] = $dataoptions; |
||
| 260 | $metadata['chartoptions'] = $chartoptions; |
||
| 261 | $metadata['tableoptions'] = $tableoptions; |
||
| 262 | } |
||
| 263 | return $metadata; |
||
| 264 | } |
||
| 265 | } |
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:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths