Esempio n. 1
0
 /**
  * @param string $period
  * @param string $date
  * @param string|false $segment
  */
 public function __construct($period, $date, $segment)
 {
     $sites = API::getInstance()->getAll($period, $date, $segment, $_restrictSitesToLogin = false, $enhanced = true, $searchTerm = false, $this->displayedMetricColumns);
     $sites->deleteRow(DataTable::ID_SUMMARY_ROW);
     /** @var DataTable $pastData */
     $pastData = $sites->getMetadata('pastData');
     $sites->filter(function (DataTable $table) use($pastData) {
         $pastRow = null;
         foreach ($table->getRows() as $row) {
             $idSite = $row->getColumn('label');
             $site = Site::getSite($idSite);
             // we cannot queue label and group as we might need them for search and sorting!
             $row->setColumn('label', $site['name']);
             $row->setMetadata('group', $site['group']);
             if ($pastData) {
                 // if we do not update the pastData labels, the evolution cannot be calculated correctly.
                 $pastRow = $pastData->getRowFromLabel($idSite);
                 if ($pastRow) {
                     $pastRow->setColumn('label', $site['name']);
                 }
             }
         }
         if ($pastData && $pastRow) {
             $pastData->setLabelsHaveChanged();
         }
     });
     $this->setSitesTable($sites);
 }
Esempio n. 2
0
 /**
  * Testing that getOne returns a row even when there are no data
  * This is necessary otherwise ResponseBuilder throws 'Call to a member function getColumns() on a non-object'
  *
  * @group Plugins
  */
 public function testWhenNoDataGetOneReturnsRow()
 {
     $dataTable = APIMultiSites::getInstance()->getOne($this->idSiteAccess, 'month', '01-01-2010');
     $this->assertEquals(1, $dataTable->getRowsCount());
     // safety net
     $this->assertEquals(0, $dataTable->getFirstRow()->getColumn('nb_visits'));
 }
 /**
  * @group        Benchmarks
  */
 public function testArchivingProcess()
 {
     if ($this->archivingLaunched) {
         echo "NOTE: Had to archive data, memory results will not be accurate. Run again for better results.";
     }
     Rules::$archivingDisabledByTests = true;
     APIMultiSites::getInstance()->getAll(self::$fixture->period, self::$fixture->date);
 }
Esempio n. 4
0
 protected function init()
 {
     $this->category = 'General_MultiSitesSummary';
     $metadataMetrics = array();
     foreach (API::getApiMetrics($enhanced = true) as $metricName => $metricSettings) {
         $metadataMetrics[$metricName] = Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]);
         $metadataMetrics[$metricSettings[API::METRIC_EVOLUTION_COL_NAME_KEY]] = Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]) . " " . Piwik::translate('MultiSites_Evolution');
     }
     $this->metrics = array_keys($metadataMetrics);
 }
Esempio n. 5
0
 public function getReportMetadata(&$reports)
 {
     $metadataMetrics = array();
     foreach (API::getApiMetrics($enhanced = true) as $metricName => $metricSettings) {
         $metadataMetrics[$metricName] = Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]);
         $metadataMetrics[$metricSettings[API::METRIC_EVOLUTION_COL_NAME_KEY]] = Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]) . " " . Piwik::translate('MultiSites_Evolution');
     }
     $reports[] = array('category' => Piwik::translate('General_MultiSitesSummary'), 'name' => Piwik::translate('General_AllWebsitesDashboard'), 'module' => 'MultiSites', 'action' => 'getAll', 'dimension' => Piwik::translate('General_Website'), 'metrics' => $metadataMetrics, 'processedMetrics' => false, 'constantRowsCount' => false, 'order' => 5);
     $reports[] = array('category' => Piwik::translate('General_MultiSitesSummary'), 'name' => Piwik::translate('General_SingleWebsitesDashboard'), 'module' => 'MultiSites', 'action' => 'getOne', 'dimension' => Piwik::translate('General_Website'), 'metrics' => $metadataMetrics, 'processedMetrics' => false, 'constantRowsCount' => false, 'order' => 5);
 }
Esempio n. 6
0
 public function renderReport($processedReport)
 {
     $isGoalPluginEnabled = Common::isGoalPluginEnabled();
     $prettyDate = $processedReport['prettyDate'];
     $reportData = $processedReport['reportData'];
     $evolutionMetrics = array();
     $multiSitesAPIMetrics = API::getApiMetrics($enhanced = true);
     foreach ($multiSitesAPIMetrics as $metricSettings) {
         $evolutionMetrics[] = $metricSettings[API::METRIC_EVOLUTION_COL_NAME_KEY];
     }
     $floatRegex = self::FLOAT_REGEXP;
     // no decimal for all metrics to shorten SMS content (keeps the monetary sign for revenue metrics)
     $reportData->filter('ColumnCallbackReplace', array(array_merge(array_keys($multiSitesAPIMetrics), $evolutionMetrics), function ($value) use($floatRegex) {
         return preg_replace_callback($floatRegex, function ($matches) {
             return round($matches[0]);
         }, $value);
     }));
     // evolution metrics formatting :
     //  - remove monetary, percentage and white spaces to shorten SMS content
     //    (this is also needed to be able to test $value != 0 and see if there is an evolution at all in SMSReport.twig)
     //  - adds a plus sign
     $reportData->filter('ColumnCallbackReplace', array($evolutionMetrics, function ($value) use($floatRegex) {
         $matched = preg_match($floatRegex, $value, $matches);
         $formatted = $matched ? sprintf("%+d", $matches[0]) : $value;
         return \Piwik\NumberFormatter::getInstance()->formatPercentEvolution($formatted);
     }));
     $dataRows = $reportData->getRows();
     $reportMetadata = $processedReport['reportMetadata'];
     $reportRowsMetadata = $reportMetadata->getRows();
     $siteHasECommerce = array();
     foreach ($reportRowsMetadata as $rowMetadata) {
         $idSite = $rowMetadata->getColumn('idsite');
         $siteHasECommerce[$idSite] = Site::isEcommerceEnabledFor($idSite);
     }
     $view = new View('@MobileMessaging/SMSReport');
     $view->assign("isGoalPluginEnabled", $isGoalPluginEnabled);
     $view->assign("reportRows", $dataRows);
     $view->assign("reportRowsMetadata", $reportRowsMetadata);
     $view->assign("prettyDate", $prettyDate);
     $view->assign("siteHasECommerce", $siteHasECommerce);
     $view->assign("displaySiteName", $processedReport['metadata']['action'] == 'getAll');
     // segment
     $segment = $processedReport['segment'];
     $displaySegment = $segment != null;
     $view->assign("displaySegment", $displaySegment);
     if ($displaySegment) {
         $view->assign("segmentName", $segment['name']);
     }
     $this->rendering .= $view->render();
 }
Esempio n. 7
0
 public function processReports(&$processedReports, $reportType, $outputType, $report)
 {
     if (!self::manageEvent($reportType)) {
         return;
     }
     $displayFormat = $report['parameters'][self::DISPLAY_FORMAT_PARAMETER];
     $evolutionGraph = $report['parameters'][self::EVOLUTION_GRAPH_PARAMETER];
     foreach ($processedReports as &$processedReport) {
         $metadata = $processedReport['metadata'];
         $isAggregateReport = !empty($metadata['dimension']);
         $processedReport['displayTable'] = $displayFormat != self::DISPLAY_FORMAT_GRAPHS_ONLY;
         $processedReport['displayGraph'] = ($isAggregateReport ? $displayFormat == self::DISPLAY_FORMAT_GRAPHS_ONLY || $displayFormat == self::DISPLAY_FORMAT_TABLES_AND_GRAPHS : $displayFormat != self::DISPLAY_FORMAT_TABLES_ONLY) && \Piwik\SettingsServer::isGdExtensionEnabled() && \Piwik\Plugin\Manager::getInstance()->isPluginActivated('ImageGraph') && !empty($metadata['imageGraphUrl']);
         $processedReport['evolutionGraph'] = $evolutionGraph;
         // remove evolution metrics from MultiSites.getAll
         if ($metadata['module'] == 'MultiSites') {
             $columns = $processedReport['columns'];
             foreach (\Piwik\Plugins\MultiSites\API::getApiMetrics($enhanced = true) as $metricSettings) {
                 unset($columns[$metricSettings[\Piwik\Plugins\MultiSites\API::METRIC_EVOLUTION_COL_NAME_KEY]]);
             }
             $processedReport['metadata'] = $metadata;
             $processedReport['columns'] = $columns;
         }
     }
 }
Esempio n. 8
0
 private function buildDataTable($sitesToProblablyAdd, $period, $date, $segment, $_restrictSitesToLogin, $enhanced, $multipleWebsitesRequested, $showColumns)
 {
     $idSites = array();
     if (!empty($sitesToProblablyAdd)) {
         foreach ($sitesToProblablyAdd as $site) {
             $idSites[] = $site['idsite'];
         }
     }
     // build the archive type used to query archive data
     $archive = Archive::build($idSites, $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) {
         if (!empty($showColumns) && !in_array($metricName, $showColumns)) {
             unset($apiMetrics[$metricName]);
             continue;
         }
         $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;
         }
     }
     $dataTable = $archive->getDataTableFromNumericAndMergeChildren($fieldsToGet);
     $this->populateLabel($dataTable);
     $totalMetrics = $this->preformatApiMetricsForTotalsCalculation($apiMetrics);
     $this->setMetricsTotalsMetadata($dataTable, $totalMetrics);
     // 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($idSites, $period, $strLastDate, $segment, $_restrictSitesToLogin);
         $pastData = $pastArchive->getDataTableFromNumericAndMergeChildren($fieldsToGet);
         $this->populateLabel($pastData);
         // labels are needed to calculate evolution
         $this->calculateEvolutionPercentages($dataTable, $pastData, $apiMetrics);
         $this->setPastTotalVisitsMetadata($dataTable, $pastData);
         if ($dataTable instanceof DataTable) {
             // needed for MultiSites\Dashboard
             $dataTable->setMetadata('pastData', $pastData);
         }
     }
     // move the site id to a metadata column
     $dataTable->queueFilter('MetadataCallbackAddMetadata', array('idsite', 'group', array('\\Piwik\\Site', 'getGroupFor'), array()));
     $dataTable->queueFilter('MetadataCallbackAddMetadata', array('idsite', 'main_url', array('\\Piwik\\Site', 'getMainUrlFor'), array()));
     // set the label of each row to the site name
     if ($multipleWebsitesRequested) {
         $dataTable->queueFilter('ColumnCallbackReplace', array('label', '\\Piwik\\Site::getNameFor'));
     } else {
         $dataTable->queueFilter('ColumnDelete', array('label'));
     }
     // replace record names with user friendly metric names
     $dataTable->queueFilter('ReplaceColumnNames', array($columnNameRewrites));
     // 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;
         }));
     }
     if ($multipleWebsitesRequested && $dataTable->getRowsCount() === 1 && $dataTable instanceof DataTable\Simple) {
         $simpleTable = $dataTable;
         $dataTable = $simpleTable->getEmptyClone();
         $dataTable->addRow($simpleTable->getFirstRow());
         unset($simpleTable);
     }
     return $dataTable;
 }
Esempio n. 9
0
 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;
 }
Esempio n. 10
0
 public function getSitesInfo($isWidgetized = false)
 {
     Piwik::checkUserHasSomeViewAccess();
     $displayRevenueColumn = Common::isGoalPluginEnabled();
     $date = Common::getRequestVar('date', 'today');
     $period = Common::getRequestVar('period', 'day');
     $siteIds = APISitesManager::getInstance()->getSitesIdWithAtLeastViewAccess();
     list($minDate, $maxDate) = Site::getMinMaxDateAcrossWebsites($siteIds);
     // overwrites the default Date set in the parent controller
     // Instead of the default current website's local date,
     // we set "today" or "yesterday" based on the default Piwik timezone
     $piwikDefaultTimezone = APISitesManager::getInstance()->getDefaultTimezone();
     if ($period != 'range') {
         $date = $this->getDateParameterInTimezone($date, $piwikDefaultTimezone);
         $this->setDate($date);
         $date = $date->toString();
     }
     $dataTable = APIMultiSites::getInstance()->getAll($period, $date, $segment = false);
     // put data into a form the template will understand better
     $digestableData = array();
     foreach ($siteIds as $idSite) {
         $isEcommerceEnabled = Site::isEcommerceEnabledFor($idSite);
         $digestableData[$idSite] = array('idsite' => $idSite, 'main_url' => Site::getMainUrlFor($idSite), 'name' => Site::getNameFor($idSite), 'visits' => 0, 'pageviews' => 0);
         if ($period != 'range') {
             $digestableData[$idSite]['visits_evolution'] = 0;
             $digestableData[$idSite]['pageviews_evolution'] = 0;
         }
         if ($displayRevenueColumn) {
             $revenueDefault = $isEcommerceEnabled ? 0 : "'-'";
             if ($period != 'range') {
                 $digestableData[$idSite]['revenue_evolution'] = $revenueDefault;
             }
         }
     }
     foreach ($dataTable->getRows() as $row) {
         $idsite = (int) $row->getMetadata('idsite');
         $site =& $digestableData[$idsite];
         $site['visits'] = (int) $row->getColumn('nb_visits');
         $site['pageviews'] = (int) $row->getColumn('nb_pageviews');
         if ($displayRevenueColumn) {
             if ($row->getColumn('revenue') !== false) {
                 $site['revenue'] = $row->getColumn('revenue');
             }
         }
         if ($period != 'range') {
             $site['visits_evolution'] = $row->getColumn('visits_evolution');
             $site['pageviews_evolution'] = $row->getColumn('pageviews_evolution');
             if ($displayRevenueColumn) {
                 $site['revenue_evolution'] = $row->getColumn('revenue_evolution');
             }
         }
     }
     $this->applyPrettyMoney($digestableData);
     $view = new View("@MultiSites/getSitesInfo");
     $view->isWidgetized = $isWidgetized;
     $view->sitesData = array_values($digestableData);
     $view->evolutionBy = $this->evolutionBy;
     $view->period = $period;
     $view->page = $this->page;
     $view->limit = $this->limit;
     $view->orderBy = $this->orderBy;
     $view->order = $this->order;
     $view->totalVisits = $dataTable->getMetadata('total_nb_visits');
     $view->totalRevenue = $dataTable->getMetadata('total_revenue');
     $view->displayRevenueColumn = $displayRevenueColumn;
     $view->totalPageviews = $dataTable->getMetadata('total_nb_pageviews');
     $view->pastTotalVisits = $dataTable->getMetadata('last_period_total_nb_visits');
     $view->totalVisitsEvolution = $dataTable->getMetadata('total_visits_evolution');
     if ($view->totalVisitsEvolution > 0) {
         $view->totalVisitsEvolution = '+' . $view->totalVisitsEvolution;
     }
     if ($period != 'range') {
         $lastPeriod = Period::factory($period, $dataTable->getMetadata('last_period_date'));
         $view->pastPeriodPretty = self::getCalendarPrettyDate($lastPeriod);
     }
     $params = $this->getGraphParamsModified();
     $view->dateSparkline = $period == 'range' ? $date : $params['date'];
     $view->autoRefreshTodayReport = false;
     // if the current date is today, or yesterday,
     // in case the website is set to UTC-12), or today in UTC+14, we refresh the page every 5min
     if (in_array($date, array('today', date('Y-m-d'), 'yesterday', Date::factory('yesterday')->toString('Y-m-d'), Date::factory('now', 'UTC+14')->toString('Y-m-d')))) {
         $view->autoRefreshTodayReport = Config::getInstance()->General['multisites_refresh_after_seconds'];
     }
     $this->setGeneralVariablesView($view);
     $this->setMinDateView($minDate, $view);
     $this->setMaxDateView($maxDate, $view);
     $view->show_sparklines = Config::getInstance()->General['show_multisites_sparklines'];
     return $view->render();
 }