/** * @param array $reports * @param array $info * @return mixed */ public function getReportMetadata(&$reports, $info) { $idSites = $info['idSites']; // If only one website is selected, we add the Graph URL if (count($idSites) != 1) { return; } $idSite = reset($idSites); // in case API.getReportMetadata was not called with date/period we use sane defaults if (empty($info['period'])) { $info['period'] = 'day'; } if (empty($info['date'])) { $info['date'] = 'today'; } // need two sets of period & date, one for single period graphs, one for multiple periods graphs if (Period::isMultiplePeriod($info['date'], $info['period'])) { $periodForMultiplePeriodGraph = $info['period']; $dateForMultiplePeriodGraph = $info['date']; $periodForSinglePeriodGraph = 'range'; $dateForSinglePeriodGraph = $info['date']; } else { $periodForSinglePeriodGraph = $info['period']; $dateForSinglePeriodGraph = $info['date']; $piwikSite = new Site($idSite); if ($periodForSinglePeriodGraph == 'range') { $periodForMultiplePeriodGraph = Config::getInstance()->General['graphs_default_period_to_plot_when_period_range']; $dateForMultiplePeriodGraph = $dateForSinglePeriodGraph; } else { $periodForMultiplePeriodGraph = $periodForSinglePeriodGraph; $dateForMultiplePeriodGraph = Range::getRelativeToEndDate($periodForSinglePeriodGraph, 'last' . self::GRAPH_EVOLUTION_LAST_PERIODS, $dateForSinglePeriodGraph, $piwikSite); } } $token_auth = Common::getRequestVar('token_auth', false); $urlPrefix = "index.php?"; foreach ($reports as &$report) { $reportModule = $report['module']; $reportAction = $report['action']; $reportUniqueId = $reportModule . '_' . $reportAction; $parameters = array(); $parameters['module'] = 'API'; $parameters['method'] = 'ImageGraph.get'; $parameters['idSite'] = $idSite; $parameters['apiModule'] = $reportModule; $parameters['apiAction'] = $reportAction; if (!empty($token_auth)) { $parameters['token_auth'] = $token_auth; } // Forward custom Report parameters to the graph URL if (!empty($report['parameters'])) { $parameters = array_merge($parameters, $report['parameters']); } if (empty($report['dimension'])) { $parameters['period'] = $periodForMultiplePeriodGraph; $parameters['date'] = $dateForMultiplePeriodGraph; } else { $parameters['period'] = $periodForSinglePeriodGraph; $parameters['date'] = $dateForSinglePeriodGraph; } // add the idSubtable if it exists $idSubtable = Common::getRequestVar('idSubtable', false); if ($idSubtable !== false) { $parameters['idSubtable'] = $idSubtable; } if (!empty($_GET['_restrictSitesToLogin']) && TaskScheduler::isTaskBeingExecuted()) { $parameters['_restrictSitesToLogin'] = $_GET['_restrictSitesToLogin']; } $report['imageGraphUrl'] = $urlPrefix . Url::getQueryStringFromParameters($parameters); // thanks to API.getRowEvolution, reports with dimensions can now be plotted using an evolution graph // however, most reports with a fixed set of dimension values are excluded // this is done so Piwik Mobile and Scheduled Reports do not display them $reportWithDimensionsSupportsEvolution = empty($report['constantRowsCount']) || in_array($reportUniqueId, self::$CONSTANT_ROW_COUNT_REPORT_EXCEPTIONS); $reportSupportsEvolution = !in_array($reportUniqueId, self::$REPORTS_DISABLED_EVOLUTION_GRAPH); if ($reportSupportsEvolution && $reportWithDimensionsSupportsEvolution) { $parameters['period'] = $periodForMultiplePeriodGraph; $parameters['date'] = $dateForMultiplePeriodGraph; $report['imageGraphEvolutionUrl'] = $urlPrefix . Url::getQueryStringFromParameters($parameters); } } }
/** * Returns the list of websites ID with the 'view' or 'admin' access for the current user. * For the superUser it returns all the websites in the database. * * @param bool $_restrictSitesToLogin * @return array list of websites ID */ public function getSitesIdWithAtLeastViewAccess($_restrictSitesToLogin = false) { if (Piwik::hasUserSuperUserAccess() && !TaskScheduler::isTaskBeingExecuted()) { return Access::getInstance()->getSitesIdWithAtLeastViewAccess(); } if (!empty($_restrictSitesToLogin) && (Piwik::hasUserSuperUserAccessOrIsTheUser($_restrictSitesToLogin) || TaskScheduler::isTaskBeingExecuted())) { if (Piwik::hasTheUserSuperUserAccess($_restrictSitesToLogin)) { return Access::getInstance()->getSitesIdWithAtLeastViewAccess(); } $accessRaw = Access::getInstance()->getRawSitesWithSomeViewAccess($_restrictSitesToLogin); $sitesId = array(); foreach ($accessRaw as $access) { $sitesId[] = $access['idsite']; } return $sitesId; } else { return Access::getInstance()->getSitesIdWithAtLeastViewAccess(); } }
private function buildDataTable($idSitesOrIdSite, $period, $date, $segment, $_restrictSitesToLogin, $enhanced, $multipleWebsitesRequested) { $allWebsitesRequested = $idSitesOrIdSite == 'all'; if ($allWebsitesRequested) { // First clear cache Site::clearCache(); // Then, warm the cache with only the data we should have access to if (Piwik::isUserIsSuperUser() && !TaskScheduler::isTaskBeingExecuted()) { $sites = APISitesManager::getInstance()->getAllSites(); } else { $sites = APISitesManager::getInstance()->getSitesWithAtLeastViewAccess($limit = false, $_restrictSitesToLogin); } // Both calls above have called Site::setSitesFromArray. We now get these sites: $sitesToProblablyAdd = Site::getSites(); } else { $sitesToProblablyAdd = array(APISitesManager::getInstance()->getSiteFromId($idSitesOrIdSite)); } // build the archive type used to query archive data $archive = Archive::build($idSitesOrIdSite, $period, $date, $segment, $_restrictSitesToLogin); // determine what data will be displayed $fieldsToGet = array(); $columnNameRewrites = array(); $apiECommerceMetrics = array(); $apiMetrics = API::getApiMetrics($enhanced); foreach ($apiMetrics as $metricName => $metricSettings) { $fieldsToGet[] = $metricSettings[self::METRIC_RECORD_NAME_KEY]; $columnNameRewrites[$metricSettings[self::METRIC_RECORD_NAME_KEY]] = $metricName; if ($metricSettings[self::METRIC_IS_ECOMMERCE_KEY]) { $apiECommerceMetrics[$metricName] = $metricSettings; } } // get the data // $dataTable instanceOf Set $dataTable = $archive->getDataTableFromNumeric($fieldsToGet); $dataTable = $this->mergeDataTableMapAndPopulateLabel($idSitesOrIdSite, $multipleWebsitesRequested, $dataTable); if ($dataTable instanceof DataTable\Map) { foreach ($dataTable->getDataTables() as $table) { $this->addMissingWebsites($table, $fieldsToGet, $sitesToProblablyAdd); } } else { $this->addMissingWebsites($dataTable, $fieldsToGet, $sitesToProblablyAdd); } // calculate total visits/actions/revenue $this->setMetricsTotalsMetadata($dataTable, $apiMetrics); // if the period isn't a range & a lastN/previousN date isn't used, we get the same // data for the last period to show the evolution of visits/actions/revenue list($strLastDate, $lastPeriod) = Range::getLastDate($date, $period); if ($strLastDate !== false) { if ($lastPeriod !== false) { // NOTE: no easy way to set last period date metadata when range of dates is requested. // will be easier if DataTable\Map::metadata is removed, and metadata that is // put there is put directly in DataTable::metadata. $dataTable->setMetadata(self::getLastPeriodMetadataName('date'), $lastPeriod); } $pastArchive = Archive::build($idSitesOrIdSite, $period, $strLastDate, $segment, $_restrictSitesToLogin); $pastData = $pastArchive->getDataTableFromNumeric($fieldsToGet); $pastData = $this->mergeDataTableMapAndPopulateLabel($idSitesOrIdSite, $multipleWebsitesRequested, $pastData); // use past data to calculate evolution percentages $this->calculateEvolutionPercentages($dataTable, $pastData, $apiMetrics); $this->setPastDataMetadata($dataTable, $pastData, $apiMetrics); } // remove eCommerce related metrics on non eCommerce Piwik sites // note: this is not optimal in terms of performance: those metrics should not be retrieved in the first place if ($enhanced) { if ($dataTable instanceof DataTable\Map) { foreach ($dataTable->getDataTables() as $table) { $this->removeEcommerceRelatedMetricsOnNonEcommercePiwikSites($table, $apiECommerceMetrics); } } else { $this->removeEcommerceRelatedMetricsOnNonEcommercePiwikSites($dataTable, $apiECommerceMetrics); } } // move the site id to a metadata column $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'idsite')); // set the label of each row to the site name if ($multipleWebsitesRequested) { $dataTable->filter('ColumnCallbackReplace', array('label', '\\Piwik\\Site::getNameFor')); } else { $dataTable->filter('ColumnDelete', array('label')); } // replace record names with user friendly metric names $dataTable->filter('ReplaceColumnNames', array($columnNameRewrites)); // Ensures data set sorted, for Metadata output $dataTable->filter('Sort', array(self::NB_VISITS_METRIC, 'desc', $naturalSort = false)); // filter rows without visits // note: if only one website is queried and there are no visits, we can not remove the row otherwise // ResponseBuilder throws 'Call to a member function getColumns() on a non-object' if ($multipleWebsitesRequested && !$enhanced) { $dataTable->filter('ColumnCallbackDeleteRow', array(self::NB_VISITS_METRIC, function ($value) { return $value == 0; })); } return $dataTable; }