public function renderReportWidget(Report $report) { Piwik::checkUserHasSomeViewAccess(); $this->checkSitePermission(); $report->checkIsEnabled(); return $report->render(); }
/** * Creates a new container widget based on the specified report in {@link construct()}. * * It will automatically use the report's categoryId, subcategoryId (if specified) and order in order to * create the container. * * @param string $containerId eg 'Products' or 'Contents' see {Piwik\Widget\WidgetContainerConfig::setId()}. * Other reports or widgets will be able to add more widgets to this container. * This is useful when you want to show for example multiple related widgets * together. * @return WidgetContainerConfig */ public function createContainerWidget($containerId) { $widget = new WidgetContainerConfig(); $widget->setCategoryId($this->report->getCategoryId()); $widget->setId($containerId); if ($this->report->getSubcategoryId()) { $widget->setSubcategoryId($this->report->getSubcategoryId()); } $orderThatListsReportsAtTheEndOfEachCategory = 100 + $this->report->getOrder(); $widget->setOrder($orderThatListsReportsAtTheEndOfEachCategory); return $widget; }
private function getGenericFiltersHavingDefaultValues() { $filters = self::getGenericFiltersInformation(); if ($this->report && $this->report->getDefaultSortColumn()) { foreach ($filters as $index => $filter) { if ($filter[0] === 'Sort') { $filters[$index][1]['filter_sort_column'] = array('string', $this->report->getDefaultSortColumn()); $filters[$index][1]['filter_sort_order'] = array('string', $this->report->getDefaultSortOrder()); } } } return $filters; }
public function getMetrics() { $metrics = parent::getMetrics(); $metrics['avg_time_on_site'] = Piwik::translate('General_VisitDuration'); $metrics['max_actions'] = Piwik::translate('General_ColumnMaxActions'); return $metrics; }
protected function init() { parent::init(); $this->reportsToMerge = $this->getReportsToMerge(); $this->module = 'API'; $this->action = 'get'; $this->categoryId = 'API'; $this->name = Piwik::translate('General_MainMetrics'); $this->documentation = ''; $this->processedMetrics = array(); foreach ($this->reportsToMerge as $report) { if (!is_array($report->processedMetrics)) { continue; } $this->processedMetrics = array_merge($this->processedMetrics, $report->processedMetrics); } $this->metrics = array(); foreach ($this->reportsToMerge as $report) { if (!is_array($report->metrics)) { continue; } $this->metrics = array_merge($this->metrics, $report->metrics); } $this->order = 6; }
protected function init() { parent::init(); $this->category = 'General_Visitors'; $this->name = Piwik::translate('VisitFrequency_ColumnReturningVisits'); $this->documentation = ''; // TODO $this->metrics = array('nb_visits_returning', 'nb_actions_returning', 'avg_time_on_site_returning', 'bounce_rate_returning', 'nb_actions_per_visit_returning', 'nb_uniq_visitors_returning'); $this->processedMetrics = false; $this->order = 40; }
protected function init() { parent::init(); $this->category = 'General_Visitors'; $this->name = Piwik::translate('VisitFrequency_ColumnReturningVisits'); $this->documentation = ''; // TODO $this->processedMetrics = array(new ReturningMetric(new AverageTimeOnSite()), new ReturningMetric(new ActionsPerVisit()), new ReturningMetric(new BounceRate())); $this->metrics = array('nb_visits_returning', 'nb_actions_returning', 'nb_uniq_visitors_returning', 'nb_users_returning', 'max_actions_returning'); $this->order = 40; }
public function renderReportWidget($reportModule = null, $reportAction = null) { Piwik::checkUserHasSomeViewAccess(); $this->checkSitePermission(); $report = Report::factory($reportModule, $reportAction); if (empty($report)) { throw new Exception(Piwik::translate('General_ExceptionReportNotFound')); } $report->checkIsEnabled(); return $report->render(); }
public function get($idSite, $period, $date, $segment = false, $columns = false) { Piwik::checkUserHasViewAccess($idSite); $archive = Archive::build($idSite, $period, $date, $segment); $requestedColumns = Piwik::getArrayFromApiParameter($columns); $report = Report::factory("VisitsSummary", "get"); $columns = $report->getMetricsRequiredForReport($this->getCoreColumns($period), $requestedColumns); $dataTable = $archive->getDataTableFromNumeric($columns); if (!empty($requestedColumns)) { $columnsToShow = $requestedColumns ?: $report->getAllMetrics(); $dataTable->queueFilter('ColumnDelete', array($columnsToRemove = array(), $columnsToShow)); } return $dataTable; }
/** * See {@link AddSegmentBySegmentValue}. * * @param DataTable $table * @return int The number of deleted rows. */ public function filter($table) { if (empty($this->report) || !$table->getRowsCount()) { return; } $dimension = $this->report->getDimension(); if (empty($dimension)) { return; } $segments = $dimension->getSegments(); if (empty($segments)) { return; } /** @var \Piwik\Plugin\Segment $segment */ $segment = reset($segments); $segmentName = $segment->getSegment(); foreach ($table->getRows() as $row) { $value = $row->getMetadata('segmentValue'); $filter = $row->getMetadata('segment'); if ($value !== false && $filter === false) { $row->setMetadata('segment', sprintf('%s==%s', $segmentName, urlencode($value))); } } }
public function indexSiteSearch() { $view = new View('@Actions/indexSiteSearch'); $keyword = Report::factory($this->pluginName, 'getSiteSearchKeywords'); $noResult = Report::factory($this->pluginName, 'getSiteSearchNoResultKeywords'); $pageUrls = Report::factory($this->pluginName, 'getPageUrlsFollowingSiteSearch'); $view->keywords = $keyword->render(); $view->noResultKeywords = $noResult->render(); $view->pagesUrlsFollowingSiteSearch = $pageUrls->render(); $categoryTrackingEnabled = Actions::isCustomVariablesPluginsEnabled(); if ($categoryTrackingEnabled) { $categories = Report::factory($this->pluginName, 'getSiteSearchCategories'); $view->categories = $categories->render(); } return $view->render(); }
public function software() { $view = new View('@DevicesDetection/software'); $view->osReport = $this->renderReport('getOsVersions'); $view->browserReport = $this->renderReport('getBrowsers'); $view->browserEngineReport = $this->renderReport('getBrowserEngines'); $isResolutionEnabled = PluginManager::getInstance()->isPluginActivated('Resolution'); if ($isResolutionEnabled) { $view->configurations = $this->renderReport(Report::factory('Resolution', 'getConfiguration')); } $isDevicePluginsEnabled = PluginManager::getInstance()->isPluginActivated('DevicePlugins'); if ($isDevicePluginsEnabled) { $view->browserPlugins = $this->renderReport(Report::factory('DevicePlugins', 'getPlugin')); } return $view->render(); }
/** * Returns the list of metrics (pages, downloads, outlinks) * * @param int $idSite * @param string $period * @param string $date * @param bool|string $segment * @param bool|array $columns * @return DataTable */ public function get($idSite, $period, $date, $segment = false, $columns = false) { Piwik::checkUserHasViewAccess($idSite); $report = Report::factory("Actions", "get"); $archive = Archive::build($idSite, $period, $date, $segment); $requestedColumns = Piwik::getArrayFromApiParameter($columns); $columns = $report->getMetricsRequiredForReport($allColumns = null, $requestedColumns); $inDbColumnNames = array_map(function ($value) { return 'Actions_' . $value; }, $columns); $dataTable = $archive->getDataTableFromNumeric($inDbColumnNames); $dataTable->deleteColumns(array_diff($requestedColumns, $columns)); $newNameMapping = array_combine($inDbColumnNames, $columns); $dataTable->filter('ReplaceColumnNames', array($newNameMapping)); $columnsToShow = $requestedColumns ?: $report->getAllMetrics(); $dataTable->queueFilter('ColumnDelete', array($columnsToRemove = array(), $columnsToShow)); return $dataTable; }
/** * @return Report[] */ private function getReportsToMerge() { $result = array(); foreach (Report::getAllReportClasses() as $reportClass) { if ($reportClass == 'Piwik\\Plugins\\API\\Reports\\Get') { continue; } /** @var Report $report */ $report = new $reportClass(); if ($report->getModule() == 'API' || $report->getAction() != 'get') { continue; } $metrics = $report->getMetrics(); if (!empty($report->parameters) || empty($metrics)) { continue; } $result[] = $report; } return $result; }
protected function makeController($module, $action, &$parameters) { $controllerClassName = $this->getClassNameController($module); // TRY TO FIND ACTION IN CONTROLLER if (class_exists($controllerClassName)) { $class = $this->getClassNameController($module); /** @var $controller Controller */ $controller = new $class(); $controllerAction = $action; if ($controllerAction === false) { $controllerAction = $controller->getDefaultAction(); } if (is_callable(array($controller, $controllerAction))) { return array($controller, $controllerAction); } if ($action === false) { $this->triggerControllerActionNotFoundError($module, $controllerAction); } } // TRY TO FIND ACTION IN WIDGET $widget = Widgets::factory($module, $action); if (!empty($widget)) { $parameters['widgetModule'] = $module; $parameters['widgetMethod'] = $action; return array(new CoreHomeController(), 'renderWidget'); } // TRY TO FIND ACTION IN REPORT $report = Report::factory($module, $action); if (!empty($report)) { $parameters['reportModule'] = $module; $parameters['reportAction'] = $action; return array(new CoreHomeController(), 'renderReportWidget'); } if (!empty($action) && 'menu' === substr($action, 0, 4)) { $reportAction = lcfirst(substr($action, 4)); // menuGetPageUrls => getPageUrls $report = Report::factory($module, $reportAction); if (!empty($report)) { $parameters['reportModule'] = $module; $parameters['reportAction'] = $reportAction; return array(new CoreHomeController(), 'renderReportMenu'); } } $this->triggerControllerActionNotFoundError($module, $action); }
/** * Constructor. Initializes display and request properties to their default values. * Posts the {@hook ViewDataTable.configure} event which plugins can use to configure the * way reports are displayed. */ public function __construct($controllerAction, $apiMethodToRequestDataTable, $overrideParams = array()) { list($controllerName, $controllerAction) = explode('.', $controllerAction); $this->requestConfig = static::getDefaultRequestConfig(); $this->config = static::getDefaultConfig(); $this->config->subtable_controller_action = $controllerAction; $this->config->setController($controllerName, $controllerAction); $this->request = new ViewDataTableRequest($this->requestConfig); $this->requestConfig->idSubtable = Common::getRequestVar('idSubtable', false, 'int'); $this->config->self_url = Request::getBaseReportUrl($controllerName, $controllerAction); $this->requestConfig->apiMethodToRequestDataTable = $apiMethodToRequestDataTable; $report = Report::factory($this->requestConfig->getApiModuleToRequest(), $this->requestConfig->getApiMethodToRequest()); if (!empty($report)) { /** @var Report $report */ $subtable = $report->getActionToLoadSubTables(); if (!empty($subtable)) { $this->config->subtable_controller_action = $subtable; } $this->config->show_goals = $report->hasGoalMetrics(); $relatedReports = $report->getRelatedReports(); if (!empty($relatedReports)) { foreach ($relatedReports as $relatedReport) { $widgetTitle = $relatedReport->getWidgetTitle(); if ($widgetTitle && Common::getRequestVar('widget', 0, 'int')) { $relatedReportName = $widgetTitle; } else { $relatedReportName = $relatedReport->getName(); } $this->config->addRelatedReport($relatedReport->getModule() . '.' . $relatedReport->getAction(), $relatedReportName); } } $metrics = $report->getMetrics(); if (!empty($metrics)) { $this->config->addTranslations($metrics); } $processedMetrics = $report->getProcessedMetrics(); if (!empty($processedMetrics)) { $this->config->addTranslations($processedMetrics); } $report->configureView($this); } /** * Triggered during {@link ViewDataTable} construction. Subscribers should customize * the view based on the report that is being displayed. * * Plugins that define their own reports must subscribe to this event in order to * specify how the Piwik UI should display the report. * * **Example** * * // event handler * public function configureViewDataTable(ViewDataTable $view) * { * switch ($view->requestConfig->apiMethodToRequestDataTable) { * case 'VisitTime.getVisitInformationPerServerTime': * $view->config->enable_sort = true; * $view->requestConfig->filter_limit = 10; * break; * } * } * * @param ViewDataTable $view The instance to configure. */ Piwik::postEvent('ViewDataTable.configure', array($this)); $this->assignRelatedReportsTitle(); $this->config->show_footer_icons = false == $this->requestConfig->idSubtable; // the exclude low population threshold value is sometimes obtained by requesting data. // to avoid issuing unecessary requests when display properties are determined by metadata, // we allow it to be a closure. if (isset($this->requestConfig->filter_excludelowpop_value) && $this->requestConfig->filter_excludelowpop_value instanceof \Closure) { $function = $this->requestConfig->filter_excludelowpop_value; $this->requestConfig->filter_excludelowpop_value = $function(); } $this->overrideViewPropertiesWithParams($overrideParams); $this->overrideViewPropertiesWithQueryParams(); }
public function test_getForDimension_ShouldReturnNullIfReportPluginNotLoaded() { PluginManager::getInstance()->loadPlugins(array()); $report = Report::getForDimension(new Keyword()); $this->assertNull($report); }
/** * Convenience method that creates and renders a ViewDataTable for a API method. * * @param string|\Piwik\Plugin\Report $apiAction The name of the API action (eg, `'getResolution'`) or * an instance of an report. * @param bool $controllerAction The name of the Controller action name that is rendering the report. Defaults * to the `$apiAction`. * @param bool $fetch If `true`, the rendered string is returned, if `false` it is `echo`'d. * @throws \Exception if `$pluginName` is not an existing plugin or if `$apiAction` is not an * existing method of the plugin's API. * @return string|void See `$fetch`. * @api */ protected function renderReport($apiAction, $controllerAction = false) { if (empty($controllerAction) && is_string($apiAction)) { $report = Report::factory($this->pluginName, $apiAction); if (!empty($report)) { $apiAction = $report; } } if ($apiAction instanceof Report) { $this->checkSitePermission(); $apiAction->checkIsEnabled(); return $apiAction->render(); } $pluginName = $this->pluginName; /** @var Proxy $apiProxy */ $apiProxy = Proxy::getInstance(); if (!$apiProxy->isExistingApiAction($pluginName, $apiAction)) { throw new \Exception("Invalid action name '{$apiAction}' for '{$pluginName}' plugin."); } $apiAction = $apiProxy->buildApiActionName($pluginName, $apiAction); if ($controllerAction !== false) { $controllerAction = $pluginName . '.' . $controllerAction; } $view = ViewDataTableFactory::build(null, $apiAction, $controllerAction); $rendered = $view->render(); return $rendered; }
public function getProcessedMetrics() { $metrics = parent::getProcessedMetrics(); $metrics['avg_time_on_site'] = Piwik::translate('General_VisitDuration'); return $metrics; }
private function isAllMetricsReport() { return $this->report->getModule() == 'API' && $this->report->getAction() == 'get'; }
private static function getAllReportsWithGoalMetrics() { $reportsWithGoals = array(); foreach (Report::getAllReports() as $report) { if ($report->hasGoalMetrics()) { $reportsWithGoals[] = array('category' => $report->getCategory(), 'name' => $report->getName(), 'module' => $report->getModule(), 'action' => $report->getAction()); } } /** * Triggered when gathering all reports that contain Goal metrics. The list of reports * will be displayed on the left column of the bottom of every _Goals_ page. * * If plugins define reports that contain goal metrics (such as **conversions** or **revenue**), * they can use this event to make sure their reports can be viewed on Goals pages. * * **Example** * * public function getReportsWithGoalMetrics(&$reports) * { * $reports[] = array( * 'category' => Piwik::translate('MyPlugin_myReportCategory'), * 'name' => Piwik::translate('MyPlugin_myReportDimension'), * 'module' => 'MyPlugin', * 'action' => 'getMyReport' * ); * } * * @param array &$reportsWithGoals The list of arrays describing reports that have Goal metrics. * Each element of this array must be an array with the following * properties: * * - **category**: The report category. This should be a translated string. * - **name**: The report's translated name. * - **module**: The plugin the report is in, eg, `'UserCountry'`. * - **action**: The API method of the report, eg, `'getCountry'`. * @ignore * @deprecated since 2.5.0 */ Piwik::postEvent('Goals.getReportsWithGoalMetrics', array(&$reportsWithGoals)); return $reportsWithGoals; }
private function addVisualizationInfoFromMetricMetadata() { $dataTable = $this->dataTable instanceof DataTable\Map ? $this->dataTable->getFirstRow() : $this->dataTable; $metrics = Report::getMetricsForTable($dataTable, $this->report); // TODO: instead of iterating & calling translate everywhere, maybe we can get all translated names in one place. // may be difficult, though, since translated metrics are specific to the 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(); } } }
public function test_getAllReports_ShouldFindAllAvailableReports() { $this->loadExampleReportPlugin(); $this->loadMorePlugins(); $reports = Report::getAllReports(); $this->assertGreaterThan(20, count($reports)); foreach ($reports as $report) { $this->assertInstanceOf('Piwik\\Plugin\\Report', $report); } }
/** * Returns if the default viewDataTable ID to use is fixed. * * @param Report $report * @return bool */ private static function isDefaultViewTypeForReportFixed($report) { if (!empty($report) && $report->isEnabled()) { return $report->alwaysUseDefaultViewDataTable(); } return false; }
public function getMetrics() { $metrics = parent::getMetrics(); if ($this->scopeOfDimension === CustomDimensions::SCOPE_ACTION) { $metrics['nb_visits'] = Piwik::translate('CustomDimensions_ColumnUniqueActions'); } if (array_key_exists('nb_hits', $metrics)) { $metrics['nb_hits'] = Piwik::translate('General_ColumnNbActions'); } return $metrics; }
/** * @param DataTable $dataTable * @param Report $report * @return Metric[] */ private function getMetricsToFormat(DataTable $dataTable, Report $report = null) { return Report::getMetricsForTable($dataTable, $report, $baseType = 'Piwik\\Plugin\\Metric'); }
public function configureViewDataTable(ViewDataTable $view) { if ($view->requestConfig->getApiModuleToRequest() != 'Events') { return; } // eg. 'Events.getCategory' $apiMethod = $view->requestConfig->getApiMethodToRequest(); $secondaryDimension = $this->getSecondaryDimensionFromRequest(); $view->config->subtable_controller_action = API::getInstance()->getActionToLoadSubtables($apiMethod, $secondaryDimension); if (Common::getRequestVar('pivotBy', false) === false) { $view->config->columns_to_display = array('label', 'nb_events', 'sum_event_value'); } $view->config->show_flatten_table = true; $view->config->show_table_all_columns = false; $view->requestConfig->filter_sort_column = 'nb_events'; $labelTranslation = $this->getColumnTranslation($apiMethod); $view->config->addTranslation('label', $labelTranslation); $view->config->addTranslations($this->getMetricTranslations()); $this->addRelatedReports($view, $secondaryDimension); $this->addTooltipEventValue($view); $subtableReport = Report::factory('Events', $view->config->subtable_controller_action); $view->config->pivot_by_dimension = $subtableReport->getDimension()->getId(); $view->config->pivot_by_column = 'nb_events'; }
/** * Triggers the Menu.Reporting.addItems hook and returns the menu. * * @return Array */ public function getMenu() { if (!$this->menu) { /** * @ignore * @deprecated */ Piwik::postEvent('Menu.Reporting.addItems', array()); foreach (Report::getAllReports() as $report) { if ($report->isEnabled()) { $report->configureReportingMenu($this); } } foreach ($this->getAllMenus() as $menu) { $menu->configureReportingMenu($this); } } return parent::getMenu(); }
/** * Returns true if pivoting by subtable is supported for a report. Will return true if the report * has a subtable dimension and if the subtable dimension is different than the report's dimension. * * @param Report $report * @return bool */ public static function isPivotingReportBySubtableSupported(Report $report) { return self::areDimensionsNotEqualAndNotNull($report->getSubtableDimension(), $report->getDimension()); }
/** * Triggers a hook to ask plugins for available Reports. * Returns metadata information about each report (category, name, dimension, metrics, etc.) * * @param string $idSites Comma separated list of website Ids * @param bool|string $period * @param bool|Date $date * @param bool $hideMetricsDoc * @param bool $showSubtableReports * @return array */ public function getReportMetadata($idSites, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false) { $idSites = Site::getIdSitesFromIdSitesString($idSites); if (!empty($idSites)) { Piwik::checkUserHasViewAccess($idSites); } // as they cache key contains a lot of information there would be an even better cache result by caching parts of // this huge method separately but that makes it also more complicated. leaving it like this for now. $key = $this->buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports); $key = CacheId::pluginAware($key); $cache = PiwikCache::getTransientCache(); if ($cache->contains($key)) { return $cache->fetch($key); } $parameters = array('idSites' => $idSites, 'period' => $period, 'date' => $date); $availableReports = array(); foreach (Report::getAllReports() as $report) { $report->configureReportMetadata($availableReports, $parameters); } /** * Triggered when gathering metadata for all available reports. * * Plugins that define new reports should use this event to make them available in via * the metadata API. By doing so, the report will become available in scheduled reports * as well as in the Piwik Mobile App. In fact, any third party app that uses the metadata * API will automatically have access to the new report. * * @param string &$availableReports The list of available reports. Append to this list * to make a report available. * * Every element of this array must contain the following * information: * * - **category**: A translated string describing the report's category. * - **name**: The translated display title of the report. * - **module**: The plugin of the report. * - **action**: The API method that serves the report. * * The following information is optional: * * - **dimension**: The report's [dimension](/guides/all-about-analytics-data#dimensions) if any. * - **metrics**: An array mapping metric names with their display names. * - **metricsDocumentation**: An array mapping metric names with their * translated documentation. * - **processedMetrics**: The array of metrics in the report that are * calculated using existing metrics. Can be set to * `false` if the report contains no processed * metrics. * - **order**: The order of the report in the list of reports * with the same category. * * @param array $parameters Contains the values of the sites and period we are * getting reports for. Some reports depend on this data. * For example, Goals reports depend on the site IDs being * requested. Contains the following information: * * - **idSites**: The array of site IDs we are getting reports for. * - **period**: The period type, eg, `'day'`, `'week'`, `'month'`, * `'year'`, `'range'`. * - **date**: A string date within the period or a date range, eg, * `'2013-01-01'` or `'2012-01-01,2013-01-01'`. * * TODO: put dimensions section in all about analytics data * @deprecated since 2.5.0 Use Report Classes instead. * @ignore */ Piwik::postEvent('API.getReportMetadata', array(&$availableReports, $parameters)); // TODO we can remove this one once we remove API.getReportMetadata event (except hideMetricsDoc) foreach ($availableReports as &$availableReport) { // can be removed once we remove hook API.getReportMetadata if (!isset($availableReport['metrics'])) { $availableReport['metrics'] = Metrics::getDefaultMetrics(); } // can be removed once we remove hook API.getReportMetadata if (!isset($availableReport['processedMetrics'])) { $availableReport['processedMetrics'] = Metrics::getDefaultProcessedMetrics(); } if ($hideMetricsDoc) { unset($availableReport['metricsDocumentation']); } else { if (!isset($availableReport['metricsDocumentation'])) { // set metric documentation to default if it's not set // can be removed once we remove hook API.getReportMetadata $availableReport['metricsDocumentation'] = Metrics::getDefaultMetricsDocumentation(); } } } /** * Triggered after all available reports are collected. * * This event can be used to modify the report metadata of reports in other plugins. You * could, for example, add custom metrics to every report or remove reports from the list * of available reports. * * @param array &$availableReports List of all report metadata. Read the {@hook API.getReportMetadata} * docs to see what this array contains. * @param array $parameters Contains the values of the sites and period we are * getting reports for. Some report depend on this data. * For example, Goals reports depend on the site IDs being * request. Contains the following information: * * - **idSites**: The array of site IDs we are getting reports for. * - **period**: The period type, eg, `'day'`, `'week'`, `'month'`, * `'year'`, `'range'`. * - **date**: A string date within the period or a date range, eg, * `'2013-01-01'` or `'2012-01-01,2013-01-01'`. */ Piwik::postEvent('API.getReportMetadata.end', array(&$availableReports, $parameters)); // Sort results to ensure consistent order usort($availableReports, array('self', 'sortReports')); $knownMetrics = array_merge(Metrics::getDefaultMetrics(), Metrics::getDefaultProcessedMetrics()); $columnsToKeep = $this->getColumnsToKeep(); $columnsToRemove = $this->getColumnsToRemove(); foreach ($availableReports as &$availableReport) { // Ensure all metrics have a translation $metrics = $availableReport['metrics']; $cleanedMetrics = array(); // TODO we can remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility foreach ($metrics as $metricId => $metricTranslation) { // When simply the column name was given, ie 'metric' => array( 'nb_visits' ) // $metricTranslation is in this case nb_visits. We look for a known translation. if (is_numeric($metricId) && isset($knownMetrics[$metricTranslation])) { $metricId = $metricTranslation; $metricTranslation = $knownMetrics[$metricTranslation]; } $cleanedMetrics[$metricId] = $metricTranslation; } $availableReport['metrics'] = $cleanedMetrics; // if hide/show columns specified, hide/show metrics & docs $availableReport['metrics'] = $this->hideShowMetricsWithParams($availableReport['metrics'], $columnsToRemove, $columnsToKeep); if (isset($availableReport['processedMetrics'])) { $availableReport['processedMetrics'] = $this->hideShowMetricsWithParams($availableReport['processedMetrics'], $columnsToRemove, $columnsToKeep); } if (isset($availableReport['metricsDocumentation'])) { $availableReport['metricsDocumentation'] = $this->hideShowMetricsWithParams($availableReport['metricsDocumentation'], $columnsToRemove, $columnsToKeep); } // Remove array elements that are false (to clean up API output) foreach ($availableReport as $attributeName => $attributeValue) { if (empty($attributeValue)) { unset($availableReport[$attributeName]); } } // when there are per goal metrics, don't display conversion_rate since it can differ from per goal sum // TODO we should remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility if (isset($availableReport['metricsGoal'])) { unset($availableReport['processedMetrics']['conversion_rate']); unset($availableReport['metricsGoal']['conversion_rate']); } // Processing a uniqueId for each report, // can be used by UIs as a key to match a given report $uniqueId = $availableReport['module'] . '_' . $availableReport['action']; if (!empty($availableReport['parameters'])) { foreach ($availableReport['parameters'] as $key => $value) { $uniqueId .= '_' . $key . '--' . $value; } } $availableReport['uniqueId'] = $uniqueId; // Order is used to order reports internally, but not meant to be used outside unset($availableReport['order']); } // remove subtable reports if (!$showSubtableReports) { foreach ($availableReports as $idx => $report) { if (isset($report['isSubtableReport']) && $report['isSubtableReport']) { unset($availableReports[$idx]); } } } $actualReports = array_values($availableReports); $cache->save($key, $actualReports); return $actualReports; // make sure array has contiguous key values }