filter === null) { $this->filter = QueryString::parse((string) $this->params); } return $this->filter; } public function detailsAction(): void { $cube = $this->prepareCube(); $this->getTabs()->add('details', [ 'label' => $this->translate('Cube details'), 'url' => $this->getRequest()->getUrl() ])->activate('details'); $cube->setBaseFilter($this->getFilter()); $this->setTitle($cube->getSlicesLabel()); $this->view->links = IcingaDbActionsHook::renderAll($cube); $this->addContent( HtmlString::create($this->view->render('/cube-details.phtml')) ); } protected function renderCube(): void { $cube = $this->prepareCube(); $this->setTitle(sprintf( $this->translate('Cube: %s'), $cube->getPathLabel() )); $this->params->shift('format'); $showSettings = $this->params->shift('showSettings'); $query = $cube->innerQuery(); $problemsOnly = (bool) $this->params->shift('problems', false); $problemToggle = (new ProblemToggle($problemsOnly ?: null)) ->setIdProtector([$this->getRequest(), 'protectId']) ->on(ProblemToggle::ON_SUCCESS, function (ProblemToggle $form) { /** @var CheckboxElement $problems */ $problems = $form->getElement('problems'); if (! $problems->isChecked()) { $this->redirectNow(Url::fromRequest()->remove('problems')); } else { $this->redirectNow(Url::fromRequest()->setParam('problems')); } })->handleRequest($this->getServerRequest()); $this->addControl($problemToggle); $sortControl = SortControl::create([ IcingaDbCube::DIMENSION_VALUE_SORT_PARAM => t('Value'), IcingaDbCube::DIMENSION_SEVERITY_SORT_PARAM . ' desc' => t('Severity'), ]); $this->params->shift($sortControl->getSortParam()); $cube->sortBy($sortControl->getSort()); $this->addControl($sortControl); $searchBar = $this->createSearchBar( $query, $this->preserveParams ); if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { if ($searchBar->hasBeenSubmitted()) { $filter = $this->getFilter(); } else { $this->addControl($searchBar); $this->sendMultipartUpdate(); return; } } else { $filter = $searchBar->getFilter(); } if ($problemsOnly) { $filter = Filter::all($filter, Filter::equal('state.is_problem', true)); } $cube->setBaseFilter($filter); $cube->problemsOnly($problemsOnly); $this->addControl($searchBar); if (count($cube->listDimensions()) > 0) { $this->view->cube = $cube; } else { $showSettings = true; } $this->view->url = Url::fromRequest() ->onlyWith($this->preserveParams) ->setFilter($searchBar->getFilter()); if ($showSettings) { $form = (new DimensionsForm()) ->setUrl($this->view->url) ->setCube($cube) ->on(DimensionsForm::ON_SUCCESS, function ($form) { $this->redirectNow($form->getRedirectUrl()); }) ->handleRequest($this->getServerRequest()); $this->view->form = $form; } else { $this->setAutorefreshInterval(15); } $this->addContent( HtmlString::create($this->view->render('/cube-index.phtml')) ); if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) { $this->sendMultipartUpdate(); } } private function prepareCube(): IcingaDbCube { $cube = $this->getCube(); $cube->chooseFacts(array_keys($cube->getAvailableFactColumns())); $dimensions = DimensionParams::fromString( $this->params->shift('dimensions', '') )->getDimensions(); if ($this->hasLegacyDimensionParams($dimensions)) { $this->transformLegacyDimensionParamsAndRedirect($dimensions); } $wantNull = $this->params->shift('wantNull'); foreach ($dimensions as $dimension) { $cube->addDimensionByName($dimension); if ($wantNull) { $cube->getDimension($dimension)->wantNull(); } $sliceParamWithPrefix = rawurlencode($cube::SLICE_PREFIX . $dimension); if ($this->params->has($sliceParamWithPrefix)) { $this->preserveParams[] = $sliceParamWithPrefix; $cube->slice($dimension, $this->params->shift($sliceParamWithPrefix)); } } return $cube; } /** * Get whether the given dimension param is legacy dimension param * * @param string $dimensionParam * * @return bool */ private function isLegacyDimensionParam(string $dimensionParam): bool { return ! Str::startsWith($dimensionParam, CustomVariableDimension::HOST_PREFIX) && ! Str::startsWith($dimensionParam, CustomVariableDimension::SERVICE_PREFIX); } /** * Get whether the dimensions contain legacy dimension * * @param array $dimensions * * @return bool */ private function hasLegacyDimensionParams(array $dimensions): bool { foreach ($dimensions as $dimension) { if ($this->isLegacyDimensionParam($dimension)) { return true; } } return false; } /** * Transform legacy dimension and slice params and redirect * * This adds the new prefix to params and then redirects so that the new URL contains the prefixed params * Slices are prefixed to differ filter and slice params * * @param array $legacyDimensions */ private function transformLegacyDimensionParamsAndRedirect(array $legacyDimensions): void { $dimensions = []; $slices = []; $dimensionPrefix = CustomVariableDimension::HOST_PREFIX; if ($this->getRequest()->getControllerName() === 'services') { $dimensionPrefix = CustomVariableDimension::SERVICE_PREFIX; } foreach ($legacyDimensions as $param) { $newParam = $param; if ($this->isLegacyDimensionParam($param)) { $newParam = $dimensionPrefix . $param; } $slice = $this->params->shift($param); if ($slice) { $slices[IcingaDbCube::SLICE_PREFIX . $newParam] = $slice; } $dimensions[] = $newParam; } $this->redirectNow( Url::fromRequest() ->setParam('dimensions', DimensionParams::fromArray($dimensions)->getParams()) ->addParams($slices) ->without($legacyDimensions) ); } public function createTabs(): Tabs { $params = Url::fromRequest() ->onlyWith($this->preserveParams) ->getParams() ->toString(); return $this->getTabs() ->add('cube/hosts', [ 'label' => $this->translate('Hosts'), 'url' => 'cube/hosts' . ($params === '' ? '' : '?' . $params) ]) ->add('cube/services', [ 'label' => $this->translate('Services'), 'url' => 'cube/services' . ($params === '' ? '' : '?' . $params) ]); } }