diff options
36 files changed, 710 insertions, 669 deletions
diff --git a/core/API/DocumentationGenerator.php b/core/API/DocumentationGenerator.php index ff830133e7..34ee2c1034 100644 --- a/core/API/DocumentationGenerator.php +++ b/core/API/DocumentationGenerator.php @@ -127,6 +127,7 @@ class Piwik_API_DocumentationGenerator 'languageCode' => 'fr', 'url' => 'http://forum.piwik.org/', + 'pageUrl' => 'http://forum.piwik.org/', 'apiModule' => 'UserCountry', 'apiAction' => 'getCountry', 'lastMinutes' => '30', diff --git a/core/Archive.php b/core/Archive.php index e1dd558a07..0d343d5bcf 100644 --- a/core/Archive.php +++ b/core/Archive.php @@ -41,6 +41,7 @@ */ class Piwik_Archive { + const FLAG_ALL_WEBSITES_REQUESTED = 'all'; /** * When saving DataTables in the DB, we sometimes replace the columns name by these IDs so we save up lots of bytes * Eg. INDEX_NB_UNIQ_VISITORS is an integer: 4 bytes, but 'nb_uniq_visitors' is 16 bytes at least @@ -277,13 +278,11 @@ class Piwik_Archive private $params; /** - * Constructor. - * * @param Piwik_Archive_Parameters $params * @param bool $forceIndexedBySite Whether to force index the result of a query by site ID. * @param bool $forceIndexedByDate Whether to force index the result of a query by period. */ - public function __construct(Piwik_Archive_Parameters $params, $forceIndexedBySite = false, + protected function __construct(Piwik_Archive_Parameters $params, $forceIndexedBySite = false, $forceIndexedByDate = false) { $this->params = $params; @@ -304,28 +303,28 @@ class Piwik_Archive * @param false|string $_restrictSitesToLogin Used only when running as a scheduled task. * @return Piwik_Archive */ - public static function build($idSite, $period, $strDate, $segment = false, $_restrictSitesToLogin = false) + public static function build($idSites, $period, $strDate, $segment = false, $_restrictSitesToLogin = false) { - $sites = Piwik_Site::getIdSitesFromIdSitesString($idSite, $_restrictSitesToLogin); - - if (self::isMultiplePeriod($strDate, $period)) { + if (Piwik_Period::isMultiplePeriod($strDate, $period)) { $oPeriod = new Piwik_Period_Range($period, $strDate); $allPeriods = $oPeriod->getSubperiods(); } else { - $timezone = count($sites) == 1 ? Piwik_Site::getTimezoneFor($sites[0]) : false; - $oPeriod = Piwik_Archive::makePeriodFromQueryParams($timezone, $period, $strDate); + $timezone = false;//count($sites) == 1 ? Piwik_Site::getTimezoneFor($sites[0]) : false; + $oPeriod = Piwik_Period::makePeriodFromQueryParams($timezone, $period, $strDate); $allPeriods = array($oPeriod); } - $segment = new Piwik_Segment($segment, $sites); - return self::factory($segment, $allPeriods, $sites); + $segment = new Piwik_Segment($segment, $idSites); + return Piwik_Archive::factory($segment, $allPeriods, $idSites, $_restrictSitesToLogin); } - public static function factory(Piwik_Segment $segment, array $periods, array $sites) + public static function factory(Piwik_Segment $segment, array $periods, $idSites, $_restrictSitesToLogin = false) { + $sites = Piwik_Site::getIdSitesFromIdSitesString($idSites, $_restrictSitesToLogin); + $forceIndexedBySite = false; $forceIndexedByDate = false; - - if (count($sites) > 1) { + if ($idSites == self::FLAG_ALL_WEBSITES_REQUESTED + || count($sites) > 1) { $forceIndexedBySite = true; } if (count($periods) > 1) { @@ -340,36 +339,6 @@ class Piwik_Archive return new Piwik_Archive($params, $forceIndexedBySite, $forceIndexedByDate); } - /** - * Creates a period instance using a Piwik_Site instance and two strings describing - * the period & date. - * - * @param string $timezone - * @param string $period The period string: day, week, month, year, range - * @param string $strDate The date or date range string. - * @return Piwik_Period - */ - public static function makePeriodFromQueryParams($timezone, $period, $date) - { - if (empty($timezone)) { - $timezone = 'UTC'; - } - - if ($period == 'range') { - $oPeriod = new Piwik_Period_Range('range', $date, $timezone, Piwik_Date::factory('today', $timezone)); - } else { - if (!($date instanceof Piwik_Date)) { - if ($date == 'now' || $date == 'today') { - $date = date('Y-m-d', Piwik_Date::factory('now', $timezone)->getTimestamp()); - } elseif ($date == 'yesterday' || $date == 'yesterdaySameTime' ) { - $date = date('Y-m-d', Piwik_Date::factory('now', $timezone)->subDay(1)->getTimestamp()); - } - $date = Piwik_Date::factory( $date ); - } - $oPeriod = Piwik_Period::factory($period, $date); - } - return $oPeriod; - } /** * Returns the value of the element $name from the current archive @@ -480,34 +449,6 @@ class Piwik_Archive } /** - * Indicate if $dateString and $period correspond to multiple periods - * - * @static - * @param $dateString - * @param $period - * @return boolean - */ - public static function isMultiplePeriod($dateString, $period) - { - return - is_string($dateString) - && (preg_match('/^(last|previous){1}([0-9]*)$/D', $dateString, $regs) - || Piwik_Period_Range::parseDateRange($dateString)) - && $period != 'range'; - } - - /** - * Indicate if $idSiteString corresponds to multiple sites. - * - * @param string $idSiteString - * @return bool - */ - public static function isMultipleSites($idSiteString) - { - return $idSiteString == 'all' || strpos($idSiteString, ',') !== false; - } - - /** * Returns the list of plugins that archive the given reports. * * @param array $archiveNames @@ -652,7 +593,15 @@ class Piwik_Archive return $idArchivesByMonth; } - + + /** + * @return Piwik_Archive_Parameters + */ + public function getParams() + { + return $this->params; + } + /** * Gets the IDs of the archives we're querying for and stores them in $this->archives. * This function will launch the archiving process for each period/site/plugin if @@ -665,7 +614,7 @@ class Piwik_Archive { $today = Piwik_Date::today(); - // for every individual query permutation, launch the archiving process and get the archive ID + /* @var Piwik_Period $period */ foreach ($this->params->getPeriods() as $period) { $periodStr = $period->getRangeString(); @@ -691,8 +640,12 @@ class Piwik_Archive continue; } - // prepare the ArchiveProcessing instance - $processing = Piwik_ArchiveProcessor::factory($period, $site, $this->params->getSegment()); + + if($period->getLabel() == 'day') { + $processing = new Piwik_ArchiveProcessor_Day($period, $site, $this->params->getSegment()); + } else { + $processing = new Piwik_ArchiveProcessor_Period($period, $site, $this->params->getSegment()); + } // process for each plugin as well foreach ($archiveGroups as $plugin) { @@ -703,14 +656,12 @@ class Piwik_Archive $doneFlag = $this->getDoneStringForPlugin($plugin); $this->initializeArchiveIdCache($doneFlag); - $processing->launchArchiving($plugin); - $idArchive = $processing->getIdArchive(); + $idArchive = $processing->preProcessArchive($plugin); - if ($processing->getNumberOfVisits() == 0) { - continue; + $visits = $processing->getNumberOfVisits(); + if($visits > 0) { + $this->idarchives[$doneFlag][$periodStr][] = $idArchive; } - - $this->idarchives[$doneFlag][$periodStr][] = $idArchive; } } } @@ -847,7 +798,7 @@ class Piwik_Archive private function getArchiveGroupOfPlugin($plugin) { if ($this->getPeriodLabel() != 'range') { - return 'all'; + return 'all';; } return $plugin; diff --git a/core/ArchiveProcessor/Day.php b/core/ArchiveProcessor/Day.php index ccef3d5b2e..cdb501b08b 100644 --- a/core/ArchiveProcessor/Day.php +++ b/core/ArchiveProcessor/Day.php @@ -24,19 +24,16 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor const LOG_VISIT_TABLE = 'log_visit'; const LOG_ACTIONS_TABLE = 'log_link_visit_action'; const LOG_CONVERSION_TABLE = "log_conversion"; - const REVENUE_SUBTOTAL_FIELD = 'revenue_subtotal'; const REVENUE_TAX_FIELD = 'revenue_tax'; const REVENUE_SHIPPING_FIELD = 'revenue_shipping'; const REVENUE_DISCOUNT_FIELD = 'revenue_discount'; const TOTAL_REVENUE_FIELD = 'revenue'; const ITEMS_COUNT_FIELD = "items"; - const CONVERSION_DATETIME_FIELD = "server_time"; const ACTION_DATETIME_FIELD = "server_time"; const VISIT_DATETIME_FIELD = 'visit_last_action_time'; const IDGOAL_FIELD = 'idgoal'; - const FIELDS_SEPARATOR = ", \n\t\t\t"; public function queryActionsByDimension($dimensions, $where = '', $additionalSelects = array(), $metrics = false, $rankingQuery = null, $joinLogActionOnColumn = false) @@ -76,7 +73,7 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor $orderBy = '`' . Piwik_Archive::INDEX_NB_ACTIONS . '` DESC'; } - $query = $this->query($select, $from, $where, $groupBy, $orderBy); + $query = $this->generateQuery($select, $from, $where, $groupBy, $orderBy); if ($rankingQuery !== null) { $sumColumns = array_keys($availableMetrics); @@ -99,18 +96,6 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor ); } - protected function query($select, $from, $where, $groupBy, $orderBy) - { - $bind = $this->getBindDatetimeSite(); - $query = $this->getSegment()->getSelectQuery($select, $from, $where, $bind, $orderBy, $groupBy); - return $query; - } - - protected function getBindDatetimeSite() - { - return array($this->getDateStart()->getDateStartUTC(), $this->getDateEnd()->getDateEndUTC(), $this->getSite()->getId()); - } - /** * @see queryVisitsByDimension() Similar to this function, * but queries metrics for the requested dimensionRecord, @@ -123,7 +108,7 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor */ public function queryConversionsByDimension($dimensions = array(), $where = false, $additionalSelects = array()) { - $dimensions = array_merge( array(self::IDGOAL_FIELD), $dimensions ); + $dimensions = array_merge(array(self::IDGOAL_FIELD), $dimensions); $availableMetrics = $this->getConversionsMetricFields(); $tableName = self::LOG_CONVERSION_TABLE; @@ -132,22 +117,11 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor $from = array($tableName); $where = $this->getWhereStatement($tableName, self::CONVERSION_DATETIME_FIELD, $where); $groupBy = $this->getGroupByStatement($dimensions, $tableName); - $orderBy = false; - $query = $this->query($select, $from, $where, $groupBy, $orderBy); + $orderBy = false; + $query = $this->generateQuery($select, $from, $where, $groupBy, $orderBy); return $this->getDb()->query($query['sql'], $query['bind']); } - protected function getSelectStatement($dimensions, $tableName, $additionalSelects, $availableMetrics, $requestedMetrics = false) - { - $selects = array_merge( - $this->getSelectDimensions($dimensions, $tableName), - $this->getSelectsMetrics($availableMetrics, $requestedMetrics), - !empty($additionalSelects) ? $additionalSelects : array() - ); - $select = implode(self::FIELDS_SEPARATOR, $selects); - return $select; - } - static public function getConversionsMetricFields() { return array( @@ -168,6 +142,129 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor } /** + * @param string $field + * @return string + */ + static public function getSqlRevenue($field) + { + return "ROUND(" . $field . "," . Piwik_Tracker_GoalManager::REVENUE_PRECISION . ")"; + } + + protected function getSelectStatement($dimensions, $tableName, $additionalSelects, $availableMetrics, $requestedMetrics = false) + { + $selects = array_merge( + $this->getSelectDimensions($dimensions, $tableName), + $this->getSelectsMetrics($availableMetrics, $requestedMetrics), + !empty($additionalSelects) ? $additionalSelects : array() + ); + $select = implode(self::FIELDS_SEPARATOR, $selects); + return $select; + } + + protected function getSelectDimensions($dimensions, $tableName, $appendSelectAs = true) + { + foreach ($dimensions as $selectAs => &$field) { + $selectAsString = $field; + if (!is_numeric($selectAs)) { + $selectAsString = $selectAs; + } + if ($selectAsString == $field) { + $field = "$tableName.$field"; + } + if ($appendSelectAs) { + $field = "$field AS $selectAsString"; + } + } + return $dimensions; + } + + protected function getSelectsMetrics($metricsAvailable, $metricsRequested = false) + { + $selects = array(); + foreach ($metricsAvailable as $metricId => $statement) { + if ($this->isMetricRequested($metricId, $metricsRequested)) { + $selects[] = $statement . " as `" . $metricId . "`"; + } + } + return $selects; + } + + /** + * @param $metricId + * @param $metricsRequested + * @return bool + */ + protected function isMetricRequested($metricId, $metricsRequested) + { + return $metricsRequested === false + || in_array($metricId, $metricsRequested); + } + + protected function getWhereStatement($tableName, $datetimeField, $extraWhere = false) + { + $where = "$tableName.$datetimeField >= ? + AND $tableName.$datetimeField <= ? + AND $tableName.idsite = ?"; + if (!empty($extraWhere)) { + $extraWhere = sprintf($extraWhere, $tableName, $tableName); + $where .= ' AND ' . $extraWhere; + } + return $where; + } + + /** + * Returns the actions by the given dimension + * + * - The basic use case is to use $dimensionRecord and optionally $where. + * - If you want to apply a limit and group the others, use $orderBy to sort the way you + * want the limit to be applied and pass a pre-configured instance of Piwik_RankingQuery. + * The ranking query instance has to have a limit and at least one label column. + * See Piwik_RankingQuery::setLimit() and Piwik_RankingQuery::addLabelColumn(). + * If $rankingQuery is set, the return value is the array returned by + * Piwik_RankingQuery::execute(). + * - By default, the method only queries log_link_visit_action. If you need data from + * log_action (e.g. to partition the result from the ranking query into the different + * action types), use $joinLogActionOnColumn and $additionalSelects to join log_action and select + * the column you need from log_action. + * + * + * @param array|string $dimensions the dimensionRecord(s) you're interested in + * @param string $where where clause + * @param bool|string $additionalSelects additional select clause + * @param bool|array $metrics Set this if you want to limit the columns that are returned. + * The possible values in the array are Piwik_Archive::INDEX_*. + * @param Piwik_RankingQuery $rankingQuery pre-configured ranking query instance + * @param bool|string $joinLogActionOnColumn column from log_link_visit_action that + * log_action should be joined on. + * can be an array to join multiple times. + * @internal param bool|string $orderBy order by clause + * @return mixed + */ + protected function getGroupByStatement($dimensions, $tableName) + { + $dimensions = $this->getSelectDimensions($dimensions, $tableName, $appendSelectAs = false); + $groupBy = implode(", ", $dimensions); + return $groupBy; + } + + public function generateQuery($select, $from, $where, $groupBy, $orderBy) + { + $bind = $this->getBindDatetimeSite(); + $query = $this->getSegment()->getSelectQuery($select, $from, $where, $bind, $orderBy, $groupBy); + return $query; + } + + protected function getBindDatetimeSite() + { + return array($this->getDateStart()->getDateStartUTC(), $this->getDateEnd()->getDateEndUTC(), $this->getSite()->getId()); + } + + public function getDb() + { + return Zend_Registry::get('db'); + } + + /** * Returns the ecommerce items * * @param string $field @@ -201,15 +298,6 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor } /** - * @param string $field - * @return string - */ - static public function getSqlRevenue($field) - { - return "ROUND(" . $field . "," . Piwik_Tracker_GoalManager::REVENUE_PRECISION . ")"; - } - - /** * Converts the given array to a datatable * @param array $array * @return Piwik_DataTable @@ -265,10 +353,10 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor */ public function getMetricsForDimension($dimension) { - if(!is_array($dimension)) { + if (!is_array($dimension)) { $dimension = array($dimension); } - if(count($dimension) == 1) { + if (count($dimension) == 1) { $dimension = array("label" => reset($dimension)); } $query = $this->queryVisitsByDimension($dimension); @@ -279,38 +367,17 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor return $metrics; } - - protected function aggregateCoreVisitsMetrics() { $query = $this->queryVisitsByDimension(); $data = $query->fetch(); - if (empty($data[Piwik_Archive::INDEX_NB_VISITS])) { - $this->setNumberOfVisits(false); - } $metrics = $this->convertMetricsIdToName($data); - $this->setNumberOfVisits($metrics['nb_visits'], $metrics['nb_visits_converted']); - $this->insertNumericRecords($metrics); return $metrics; } /** - * @param $data - * @return array - */ - protected function convertMetricsIdToName($data) - { - $metrics = array(); - foreach ($data as $metricId => $value) { - $readableMetric = Piwik_Archive::$mappingFromIdToName[$metricId]; - $metrics[$readableMetric] = $value; - } - return $metrics; - } - - /** * Query visits by dimension * * @param array|string $dimensions Can be a string, eg. "referer_name", will be aliased as 'label' in the returned rows @@ -340,7 +407,7 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor if ($rankingQuery) { $orderBy = '`' . Piwik_Archive::INDEX_NB_VISITS . '` DESC'; } - $query = $this->query($select, $from, $where, $groupBy, $orderBy); + $query = $this->generateQuery($select, $from, $where, $groupBy, $orderBy); if ($rankingQuery) { unset($availableMetrics[Piwik_Archive::INDEX_MAX_ACTIONS]); @@ -371,100 +438,22 @@ class Piwik_ArchiveProcessor_Day extends Piwik_ArchiveProcessor ); } - protected function getWhereStatement($tableName, $datetimeField, $extraWhere = false) - { - $where = "$tableName.$datetimeField >= ? - AND $tableName.$datetimeField <= ? - AND $tableName.idsite = ?"; - if (!empty($extraWhere)) { - $extraWhere = sprintf($extraWhere, $tableName, $tableName); - $where .= ' AND ' . $extraWhere; - } - return $where; - } - - - protected function getSelectsMetrics($metricsAvailable, $metricsRequested = false) - { - $selects = array(); - foreach ($metricsAvailable as $metricId => $statement) { - if ($this->isMetricRequested($metricId, $metricsRequested)) { - $selects[] = $statement . " as `" . $metricId . "`"; - } - } - return $selects; - } - /** - * @param $metricId - * @param $metricsRequested - * @return bool - */ - protected function isMetricRequested($metricId, $metricsRequested) - { - return $metricsRequested === false - || in_array($metricId, $metricsRequested); - } - - /** - * Returns the actions by the given dimension - * - * - The basic use case is to use $dimensionRecord and optionally $where. - * - If you want to apply a limit and group the others, use $orderBy to sort the way you - * want the limit to be applied and pass a pre-configured instance of Piwik_RankingQuery. - * The ranking query instance has to have a limit and at least one label column. - * See Piwik_RankingQuery::setLimit() and Piwik_RankingQuery::addLabelColumn(). - * If $rankingQuery is set, the return value is the array returned by - * Piwik_RankingQuery::execute(). - * - By default, the method only queries log_link_visit_action. If you need data from - * log_action (e.g. to partition the result from the ranking query into the different - * action types), use $joinLogActionOnColumn and $additionalSelects to join log_action and select - * the column you need from log_action. - * - * - * @param array|string $dimensions the dimensionRecord(s) you're interested in - * @param string $where where clause - * @param bool|string $additionalSelects additional select clause - * @param bool|array $metrics Set this if you want to limit the columns that are returned. - * The possible values in the array are Piwik_Archive::INDEX_*. - * @param Piwik_RankingQuery $rankingQuery pre-configured ranking query instance - * @param bool|string $joinLogActionOnColumn column from log_link_visit_action that - * log_action should be joined on. - * can be an array to join multiple times. - * @internal param bool|string $orderBy order by clause - * @return mixed + * @param $data + * @return array */ - protected function getGroupByStatement($dimensions, $tableName) - { - $dimensions = $this->getSelectDimensions($dimensions, $tableName, $appendSelectAs = false); - $groupBy = implode(", ", $dimensions); - return $groupBy; - } - - protected function getSelectDimensions($dimensions, $tableName, $appendSelectAs = true) + protected function convertMetricsIdToName($data) { - foreach ($dimensions as $selectAs => &$field) { - $selectAsString = $field; - if(!is_numeric($selectAs)) { - $selectAsString = $selectAs; - } - if($selectAsString == $field) { - $field = "$tableName.$field"; - } - if($appendSelectAs) { - $field = "$field AS $selectAsString"; - } + $metrics = array(); + foreach ($data as $metricId => $value) { + $readableMetric = Piwik_Archive::$mappingFromIdToName[$metricId]; + $metrics[$readableMetric] = $value; } - return $dimensions; + return $metrics; } protected function compute() { Piwik_PostEvent('ArchiveProcessing_Day.compute', $this); } - - public function getDb() - { - return Zend_Registry::get('db'); - } } diff --git a/core/DataAccess/Archiver.php b/core/DataAccess/Archiver.php index e01605676c..fdcfc83135 100644 --- a/core/DataAccess/Archiver.php +++ b/core/DataAccess/Archiver.php @@ -14,7 +14,7 @@ */ class Piwik_DataAccess_Archiver { - public static function deleteTemporaryLockedArchive($numericTable, $requestedPlugin, $segment, $period, $idArchive) + public static function deletePreviousArchiveStatus($numericTable, $requestedPlugin, $segment, $period, $idArchive) { $done = Piwik_ArchiveProcessor_Rules::getDoneStringFlagFor($segment, $period->getLabel(), $requestedPlugin); Piwik_Query("DELETE FROM " . $numericTable . " @@ -140,7 +140,7 @@ class Piwik_DataAccess_Archiver $firstPeriod = reset($periods); $table = Piwik_Common::prefixTable("archive_numeric_$tableMonth"); - Piwik_TablePartitioning_Monthly::createArchiveTablesIfAbsent($firstPeriod); + Piwik_TablePartitioning_Monthly::createArchiveTablesIfAbsent($firstPeriod->getDateStart()); // if looking for a range archive. NOTE: we assume there's only one period if its a range. $bind = array($firstPeriod->getId()); @@ -211,8 +211,15 @@ class Piwik_DataAccess_Archiver // get data from every table we're querying $rows = array(); foreach ($archiveIds as $period => $ids) { - $tableMonth = $this->getTableMonthFromDateRange($period); - + if(empty($ids)) { + throw new Exception("Unexpected: id archive not found for period '$period' '"); + } + // $period = "2009-01-04,2009-01-04", + $date = substr($period, 0, 10); + $tableMonth = str_replace('-', '_', substr($date, 0, 7) ); + + Piwik_TablePartitioning_Monthly::createArchiveTablesIfAbsent(Piwik_Date::factory($date)); + $table = Piwik_Common::prefixTable($archiveTableType."_".$tableMonth); $sql = sprintf($getValuesSql, $table, implode(',', $ids)); foreach (Piwik_FetchAll($sql, $bind) as $row) { @@ -271,18 +278,7 @@ class Piwik_DataAccess_Archiver } return $result; } - - /** - * Returns the table & month that an archive for a specific date range is stored - * in. - * - * @param string $dateRange eg, "2012-01-01,2012-01-02" - * @return string eg, "2012_01" - */ - private function getTableMonthFromDateRange($dateRange) - { - return str_replace('-', '_', substr($dateRange, 0, 7)); - } + static public function purgeOutdatedArchives($numericTable, $blobTable, $purgeArchivesOlderThan) { diff --git a/core/Period.php b/core/Period.php index b004f1731a..b3cfa25f2a 100644 --- a/core/Period.php +++ b/core/Period.php @@ -84,6 +84,24 @@ abstract class Piwik_Period } } + + /** + * Indicate if $dateString and $period correspond to multiple periods + * + * @static + * @param $dateString + * @param $period + * @return boolean + */ + public static function isMultiplePeriod($dateString, $period) + { + return + is_string($dateString) + && (preg_match('/^(last|previous){1}([0-9]*)$/D', $dateString, $regs) + || Piwik_Period_Range::parseDateRange($dateString)) + && $period != 'range'; + } + /** * The advanced factory method is easier to use from the API than the factory * method above. It doesn't require an instance of Piwik_Date and works for @@ -97,14 +115,45 @@ abstract class Piwik_Period */ static public function advancedFactory($strPeriod, $strDate) { - if (Piwik_Archive::isMultiplePeriod($strDate, $strPeriod) || $strPeriod == 'range') { + if (Piwik_Period::isMultiplePeriod($strDate, $strPeriod) || $strPeriod == 'range') { return new Piwik_Period_Range($strPeriod, $strDate); } - return self::factory($strPeriod, Piwik_Date::factory($strDate)); + return Piwik_Period::factory($strPeriod, Piwik_Date::factory($strDate)); } /** + * Creates a period instance using a Piwik_Site instance and two strings describing + * the period & date. + * + * @param string $timezone + * @param string $period The period string: day, week, month, year, range + * @param string $strDate The date or date range string. + * @return Piwik_Period + */ + public static function makePeriodFromQueryParams($timezone, $period, $date) + { + if (empty($timezone)) { + $timezone = 'UTC'; + } + + if ($period == 'range') { + $oPeriod = new Piwik_Period_Range('range', $date, $timezone, Piwik_Date::factory('today', $timezone)); + } else { + if (!($date instanceof Piwik_Date)) { + if ($date == 'now' || $date == 'today') { + $date = date('Y-m-d', Piwik_Date::factory('now', $timezone)->getTimestamp()); + } elseif ($date == 'yesterday' || $date == 'yesterdaySameTime' ) { + $date = date('Y-m-d', Piwik_Date::factory('now', $timezone)->subDay(1)->getTimestamp()); + } + $date = Piwik_Date::factory( $date ); + } + $oPeriod = Piwik_Period::factory($period, $date); + } + return $oPeriod; + } + + /** * Returns the first day of the period * * @return Piwik_Date First day of the period diff --git a/core/TablePartitioning.php b/core/TablePartitioning.php index d870a27432..7dee00bf9c 100644 --- a/core/TablePartitioning.php +++ b/core/TablePartitioning.php @@ -110,14 +110,13 @@ class Piwik_TablePartitioning_Monthly extends Piwik_TablePartitioning } /** - * Creates archive_blob & archive_numeric tables for a period if they don't - * already exist. + * Creates archive_blob & archive_numeric tables for a period if they don't already exist. * - * @param Piwik_Period $periodInMonth + * @param Piwik_Date */ - public static function createArchiveTablesIfAbsent($periodInMonth) + public static function createArchiveTablesIfAbsent($dateInMonth) { - $timestamp = $periodInMonth->getDateStart()->getTimestamp(); + $timestamp = $dateInMonth->getTimestamp(); self::$blobArchiveTable->setTimestamp($timestamp); self::$blobArchiveTable->getTableName(); diff --git a/core/Tracker.php b/core/Tracker.php index 6524d6a398..6f6e26738d 100644 --- a/core/Tracker.php +++ b/core/Tracker.php @@ -491,7 +491,7 @@ class Piwik_Tracker Piwik_PostEvent('Tracker.getDatabaseConfig', $configDb); - $db = self::factory($configDb); + $db = Piwik_Tracker::factory($configDb); $db->connect(); return $db; @@ -773,7 +773,7 @@ class Piwik_Tracker $pluginsDisabled[] = 'AnonymizeIP'; } - // Disable provider plugin, because it is so slow to do reverse ip lookup in dev environment somehow + // Disable provider plugin, because it is so slow to do many reverse ip lookups self::setPluginsNotToLoad($pluginsDisabled); // we load 'DevicesDetection' in tests only (disabled by default) diff --git a/core/ViewDataTable.php b/core/ViewDataTable.php index 12c48440e9..6df1f552d1 100644 --- a/core/ViewDataTable.php +++ b/core/ViewDataTable.php @@ -1436,7 +1436,7 @@ abstract class Piwik_ViewDataTable $period = new Piwik_Period_Range('range', $strDate, $timezone); $reportDate = $period->getDateStart(); } // if a multiple period, this function is irrelevant - else if (Piwik_Archive::isMultiplePeriod($strDate, $strPeriod)) { + else if (Piwik_Period::isMultiplePeriod($strDate, $strPeriod)) { return false; } // otherwise, use the date as given else { diff --git a/plugins/API/API.php b/plugins/API/API.php index 0fcb1a54b9..e2721119f4 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -1158,7 +1158,7 @@ class Piwik_API_API $period = 'day'; } - if (!Piwik_Archive::isMultiplePeriod($date, $period)) { + if (!Piwik_Period::isMultiplePeriod($date, $period)) { throw new Exception("Row evolutions can not be processed with this combination of \'date\' and \'period\' parameters."); } diff --git a/plugins/Actions/Archiver.php b/plugins/Actions/Archiver.php index d7e8e93b23..d7e69c4eff 100644 --- a/plugins/Actions/Archiver.php +++ b/plugins/Actions/Archiver.php @@ -252,14 +252,9 @@ class Piwik_Actions_Archiver extends Piwik_PluginsArchiver // to the outer select. therefore, $segment needs to know about it. $select = sprintf($select, $sprintfField); - $bind = array($this->getProcessor()->getDateStart()->getDateStartUTC(), - $this->getProcessor()->getDateEnd()->getDateEndUTC(), - $this->getProcessor()->getSite()->getId() - ); // get query with segmentation - $query = $this->getProcessor()->getSegment()->getSelectQuery( - $select, $from, $where, $bind, $orderBy, $groupBy); + $query = $this->getProcessor()->generateQuery($select, $from, $where, $groupBy, $orderBy); // replace the rest of the %s $querySql = str_replace("%s", $sprintfField, $query['sql']); @@ -270,7 +265,7 @@ class Piwik_Actions_Archiver extends Piwik_PluginsArchiver } // get result - $resultSet = $this->getProcessor()->getDb()->query($querySql, $bind); + $resultSet = $this->getProcessor()->getDb()->query($querySql, $query['bind']); $modified = Piwik_Actions_ArchivingHelper::updateActionsTableWithRowQuery($resultSet, $sprintfField, $this->actionsTablesByType); return $modified; } @@ -570,11 +565,12 @@ class Piwik_Actions_Archiver extends Piwik_PluginsArchiver self::OUTLINKS_RECORD_NAME, self::SITE_SEARCH_RECORD_NAME, ); + $aggregation = null; $nameToCount = $this->getProcessor()->aggregateDataTableReports($dataTableToSum, Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation, - $aggregation = null, + $aggregation, self::$invalidSummedColumnNameToRenamedNameFromPeriodArchive); $this->getProcessor()->archiveNumericValuesGeneral(array( diff --git a/plugins/Goals/Archiver.php b/plugins/Goals/Archiver.php index 1946594122..009953f322 100644 --- a/plugins/Goals/Archiver.php +++ b/plugins/Goals/Archiver.php @@ -266,7 +266,6 @@ class Piwik_Goals_Archiver extends Piwik_PluginsArchiver // Per item doesn't support segment // Also, when querying Goal metrics for visitorType==returning, we wouldnt want to trigger an extra request // event if it did support segment - // (when this is implemented, we should have shouldProcessReportsForPlugin() support partial archiving based on which metric is requested) if (!$this->getProcessor()->getSegment()->isEmpty()) { return false; } diff --git a/plugins/ImageGraph/API.php b/plugins/ImageGraph/API.php index d80572bec0..ddc31e56b3 100644 --- a/plugins/ImageGraph/API.php +++ b/plugins/ImageGraph/API.php @@ -169,7 +169,7 @@ class Piwik_ImageGraph_API $reportHasDimension = !empty($metadata['dimension']); $constantRowsCount = !empty($metadata['constantRowsCount']); - $isMultiplePeriod = Piwik_Archive::isMultiplePeriod($date, $period); + $isMultiplePeriod = Piwik_Period::isMultiplePeriod($date, $period); if (!$reportHasDimension && !$isMultiplePeriod) { throw new Exception('The graph cannot be drawn for this combination of \'date\' and \'period\' parameters.'); } diff --git a/plugins/ImageGraph/ImageGraph.php b/plugins/ImageGraph/ImageGraph.php index 4e48e93d1d..06e973f462 100644 --- a/plugins/ImageGraph/ImageGraph.php +++ b/plugins/ImageGraph/ImageGraph.php @@ -69,7 +69,7 @@ class Piwik_ImageGraph extends Piwik_Plugin } // need two sets of period & date, one for single period graphs, one for multiple periods graphs - if (Piwik_Archive::isMultiplePeriod($info['date'], $info['period'])) { + if (Piwik_Period::isMultiplePeriod($info['date'], $info['period'])) { $periodForMultiplePeriodGraph = $info['period']; $dateForMultiplePeriodGraph = $info['date']; diff --git a/plugins/MultiSites/API.php b/plugins/MultiSites/API.php index bf4250ff0e..e9984b99aa 100755 --- a/plugins/MultiSites/API.php +++ b/plugins/MultiSites/API.php @@ -233,9 +233,9 @@ class Piwik_MultiSites_API // data for the last period to show the evolution of visits/actions/revenue list($strLastDate, $lastPeriod) = Piwik_Period_Range::getLastDate($date, $period); if ( - false && - - $strLastDate !== false) { + // FIXMEA broken without this false + false + && $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_Array::metadata is removed, and metadata that is diff --git a/plugins/Transitions/API.php b/plugins/Transitions/API.php index 7e17fa2996..7294a78560 100644 --- a/plugins/Transitions/API.php +++ b/plugins/Transitions/API.php @@ -65,11 +65,11 @@ class Piwik_Transitions_API $segment = new Piwik_Segment($segment, $idSite); $site = new Piwik_Site($idSite); $period = Piwik_Period::advancedFactory($period, $date); - $archiveProcessing = Piwik_ArchiveProcessor::factory($period, $site, $segment); + $archiveProcessing = new Piwik_ArchiveProcessor_Day($period, $site, $segment); // prepare the report $report = array( - 'date' => Piwik_Period_Day::advancedFactory($period, $date)->getLocalizedShortString() + 'date' => Piwik_Period_Day::advancedFactory($period->getLabel(), $date)->getLocalizedShortString() ); // add data to the report @@ -178,7 +178,7 @@ class Piwik_Transitions_API $idaction, $actionType, $limitBeforeGrouping) { - $data = $transitionsArchiving->queryInternalReferrers( + $data = $this->queryInternalReferrers( $idaction, $actionType, $archiveProcessing, $limitBeforeGrouping); if ($data['pageviews'] == 0) { @@ -207,7 +207,7 @@ class Piwik_Transitions_API $idaction, $actionType, $limitBeforeGrouping, $includeLoops = false) { - $data = $transitionsArchiving->queryFollowingActions( + $data = $this->queryFollowingActions( $idaction, $actionType, $archiveProcessing, $limitBeforeGrouping, $includeLoops); foreach ($data as $tableName => $table) { @@ -215,6 +215,335 @@ class Piwik_Transitions_API } } + + + /** + * Get information about the following actions (following pages, site searches, outlinks, downloads) + * + * @param $idaction + * @param $actionType + * @param Piwik_ArchiveProcessor_Day $archiveProcessing + * @param $limitBeforeGrouping + * @param $includeLoops + * @return array(followingPages:Piwik_DataTable, outlinks:Piwik_DataTable, downloads:Piwik_DataTable) + */ + public function queryFollowingActions($idaction, $actionType, Piwik_ArchiveProcessor_Day $archiveProcessing, + $limitBeforeGrouping = false, $includeLoops = false) + { + $types = array(); + + $isTitle = ($actionType == 'title'); + if (!$isTitle) { + // specific setup for page urls + $types[Piwik_Tracker_Action::TYPE_ACTION_URL] = 'followingPages'; + $dimension = 'IF( idaction_url IS NULL, idaction_name, idaction_url )'; + // site search referrers are logged with url=NULL + // when we find one, we have to join on name + $joinLogActionColumn = $dimension; + $selects = array('log_action.name', 'log_action.url_prefix', 'log_action.type'); + } else { + // specific setup for page titles: + $types[Piwik_Tracker_Action::TYPE_ACTION_NAME] = 'followingPages'; + // join log_action on name and url and pick depending on url type + // the table joined on url is log_action1 + $joinLogActionColumn = array('idaction_url', 'idaction_name'); + $dimension = ' + CASE + ' /* following site search */ . ' + WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.idaction + ' /* following page view: use page title */ . ' + WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.idaction + ' /* following download or outlink: use url */ . ' + ELSE log_action1.idaction + END + '; + $selects = array( + 'CASE + ' /* following site search */ . ' + WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.name + ' /* following page view: use page title */ . ' + WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.name + ' /* following download or outlink: use url */ . ' + ELSE log_action1.name + END AS name', + 'CASE + ' /* following site search */ . ' + WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.type + ' /* following page view: use page title */ . ' + WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.type + ' /* following download or outlink: use url */ . ' + ELSE log_action1.type + END AS type', + 'NULL AS url_prefix' + ); + } + + // these types are available for both titles and urls + $types[Piwik_Tracker_Action::TYPE_SITE_SEARCH] = 'followingSiteSearches'; + $types[Piwik_Tracker_Action::TYPE_OUTLINK] = 'outlinks'; + $types[Piwik_Tracker_Action::TYPE_DOWNLOAD] = 'downloads'; + + $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping); + $rankingQuery->addLabelColumn(array('name', 'url_prefix')); + $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($types)); + + $type = $this->getColumnTypeSuffix($actionType); + $where = 'log_link_visit_action.idaction_' . $type . '_ref = ' . intval($idaction); + if (!$includeLoops) { + $where .= ' AND (log_link_visit_action.idaction_' . $type . ' IS NULL OR ' + . 'log_link_visit_action.idaction_' . $type . ' != ' . intval($idaction) . ')'; + } + + $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS); + $data = $archiveProcessing->queryActionsByDimension(array($dimension), $where, $selects, $metrics, $rankingQuery, $joinLogActionColumn); + + $this->totalTransitionsToFollowingActions = 0; + $dataTables = array(); + foreach ($types as $type => $recordName) { + $dataTable = new Piwik_DataTable; + if (isset($data[$type])) { + foreach ($data[$type] as &$record) { + $actions = intval($record[Piwik_Archive::INDEX_NB_ACTIONS]); + $dataTable->addRow(new Piwik_DataTable_Row(array( + Piwik_DataTable_Row::COLUMNS => array( + 'label' => $this->getPageLabel($record, $isTitle), + Piwik_Archive::INDEX_NB_ACTIONS => $actions + ) + ))); + $this->totalTransitionsToFollowingActions += $actions; + } + } + $dataTables[$recordName] = $dataTable; + } + + return $dataTables; + } + + + /** + * After calling this method, the query*()-Methods will return urls in their + * normalized form (without the prefix reconstructed) + */ + public function returnNormalizedUrls() + { + $this->returnNormalizedUrls = true; + } + + /** + * Get information about external referrers (i.e. search engines, websites & campaigns) + * + * @param $idaction + * @param $actionType + * @param Piwik_ArchiveProcessor_Day $archiveProcessing + * @param $limitBeforeGrouping + * @return Piwik_DataTable + */ + public function queryExternalReferrers($idaction, $actionType, $archiveProcessing, + $limitBeforeGrouping = false) + { + $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping); + + // we generate a single column that contains the interesting data for each referrer. + // the reason we cannot group by referer_* becomes clear when we look at search engine keywords. + // referer_url contains the url from the search engine, referer_keyword the keyword we want to + // group by. when we group by both, we don't get a single column for the keyword but instead + // one column per keyword + search engine url. this way, we could not get the top keywords using + // the ranking query. + $dimensions = array('referrer_data', 'referer_type'); + $rankingQuery->addLabelColumn('referrer_data'); + $selects = array( + 'CASE referer_type + WHEN ' . Piwik_Common::REFERER_TYPE_DIRECT_ENTRY . ' THEN \'\' + WHEN ' . Piwik_Common::REFERER_TYPE_SEARCH_ENGINE . ' THEN referer_keyword + WHEN ' . Piwik_Common::REFERER_TYPE_WEBSITE . ' THEN referer_url + WHEN ' . Piwik_Common::REFERER_TYPE_CAMPAIGN . ' THEN CONCAT(referer_name, \' \', referer_keyword) + END AS referrer_data'); + + // get one limited group per referrer type + $rankingQuery->partitionResultIntoMultipleGroups('referer_type', array( + Piwik_Common::REFERER_TYPE_DIRECT_ENTRY, + Piwik_Common::REFERER_TYPE_SEARCH_ENGINE, + Piwik_Common::REFERER_TYPE_WEBSITE, + Piwik_Common::REFERER_TYPE_CAMPAIGN + )); + + $type = $this->getColumnTypeSuffix($actionType); + $where = 'visit_entry_idaction_' . $type . ' = ' . intval($idaction); + + $metrics = array(Piwik_Archive::INDEX_NB_VISITS); + $data = $archiveProcessing->queryVisitsByDimension($dimensions, $where, $selects, $metrics, $rankingQuery); + + $referrerData = array(); + $referrerSubData = array(); + + foreach ($data as $referrerType => &$subData) { + $referrerData[$referrerType] = array(Piwik_Archive::INDEX_NB_VISITS => 0); + if ($referrerType != Piwik_Common::REFERER_TYPE_DIRECT_ENTRY) { + $referrerSubData[$referrerType] = array(); + } + + foreach ($subData as &$row) { + if ($referrerType == Piwik_Common::REFERER_TYPE_SEARCH_ENGINE && empty($row['referrer_data'])) { + $row['referrer_data'] = Piwik_Referers_API::LABEL_KEYWORD_NOT_DEFINED; + } + + $referrerData[$referrerType][Piwik_Archive::INDEX_NB_VISITS] += $row[Piwik_Archive::INDEX_NB_VISITS]; + + $label = $row['referrer_data']; + if ($label) { + $referrerSubData[$referrerType][$label] = array( + Piwik_Archive::INDEX_NB_VISITS => $row[Piwik_Archive::INDEX_NB_VISITS] + ); + } + } + } + + //FIXMEA refactor after integration tests written + $array = new Piwik_DataArray($referrerData, $referrerSubData); + return Piwik_ArchiveProcessor_Day::getDataTableFromDataArray($array); + } + + /** + * Get information about internal referrers (previous pages & loops, i.e. page refreshes) + * + * @param $idaction + * @param $actionType + * @param Piwik_ArchiveProcessor_Day $archiveProcessing + * @param $limitBeforeGrouping + * @return array(previousPages:Piwik_DataTable, loops:integer) + */ + protected function queryInternalReferrers($idaction, $actionType, $archiveProcessing, + $limitBeforeGrouping = false) + { + $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping); + $rankingQuery->addLabelColumn(array('name', 'url_prefix')); + $rankingQuery->setColumnToMarkExcludedRows('is_self'); + $rankingQuery->partitionResultIntoMultipleGroups('action_partition', array(0, 1, 2)); + + $type = $this->getColumnTypeSuffix($actionType); + $mainActionType = Piwik_Tracker_Action::TYPE_ACTION_URL; + $dimension = 'idaction_url_ref'; + $isTitle = $actionType == 'title'; + + if ($isTitle) { + $mainActionType = Piwik_Tracker_Action::TYPE_ACTION_NAME; + $dimension = 'idaction_name_ref'; + } + + $selects = array( + 'log_action.name', + 'log_action.url_prefix', + 'CASE WHEN log_link_visit_action.idaction_' . $type . '_ref = ' . intval($idaction) . ' THEN 1 ELSE 0 END AS is_self', + 'CASE + WHEN log_action.type = ' . $mainActionType . ' THEN 1 + WHEN log_action.type = ' . Piwik_Tracker_Action::TYPE_SITE_SEARCH . ' THEN 2 + ELSE 0 + END AS action_partition' + ); + + $where = ' + log_link_visit_action.idaction_' . $type . ' = ' . intval($idaction); + + if ($dimension == 'idaction_url_ref') { + // site search referrers are logged with url_ref=NULL + // when we find one, we have to join on name_ref + $dimension = 'IF( idaction_url_ref IS NULL, idaction_name_ref, idaction_url_ref )'; + $joinLogActionOn = $dimension; + } else { + $joinLogActionOn = $dimension; + } + $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS); + $data = $archiveProcessing->queryActionsByDimension(array($dimension), $where, $selects, $metrics, $rankingQuery, $joinLogActionOn); + + $loops = 0; + $nbPageviews = 0; + $previousPagesDataTable = new Piwik_DataTable; + if (isset($data['result'][1])) { + foreach ($data['result'][1] as &$page) { + $nbActions = intval($page[Piwik_Archive::INDEX_NB_ACTIONS]); + $previousPagesDataTable->addRow(new Piwik_DataTable_Row(array( + Piwik_DataTable_Row::COLUMNS => array( + 'label' => $this->getPageLabel($page, $isTitle), + Piwik_Archive::INDEX_NB_ACTIONS => $nbActions + ) + ))); + $nbPageviews += $nbActions; + } + } + + $previousSearchesDataTable = new Piwik_DataTable; + if (isset($data['result'][2])) { + foreach ($data['result'][2] as &$search) { + $nbActions = intval($search[Piwik_Archive::INDEX_NB_ACTIONS]); + $previousSearchesDataTable->addRow(new Piwik_DataTable_Row(array( + Piwik_DataTable_Row::COLUMNS => array( + 'label' => $search['name'], + Piwik_Archive::INDEX_NB_ACTIONS => $nbActions + ) + ))); + $nbPageviews += $nbActions; + } + } + + if (isset($data['result'][0])) { + foreach ($data['result'][0] as &$referrer) { + $nbPageviews += intval($referrer[Piwik_Archive::INDEX_NB_ACTIONS]); + } + } + + if (count($data['excludedFromLimit'])) { + $loops += intval($data['excludedFromLimit'][0][Piwik_Archive::INDEX_NB_ACTIONS]); + $nbPageviews += $loops; + } + + return array( + 'pageviews' => $nbPageviews, + 'previousPages' => $previousPagesDataTable, + 'previousSiteSearches' => $previousSearchesDataTable, + 'loops' => $loops + ); + } + + private function getPageLabel(&$pageRecord, $isTitle) + { + if ($isTitle) { + $label = $pageRecord['name']; + if (empty($label)) { + $label = Piwik_Actions_ArchivingHelper::getUnknownActionName( + Piwik_Tracker_Action::TYPE_ACTION_NAME); + } + return $label; + } else if ($this->returnNormalizedUrls) { + return $pageRecord['name']; + } else { + return Piwik_Tracker_Action::reconstructNormalizedUrl( + $pageRecord['name'], $pageRecord['url_prefix']); + } + } + + private function getColumnTypeSuffix($actionType) + { + if ($actionType == 'title') { + return 'name'; + } + return 'url'; + } + + private $limitBeforeGrouping = 5; + private $totalTransitionsToFollowingActions = 0; + + private $returnNormalizedUrls = false; + + + /** + * Get the sum of all transitions to following actions (pages, outlinks, downloads). + * Only works if queryFollowingActions() has been used directly before. + */ + protected function getTotalTransitionsToFollowingActions() + { + return $this->totalTransitionsToFollowingActions; + } + /** * Add the external referrers to the report: * direct entries, websites, campaigns, search engines diff --git a/plugins/Transitions/Transitions.php b/plugins/Transitions/Transitions.php index b887669a70..2c51da023e 100644 --- a/plugins/Transitions/Transitions.php +++ b/plugins/Transitions/Transitions.php @@ -15,11 +15,6 @@ class Piwik_Transitions extends Piwik_Plugin { - private $limitBeforeGrouping = 5; - private $totalTransitionsToFollowingActions = 0; - - private $returnNormalizedUrls = false; - public function getInformation() { return array( @@ -50,325 +45,5 @@ class Piwik_Transitions extends Piwik_Plugin $jsFiles[] = 'plugins/Transitions/templates/transitions.js'; } - /** - * After calling this method, the query*()-Methods will return urls in their - * normalized form (without the prefix reconstructed) - */ - public function returnNormalizedUrls() - { - $this->returnNormalizedUrls = true; - } - - /** - * Get information about external referrers (i.e. search engines, websites & campaigns) - * - * @param $idaction - * @param $actionType - * @param Piwik_ArchiveProcessor_Day $archiveProcessing - * @param $limitBeforeGrouping - * @return Piwik_DataTable - */ - public function queryExternalReferrers($idaction, $actionType, $archiveProcessing, - $limitBeforeGrouping = false) - { - $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping); - - // we generate a single column that contains the interesting data for each referrer. - // the reason we cannot group by referer_* becomes clear when we look at search engine keywords. - // referer_url contains the url from the search engine, referer_keyword the keyword we want to - // group by. when we group by both, we don't get a single column for the keyword but instead - // one column per keyword + search engine url. this way, we could not get the top keywords using - // the ranking query. - $dimensions = array('referrer_data', 'referer_type'); - $rankingQuery->addLabelColumn('referrer_data'); - $selects = array( - 'CASE referer_type - WHEN ' . Piwik_Common::REFERER_TYPE_DIRECT_ENTRY . ' THEN \'\' - WHEN ' . Piwik_Common::REFERER_TYPE_SEARCH_ENGINE . ' THEN referer_keyword - WHEN ' . Piwik_Common::REFERER_TYPE_WEBSITE . ' THEN referer_url - WHEN ' . Piwik_Common::REFERER_TYPE_CAMPAIGN . ' THEN CONCAT(referer_name, \' \', referer_keyword) - END AS referrer_data'); - - // get one limited group per referrer type - $rankingQuery->partitionResultIntoMultipleGroups('referer_type', array( - Piwik_Common::REFERER_TYPE_DIRECT_ENTRY, - Piwik_Common::REFERER_TYPE_SEARCH_ENGINE, - Piwik_Common::REFERER_TYPE_WEBSITE, - Piwik_Common::REFERER_TYPE_CAMPAIGN - )); - - $type = $this->getColumnTypeSuffix($actionType); - $where = 'visit_entry_idaction_' . $type . ' = ' . intval($idaction); - - $metrics = array(Piwik_Archive::INDEX_NB_VISITS); - $data = $archiveProcessing->queryVisitsByDimension($dimensions, $where, $selects, $metrics, $rankingQuery); - - $referrerData = array(); - $referrerSubData = array(); - - foreach ($data as $referrerType => &$subData) { - $referrerData[$referrerType] = array(Piwik_Archive::INDEX_NB_VISITS => 0); - if ($referrerType != Piwik_Common::REFERER_TYPE_DIRECT_ENTRY) { - $referrerSubData[$referrerType] = array(); - } - - foreach ($subData as &$row) { - if ($referrerType == Piwik_Common::REFERER_TYPE_SEARCH_ENGINE && empty($row['referrer_data'])) { - $row['referrer_data'] = Piwik_Referers_API::LABEL_KEYWORD_NOT_DEFINED; - } - - $referrerData[$referrerType][Piwik_Archive::INDEX_NB_VISITS] += $row[Piwik_Archive::INDEX_NB_VISITS]; - - $label = $row['referrer_data']; - if ($label) { - $referrerSubData[$referrerType][$label] = array( - Piwik_Archive::INDEX_NB_VISITS => $row[Piwik_Archive::INDEX_NB_VISITS] - ); - } - } - } - - //FIXMEA refactor after integration tests written - $array = new Piwik_DataArray($referrerData, $referrerSubData); - return Piwik_ArchiveProcessor_Day::getDataTableFromDataArray($array); - } - - /** - * Get information about internal referrers (previous pages & loops, i.e. page refreshes) - * - * @param $idaction - * @param $actionType - * @param Piwik_ArchiveProcessor_Day $archiveProcessing - * @param $limitBeforeGrouping - * @return array(previousPages:Piwik_DataTable, loops:integer) - */ - public function queryInternalReferrers($idaction, $actionType, $archiveProcessing, - $limitBeforeGrouping = false) - { - $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping); - $rankingQuery->addLabelColumn(array('name', 'url_prefix')); - $rankingQuery->setColumnToMarkExcludedRows('is_self'); - $rankingQuery->partitionResultIntoMultipleGroups('action_partition', array(0, 1, 2)); - - $type = $this->getColumnTypeSuffix($actionType); - $mainActionType = Piwik_Tracker_Action::TYPE_ACTION_URL; - $dimension = 'idaction_url_ref'; - $isTitle = $actionType == 'title'; - if ($isTitle) { - $mainActionType = Piwik_Tracker_Action::TYPE_ACTION_NAME; - $dimension = 'idaction_name_ref'; - } - - $selects = array( - 'log_action.name', - 'log_action.url_prefix', - 'CASE WHEN log_link_visit_action.idaction_' . $type . '_ref = ' . intval($idaction) . ' THEN 1 ELSE 0 END AS is_self', - 'CASE - WHEN log_action.type = ' . $mainActionType . ' THEN 1 - WHEN log_action.type = ' . Piwik_Tracker_Action::TYPE_SITE_SEARCH . ' THEN 2 - ELSE 0 - END AS action_partition' - ); - - $where = ' - log_link_visit_action.idaction_' . $type . ' = ' . intval($idaction); - - if ($dimension == 'idaction_url_ref') { - // site search referrers are logged with url_ref=NULL - // when we find one, we have to join on name_ref - $dimension = 'IF( idaction_url_ref IS NULL, idaction_name_ref, idaction_url_ref )'; - $joinLogActionOn = $dimension; - } else { - $joinLogActionOn = $dimension; - $dimension = array($dimension); - } - - $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS); - $data = $archiveProcessing->queryActionsByDimension($dimension, $where, $selects, $metrics, $rankingQuery, $joinLogActionOn); - - $loops = 0; - $nbPageviews = 0; - $previousPagesDataTable = new Piwik_DataTable; - if (isset($data['result'][1])) { - foreach ($data['result'][1] as &$page) { - $nbActions = intval($page[Piwik_Archive::INDEX_NB_ACTIONS]); - $previousPagesDataTable->addRow(new Piwik_DataTable_Row(array( - Piwik_DataTable_Row::COLUMNS => array( - 'label' => $this->getPageLabel($page, $isTitle), - Piwik_Archive::INDEX_NB_ACTIONS => $nbActions - ) - ))); - $nbPageviews += $nbActions; - } - } - - $previousSearchesDataTable = new Piwik_DataTable; - if (isset($data['result'][2])) { - foreach ($data['result'][2] as &$search) { - $nbActions = intval($search[Piwik_Archive::INDEX_NB_ACTIONS]); - $previousSearchesDataTable->addRow(new Piwik_DataTable_Row(array( - Piwik_DataTable_Row::COLUMNS => array( - 'label' => $search['name'], - Piwik_Archive::INDEX_NB_ACTIONS => $nbActions - ) - ))); - $nbPageviews += $nbActions; - } - } - - if (isset($data['result'][0])) { - foreach ($data['result'][0] as &$referrer) { - $nbPageviews += intval($referrer[Piwik_Archive::INDEX_NB_ACTIONS]); - } - } - - if (count($data['excludedFromLimit'])) { - $loops += intval($data['excludedFromLimit'][0][Piwik_Archive::INDEX_NB_ACTIONS]); - $nbPageviews += $loops; - } - - return array( - 'pageviews' => $nbPageviews, - 'previousPages' => $previousPagesDataTable, - 'previousSiteSearches' => $previousSearchesDataTable, - 'loops' => $loops - ); - } - - private function getPageLabel(&$pageRecord, $isTitle) - { - if ($isTitle) { - $label = $pageRecord['name']; - if (empty($label)) { - $label = Piwik_Actions_ArchivingHelper::getUnknownActionName( - Piwik_Tracker_Action::TYPE_ACTION_NAME); - } - return $label; - } else if ($this->returnNormalizedUrls) { - return $pageRecord['name']; - } else { - return Piwik_Tracker_Action::reconstructNormalizedUrl( - $pageRecord['name'], $pageRecord['url_prefix']); - } - } - - /** - * Get information about the following actions (following pages, site searches, outlinks, downloads) - * - * @param $idaction - * @param $actionType - * @param Piwik_ArchiveProcessor_Day $archiveProcessing - * @param $limitBeforeGrouping - * @param $includeLoops - * @return array(followingPages:Piwik_DataTable, outlinks:Piwik_DataTable, downloads:Piwik_DataTable) - */ - public function queryFollowingActions($idaction, $actionType, Piwik_ArchiveProcessor_Day $archiveProcessing, - $limitBeforeGrouping = false, $includeLoops = false) - { - $types = array(); - - $isTitle = ($actionType == 'title'); - if (!$isTitle) { - // specific setup for page urls - $types[Piwik_Tracker_Action::TYPE_ACTION_URL] = 'followingPages'; - $dimension = 'IF( idaction_url IS NULL, idaction_name, idaction_url )'; - // site search referrers are logged with url=NULL - // when we find one, we have to join on name - $joinLogActionColumn = $dimension; - $selects = array('log_action.name', 'log_action.url_prefix', 'log_action.type'); - } else { - // specific setup for page titles: - $types[Piwik_Tracker_Action::TYPE_ACTION_NAME] = 'followingPages'; - // join log_action on name and url and pick depending on url type - // the table joined on url is log_action1 - $joinLogActionColumn = array('idaction_url', 'idaction_name'); - $dimension = ' - CASE - ' /* following site search */ . ' - WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.idaction - ' /* following page view: use page title */ . ' - WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.idaction - ' /* following download or outlink: use url */ . ' - ELSE log_action1.idaction - END - '; - $selects = array( - 'CASE - ' /* following site search */ . ' - WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.name - ' /* following page view: use page title */ . ' - WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.name - ' /* following download or outlink: use url */ . ' - ELSE log_action1.name - END AS name', - 'CASE - ' /* following site search */ . ' - WHEN log_link_visit_action.idaction_url IS NULL THEN log_action2.type - ' /* following page view: use page title */ . ' - WHEN log_action1.type = ' . Piwik_Tracker_Action::TYPE_ACTION_URL . ' THEN log_action2.type - ' /* following download or outlink: use url */ . ' - ELSE log_action1.type - END AS type', - 'NULL AS url_prefix' - ); - } - - // these types are available for both titles and urls - $types[Piwik_Tracker_Action::TYPE_SITE_SEARCH] = 'followingSiteSearches'; - $types[Piwik_Tracker_Action::TYPE_OUTLINK] = 'outlinks'; - $types[Piwik_Tracker_Action::TYPE_DOWNLOAD] = 'downloads'; - - $rankingQuery = new Piwik_RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping); - $rankingQuery->addLabelColumn(array('name', 'url_prefix')); - $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($types)); - - $type = $this->getColumnTypeSuffix($actionType); - $where = 'log_link_visit_action.idaction_' . $type . '_ref = ' . intval($idaction); - if (!$includeLoops) { - $where .= ' AND (log_link_visit_action.idaction_' . $type . ' IS NULL OR ' - . 'log_link_visit_action.idaction_' . $type . ' != ' . intval($idaction) . ')'; - } - - $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS); - $data = $archiveProcessing->queryActionsByDimension($dimension, $where, $selects, $metrics, $rankingQuery, $joinLogActionColumn); - - $this->totalTransitionsToFollowingActions = 0; - $dataTables = array(); - foreach ($types as $type => $recordName) { - $dataTable = new Piwik_DataTable; - if (isset($data[$type])) { - foreach ($data[$type] as &$record) { - $actions = intval($record[Piwik_Archive::INDEX_NB_ACTIONS]); - $dataTable->addRow(new Piwik_DataTable_Row(array( - Piwik_DataTable_Row::COLUMNS => array( - 'label' => $this->getPageLabel($record, $isTitle), - Piwik_Archive::INDEX_NB_ACTIONS => $actions - ) - ))); - $this->totalTransitionsToFollowingActions += $actions; - } - } - $dataTables[$recordName] = $dataTable; - } - - return $dataTables; - } - - /** - * Get the sum of all transitions to following actions (pages, outlinks, downloads). - * Only works if queryFollowingActions() has been used directly before. - */ - public function getTotalTransitionsToFollowingActions() - { - return $this->totalTransitionsToFollowingActions; - } - - private function getColumnTypeSuffix($actionType) - { - if ($actionType == 'title') { - return 'name'; - } - return 'url'; - } }
\ No newline at end of file diff --git a/plugins/VisitTime/API.php b/plugins/VisitTime/API.php index 65952ba24d..807b399869 100644 --- a/plugins/VisitTime/API.php +++ b/plugins/VisitTime/API.php @@ -64,24 +64,25 @@ class Piwik_VisitTime_API { Piwik::checkUserHasViewAccess($idSite); - // disabled for multiple sites/dates - if (Piwik_Archive::isMultipleSites($idSite)) { - throw new Exception("VisitTime.getByDayOfWeek does not support multiple sites."); - } - - if (Piwik_Archive::isMultiplePeriod($date, $period)) { - throw new Exception("VisitTime.getByDayOfWeek does not support multiple dates."); - } - // metrics to query $metrics = Piwik_Archive::getVisitsMetricNames(); unset($metrics[Piwik_Archive::INDEX_MAX_ACTIONS]); // get metric data for every day within the supplied period - $oPeriod = Piwik_Archive::makePeriodFromQueryParams(Piwik_Site::getTimezoneFor($idSite), $period, $date); + $oPeriod = Piwik_Period::makePeriodFromQueryParams(Piwik_Site::getTimezoneFor($idSite), $period, $date); $dateRange = $oPeriod->getDateStart()->toString() . ',' . $oPeriod->getDateEnd()->toString(); $archive = Piwik_Archive::build($idSite, 'day', $dateRange, $segment); + + // disabled for multiple sites/dates + if ( count( $archive->getParams()->getIdSites() ) > 1) { + throw new Exception("VisitTime.getByDayOfWeek does not support multiple sites."); + } + + if ( count ($archive->getParams()->getPeriods() ) > 1) { + throw new Exception("VisitTime.getByDayOfWeek does not support multiple dates."); + } + $dataTable = $archive->getDataTableFromNumeric($metrics); // if there's no data for this report, don't bother w/ anything else diff --git a/plugins/VisitTime/Controller.php b/plugins/VisitTime/Controller.php index 9c2fce1087..778f3a6f0e 100644 --- a/plugins/VisitTime/Controller.php +++ b/plugins/VisitTime/Controller.php @@ -73,7 +73,7 @@ class Piwik_VisitTime_Controller extends Piwik_Controller $period = Piwik_Common::getRequestVar('period'); // create a period instance - $oPeriod = Piwik_Archive::makePeriodFromQueryParams(Piwik_Site::getTimezoneFor($idSite), $period, $date); + $oPeriod = Piwik_Period::makePeriodFromQueryParams(Piwik_Site::getTimezoneFor($idSite), $period, $date); // set the footer message using the period start & end date $start = $oPeriod->getDateStart()->toString(); diff --git a/tests/PHPUnit/Core/ArchiveProcessingTest.php b/tests/PHPUnit/Core/ArchiveProcessingTest.php index 566502f803..c8defbb209 100644 --- a/tests/PHPUnit/Core/ArchiveProcessingTest.php +++ b/tests/PHPUnit/Core/ArchiveProcessingTest.php @@ -53,7 +53,12 @@ class ArchiveProcessingTest extends DatabaseTestCase $period = Piwik_Period::factory($periodLabel, $date); $segment = new Piwik_Segment('', $site->getId()); - return Piwik_ArchiveProcessor::factory($period, $site, $segment); + + if($period->getLabel() == 'day') { + return new Piwik_ArchiveProcessor_Day($period, $site, $segment); + } else { + return new Piwik_ArchiveProcessor_Period($period, $site, $segment); + } } /** diff --git a/tests/PHPUnit/Core/ReleaseCheckListTest.php b/tests/PHPUnit/Core/ReleaseCheckListTest.php index a14ed292f7..9dbc6ff4a0 100644 --- a/tests/PHPUnit/Core/ReleaseCheckListTest.php +++ b/tests/PHPUnit/Core/ReleaseCheckListTest.php @@ -135,7 +135,7 @@ class ReleaseCheckListTest extends PHPUnit_Framework_TestCase * @group Core * @group ReleaseCheckList */ - public function testSvnEolStyle() + public function testEndOfLines() { if (Piwik_Common::isWindows()) { // SVN native does not make this work on windows @@ -154,7 +154,7 @@ class ReleaseCheckListTest extends PHPUnit_Framework_TestCase } // skip files with these file extensions - if (preg_match('/\.(bmp|fdf|gif|deflate|gz|ico|jar|jpg|p12|pdf|png|rar|swf|vsd|z|zip|ttf|so|dat|eps)$/', $file)) { + if (preg_match('/\.(bmp|fdf|gif|deflate|gz|ico|jar|jpg|p12|pdf|png|rar|swf|vsd|z|zip|ttf|so|dat|eps|phar)$/', $file)) { continue; } diff --git a/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml b/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml index 8a400626b7..92c79f743a 100755 --- a/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml +++ b/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml @@ -6,10 +6,6 @@ <nb_actions>29</nb_actions> <nb_pageviews>25</nb_pageviews> <revenue>120</revenue> - <visits_evolution>100%</visits_evolution> - <actions_evolution>100%</actions_evolution> - <pageviews_evolution>100%</pageviews_evolution> - <revenue_evolution>100%</revenue_evolution> <idsite>1</idsite> </row> <row> @@ -18,10 +14,6 @@ <nb_actions>1</nb_actions> <nb_pageviews>1</nb_pageviews> <revenue>0</revenue> - <visits_evolution>100%</visits_evolution> - <actions_evolution>100%</actions_evolution> - <pageviews_evolution>100%</pageviews_evolution> - <revenue_evolution>0%</revenue_evolution> <idsite>2</idsite> </row> </result>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getOne_month.xml b/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getOne_month.xml index febd0b7d2f..cb5be388e9 100755 --- a/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getOne_month.xml +++ b/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getOne_month.xml @@ -2,10 +2,6 @@ <result> <nb_visits>26</nb_visits> <nb_actions>29</nb_actions> - <visits_evolution>100%</visits_evolution> - <actions_evolution>100%</actions_evolution> - <pageviews_evolution>100%</pageviews_evolution> - <revenue_evolution>100%</revenue_evolution> <nb_pageviews>25</nb_pageviews> <revenue>120</revenue> </result>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__Referers.getNumberOfDistinctCampaigns_day.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__Referers.getNumberOfDistinctCampaigns_day.xml index f5722c2b94..606fbb5241 100644 --- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__Referers.getNumberOfDistinctCampaigns_day.xml +++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__Referers.getNumberOfDistinctCampaigns_day.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" ?> -<result>0</result>
\ No newline at end of file +<result>1</result>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__Referers.getNumberOfDistinctCampaigns_day.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__Referers.getNumberOfDistinctCampaigns_day.xml index f5722c2b94..606fbb5241 100644 --- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__Referers.getNumberOfDistinctCampaigns_day.xml +++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__Referers.getNumberOfDistinctCampaigns_day.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" ?> -<result>0</result>
\ No newline at end of file +<result>1</result>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml index d7dfbaef5a..c48354bc4f 100755 --- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml +++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml @@ -12,5 +12,16 @@ <nb_actions_per_visit>1</nb_actions_per_visit> <avg_time_on_site>0</avg_time_on_site> </result> - <result idSite="2" /> + <result idSite="2"> + <nb_uniq_visitors>0</nb_uniq_visitors> + <nb_visits>0</nb_visits> + <nb_actions>0</nb_actions> + <nb_visits_converted>0</nb_visits_converted> + <bounce_count>0</bounce_count> + <sum_visit_length>0</sum_visit_length> + <max_actions>0</max_actions> + <bounce_rate>0%</bounce_rate> + <nb_actions_per_visit>0</nb_actions_per_visit> + <avg_time_on_site>0</avg_time_on_site> + </result> </results>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_day.xml index 1c7f2179e5..1721148e02 100644 --- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_day.xml +++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_day.xml @@ -1,5 +1,10 @@ <?xml version="1.0" encoding="utf-8" ?> <results> - <result idSite="1" /> + <result idSite="1"> + <nb_conversions>0</nb_conversions> + <nb_visits_converted>0</nb_visits_converted> + <conversion_rate>0</conversion_rate> + <revenue>0</revenue> + </result> <result idSite="2" /> </results>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_month.xml index bf1f38aa48..1c7f2179e5 100644 --- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_month.xml +++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__Goals.get_month.xml @@ -1,15 +1,5 @@ <?xml version="1.0" encoding="utf-8" ?> <results> - <result idSite="1"> - <nb_conversions>0</nb_conversions> - <nb_visits_converted>0</nb_visits_converted> - <conversion_rate>0</conversion_rate> - <revenue>0</revenue> - </result> - <result idSite="2"> - <nb_conversions>0</nb_conversions> - <nb_visits_converted>0</nb_visits_converted> - <conversion_rate>0</conversion_rate> - <revenue>0</revenue> - </result> + <result idSite="1" /> + <result idSite="2" /> </results>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_all_sites__PDFReports.generateReport_month.original.sms.txt b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_all_sites__PDFReports.generateReport_month.original.sms.txt index 398cd7cdd7..b5ad16e1ba 100644 --- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_all_sites__PDFReports.generateReport_month.original.sms.txt +++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_all_sites__PDFReports.generateReport_month.original.sms.txt @@ -1 +1 @@ -2010, January. Site 1: 3 Visits (+100%), 8 Actions (+100%). Site 2: 1 Visits (+100%), 3 Actions (+100%)
\ No newline at end of file +2010, January. Site 1: 3 Visits, 8 Actions. Site 2: 1 Visits, 3 Actions
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_one_site__PDFReports.generateReport_month.original.sms.txt b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_one_site__PDFReports.generateReport_month.original.sms.txt index 96518ebcbc..17121891e8 100644 --- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_one_site__PDFReports.generateReport_month.original.sms.txt +++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_via_sms_one_site__PDFReports.generateReport_month.original.sms.txt @@ -1 +1 @@ -2010, January. 3 Visits (+100%), 8 Actions (+100%)
\ No newline at end of file +2010, January. 3 Visits, 8 Actions
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml index 106f23f16b..c234bed59e 100755 --- a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml +++ b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml @@ -1,10 +1,2 @@ <?xml version="1.0" encoding="utf-8" ?> -<results> - <result date="2009-01-04" /> - <result date="2009-01-05" /> - <result date="2009-01-06" /> - <result date="2009-01-07" /> - <result date="2009-01-08" /> - <result date="2009-01-09" /> - <result date="2009-01-10" /> -</results>
\ No newline at end of file +<result />
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml index 5cfb246edc..c234bed59e 100755 --- a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml +++ b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml @@ -1,10 +1,2 @@ <?xml version="1.0" encoding="utf-8" ?> -<results> - <result date="From 2008-12-29 to 2009-01-04" /> - <result date="From 2009-01-05 to 2009-01-11" /> - <result date="From 2009-01-12 to 2009-01-18" /> - <result date="From 2009-01-19 to 2009-01-25" /> - <result date="From 2009-01-26 to 2009-02-01" /> - <result date="From 2009-02-02 to 2009-02-08" /> - <result date="From 2009-02-09 to 2009-02-15" /> -</results>
\ No newline at end of file +<result />
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_noVisit__MultiSites.getOne_day.xml b/tests/PHPUnit/Integration/expected/test_noVisit__MultiSites.getOne_day.xml index 2c523aeb3e..af9517fd59 100644 --- a/tests/PHPUnit/Integration/expected/test_noVisit__MultiSites.getOne_day.xml +++ b/tests/PHPUnit/Integration/expected/test_noVisit__MultiSites.getOne_day.xml @@ -2,10 +2,6 @@ <result> <nb_visits>0</nb_visits> <nb_actions>0</nb_actions> - <visits_evolution>0%</visits_evolution> - <actions_evolution>0%</actions_evolution> - <pageviews_evolution>0%</pageviews_evolution> - <revenue_evolution>0%</revenue_evolution> <nb_pageviews>0</nb_pageviews> <revenue>0</revenue> </result>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_noVisit__VisitTime.getByDayOfWeek_day.xml b/tests/PHPUnit/Integration/expected/test_noVisit__VisitTime.getByDayOfWeek_day.xml index c234bed59e..162b8f9429 100755 --- a/tests/PHPUnit/Integration/expected/test_noVisit__VisitTime.getByDayOfWeek_day.xml +++ b/tests/PHPUnit/Integration/expected/test_noVisit__VisitTime.getByDayOfWeek_day.xml @@ -1,2 +1,43 @@ <?xml version="1.0" encoding="utf-8" ?> -<result />
\ No newline at end of file +<result> + <row> + <label>Monday</label> + <nb_visits>0</nb_visits> + <day_of_week>1</day_of_week> + </row> + <row> + <label>Tuesday</label> + <nb_visits>0</nb_visits> + <day_of_week>2</day_of_week> + </row> + <row> + <label>Wednesday</label> + <nb_visits>0</nb_visits> + <day_of_week>3</day_of_week> + </row> + <row> + <label>Thursday</label> + <nb_visits>0</nb_visits> + <nb_uniq_visitors>0</nb_uniq_visitors> + <nb_actions>0</nb_actions> + <sum_visit_length>0</sum_visit_length> + <bounce_count>0</bounce_count> + <nb_visits_converted>0</nb_visits_converted> + <day_of_week>4</day_of_week> + </row> + <row> + <label>Friday</label> + <nb_visits>0</nb_visits> + <day_of_week>5</day_of_week> + </row> + <row> + <label>Saturday</label> + <nb_visits>0</nb_visits> + <day_of_week>6</day_of_week> + </row> + <row> + <label>Sunday</label> + <nb_visits>0</nb_visits> + <day_of_week>7</day_of_week> + </row> +</result>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Referers.getKeywords_range.xml b/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Referers.getKeywords_range.xml index 5777d1404b..f923223e23 100644 --- a/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Referers.getKeywords_range.xml +++ b/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Referers.getKeywords_range.xml @@ -38,5 +38,17 @@ </goals> <nb_conversions>2</nb_conversions> <revenue>0</revenue> + <subtable> + <row> + <label>Google</label> + <nb_visits>1</nb_visits> + <nb_actions>3</nb_actions> + <max_actions>3</max_actions> + <sum_visit_length>364</sum_visit_length> + <bounce_count>0</bounce_count> + <nb_visits_converted>1</nb_visits_converted> + <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> + </row> + </subtable> </row> </result>
\ No newline at end of file diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_day.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_day.xml index 5346f832dd..1d63dcbf33 100644 --- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_day.xml +++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_day.xml @@ -40,6 +40,18 @@ </goals> <nb_conversions>2</nb_conversions> <revenue>0</revenue> + <subtable> + <row> + <label>Google</label> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_visits>1</nb_visits> + <nb_actions>3</nb_actions> + <max_actions>3</max_actions> + <sum_visit_length>364</sum_visit_length> + <bounce_count>0</bounce_count> + <nb_visits_converted>1</nb_visits_converted> + </row> + </subtable> </row> </result> <result date="2010-01-04" /> diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_week.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_week.xml index 1ed17bcbca..547c6fb298 100644 --- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_week.xml +++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__Referers.getKeywords_week.xml @@ -40,6 +40,18 @@ </goals> <nb_conversions>2</nb_conversions> <revenue>0</revenue> + <subtable> + <row> + <label>Google</label> + <nb_visits>1</nb_visits> + <nb_actions>3</nb_actions> + <max_actions>3</max_actions> + <sum_visit_length>364</sum_visit_length> + <bounce_count>0</bounce_count> + <nb_visits_converted>1</nb_visits_converted> + <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> + </row> + </subtable> </row> </result> <result date="From 2010-01-04 to 2010-01-10" /> |