Ejemplo n.º 1
0
 /**
  * Returns true if it is likely that the data for this report has been purged and if the
  * user should be told about that.
  *
  * In order for this function to return true, the following must also be true:
  * - The data table for this report must either be empty or not have been fetched.
  * - The period of this report is not a multiple period.
  * - The date of this report must be older than the delete_reports_older_than config option.
  * @param  DataTableInterface $dataTable
  * @return bool
  */
 public static function hasReportBeenPurged($dataTable)
 {
     $strPeriod = Common::getRequestVar('period', false);
     $strDate = Common::getRequestVar('date', false);
     if (false !== $strPeriod && false !== $strDate && (is_null($dataTable) || !empty($dataTable) && $dataTable->getRowsCount() == 0)) {
         // if range, only look at the first date
         if ($strPeriod == 'range') {
             $idSite = Common::getRequestVar('idSite', '');
             if (intval($idSite) != 0) {
                 $site = new Site($idSite);
                 $timezone = $site->getTimezone();
             } else {
                 $timezone = 'UTC';
             }
             $period = new Range('range', $strDate, $timezone);
             $reportDate = $period->getDateStart();
         } elseif (Period::isMultiplePeriod($strDate, $strPeriod)) {
             // if a multiple period, this function is irrelevant
             return false;
         } else {
             // otherwise, use the date as given
             $reportDate = Date::factory($strDate);
         }
         $reportYear = $reportDate->toString('Y');
         $reportMonth = $reportDate->toString('m');
         if (static::shouldReportBePurged($reportYear, $reportMonth)) {
             return true;
         }
     }
     return false;
 }
Ejemplo n.º 2
0
 public function getLastDate($date, $period, $comparedToXPeriods)
 {
     $pastDate = Range::getDateXPeriodsAgo(abs($comparedToXPeriods), $date, $period);
     if (empty($pastDate[0])) {
         throw new \Exception('Not possible to compare this date/period combination');
     }
     return $pastDate[0];
 }
Ejemplo n.º 3
0
Archivo: API.php Proyecto: piwik/piwik
 public function getTemperaturesEvolution($date, $period)
 {
     $temperatures = array();
     $date = Date::factory('2013-10-10', 'UTC');
     $period = new Range($period, 'last30');
     $period->setDefaultEndDate($date);
     foreach ($period->getSubperiods() as $subPeriod) {
         if (self::$disableRandomness) {
             $server1 = 50;
             $server2 = 40;
         } else {
             $server1 = mt_rand(50, 90);
             $server2 = mt_rand(40, 110);
         }
         $value = array('server1' => $server1, 'server2' => $server2);
         $temperatures[$subPeriod->getLocalizedShortString()] = $value;
     }
     return DataTable::makeFromIndexedArray($temperatures);
 }
Ejemplo n.º 4
0
 public function index()
 {
     $view = new View('@Referrers/index');
     $view->graphEvolutionReferrers = $this->getEvolutionGraph(Common::REFERRER_TYPE_DIRECT_ENTRY, array(), array('nb_visits'));
     $view->nameGraphEvolutionReferrers = 'Referrers.getEvolutionGraph';
     // building the referrers summary report
     $view->dataTableReferrerType = $this->renderReport(new GetReferrerType());
     $nameValues = $this->getReferrersVisitorsByType();
     $totalVisits = array_sum($nameValues);
     foreach ($nameValues as $name => $value) {
         $view->{$name} = $value;
         // calculate percent of total, if there were any visits
         if ($value != 0 && $totalVisits != 0) {
             $percentName = $name . 'Percent';
             $view->{$percentName} = round($value / $totalVisits * 100, 0);
         }
     }
     // set distinct metrics
     $distinctMetrics = $this->getDistinctReferrersMetrics();
     foreach ($distinctMetrics as $name => $value) {
         $view->{$name} = $value;
     }
     // calculate evolution for visit metrics & distinct metrics
     list($lastPeriodDate, $ignore) = Range::getLastDate();
     if ($lastPeriodDate !== false) {
         $date = Common::getRequestVar('date');
         $period = Common::getRequestVar('period');
         $prettyDate = self::getPrettyDate($date, $period);
         $prettyLastPeriodDate = self::getPrettyDate($lastPeriodDate, $period);
         // visit metrics
         $previousValues = $this->getReferrersVisitorsByType($lastPeriodDate);
         $this->addEvolutionPropertiesToView($view, $prettyDate, $nameValues, $prettyLastPeriodDate, $previousValues);
         // distinct metrics
         $previousValues = $this->getDistinctReferrersMetrics($lastPeriodDate);
         $this->addEvolutionPropertiesToView($view, $prettyDate, $distinctMetrics, $prettyLastPeriodDate, $previousValues);
     }
     // sparkline for the historical data of the above values
     $view->urlSparklineSearchEngines = $this->getReferrerUrlSparkline(Common::REFERRER_TYPE_SEARCH_ENGINE);
     $view->urlSparklineDirectEntry = $this->getReferrerUrlSparkline(Common::REFERRER_TYPE_DIRECT_ENTRY);
     $view->urlSparklineWebsites = $this->getReferrerUrlSparkline(Common::REFERRER_TYPE_WEBSITE);
     $view->urlSparklineCampaigns = $this->getReferrerUrlSparkline(Common::REFERRER_TYPE_CAMPAIGN);
     // sparklines for the evolution of the distinct keywords count/websites count/ etc
     $view->urlSparklineDistinctSearchEngines = $this->getUrlSparkline('getLastDistinctSearchEnginesGraph');
     $view->urlSparklineDistinctKeywords = $this->getUrlSparkline('getLastDistinctKeywordsGraph');
     $view->urlSparklineDistinctWebsites = $this->getUrlSparkline('getLastDistinctWebsitesGraph');
     $view->urlSparklineDistinctCampaigns = $this->getUrlSparkline('getLastDistinctCampaignsGraph');
     $view->totalVisits = $totalVisits;
     $view->referrersReportsByDimension = $this->getReferrersReportsByDimensionView($totalVisits);
     return $view->render();
 }
Ejemplo n.º 5
0
 public function beforeRender()
 {
     if ($this->requestConfig->idSubtable && $this->config->show_embedded_subtable) {
         $this->config->show_visualization_only = true;
     }
     // we do not want to get a datatable\map
     $period = Common::getRequestVar('period', 'day', 'string');
     if (Period\Range::parseDateRange($period)) {
         $period = 'range';
     }
     if ($this->dataTable->getRowsCount()) {
         $request = new ApiRequest(array('method' => 'API.get', 'module' => 'API', 'action' => 'get', 'format' => 'original', 'filter_limit' => '-1', 'disable_generic_filters' => 1, 'expanded' => 0, 'flat' => 0, 'filter_offset' => 0, 'period' => $period, 'showColumns' => implode(',', $this->config->columns_to_display), 'columns' => implode(',', $this->config->columns_to_display), 'pivotBy' => ''));
         $dataTable = $request->process();
         $this->assignTemplateVar('siteSummary', $dataTable);
     }
 }
 private function getOldestDateToProcessForNewSegment(Date $segmentCreatedTime)
 {
     if ($this->processNewSegmentsFrom == self::CREATION_TIME) {
         $this->logger->debug("process_new_segments_from set to segment_creation_time, oldest date to process is {time}", array('time' => $segmentCreatedTime));
         return $segmentCreatedTime;
     } elseif (preg_match("/^last([0-9]+)\$/", $this->processNewSegmentsFrom, $matches)) {
         $lastN = $matches[1];
         list($lastDate, $lastPeriod) = Range::getDateXPeriodsAgo($lastN, $segmentCreatedTime, 'day');
         $result = Date::factory($lastDate);
         $this->logger->debug("process_new_segments_from set to last{N}, oldest date to process is {time}", array('N' => $lastN, 'time' => $result));
         return $result;
     } else {
         $this->logger->debug("process_new_segments_from set to beginning_of_time or cannot recognize value");
         return null;
     }
 }
 public function filter($table)
 {
     foreach ($table->getRows() as $row) {
         $typeReferrer = $row->getColumn('label');
         if ($typeReferrer != Common::REFERRER_TYPE_DIRECT_ENTRY) {
             if (!$this->expanded) {
                 $row->setNonLoadedSubtableId($typeReferrer);
             } else {
                 if (!Range::isMultiplePeriod($this->date, $this->period)) {
                     // otherwise, we have to get the other datatables
                     // NOTE: not yet possible to do this w/ DataTable\Map instances
                     // (actually it would be maybe possible by using $map->mergeChildren() or so build it would be slow)
                     $subtable = API::getInstance()->getReferrerType($this->idSite, $this->period, $this->date, $this->segment, $type = false, $idSubtable = $typeReferrer);
                     if ($this->expanded) {
                         $subtable->applyQueuedFilters();
                     }
                     $row->setSubtable($subtable);
                 }
             }
         }
     }
 }
Ejemplo n.º 8
0
 protected function addFilter_prettyDate()
 {
     $prettyDate = new Twig_SimpleFilter('prettyDate', function ($dateString, $period) {
         return Range::factory($period, $dateString)->getLocalizedShortString();
     });
     $this->twig->addFilter($prettyDate);
 }
Ejemplo n.º 9
0
 /**
  * @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') {
             // for period=range, show the configured sub-periods
             $periodForMultiplePeriodGraph = Config::getInstance()->General['graphs_default_period_to_plot_when_period_range'];
             $dateForMultiplePeriodGraph = $dateForSinglePeriodGraph;
         } else {
             if ($info['period'] == 'day' || !Config::getInstance()->General['graphs_show_evolution_within_selected_period']) {
                 // for period=day, always show the last n days
                 // if graphs_show_evolution_within_selected_period=false, show the last n periods
                 $periodForMultiplePeriodGraph = $periodForSinglePeriodGraph;
                 $dateForMultiplePeriodGraph = Range::getRelativeToEndDate($periodForSinglePeriodGraph, 'last' . self::GRAPH_EVOLUTION_LAST_PERIODS, $dateForSinglePeriodGraph, $piwikSite);
             } else {
                 // if graphs_show_evolution_within_selected_period=true, show the days within the period
                 // (except if the period is day, see above)
                 $periodForMultiplePeriodGraph = 'day';
                 $period = PeriodFactory::build($info['period'], $info['date']);
                 $start = $period->getDateStart()->toString();
                 $end = $period->getDateEnd()->toString();
                 $dateForMultiplePeriodGraph = $start . ',' . $end;
             }
         }
     }
     $token_auth = Common::getRequestVar('token_auth', false);
     $segment = Request::getRawSegmentFromRequest();
     /** @var Scheduler $scheduler */
     $scheduler = StaticContainer::getContainer()->get('Piwik\\Scheduler\\Scheduler');
     $isRunningTask = $scheduler->isRunningTask();
     // add the idSubtable if it exists
     $idSubtable = Common::getRequestVar('idSubtable', 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;
         }
         if ($idSubtable !== false) {
             $parameters['idSubtable'] = $idSubtable;
         }
         if (!empty($_GET['_restrictSitesToLogin']) && $isRunningTask) {
             $parameters['_restrictSitesToLogin'] = $_GET['_restrictSitesToLogin'];
         }
         if (!empty($segment)) {
             $parameters['segment'] = $segment;
         }
         $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);
         }
     }
 }
Ejemplo n.º 10
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;
 }
Ejemplo n.º 11
0
 /**
  * Assigns variables to {@link Piwik\View} instances that display an entire page.
  *
  * The following variables assigned:
  *
  * **date** - The value of the **date** query parameter.
  * **idSite** - The value of the **idSite** query parameter.
  * **rawDate** - The value of the **date** query parameter.
  * **prettyDate** - A pretty string description of the current period.
  * **siteName** - The current site's name.
  * **siteMainUrl** - The URL of the current site.
  * **startDate** - The start date of the current period. A {@link Piwik\Date} instance.
  * **endDate** - The end date of the current period. A {@link Piwik\Date} instance.
  * **language** - The current language's language code.
  * **config_action_url_category_delimiter** - The value of the `[General] action_url_category_delimiter`
  *                                            INI config option.
  * **topMenu** - The result of `MenuTop::getInstance()->getMenu()`.
  *
  * As well as the variables set by {@link setPeriodVariablesView()}.
  *
  * Will exit on error.
  *
  * @param View $view
  * @return void
  * @api
  */
 protected function setGeneralVariablesView($view)
 {
     $view->idSite = $this->idSite;
     $this->checkSitePermission();
     $this->setPeriodVariablesView($view);
     $view->siteName = $this->site->getName();
     $view->siteMainUrl = $this->site->getMainUrl();
     $siteTimezone = $this->site->getTimezone();
     $datetimeMinDate = $this->site->getCreationDate()->getDatetime();
     $minDate = Date::factory($datetimeMinDate, $siteTimezone);
     $this->setMinDateView($minDate, $view);
     $maxDate = Date::factory('now', $siteTimezone);
     $this->setMaxDateView($maxDate, $view);
     $rawDate = Common::getRequestVar('date');
     Period::checkDateFormat($rawDate);
     $periodStr = Common::getRequestVar('period');
     if ($periodStr != 'range') {
         $date = Date::factory($this->strDate);
         $validDate = $this->getValidDate($date, $minDate, $maxDate);
         $period = Period\Factory::build($periodStr, $validDate);
         if ($date->toString() !== $validDate->toString()) {
             // we to not always change date since it could convert a strDate "today" to "YYYY-MM-DD"
             // only change $this->strDate if it was not valid before
             $this->setDate($validDate);
         }
     } else {
         $period = new Range($periodStr, $rawDate, $siteTimezone);
     }
     // Setting current period start & end dates, for pre-setting the calendar when "Date Range" is selected
     $dateStart = $period->getDateStart();
     $dateStart = $this->getValidDate($dateStart, $minDate, $maxDate);
     $dateEnd = $period->getDateEnd();
     $dateEnd = $this->getValidDate($dateEnd, $minDate, $maxDate);
     if ($periodStr == 'range') {
         // make sure we actually display the correct calendar pretty date
         $newRawDate = $dateStart->toString() . ',' . $dateEnd->toString();
         $period = new Range($periodStr, $newRawDate, $siteTimezone);
     }
     $view->date = $this->strDate;
     $view->prettyDate = self::getCalendarPrettyDate($period);
     $view->prettyDateLong = $period->getLocalizedLongString();
     $view->rawDate = $rawDate;
     $view->startDate = $dateStart;
     $view->endDate = $dateEnd;
     $language = LanguagesManager::getLanguageForSession();
     $view->language = !empty($language) ? $language : LanguagesManager::getLanguageCodeForCurrentUser();
     $this->setBasicVariablesView($view);
     $view->topMenu = MenuTop::getInstance()->getMenu();
     $view->adminMenu = MenuAdmin::getInstance()->getMenu();
     $notifications = $view->notifications;
     if (empty($notifications)) {
         $view->notifications = NotificationManager::getAllNotificationsToDisplay();
         NotificationManager::cancelAllNonPersistent();
     }
 }
Ejemplo n.º 12
0
 /**
  * Returns a date range string given a period type, end date and number of periods
  * the range spans over.
  *
  * @param string $period The sub period type, `'day'`, `'week'`, `'month'` and `'year'`.
  * @param int $lastN The number of periods of type `$period` that the result range should
  *                   span.
  * @param string $endDate The desired end date of the range.
  * @param Site $site The site whose timezone should be used.
  * @return string The date range string, eg, `'2012-01-02,2013-01-02'`.
  * @api
  */
 public static function getRelativeToEndDate($period, $lastN, $endDate, $site)
 {
     $last30Relative = new Range($period, $lastN, $site->getTimezone());
     $last30Relative->setDefaultEndDate(Date::factory($endDate));
     $date = $last30Relative->getDateStart()->toString() . "," . $last30Relative->getDateEnd()->toString();
     return $date;
 }
Ejemplo n.º 13
0
 /**
  * @param string $whereClause
  * @param array $bindIdSites
  * @param $idSite
  * @param $period
  * @param $date
  * @param $visitorId
  * @param $minTimestamp
  * @return array
  * @throws Exception
  */
 private function getWhereClauseAndBind($whereClause, $bindIdSites, $idSite, $period, $date, $visitorId, $minTimestamp)
 {
     $where = array();
     $where[] = $whereClause;
     $whereBind = $bindIdSites;
     if (!empty($visitorId)) {
         $where[] = "log_visit.idvisitor = ? ";
         $whereBind[] = @Common::hex2bin($visitorId);
     }
     if (!empty($minTimestamp)) {
         $where[] = "log_visit.visit_last_action_time > ? ";
         $whereBind[] = date("Y-m-d H:i:s", $minTimestamp);
     }
     // SQL Filter with provided period
     if (!empty($period) && !empty($date)) {
         $currentSite = $this->makeSite($idSite);
         $currentTimezone = $currentSite->getTimezone();
         $dateString = $date;
         if ($period == 'range') {
             $processedPeriod = new Range('range', $date);
             if ($parsedDate = Range::parseDateRange($date)) {
                 $dateString = $parsedDate[2];
             }
         } else {
             $processedDate = Date::factory($date);
             $processedPeriod = Period\Factory::build($period, $processedDate);
         }
         $dateStart = $processedPeriod->getDateStart()->setTimezone($currentTimezone);
         $where[] = "log_visit.visit_last_action_time >= ?";
         $whereBind[] = $dateStart->toString('Y-m-d H:i:s');
         if (!in_array($date, array('now', 'today', 'yesterdaySameTime')) && strpos($date, 'last') === false && strpos($date, 'previous') === false && Date::factory($dateString)->toString('Y-m-d') != Date::factory('now', $currentTimezone)->toString()) {
             $dateEnd = $processedPeriod->getDateEnd()->setTimezone($currentTimezone);
             $where[] = " log_visit.visit_last_action_time <= ?";
             $dateEndString = $dateEnd->addDay(1)->toString('Y-m-d H:i:s');
             $whereBind[] = $dateEndString;
         }
     }
     if (count($where) > 0) {
         $where = join("\n\t\t\t\tAND ", $where);
     } else {
         $where = false;
     }
     return array($whereBind, $where);
 }
Ejemplo n.º 14
0
 /**
  * @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);
         }
     }
 }
Ejemplo n.º 15
0
 /**
  * Returns true if `$dateString` and `$period` represent multiple periods.
  * 
  * Will return true for date/period combinations where date references multiple
  * dates and period is not `'range'`. For example, will return true for:
  * 
  * - **date** = `2012-01-01,2012-02-01` and **period** = `'day'`
  * - **date** = `2012-01-01,2012-02-01` and **period** = `'week'`
  * - **date** = `last7` and **period** = `'month'`
  * 
  * etc.
  * 
  * @static
  * @param  $dateString The **date** query parameter value.
  * @param  $period The **period** query parameter value.
  * @return boolean
  */
 public static function isMultiplePeriod($dateString, $period)
 {
     return is_string($dateString) && (preg_match('/^(last|previous){1}([0-9]*)$/D', $dateString, $regs) || Range::parseDateRange($dateString)) && $period != 'range';
 }
Ejemplo n.º 16
0
 /**
  * @deprecated
  */
 public function getLastDate($date, $period)
 {
     $lastDate = Range::getLastDate($date, $period);
     return array_shift($lastDate);
 }
 private function getOldestDateToProcessForNewSegment($idSite, $segment)
 {
     /**
      * @var Date $segmentCreatedTime
      * @var Date $segmentLastEditedTime
      */
     list($segmentCreatedTime, $segmentLastEditedTime) = $this->getCreatedTimeOfSegment($idSite, $segment);
     if ($this->processNewSegmentsFrom == self::CREATION_TIME) {
         $this->logger->debug("process_new_segments_from set to segment_creation_time, oldest date to process is {time}", array('time' => $segmentCreatedTime));
         return $segmentCreatedTime;
     } elseif ($this->processNewSegmentsFrom == self::LAST_EDIT_TIME) {
         $this->logger->debug("process_new_segments_from set to segment_last_edit_time, segment last edit time is {time}", array('time' => $segmentLastEditedTime));
         if ($segmentLastEditedTime === null || $segmentLastEditedTime->getTimestamp() < $segmentCreatedTime->getTimestamp()) {
             $this->logger->debug("segment last edit time is older than created time, using created time instead");
             $segmentLastEditedTime = $segmentCreatedTime;
         }
         return $segmentLastEditedTime;
     } elseif (preg_match("/^last([0-9]+)\$/", $this->processNewSegmentsFrom, $matches)) {
         $lastN = $matches[1];
         list($lastDate, $lastPeriod) = Range::getDateXPeriodsAgo($lastN, $segmentCreatedTime, 'day');
         $result = Date::factory($lastDate);
         $this->logger->debug("process_new_segments_from set to last{N}, oldest date to process is {time}", array('N' => $lastN, 'time' => $result));
         return $result;
     } else {
         $this->logger->debug("process_new_segments_from set to beginning_of_time or cannot recognize value");
         return null;
     }
 }
Ejemplo n.º 18
0
 private function loadLastVisitorDetailsFromDatabase($idSite, $period, $date, $segment = false, $countVisitorsToFetch = 100, $visitorId = false, $minTimestamp = false, $filterSortOrder = false)
 {
     $where = $whereBind = array();
     list($whereClause, $idSites) = $this->getIdSitesWhereClause($idSite);
     $where[] = $whereClause;
     $whereBind = $idSites;
     if (strtolower($filterSortOrder) !== 'asc') {
         $filterSortOrder = 'DESC';
     }
     $orderBy = "idsite, visit_last_action_time " . $filterSortOrder;
     $orderByParent = "sub.visit_last_action_time " . $filterSortOrder;
     if (!empty($visitorId)) {
         $where[] = "log_visit.idvisitor = ? ";
         $whereBind[] = @Common::hex2bin($visitorId);
     }
     if (!empty($minTimestamp)) {
         $where[] = "log_visit.visit_last_action_time > ? ";
         $whereBind[] = date("Y-m-d H:i:s", $minTimestamp);
     }
     // If no other filter, only look at the last 24 hours of stats
     if (empty($visitorId) && empty($countVisitorsToFetch) && empty($period) && empty($date)) {
         $period = 'day';
         $date = 'yesterdaySameTime';
     }
     // SQL Filter with provided period
     if (!empty($period) && !empty($date)) {
         $currentSite = new Site($idSite);
         $currentTimezone = $currentSite->getTimezone();
         $dateString = $date;
         if ($period == 'range') {
             $processedPeriod = new Range('range', $date);
             if ($parsedDate = Range::parseDateRange($date)) {
                 $dateString = $parsedDate[2];
             }
         } else {
             $processedDate = Date::factory($date);
             if ($date == 'today' || $date == 'now' || $processedDate->toString() == Date::factory('now', $currentTimezone)->toString()) {
                 $processedDate = $processedDate->subDay(1);
             }
             $processedPeriod = Period\Factory::build($period, $processedDate);
         }
         $dateStart = $processedPeriod->getDateStart()->setTimezone($currentTimezone);
         $where[] = "log_visit.visit_last_action_time >= ?";
         $whereBind[] = $dateStart->toString('Y-m-d H:i:s');
         if (!in_array($date, array('now', 'today', 'yesterdaySameTime')) && strpos($date, 'last') === false && strpos($date, 'previous') === false && Date::factory($dateString)->toString('Y-m-d') != Date::factory('now', $currentTimezone)->toString()) {
             $dateEnd = $processedPeriod->getDateEnd()->setTimezone($currentTimezone);
             $where[] = " log_visit.visit_last_action_time <= ?";
             $dateEndString = $dateEnd->addDay(1)->toString('Y-m-d H:i:s');
             $whereBind[] = $dateEndString;
         }
     }
     if (count($where) > 0) {
         $where = join("\n\t\t\t\tAND ", $where);
     } else {
         $where = false;
     }
     $segment = new Segment($segment, $idSite);
     // Subquery to use the indexes for ORDER BY
     $select = "log_visit.*";
     $from = "log_visit";
     $subQuery = $segment->getSelectQuery($select, $from, $where, $whereBind, $orderBy);
     $sqlLimit = $countVisitorsToFetch >= 1 ? " LIMIT 0, " . (int) $countVisitorsToFetch : "";
     // Group by idvisit so that a visitor converting 2 goals only appears once
     $sql = "\n\t\t\tSELECT sub.* FROM (\n\t\t\t\t" . $subQuery['sql'] . "\n\t\t\t\t{$sqlLimit}\n\t\t\t) AS sub\n\t\t\tGROUP BY sub.idvisit\n\t\t\tORDER BY {$orderByParent}\n\t\t";
     try {
         $data = Db::fetchAll($sql, $subQuery['bind']);
     } catch (Exception $e) {
         echo $e->getMessage();
         exit;
     }
     $dataTable = new DataTable();
     $dataTable->addRowsFromSimpleArray($data);
     // $dataTable->disableFilter('Truncate');
     if (!empty($data[0])) {
         $columnsToNotAggregate = array_map(function () {
             return 'skip';
         }, $data[0]);
         $dataTable->setMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME, $columnsToNotAggregate);
     }
     return $dataTable;
 }
Ejemplo n.º 19
0
 /**
  * @group Core
  *
  *
  * @dataProvider getDataForLastNLimitsTest
  */
 public function testLastNLimits($period, $lastN, $expectedLastN)
 {
     $range = new Range($period, 'last' . $lastN);
     $this->assertEquals($expectedLastN, $range->getNumberOfSubperiods());
 }
Ejemplo n.º 20
0
 /**
  * Returns the entire date range and lastN value for the current request, based on
  * a period type and end date.
  *
  * @param string $period The period type, 'day', 'week', 'month' or 'year'
  * @param string $endDate The end date.
  * @param int|null $defaultLastN The default lastN to use. If null, the result of
  *                               getDefaultLastN is used.
  * @return array An array w/ two elements. The first is a whole date range and the second
  *               is the lastN number used, ie, array('2010-01-01,2012-01-02', 2).
  */
 public static function getDateRangeAndLastN($period, $endDate, $defaultLastN = null)
 {
     if ($defaultLastN === null) {
         $defaultLastN = self::getDefaultLastN($period);
     }
     $lastNParamName = self::getLastNParamName($period);
     $lastN = Common::getRequestVar($lastNParamName, $defaultLastN, 'int');
     $site = new Site(Common::getRequestVar('idSite'));
     $dateRange = Range::getRelativeToEndDate($period, 'last' . $lastN, $endDate, $site);
     return array($dateRange, $lastN);
 }
Ejemplo n.º 21
0
 public function getSparklines()
 {
     $metrics = $this->getReferrersVisitorsByType();
     $distinctMetrics = $this->getDistinctReferrersMetrics();
     $numberFormatter = NumberFormatter::getInstance();
     $totalVisits = array_sum($metrics);
     foreach ($metrics as $name => $value) {
         // calculate percent of total, if there were any visits
         if ($value != 0 && $totalVisits != 0) {
             $percentName = $name . 'Percent';
             $metrics[$percentName] = round($value / $totalVisits * 100, 0);
         }
     }
     // calculate evolution for visit metrics & distinct metrics
     list($lastPeriodDate, $ignore) = Range::getLastDate();
     if ($lastPeriodDate !== false) {
         $date = Common::getRequestVar('date');
         $period = Common::getRequestVar('period');
         $prettyDate = self::getPrettyDate($date, $period);
         $prettyLastPeriodDate = self::getPrettyDate($lastPeriodDate, $period);
         // visit metrics
         $previousValues = $this->getReferrersVisitorsByType($lastPeriodDate);
         $metrics = $this->addEvolutionPropertiesToView($prettyDate, $metrics, $prettyLastPeriodDate, $previousValues);
         // distinct metrics
         $previousValues = $this->getDistinctReferrersMetrics($lastPeriodDate);
         $distinctMetrics = $this->addEvolutionPropertiesToView($prettyDate, $distinctMetrics, $prettyLastPeriodDate, $previousValues);
     }
     /** @var Sparklines $view */
     $view = ViewDataTable\Factory::build(Sparklines::ID, $api = '', $controller = '', $force = true, $loadUserParams = false);
     // DIRECT ENTRY
     $metrics['visitorsFromDirectEntry'] = $numberFormatter->formatNumber($metrics['visitorsFromDirectEntry']);
     $values = array($metrics['visitorsFromDirectEntry']);
     $descriptions = array(Piwik::translate('Referrers_TypeDirectEntries'));
     if (!empty($metrics['visitorsFromDirectEntryPercent'])) {
         $metrics['visitorsFromDirectEntryPercent'] = $numberFormatter->formatPercent($metrics['visitorsFromDirectEntryPercent'], $precision = 1);
         $values[] = $metrics['visitorsFromDirectEntryPercent'];
         $descriptions[] = Piwik::translate('Referrers_XPercentOfVisits');
     }
     $directEntryParams = $this->getReferrerSparklineParams(Common::REFERRER_TYPE_DIRECT_ENTRY);
     $view->config->addSparkline($directEntryParams, $values, $descriptions, @$metrics['visitorsFromDirectEntryEvolution']);
     // WEBSITES
     $metrics['visitorsFromWebsites'] = $numberFormatter->formatNumber($metrics['visitorsFromWebsites']);
     $values = array($metrics['visitorsFromWebsites']);
     $descriptions = array(Piwik::translate('Referrers_TypeWebsites'));
     if (!empty($metrics['visitorsFromWebsitesPercent'])) {
         $metrics['visitorsFromWebsitesPercent'] = $numberFormatter->formatPercent($metrics['visitorsFromWebsitesPercent'], $precision = 1);
         $values[] = $metrics['visitorsFromWebsitesPercent'];
         $descriptions[] = Piwik::translate('Referrers_XPercentOfVisits');
     }
     $searchEngineParams = $this->getReferrerSparklineParams(Common::REFERRER_TYPE_WEBSITE);
     $view->config->addSparkline($searchEngineParams, $values, $descriptions, @$metrics['visitorsFromWebsitesEvolution']);
     // SEARCH ENGINES
     $metrics['visitorsFromSearchEngines'] = $numberFormatter->formatNumber($metrics['visitorsFromSearchEngines']);
     $values = array($metrics['visitorsFromSearchEngines']);
     $descriptions = array(Piwik::translate('Referrers_TypeSearchEngines'));
     if (!empty($metrics['visitorsFromSearchEnginesPercent'])) {
         $metrics['visitorsFromSearchEnginesPercent'] = $numberFormatter->formatPercent($metrics['visitorsFromSearchEnginesPercent'], $precision = 1);
         $values[] = $metrics['visitorsFromSearchEnginesPercent'];
         $descriptions[] = Piwik::translate('Referrers_XPercentOfVisits');
     }
     $searchEngineParams = $this->getReferrerSparklineParams(Common::REFERRER_TYPE_SEARCH_ENGINE);
     $view->config->addSparkline($searchEngineParams, $values, $descriptions, @$metrics['visitorsFromSearchEnginesEvolution']);
     // CAMPAIGNS
     $metrics['visitorsFromCampaigns'] = $numberFormatter->formatNumber($metrics['visitorsFromCampaigns']);
     $values = array($metrics['visitorsFromCampaigns']);
     $descriptions = array(Piwik::translate('Referrers_TypeCampaigns'));
     if (!empty($metrics['visitorsFromCampaignsPercent'])) {
         $metrics['visitorsFromCampaignsPercent'] = $numberFormatter->formatPercent($metrics['visitorsFromCampaignsPercent'], $precision = 1);
         $values[] = $metrics['visitorsFromCampaignsPercent'];
         $descriptions[] = Piwik::translate('Referrers_XPercentOfVisits');
     }
     $searchEngineParams = $this->getReferrerSparklineParams(Common::REFERRER_TYPE_CAMPAIGN);
     $view->config->addSparkline($searchEngineParams, $values, $descriptions, @$metrics['visitorsFromCampaignsEvolution']);
     // DISTINCT SEARCH ENGINES
     $sparklineParams = $this->getDistinctSparklineUrlParams('getLastDistinctSearchEnginesGraph');
     $value = $distinctMetrics['numberDistinctSearchEngines'];
     $value = $numberFormatter->formatNumber($value);
     $description = Piwik::translate('Referrers_DistinctSearchEngines');
     $view->config->addSparkline($sparklineParams, $value, $description, @$distinctMetrics['numberDistinctSearchEnginesEvolution']);
     // DISTINCT WEBSITES
     $sparklineParams = $this->getDistinctSparklineUrlParams('getLastDistinctWebsitesGraph');
     $distinctMetrics['numberDistinctWebsites'] = $numberFormatter->formatNumber($distinctMetrics['numberDistinctWebsites']);
     $distinctMetrics['numberDistinctWebsitesUrls'] = $numberFormatter->formatNumber($distinctMetrics['numberDistinctWebsitesUrls']);
     $values = array($distinctMetrics['numberDistinctWebsites'], $distinctMetrics['numberDistinctWebsitesUrls']);
     $descriptions = array(Piwik::translate('Referrers_DistinctWebsites'), Piwik::translate('Referrers_UsingNDistinctUrls'));
     $view->config->addSparkline($sparklineParams, $values, $descriptions, @$distinctMetrics['numberDistinctWebsitesEvolution']);
     // DISTINCT KEYWORDS
     $sparklineParams = $this->getDistinctSparklineUrlParams('getLastDistinctKeywordsGraph');
     $value = $distinctMetrics['numberDistinctKeywords'];
     $value = $numberFormatter->formatNumber($value);
     $description = Piwik::translate('Referrers_DistinctKeywords');
     $view->config->addSparkline($sparklineParams, $value, $description, @$distinctMetrics['numberDistinctKeywordsEvolution']);
     // DISTINCT CAMPAIGNS
     $sparklineParams = $this->getDistinctSparklineUrlParams('getLastDistinctCampaignsGraph');
     $value = $distinctMetrics['numberDistinctCampaigns'];
     $value = $numberFormatter->formatNumber($value);
     $description = Piwik::translate('Referrers_DistinctCampaigns');
     $view->config->addSparkline($sparklineParams, $value, $description, @$distinctMetrics['numberDistinctCampaignsEvolution']);
     return $view->render();
 }
Ejemplo n.º 22
0
 /**
  * Returns the array of new processed parameters once the parameters are applied.
  * For example: if you set range=last30 and date=2008-03-10,
  *  the date element of the returned array will be "2008-02-10,2008-03-10"
  *
  * Parameters you can set:
  * - range: last30, previous10, etc.
  * - date: YYYY-MM-DD, today, yesterday
  * - period: day, week, month, year
  *
  * @param array $paramsToSet array( 'date' => 'last50', 'viewDataTable' =>'sparkline' )
  * @throws \Piwik\NoAccessException
  * @return array
  */
 protected function getGraphParamsModified($paramsToSet = array())
 {
     if (!isset($paramsToSet['period'])) {
         $period = Common::getRequestVar('period');
     } else {
         $period = $paramsToSet['period'];
     }
     if ($period == 'range') {
         return $paramsToSet;
     }
     if (!isset($paramsToSet['range'])) {
         $range = 'last30';
     } else {
         $range = $paramsToSet['range'];
     }
     if (!isset($paramsToSet['date'])) {
         $endDate = $this->strDate;
     } else {
         $endDate = $paramsToSet['date'];
     }
     if (is_null($this->site)) {
         throw new NoAccessException("Website not initialized, check that you are logged in and/or using the correct token_auth.");
     }
     $paramDate = Range::getRelativeToEndDate($period, $range, $endDate, $this->site);
     $params = array_merge($paramsToSet, array('date' => $paramDate));
     return $params;
 }
Ejemplo n.º 23
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;
 }
Ejemplo n.º 24
0
 /**
  * @link https://github.com/piwik/piwik/pull/7057
  */
 public function testPrevious0_shouldBehaveLikePrevious1()
 {
     $range = new Range('day', 'previous0');
     $expected = new Range('day', 'previous1');
     $this->assertEquals(1, $range->getNumberOfSubperiods());
     $this->assertEquals($expected->getRangeString(), $range->getRangeString());
 }
Ejemplo n.º 25
0
 /**
  * Returns a new Archive instance that will query archive data for the given set of
  * sites and periods, using an optional Segment.
  *
  * This method uses data that is found in query parameters, so the parameters to this
  * function can be string values.
  *
  * If you want to create an Archive instance with an array of Period instances, use
  * {@link Archive::factory()}.
  *
  * @param string|int|array $idSites A single ID (eg, `'1'`), multiple IDs (eg, `'1,2,3'` or `array(1, 2, 3)`),
  *                                  or `'all'`.
  * @param string $period 'day', `'week'`, `'month'`, `'year'` or `'range'`
  * @param Date|string $strDate 'YYYY-MM-DD', magic keywords (ie, 'today'; {@link Date::factory()}
  *                             or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD').
  * @param bool|false|string $segment Segment definition or false if no segment should be used. {@link Piwik\Segment}
  * @param bool|false|string $_restrictSitesToLogin Used only when running as a scheduled task.
  * @return Archive
  */
 public static function build($idSites, $period, $strDate, $segment = false, $_restrictSitesToLogin = false)
 {
     $websiteIds = Site::getIdSitesFromIdSitesString($idSites, $_restrictSitesToLogin);
     if (Period::isMultiplePeriod($strDate, $period)) {
         $oPeriod = new Range($period, $strDate);
         $allPeriods = $oPeriod->getSubperiods();
     } else {
         $timezone = count($websiteIds) == 1 ? Site::getTimezoneFor($websiteIds[0]) : false;
         $oPeriod = Period::makePeriodFromQueryParams($timezone, $period, $strDate);
         $allPeriods = array($oPeriod);
     }
     $segment = new Segment($segment, $websiteIds);
     $idSiteIsAll = $idSites == self::REQUEST_ALL_WEBSITES_FLAG;
     $isMultipleDate = Period::isMultiplePeriod($strDate, $period);
     return Archive::factory($segment, $allPeriods, $websiteIds, $idSiteIsAll, $isMultipleDate);
 }