| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugin; |
|
|
| use Piwik\API\DataTablePostProcessor; |
| use Piwik\API\Proxy; |
| use Piwik\API\Request; |
| use Piwik\API\Request as ApiRequest; |
| use Piwik\API\ResponseBuilder; |
| use Piwik\ArchiveProcessor\Rules; |
| use Piwik\Common; |
| use Piwik\Container\StaticContainer; |
| use Piwik\DataTable; |
| use Piwik\DataTable\DataTableInterface; |
| use Piwik\Date; |
| use Piwik\Http\BadRequestException; |
| use Piwik\Log; |
| use Piwik\Metrics\Formatter\Html as HtmlFormatter; |
| use Piwik\NoAccessException; |
| use Piwik\Option; |
| use Piwik\Period; |
| use Piwik\Piwik; |
| use Piwik\Plugins\API\API as ApiApi; |
| use Piwik\Plugins\API\Filter\DataComparisonFilter; |
| use Piwik\Plugins\Monolog\Processor\ExceptionToTextProcessor; |
| use Piwik\Plugins\PrivacyManager\PrivacyManager; |
| use Piwik\SettingsPiwik; |
| use Piwik\View; |
| use Piwik\ViewDataTable\Manager as ViewDataTableManager; |
| use Piwik\Plugin\Manager as PluginManager; |
| use Piwik\Log\LoggerInterface; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class Visualization extends ViewDataTable |
| { |
| |
| |
| |
| |
| |
| |
| |
| public const TEMPLATE_FILE = ''; |
|
|
| private $templateVars = array(); |
| private $reportLastUpdatedMessage = null; |
| protected $metricsFormatter = null; |
|
|
| |
| |
| |
| protected $report; |
|
|
| final public function __construct($controllerAction, $apiMethodToRequestDataTable, $params = array()) |
| { |
| $templateFile = static::TEMPLATE_FILE; |
|
|
| if (empty($templateFile)) { |
| throw new \Exception('You have not defined a constant named TEMPLATE_FILE in your visualization class.'); |
| } |
|
|
| $this->metricsFormatter = new HtmlFormatter(); |
|
|
| parent::__construct($controllerAction, $apiMethodToRequestDataTable, $params); |
|
|
| $this->report = ReportsProvider::factory($this->requestConfig->getApiModuleToRequest(), $this->requestConfig->getApiMethodToRequest()); |
| } |
|
|
| public function render() |
| { |
| $this->overrideSomeConfigPropertiesIfNeeded(); |
|
|
| try { |
| $this->beforeLoadDataTable(); |
| $this->loadDataTableFromAPI(); |
| $this->postDataTableLoadedFromAPI(); |
|
|
| $requestPropertiesAfterLoadDataTable = $this->requestConfig->getProperties(); |
|
|
| $this->applyFilters(); |
| $this->addVisualizationInfoFromMetricMetadata(); |
| $this->afterAllFiltersAreApplied(); |
|
|
| $this->beforeRender(); |
| $this->fireBeforeRenderHook(); |
|
|
| $this->logMessageIfRequestPropertiesHaveChanged($requestPropertiesAfterLoadDataTable); |
| } catch (NoAccessException $e) { |
| throw $e; |
| } catch (\Exception $e) { |
| StaticContainer::get(LoggerInterface::class)->error('Failed to get data from API: {exception}', [ |
| 'exception' => $e, |
| 'ignoreInScreenWriter' => true, |
| ]); |
|
|
| $message = ExceptionToTextProcessor::getMessageAndWholeBacktrace($e); |
|
|
| $loadingError = array('message' => $message); |
| } |
|
|
| $view = new View("@CoreHome/_dataTable"); |
| $view->assign($this->templateVars); |
|
|
| if (!empty($loadingError)) { |
| $view->error = $loadingError; |
| } |
|
|
| $view->visualization = $this; |
| $view->visualizationTemplate = static::TEMPLATE_FILE; |
| $view->visualizationCssClass = $this->getDefaultDataTableCssClass(); |
| $view->reportMetdadata = $this->getReportMetadata(); |
|
|
| if (!($this->dataTable instanceof DataTableInterface)) { |
| $view->dataTable = null; |
| $view->dataTableHasNoData = true; |
| } else { |
| $view->dataTableHasNoData = !$this->isThereDataToDisplay(); |
| $view->dataTable = $this->dataTable; |
|
|
| |
| |
| $view->showReportDataWasPurgedMessage = $this->hasReportBeenPurged(); |
| $view->showPluginArchiveDisabled = $this->hasReportSegmentDisabled(); |
| $view->deleteReportsOlderThan = Option::get('delete_reports_older_than'); |
| } |
|
|
| $view->idSubtable = $this->requestConfig->idSubtable; |
| $clientSideParameters = $this->getClientSideParametersToSet(); |
| if (isset($clientSideParameters['showtitle'])) { |
| unset($clientSideParameters['showtitle']); |
| } |
| $view->clientSideParameters = $clientSideParameters; |
| $view->clientSideProperties = $this->getClientSidePropertiesToSet(); |
| $view->properties = array_merge($this->requestConfig->getProperties(), $this->config->getProperties()); |
| $view->reportLastUpdatedMessage = $this->reportLastUpdatedMessage; |
| $view->footerIcons = $this->config->footer_icons; |
| $view->isWidget = Common::getRequestVar('widget', 0, 'int'); |
| $view->notifications = []; |
| $view->isComparing = $this->isComparing(); |
|
|
| $view->rowIdentifier = $this->report ? ($this->report->getRowIdentifier() ?: 'label') : 'label'; |
| $view->clientSideProperties['row_identifier'] = $view->rowIdentifier; |
|
|
| if ( |
| !$this->supportsComparison() |
| && DataComparisonFilter::isCompareParamsPresent() |
| && empty($view->dataTableHasNoData) |
| ) { |
| if (empty($view->properties['show_footer_message'])) { |
| $view->properties['show_footer_message'] = ''; |
| } |
| $view->properties['show_footer_message'] .= '<br/>' . Piwik::translate('General_VisualizationDoesNotSupportComparison'); |
| } |
|
|
| if (empty($this->dataTable) || !$this->hasAnyData($this->dataTable)) { |
| |
| |
| |
| Piwik::postEvent('Visualization.onNoData', [$view]); |
| } |
|
|
| return $view->render(); |
| } |
|
|
| protected function checkRequestIsNotForMultiplePeriods() |
| { |
| $date = $this->requestConfig->getRequestParam('date'); |
| $period = $this->requestConfig->getRequestParam('period'); |
| if (Period::isMultiplePeriod($date, $period)) { |
| throw new BadRequestException("The '" . static::ID . "' visualization does not support multiple periods."); |
| } |
| } |
|
|
| protected function checkRequestIsOnlyForMultiplePeriods() |
| { |
| try { |
| $this->checkRequestIsNotForMultiplePeriods(); |
| } catch (BadRequestException $ex) { |
| return; |
| } |
|
|
| throw new BadRequestException("The '" . static::ID . "' visualization does not support single periods."); |
| } |
|
|
| private function hasAnyData(DataTable\DataTableInterface $dataTable) |
| { |
| $hasData = false; |
| $dataTable->filter(function (DataTable $table) use (&$hasData) { |
| if ($hasData || $table->getRowsCount() == 0) { |
| return; |
| } |
|
|
| foreach ($table->getRows() as $row) { |
| foreach ($row->getColumns() as $column => $value) { |
| if ($value != 0 && $value !== '0%') { |
| $hasData = true; |
| return; |
| } |
| } |
| } |
| }); |
| return $hasData; |
| } |
|
|
| protected function loadDataTableFromAPI() |
| { |
|
|
| if (!is_null($this->dataTable)) { |
| |
| |
| return $this->dataTable; |
| } |
|
|
| |
| $request = $this->buildApiRequestArray(); |
|
|
| $module = $this->requestConfig->getApiModuleToRequest(); |
| $method = $this->requestConfig->getApiMethodToRequest(); |
|
|
| [$module, $method] = Request::getRenamedModuleAndAction($module, $method); |
|
|
| PluginManager::getInstance()->checkIsPluginActivated($module); |
|
|
| $proxyRequestParams = $request; |
| if ($this->isComparing()) { |
| $proxyRequestParams = array_merge($proxyRequestParams, [ |
| 'disable_root_datatable_post_processor' => 1, |
| ]); |
| } |
|
|
| $class = ApiRequest::getClassNameAPI($module); |
| $dataTable = Proxy::getInstance()->call($class, $method, $proxyRequestParams); |
|
|
| $response = new ResponseBuilder($format = 'original', $request); |
| $response->disableSendHeader(); |
| $response->disableDataTablePostProcessor(); |
|
|
| $this->dataTable = $response->getResponse($dataTable, $module, $method); |
| } |
|
|
| private function getReportMetadata() |
| { |
| $request = $this->request->getRequestArray() + $_GET + $_POST; |
|
|
| $idSite = Common::getRequestVar('idSite', null, 'int', $request); |
| $module = $this->requestConfig->getApiModuleToRequest(); |
| $action = $this->requestConfig->getApiMethodToRequest(); |
|
|
| $apiParameters = array(); |
| $entityNames = StaticContainer::get('entities.idNames'); |
| foreach ($entityNames as $entityName) { |
| $idEntity = Common::getRequestVar($entityName, 0, 'int'); |
| if ($idEntity > 0) { |
| $apiParameters[$entityName] = $idEntity; |
| } |
| } |
|
|
| $metadata = ApiApi::getInstance()->getMetadata($idSite, $module, $action, $apiParameters); |
|
|
| if (!empty($metadata)) { |
| return array_shift($metadata); |
| } |
|
|
| return false; |
| } |
|
|
| private function overrideSomeConfigPropertiesIfNeeded() |
| { |
| if (empty($this->config->footer_icons)) { |
| $this->config->footer_icons = ViewDataTableManager::configureFooterIcons($this); |
| } |
|
|
| if (!$this->isPluginActivated('Goals')) { |
| $this->config->show_goals = false; |
| } |
| } |
|
|
| private function isPluginActivated($pluginName) |
| { |
| return PluginManager::getInstance()->isPluginActivated($pluginName); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function assignTemplateVar($vars, $value = null) |
| { |
| if (is_string($vars)) { |
| $this->templateVars[$vars] = $value; |
| } elseif (is_array($vars)) { |
| foreach ($vars as $key => $value) { |
| $this->templateVars[$key] = $value; |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| protected function isThereDataToDisplay() |
| { |
| return !empty($this->dataTable) && 0 < $this->dataTable->getRowsCount(); |
| } |
|
|
| |
| |
| |
| |
| private function postDataTableLoadedFromAPI() |
| { |
| $columns = $this->dataTable->getColumns(); |
| $hasNbVisits = in_array('nb_visits', $columns); |
| $hasNbUniqVisitors = in_array('nb_uniq_visitors', $columns); |
|
|
| |
| if ($this->isComparing()) { |
| $request = $this->getRequestArray(); |
| if (!empty($request['comparePeriods'])) { |
| foreach ($request['comparePeriods'] as $comparePeriod) { |
| if (!SettingsPiwik::isUniqueVisitorsEnabled($comparePeriod)) { |
| $hasNbUniqVisitors = false; |
| break; |
| } |
| } |
| } |
| } |
|
|
| |
| |
| if (empty($this->config->columns_to_display)) { |
| $this->config->setDefaultColumnsToDisplay($columns, $hasNbVisits, $hasNbUniqVisitors); |
| } |
|
|
| if (empty($this->requestConfig->filter_sort_column)) { |
| $this->requestConfig->setDefaultSort($this->config->columns_to_display, $hasNbUniqVisitors, $columns); |
| } |
|
|
| |
| $metadata = null; |
| if ($this->dataTable instanceof DataTable) { |
| $metadata = $this->dataTable->getAllTableMetadata(); |
| } else { |
| |
| if ($this->dataTable instanceof DataTable\Map) { |
| |
| $dataTable = $this->dataTable->getDataTables(); |
| |
| foreach ($dataTable as $item) { |
| $itemMetaData = $item->getAllTableMetadata(); |
| |
| if ( |
| !empty($itemMetaData[DataTable::ARCHIVED_DATE_METADATA_NAME]) |
| && ( |
| empty($metadata[DataTable::ARCHIVED_DATE_METADATA_NAME]) |
| || strtotime($itemMetaData[DataTable::ARCHIVED_DATE_METADATA_NAME]) > strtotime($metadata[DataTable::ARCHIVED_DATE_METADATA_NAME]) |
| ) |
| ) { |
| $metadata = $itemMetaData; |
| } |
| } |
| } |
| } |
|
|
| |
| if (!empty($metadata[DataTable::ARCHIVED_DATE_METADATA_NAME])) { |
| $this->reportLastUpdatedMessage = $this->makePrettyArchivedOnText($metadata[DataTable::ARCHIVED_DATE_METADATA_NAME]); |
| } |
|
|
| $pivotBy = Common::getRequestVar('pivotBy', false) ?: $this->requestConfig->pivotBy; |
| if ( |
| empty($pivotBy) |
| && $this->dataTable instanceof DataTable |
| ) { |
| $this->config->disablePivotBySubtableIfTableHasNoSubtables($this->dataTable); |
| } |
| } |
|
|
| private function addVisualizationInfoFromMetricMetadata() |
| { |
| $dataTable = $this->dataTable instanceof DataTable\Map ? $this->dataTable->getFirstRow() : $this->dataTable; |
|
|
| $metrics = Report::getMetricsForTable($dataTable, $this->report); |
|
|
| |
| |
| foreach ($metrics as $metric) { |
| $name = $metric->getName(); |
|
|
| if (empty($this->config->translations[$name])) { |
| $this->config->translations[$name] = $metric->getTranslatedName(); |
| } |
|
|
| if (empty($this->config->metrics_documentation[$name])) { |
| $this->config->metrics_documentation[$name] = $metric->getDocumentation(); |
| } |
| } |
| } |
|
|
| private function applyFilters() |
| { |
| $postProcessor = $this->makeDataTablePostProcessor(); |
| $self = $this; |
|
|
| $postProcessor->setCallbackBeforeGenericFilters(function (DataTable\DataTableInterface $dataTable) use ($self, $postProcessor) { |
|
|
| $self->setDataTable($dataTable); |
|
|
| |
| foreach ($self->config->getPriorityFilters() as $filter) { |
| $dataTable->filter($filter[0], $filter[1]); |
| } |
|
|
| $self->beforeGenericFiltersAreAppliedToLoadedDataTable(); |
|
|
| if (!in_array($self->requestConfig->filter_sort_column, $self->config->columns_to_display)) { |
| $hasNbUniqVisitors = in_array('nb_uniq_visitors', $self->config->columns_to_display); |
| $columns = $dataTable->getColumns(); |
| $self->requestConfig->setDefaultSort($self->config->columns_to_display, $hasNbUniqVisitors, $columns); |
| } |
|
|
| $postProcessor->setRequest($self->buildApiRequestArray()); |
| }); |
|
|
| $postProcessor->setCallbackAfterGenericFilters(function (DataTable\DataTableInterface $dataTable) use ($self) { |
|
|
| $self->setDataTable($dataTable); |
| $self->afterGenericFiltersAreAppliedToLoadedDataTable(); |
|
|
| |
| foreach ($self->config->getPresentationFilters() as $filter) { |
| $dataTable->queueFilter($filter[0], $filter[1]); |
| } |
|
|
| if (!empty($this->dataTable)) { |
| $self->removeEmptyColumnsFromDisplay(); |
| } |
| }); |
|
|
| $this->dataTable = $postProcessor->process($this->dataTable); |
| } |
|
|
| private function removeEmptyColumnsFromDisplay() |
| { |
| if ($this->dataTable instanceof DataTable\Map) { |
| $emptyColumns = $this->dataTable->getMetadataIntersectArray(DataTable::EMPTY_COLUMNS_METADATA_NAME); |
| } else { |
| $emptyColumns = $this->dataTable->getMetadata(DataTable::EMPTY_COLUMNS_METADATA_NAME); |
| } |
|
|
| if (is_array($emptyColumns)) { |
| foreach ($emptyColumns as $emptyColumn) { |
| $key = array_search($emptyColumn, $this->config->columns_to_display); |
| if ($key !== false) { |
| unset($this->config->columns_to_display[$key]); |
| } |
| } |
|
|
| $this->config->columns_to_display = array_values($this->config->columns_to_display); |
| } |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| private function makePrettyArchivedOnText($dateText) |
| { |
| $date = Date::factory($dateText); |
| $today = mktime(0, 0, 0); |
| $metricsFormatter = new HtmlFormatter(); |
|
|
| if ($date->getTimestamp() > $today) { |
| $elapsedSeconds = time() - $date->getTimestamp(); |
| $timeAgo = $metricsFormatter->getPrettyTimeFromSeconds($elapsedSeconds); |
|
|
| return Piwik::translate('CoreHome_ReportGeneratedXAgo', $timeAgo); |
| } |
|
|
| $prettyDate = $date->getLocalized(Date::DATE_FORMAT_SHORT); |
|
|
| $timezoneAppend = ' (UTC)'; |
| return Piwik::translate('CoreHome_ReportGeneratedOn', $prettyDate) . $timezoneAppend; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| private function hasReportBeenPurged() |
| { |
| if (!$this->isPluginActivated('PrivacyManager')) { |
| return false; |
| } |
|
|
| return PrivacyManager::hasReportBeenPurged($this->dataTable); |
| } |
|
|
| |
| |
| |
| |
| |
|
|
| private function hasReportSegmentDisabled() |
| { |
| $module = $this->requestConfig->getApiModuleToRequest(); |
| $rawSegment = \Piwik\API\Request::getRawSegmentFromRequest(); |
|
|
| if (!empty($rawSegment) && Rules::isSegmentPluginArchivingDisabled($module)) { |
| return true; |
| } |
| return false; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| private function getClientSidePropertiesToSet() |
| { |
| $result = array(); |
|
|
| foreach ($this->config->clientSideProperties as $name) { |
| if (property_exists($this->requestConfig, $name)) { |
| $result[$name] = $this->getIntIfValueIsBool($this->requestConfig->$name); |
| } elseif (property_exists($this->config, $name)) { |
| $result[$name] = $this->getIntIfValueIsBool($this->config->$name); |
| } |
| } |
|
|
| return $result; |
| } |
|
|
| private function getIntIfValueIsBool($value) |
| { |
| return is_bool($value) ? (int)$value : $value; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| protected function getClientSideParametersToSet() |
| { |
| |
| $javascriptVariablesToSet = array(); |
|
|
| foreach ($this->config->custom_parameters as $name => $value) { |
| $javascriptVariablesToSet[$name] = $value; |
| } |
|
|
| foreach ($_GET as $name => $value) { |
| try { |
| $requestValue = Common::getRequestVar($name); |
| } catch (\Exception $e) { |
| $requestValue = ''; |
| } |
| $javascriptVariablesToSet[$name] = $requestValue; |
| } |
|
|
| foreach ($this->requestConfig->clientSideParameters as $name) { |
| $valueToConvert = false; |
|
|
| if (property_exists($this->requestConfig, $name)) { |
| $valueToConvert = $this->requestConfig->$name; |
| } elseif (property_exists($this->config, $name)) { |
| $valueToConvert = $this->config->$name; |
| } |
|
|
| |
| |
| |
| if (is_array($valueToConvert) && isset($javascriptVariablesToSet[$name])) { |
| continue; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| if (false !== $valueToConvert) { |
| $javascriptVariablesToSet[$name] = $this->getIntIfValueIsBool($valueToConvert); |
| } |
| } |
|
|
| $javascriptVariablesToSet['module'] = $this->config->controllerName; |
| $javascriptVariablesToSet['action'] = $this->config->controllerAction; |
| if (!isset($javascriptVariablesToSet['viewDataTable'])) { |
| $javascriptVariablesToSet['viewDataTable'] = static::getViewDataTableId(); |
| } |
|
|
| if ( |
| $this->dataTable && |
| |
| !($this->dataTable instanceof DataTable\Map) && |
| empty($javascriptVariablesToSet['totalRows']) |
| ) { |
| $javascriptVariablesToSet['totalRows'] = |
| $this->dataTable->getMetadata(DataTable::TOTAL_ROWS_BEFORE_LIMIT_METADATA_NAME) ?: $this->dataTable->getRowsCount(); |
| } |
|
|
| $deleteFromJavascriptVariables = array( |
| 'filter_excludelowpop', |
| 'filter_excludelowpop_value', |
| ); |
|
|
| foreach ($deleteFromJavascriptVariables as $name) { |
| if (isset($javascriptVariablesToSet[$name])) { |
| unset($javascriptVariablesToSet[$name]); |
| } |
| } |
|
|
| $rawSegment = \Piwik\API\Request::getRawSegmentFromRequest(); |
| if (!empty($rawSegment)) { |
| $javascriptVariablesToSet['segment'] = $rawSegment; |
| } |
|
|
| if (isset($javascriptVariablesToSet['compareSegments'])) { |
| $javascriptVariablesToSet['compareSegments'] = Common::unsanitizeInputValues($javascriptVariablesToSet['compareSegments']); |
| } |
|
|
| return $javascriptVariablesToSet; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function beforeLoadDataTable() |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function beforeGenericFiltersAreAppliedToLoadedDataTable() |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| public function afterGenericFiltersAreAppliedToLoadedDataTable() |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public function afterAllFiltersAreApplied() |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public function beforeRender() |
| { |
| |
| } |
|
|
| private function fireBeforeRenderHook() |
| { |
| |
| |
| |
| |
| |
| |
| Piwik::postEvent('Visualization.beforeRender', [$this]); |
| } |
|
|
| private function makeDataTablePostProcessor() |
| { |
| $request = $this->buildApiRequestArray(); |
| $module = $this->requestConfig->getApiModuleToRequest(); |
| $method = $this->requestConfig->getApiMethodToRequest(); |
|
|
| $processor = new DataTablePostProcessor($module, $method, $request); |
| $processor->setFormatter($this->metricsFormatter); |
|
|
| return $processor; |
| } |
|
|
| private function logMessageIfRequestPropertiesHaveChanged(array $requestPropertiesBefore) |
| { |
| $requestProperties = $this->requestConfig->getProperties(); |
|
|
| $diff = array_diff_assoc( |
| $this->makeSureArrayContainsOnlyStrings($requestProperties), |
| $this->makeSureArrayContainsOnlyStrings($requestPropertiesBefore) |
| ); |
|
|
| if (!empty($diff['filter_sort_column'])) { |
| |
| unset($diff['filter_sort_column']); |
| } |
| if (!empty($diff['filter_sort_order'])) { |
| |
| unset($diff['filter_sort_order']); |
| } |
|
|
| if (empty($diff)) { |
| return; |
| } |
|
|
| $details = array( |
| 'changedProperties' => $diff, |
| 'apiMethod' => $this->requestConfig->apiMethodToRequestDataTable, |
| 'controller' => $this->config->controllerName . '.' . $this->config->controllerAction, |
| 'viewDataTable' => static::getViewDataTableId(), |
| ); |
|
|
| $message = 'Some ViewDataTable::requestConfig properties have changed after requesting the data table. ' |
| . 'That means the changed values had probably no effect. For instance in beforeRender() hook. ' |
| . 'Probably a bug? Details:' |
| . print_r($details, 1); |
|
|
| Log::warning($message); |
| } |
|
|
| private function makeSureArrayContainsOnlyStrings($array) |
| { |
| $result = array(); |
|
|
| foreach ($array as $key => $value) { |
| $result[$key] = json_encode($value); |
| } |
|
|
| return $result; |
| } |
|
|
| |
| |
| |
| |
| |
| public function buildApiRequestArray() |
| { |
| $request = $this->getRequestArray(); |
|
|
| if (false === $this->config->enable_sort) { |
| $request['filter_sort_column'] = ''; |
| $request['filter_sort_order'] = ''; |
| } |
|
|
| if (!array_key_exists('format_metrics', $request) || $request['format_metrics'] === 'bc') { |
| $request['format_metrics'] = '1'; |
| } |
|
|
| if (!$this->requestConfig->disable_queued_filters && array_key_exists('disable_queued_filters', $request)) { |
| unset($request['disable_queued_filters']); |
| } |
|
|
| if ($this->isComparing()) { |
| $request['compare'] = '1'; |
| } |
|
|
| return $request; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| protected function applyMetricsFormatting(bool $forceFormatting = false) |
| { |
| $postProcessor = $this->makeDataTablePostProcessor(); |
| $this->dataTable = $postProcessor->applyMetricsFormatting($this->dataTable, $forceFormatting); |
| } |
| } |
|
|