diff --git a/core/Archive/ArchiveQueryFactory.php b/core/Archive/ArchiveQueryFactory.php
index de69f39066b..9359f0c584c 100644
--- a/core/Archive/ArchiveQueryFactory.php
+++ b/core/Archive/ArchiveQueryFactory.php
@@ -29,7 +29,7 @@ public function build($idSites, $strPeriod, $strDate, $strSegment = false, $_res
{
list($websiteIds, $timezone, $idSiteIsAll) = $this->getSiteInfoFromQueryParam($idSites, $_restrictSitesToLogin);
list($allPeriods, $isMultipleDate) = $this->getPeriodInfoFromQueryParam($strDate, $strPeriod, $timezone);
- $segment = $this->getSegmentFromQueryParam($strSegment, $websiteIds);
+ $segment = $this->getSegmentFromQueryParam($strSegment, $websiteIds, $allPeriods);
return $this->factory($segment, $allPeriods, $websiteIds, $idSiteIsAll, $isMultipleDate);
}
@@ -118,10 +118,13 @@ protected function getPeriodInfoFromQueryParam($strDate, $strPeriod, $timezone)
*
* @param string $strSegment the value of the 'segment' query parameter.
* @param int[] $websiteIds the list of sites being queried.
+ * @param Period[] $allPeriods list of all periods
* @return Segment
*/
- protected function getSegmentFromQueryParam($strSegment, $websiteIds)
+ protected function getSegmentFromQueryParam($strSegment, $websiteIds, $allPeriods)
{
- return new Segment($strSegment, $websiteIds);
+ // we might have multiple periods, so use the start date of the first one and
+ // the end date of the last one to limit the possible segment subquery
+ return new Segment($strSegment, $websiteIds, reset($allPeriods)->getDateTimeStart(), end($allPeriods)->getDateTimeEnd());
}
}
\ No newline at end of file
diff --git a/core/ArchiveProcessor.php b/core/ArchiveProcessor.php
index af8feb6716e..202eb5f04de 100644
--- a/core/ArchiveProcessor.php
+++ b/core/ArchiveProcessor.php
@@ -650,7 +650,7 @@ public function processDependentArchive($plugin, $segment)
return;
}
- $newSegment = new Segment($newSegment, $idSites);
+ $newSegment = new Segment($newSegment, $idSites, $params->getDateStart(), $params->getDateEnd());
if (ArchiveProcessor\Rules::isSegmentPreProcessed($idSites, $newSegment)) {
// will be processed anyway
return;
diff --git a/core/CronArchive.php b/core/CronArchive.php
index cbe9a34234d..b52fa24ab85 100644
--- a/core/CronArchive.php
+++ b/core/CronArchive.php
@@ -589,7 +589,7 @@ private function launchArchivingFor($archives)
$idSite = $archive['idsite'];
$dateStr = $archive['period'] == Range::PERIOD_ID ? ($archive['date1'] . ',' . $archive['date2']) : $archive['date1'];
$period = PeriodFactory::build($this->periodIdsToLabels[$archive['period']], $dateStr);
- $params = new Parameters(new Site($idSite), $period, new Segment($segment, [$idSite]));
+ $params = new Parameters(new Site($idSite), $period, new Segment($segment, [$idSite], $period->getDateStart(), $period->getDateEnd()));
$loader = new Loader($params);
if ($loader->canSkipThisArchive()) {
@@ -941,7 +941,7 @@ public function invalidateArchivedReportsForSitesThatNeedToBeArchivedAgain()
continue;
}
- $params = new Parameters(new Site($idSite), $period, new Segment('', [$idSite]));
+ $params = new Parameters(new Site($idSite), $period, new Segment('', [$idSite], $period->getDateStart(), $period->getDateEnd()));
if ($this->isThereExistingValidPeriod($params)) {
$this->logger->info(' Found usable archive for custom date range {date} for site {idSite}, skipping archiving.', ['date' => $date, 'idSite' => $idSite]);
continue;
@@ -989,7 +989,7 @@ private function invalidateRecentDate($dateStr)
$date = Date::factory($dateStr);
$period = PeriodFactory::build('day', $date);
- $params = new Parameters(new Site($idSite), $period, new Segment('', [$idSite]));
+ $params = new Parameters(new Site($idSite), $period, new Segment('', [$idSite], $period->getDateStart(), $period->getDateEnd()));
if ($this->isThereExistingValidPeriod($params, $isYesterday)) {
$this->logger->debug(" Found existing valid archive for $dateStr, skipping invalidation...");
continue;
@@ -1420,7 +1420,7 @@ private function canSkipArchiveBecauseNoPoint(array $invalidatedArchive)
$dateStr = $periodLabel == 'range' ? ($invalidatedArchive['date1'] . ',' . $invalidatedArchive['date2']) : $invalidatedArchive['date1'];
$period = PeriodFactory::build($periodLabel, $dateStr);
- $segment = new Segment($invalidatedArchive['segment'], [$invalidatedArchive['idsite']]);
+ $segment = new Segment($invalidatedArchive['segment'], [$invalidatedArchive['idsite']], $period->getDateStart(), $period->getDateEnd());
$params = new Parameters($site, $period, $segment);
diff --git a/core/Segment.php b/core/Segment.php
index 26f6de430b1..7062f102cda 100644
--- a/core/Segment.php
+++ b/core/Segment.php
@@ -75,6 +75,16 @@ class Segment
*/
protected $idSites = null;
+ /**
+ * @var Date
+ */
+ protected $startDate = null;
+
+ /**
+ * @var Date
+ */
+ protected $endDate = null;
+
/**
* @var LogQueryBuilder
*/
@@ -93,12 +103,20 @@ class Segment
/**
* Constructor.
*
+ * When using segments that contain a != or !@ condition on a non visit dimension (e.g. action, conversion, ...) it
+ * is needed to use a subquery to get correct results. To avoid subqueries that fetch too many data it's required to
+ * set a startDate in this case. That date will be used to limit the subquery (along with possibly given idSites or
+ * endDate). If no startDate is given for such a segment it will generate a query that directly joins the according
+ * tables, but trigger a php warning as results might be incorrect.
+ *
* @param string $segmentCondition The segment condition, eg, `'browserCode=ff;countryCode=CA'`.
* @param array $idSites The list of sites the segment will be used with. Some segments are
* dependent on the site, such as goal segments.
+ * @param Date|null $startDate start date used to limit subqueries
+ * @param Date|null $endDate end date used to limit subqueries
* @throws
*/
- public function __construct($segmentCondition, $idSites)
+ public function __construct($segmentCondition, $idSites, Date $startDate = null, Date $endDate = null)
{
$this->segmentQueryBuilder = StaticContainer::get('Piwik\DataAccess\LogQueryBuilder');
@@ -111,6 +129,14 @@ public function __construct($segmentCondition, $idSites)
$this->originalString = $segmentCondition;
+ if ($startDate instanceof Date) {
+ $this->startDate = $startDate;
+ }
+
+ if ($endDate instanceof Date) {
+ $this->endDate = $endDate;
+ }
+
// The segment expression can be urlencoded. Unfortunately, both the encoded and decoded versions
// can usually be parsed successfully. To pick the right one, we try both and pick the one w/ more
// successfully parsed subexpressions.
@@ -195,6 +221,12 @@ protected function initializeSegment($string, $idSites)
$string = substr($string, 0, self::SEGMENT_TRUNCATE_LIMIT);
$this->string = $string;
+
+ if (empty($idSites)) {
+ $idSites = [];
+ } else if (!is_array($idSites)) {
+ $idSites = [$idSites];
+ }
$this->idSites = $idSites;
$segment = new SegmentExpression($string);
$this->segmentExpression = $segment;
@@ -209,8 +241,7 @@ protected function initializeSegment($string, $idSites)
$cleanedExpressions = array();
foreach ($expressions as $expression) {
$operand = $expression[SegmentExpression::INDEX_OPERAND];
- $cleanedExpression = $this->getCleanedExpression($operand);
- $expression[SegmentExpression::INDEX_OPERAND] = $cleanedExpression;
+ $expression[SegmentExpression::INDEX_OPERAND] = $this->getCleanedExpression($operand);
$cleanedExpressions[] = $expression;
}
@@ -226,7 +257,8 @@ private function getExpressionsWithUnionsResolved($expressions)
$availableSegment = $this->getSegmentByName($name);
- if (!empty($availableSegment['unionOfSegments'])) {
+ // We leave segments using !@ and != operands untouched for segments not on log_visit table as they will be build using a subquery
+ if (!$this->doesSegmentNeedSubquery($operand[SegmentExpression::INDEX_OPERAND_OPERATOR], $name) && !empty($availableSegment['unionOfSegments'])) {
$count = 0;
foreach ($availableSegment['unionOfSegments'] as $segmentNameOfUnion) {
$count++;
@@ -252,6 +284,51 @@ private function getExpressionsWithUnionsResolved($expressions)
return $expressionsWithUnions;
}
+ private function isVisitSegment($name)
+ {
+ $availableSegment = $this->getSegmentByName($name);
+
+ if (!empty($availableSegment['unionOfSegments'])) {
+ foreach ($availableSegment['unionOfSegments'] as $segmentNameOfUnion) {
+ $unionSegment = $this->getSegmentByName($segmentNameOfUnion);
+ if (strpos($unionSegment['sqlSegment'], 'log_visit.') === 0) {
+ return true;
+ }
+ }
+ } else if (strpos($availableSegment['sqlSegment'], 'log_visit.') === 0) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private function doesSegmentNeedSubquery($operator, $segmentName)
+ {
+ $requiresSubQuery = in_array($operator, [
+ SegmentExpression::MATCH_DOES_NOT_CONTAIN,
+ SegmentExpression::MATCH_NOT_EQUAL
+ ]) && !$this->isVisitSegment($segmentName);
+
+ if ($requiresSubQuery && empty($this->startDate)) {
+ $e = new Exception();
+ Log::warning("Avoiding segment subquery due to missing start date. Please ensure a start date is set when initializing a segment if it's used to build a query. Stacktrace:\n" . $e->getTraceAsString());
+ return false;
+ }
+
+ return $requiresSubQuery;
+ }
+
+ private function getInvertedOperatorForSubQuery($operator)
+ {
+ if ($operator === SegmentExpression::MATCH_DOES_NOT_CONTAIN) {
+ return SegmentExpression::MATCH_CONTAINS;
+ } else if ($operator === SegmentExpression::MATCH_NOT_EQUAL) {
+ return SegmentExpression::MATCH_EQUAL;
+ }
+
+ throw new Exception("Operator not support for subqueries");
+ }
+
/**
* Returns `true` if the segment is empty, `false` if otherwise.
*/
@@ -277,9 +354,6 @@ public function willBeArchived()
}
$idSites = $this->idSites;
- if (!is_array($idSites)) {
- $idSites = array($this->idSites);
- }
return Rules::isRequestAuthorizedToArchive()
|| Rules::isBrowserArchivingAvailableForSegments()
@@ -297,6 +371,40 @@ protected function getCleanedExpression($expression)
$segment = $this->getSegmentByName($name);
$sqlName = $segment['sqlSegment'];
+ // Build subqueries for segments that are not on log_visit table but use !@ or != as operator
+ // This is required to ensure segments like actionUrl!@value really do not include any visit having an action containing `value`
+ if ($this->doesSegmentNeedSubquery($matchType, $name)) {
+ $operator = $this->getInvertedOperatorForSubQuery($matchType);
+ $stringSegment = $name . $operator . $value;
+ $segmentObj = new Segment($stringSegment, $this->idSites, $this->startDate, $this->endDate);
+
+ $select = 'log_visit.idvisit';
+ $from = 'log_visit';
+ $datetimeField = 'visit_last_action_time';
+ $where = [];
+ $bind = [];
+ if (!empty($this->idSites)) {
+ $where[] = "$from.idsite IN (" . Common::getSqlStringFieldsArray($this->idSites) . ")";
+ $bind = $this->idSites;
+ }
+ if ($this->startDate instanceof Date) {
+ $where[] = "$from.$datetimeField >= ?";
+ $bind[] = $this->startDate->toString(Date::DATE_TIME_FORMAT);
+ }
+ if ($this->endDate instanceof Date) {
+ $where[] = "$from.$datetimeField <= ?";
+ $bind[] = $this->endDate->toString(Date::DATE_TIME_FORMAT);
+ }
+
+ $logQueryBuilder = StaticContainer::get('Piwik\DataAccess\LogQueryBuilder');
+ $forceGroupByBackup = $logQueryBuilder->getForcedInnerGroupBySubselect();
+ $logQueryBuilder->forceInnerGroupBySubselect(LogQueryBuilder::FORCE_INNER_GROUP_BY_NO_SUBSELECT);
+ $query = $segmentObj->getSelectQuery($select, $from, implode(' AND ', $where), $bind);
+ $logQueryBuilder->forceInnerGroupBySubselect($forceGroupByBackup);
+
+ return ['log_visit.idvisit', SegmentExpression::MATCH_ACTIONS_NOT_CONTAINS, $query];
+ }
+
if ($matchType != SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY
&& $matchType != SegmentExpression::MATCH_IS_NULL_OR_EMPTY) {
diff --git a/core/Segment/SegmentExpression.php b/core/Segment/SegmentExpression.php
index dc710197074..8e9462a7085 100644
--- a/core/Segment/SegmentExpression.php
+++ b/core/Segment/SegmentExpression.php
@@ -42,6 +42,7 @@ class SegmentExpression
// Special case, since we look up Page URLs/Page titles in a sub SQL query
const MATCH_ACTIONS_CONTAINS = 'IN';
+ const MATCH_ACTIONS_NOT_CONTAINS = 'NOTIN';
const INDEX_BOOL_OPERATOR = 0;
const INDEX_OPERAND = 1;
@@ -289,6 +290,14 @@ protected function getSqlMatchFromDefinition($def, &$availableTables)
$sqlMatch = '%s IN (' . $value['SQL'] . ')';
$value = $value['bind'];
break;
+ case self::MATCH_ACTIONS_NOT_CONTAINS:
+ // this match type is not accessible from the outside
+ // (it won't be matched in self::parseSubExpressions())
+ // it can be used internally to inject sub-expressions into the query.
+ // see Segment::getCleanedExpression()
+ $sqlMatch = '%s NOT IN (' . $value['sql'] . ')';
+ $value = $value['bind'];
+ break;
default:
throw new Exception("Filter contains the match type '" . $matchType . "' which is not supported");
break;
@@ -298,7 +307,7 @@ protected function getSqlMatchFromDefinition($def, &$availableTables)
$alsoMatchNULLValues = $alsoMatchNULLValues && !empty($value);
$sqlMatch = str_replace('%s', $field, $sqlMatch);
- if ($matchType === self::MATCH_ACTIONS_CONTAINS
+ if ($matchType === self::MATCH_ACTIONS_CONTAINS || $matchType === self::MATCH_ACTIONS_NOT_CONTAINS
|| is_null($value)
) {
$sqlExpression = "( $sqlMatch )";
diff --git a/plugins/CustomVariables b/plugins/CustomVariables
index 9b96b7eff45..49a252c8579 160000
--- a/plugins/CustomVariables
+++ b/plugins/CustomVariables
@@ -1 +1 @@
-Subproject commit 9b96b7eff455fe63fd2247dbc6a18416905d0dac
+Subproject commit 49a252c85792d4d6f52acb1232004deb180790d5
diff --git a/plugins/Live/Model.php b/plugins/Live/Model.php
index 9590cf00e3a..023d7169832 100644
--- a/plugins/Live/Model.php
+++ b/plugins/Live/Model.php
@@ -359,11 +359,12 @@ private function getLastMinutesCounterForQuery($idSite, $lastMinutes, $segment,
$now = $now ?: time();
$bind = $idSites;
- $bind[] = Date::factory($now - $lastMinutes * 60)->toString('Y-m-d H:i:s');
+ $startDate = Date::factory($now - $lastMinutes * 60);
+ $bind[] = $startDate->toString('Y-m-d H:i:s');
$where = $whereIdSites . "AND " . $where;
- $segment = new Segment($segment, $idSite);
+ $segment = new Segment($segment, $idSite, $startDate, $endDate = null);
$query = $segment->getSelectQuery($select, $from, $where, $bind);
$numVisitors = Db::getReader()->fetchOne($query['sql'], $query['bind']);
@@ -428,7 +429,7 @@ public function queryAdjacentVisitorId($idSite, $visitorId, $visitLastActionTime
$orderBy = "MAX(log_visit.visit_last_action_time) $orderByDir";
$groupBy = "log_visit.idvisitor";
- $segment = new Segment($segment, $idSite);
+ $segment = new Segment($segment, $idSite, $dateOneDayAgo, $dateOneDayInFuture);
$queryInfo = $segment->getSelectQuery($select, $from, $where, $whereBind, $orderBy, $groupBy);
$sql = "SELECT sub.idvisitor, sub.visit_last_action_time FROM ({$queryInfo['sql']}) as sub
@@ -466,7 +467,7 @@ public function makeLogVisitsQueryString($idSite, $startDate, $endDate, $segment
$filterSortOrder = 'DESC';
}
- $segment = new Segment($segment, $idSite);
+ $segment = new Segment($segment, $idSite, $startDate, $endDate);
// Subquery to use the indexes for ORDER BY
$select = "log_visit.*";
diff --git a/plugins/SegmentEditor/SegmentEditor.php b/plugins/SegmentEditor/SegmentEditor.php
index de89ca2c98d..59ac72ee9c5 100644
--- a/plugins/SegmentEditor/SegmentEditor.php
+++ b/plugins/SegmentEditor/SegmentEditor.php
@@ -201,12 +201,12 @@ private function getSegmentIfIsUnprocessed()
if (empty($segment)) {
return null;
}
- $segment = new Segment($segment, [$idSite]);
// get period
$date = Common::getRequestVar('date', false);
$periodStr = Common::getRequestVar('period', false);
$period = Period\Factory::build($periodStr, $date);
+ $segment = new Segment($segment, [$idSite], $period->getDateStart(), $period->getDateEnd());
// check if archiving is enabled. if so, the segment should have been processed.
$isArchivingDisabled = Rules::isArchivingDisabledFor([$idSite], $segment, $period);
diff --git a/plugins/Transitions/API.php b/plugins/Transitions/API.php
index 39435541a27..a517e8653d2 100644
--- a/plugins/Transitions/API.php
+++ b/plugins/Transitions/API.php
@@ -73,9 +73,9 @@ public function getTransitionsForAction($actionName, $actionType, $idSite, $peri
}
// prepare log aggregator
- $segment = new Segment($segment, $idSite);
$site = new Site($idSite);
$period = Period\Factory::build($period, $date);
+ $segment = new Segment($segment, $idSite, $period->getDateStart(), $period->getDateEnd());
$params = new ArchiveProcessor\Parameters($site, $period, $segment);
$logAggregator = new LogAggregator($params);
diff --git a/tests/PHPUnit/Integration/Archive/ChunksTest.php b/tests/PHPUnit/Integration/Archive/ChunksTest.php
index 96a598128e1..3a8c7bb71af 100644
--- a/tests/PHPUnit/Integration/Archive/ChunksTest.php
+++ b/tests/PHPUnit/Integration/Archive/ChunksTest.php
@@ -129,7 +129,7 @@ private function createArchiveProcessorParameters()
{
$oPeriod = PeriodFactory::makePeriodFromQueryParams('UTC', 'day', $this->date);
- $segment = new Segment(false, array(1));
+ $segment = new Segment(false, array(1), $oPeriod->getDateStart(), $oPeriod->getDateEnd());
$params = new Parameters(new Site(1), $oPeriod, $segment);
return $params;
diff --git a/tests/PHPUnit/Integration/ArchiveProcessingTest.php b/tests/PHPUnit/Integration/ArchiveProcessingTest.php
index 2db256a1419..9e63b2536dd 100644
--- a/tests/PHPUnit/Integration/ArchiveProcessingTest.php
+++ b/tests/PHPUnit/Integration/ArchiveProcessingTest.php
@@ -89,7 +89,7 @@ private function _createArchiveProcessor($periodLabel, $dateLabel, $siteTimezone
$site = $this->_createWebsite($siteTimezone);
$date = Date::factory($dateLabel);
$period = Period\Factory::build($periodLabel, $date);
- $segment = new Segment('', $site->getId());
+ $segment = new Segment('', $site->getId(), $period->getDateStart(), $period->getDateEnd());
$params = new ArchiveProcessor\Parameters($site, $period, $segment);
return new ArchiveProcessorTest($params);
diff --git a/tests/PHPUnit/Integration/SegmentTest.php b/tests/PHPUnit/Integration/SegmentTest.php
index 9c0e2464fea..ecca62eaf3c 100644
--- a/tests/PHPUnit/Integration/SegmentTest.php
+++ b/tests/PHPUnit/Integration/SegmentTest.php
@@ -10,10 +10,10 @@
use Exception;
use Piwik\ArchiveProcessor\Rules;
-use Piwik\Cache;
use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
+use Piwik\Date;
use Piwik\Db;
use Piwik\Segment;
use Piwik\Tests\Framework\Fixture;
@@ -274,7 +274,7 @@ public function test_getSelectQuery_whenJoinActionOnConversion()
$bind = array(1);
$segment = 'visitConvertedGoalId!=2;siteSearchCategory==Test;visitConvertedGoalId==1';
- $segment = new Segment($segment, $idSites = array());
+ $segment = new Segment($segment, $idSites = array(), Date::factory('2020-02-02 02:00:00'));
$query = $segment->getSelectQuery($select, $from, $where, $bind);
$this->assertQueryDoesNotFail($query);
@@ -286,11 +286,16 @@ public function test_getSelectQuery_whenJoinActionOnConversion()
FROM
" . Common::prefixTable('log_conversion') . " AS log_conversion
LEFT JOIN " . Common::prefixTable('log_link_visit_action') . " AS log_link_visit_action ON log_link_visit_action.idvisit = log_conversion.idvisit
+ LEFT JOIN log_visit AS log_visit ON log_visit.idvisit = log_conversion.idvisit
WHERE
( log_conversion.idvisit = ? )
AND
- ( ( log_conversion.idgoal IS NULL OR log_conversion.idgoal <> ? ) AND log_link_visit_action.search_cat = ? AND log_conversion.idgoal = ? )",
- "bind" => array(1, 2, 'Test', 1));
+ ( ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM " . Common::prefixTable('log_visit') . " AS log_visit
+ LEFT JOIN " . Common::prefixTable('log_conversion') . " AS log_conversion ON log_conversion.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? ) AND ( log_conversion.idgoal = ? )) )
+ AND log_link_visit_action.search_cat = ? AND log_conversion.idgoal = ? )",
+ "bind" => array(1, '2020-02-02 02:00:00', 2, 'Test', 1));
$this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query));
}
@@ -868,6 +873,124 @@ public function test_getSelectQuery_whenUnionOfSegmentsAreUsed()
$this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query));
}
+ public function test_getSelectQuery_whenUnionOfSegmentsAreUsedWithNotContainsCompare_usesSubQueryWithGivenStartDate()
+ {
+ $select = 'log_visit.*';
+ $from = 'log_visit';
+ $where = false;
+ $bind = array();
+
+ $segment = 'actionUrl!@myTestUrl';
+ $segment = new Segment($segment, $idSites = array(), Date::factory('2020-02-02 02:00:00'), Date::factory('2020-02-29 02:00:00'));
+
+ $logVisitTable = Common::prefixTable('log_visit');
+ $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action');
+
+ $query = $segment->getSelectQuery($select, $from, $where, $bind);
+
+ $expected = array(
+ "sql" => " SELECT log_visit.* FROM $logVisitTable AS log_visit
+ WHERE ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM $logVisitTable AS log_visit LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? AND log_visit.visit_last_action_time <= ? ) AND ( (( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 3 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 2 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 10 )) ) ))) ) ",
+ "bind" => array('2020-02-02 02:00:00', '2020-02-29 02:00:00', 'myTestUrl', 'myTestUrl', 'myTestUrl', 'myTestUrl'));
+
+ $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query));
+ }
+
+ public function test_getSelectQuery_whenUnionOfSegmentsAreUsedWithNotContainsCompare_usesNoSubQueryWithoutStartDate()
+ {
+ $select = 'log_visit.*';
+ $from = 'log_visit';
+ $where = false;
+ $bind = array();
+
+ $segment = 'actionUrl!@myTestUrl';
+
+ // When no start date is given for the segment object, it will not generate a subquery, as it might have too many results
+ // instead it will try to directly join the tables, which might cause incorrect results for action dimensions
+ $segment = new Segment($segment, $idSites = array(), $startDate = null, $endDate = null);
+
+ $logVisitTable = Common::prefixTable('log_visit');
+ $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action');
+
+ $query = $segment->getSelectQuery($select, $from, $where, $bind);
+
+ $expected = array(
+ "sql" => " SELECT log_inner.* FROM (
+ SELECT log_visit.* FROM $logVisitTable AS log_visit
+ LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE (( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name NOT LIKE CONCAT('%', ?, '%') AND type = 1 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name NOT LIKE CONCAT('%', ?, '%') AND type = 3 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name NOT LIKE CONCAT('%', ?, '%') AND type = 2 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name NOT LIKE CONCAT('%', ?, '%') AND type = 10 )) ) )
+ GROUP BY log_visit.idvisit ORDER BY NULL )
+ AS log_inner",
+ "bind" => array('myTestUrl', 'myTestUrl', 'myTestUrl', 'myTestUrl'));
+
+ $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query));
+ }
+
+ public function test_getSelectQuery_whenUsingNotEqualsCompareOnActionDimension()
+ {
+ $select = 'log_visit.*';
+ $from = 'log_visit';
+ $where = false;
+ $bind = array();
+
+ $segment = 'siteSearchCategory!=myCategory';
+ $segment = new Segment($segment, $idSites = array(), Date::factory('2020-02-02 02:00:00'));
+
+ $logVisitTable = Common::prefixTable('log_visit');
+ $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action');
+
+ $query = $segment->getSelectQuery($select, $from, $where, $bind);
+
+ $expected = array(
+ "sql" => " SELECT log_visit.* FROM $logVisitTable AS log_visit
+ WHERE ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM $logVisitTable AS log_visit LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? ) AND ( log_link_visit_action.search_cat = ? )) ) ",
+ "bind" => array('2020-02-02 02:00:00', 'myCategory'));
+
+ $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query));
+ }
+
+ public function test_getSelectQuery_whenUsingNotEqualsAndNotContainsCompareOnActionDimensionWithIdSitesAndDates()
+ {
+ $select = 'log_visit.*';
+ $from = 'log_visit';
+ $where = false;
+ $bind = array();
+
+ $segment = 'siteSearchCategory!=myCategory;actionUrl!@myTestUrl';
+ $segment = new Segment($segment, $idSites = array(1,5), Date::factory('2020-02-02 12:00:00'), Date::factory('2020-02-05 09:00:00'));
+
+ $logVisitTable = Common::prefixTable('log_visit');
+ $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action');
+
+ $query = $segment->getSelectQuery($select, $from, $where, $bind);
+
+ $expected = array(
+ "sql" => " SELECT log_visit.* FROM $logVisitTable AS log_visit
+ WHERE ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM $logVisitTable AS log_visit LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.idsite IN (?,?) AND log_visit.visit_last_action_time >= ? AND log_visit.visit_last_action_time <= ? ) AND ( log_link_visit_action.search_cat = ? )) )
+ AND ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM $logVisitTable AS log_visit LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.idsite IN (?,?) AND log_visit.visit_last_action_time >= ? AND log_visit.visit_last_action_time <= ? ) AND
+ ( (( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 3 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 2 )) ) OR
+ ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 10 )) ) ))) ) ",
+ "bind" => array(1, 5, '2020-02-02 12:00:00', '2020-02-05 09:00:00', 'myCategory', 1, 5, '2020-02-02 12:00:00', '2020-02-05 09:00:00', 'myTestUrl', 'myTestUrl', 'myTestUrl', 'myTestUrl'));
+
+ $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query));
+ }
+
public function test_getSelectQuery_whenJoinConversionOnLogLinkVisitAction_segmentUsesPageUrl()
{
$this->insertPageUrlAsAction('example.com/anypage');
@@ -1293,7 +1416,7 @@ public function test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_
* pageUrl!@found -- Matches none
*/
$segment = 'visitServerHour==12,pageUrl==xyz;pageUrl!=abcdefg,pageUrl=@does-not-exist,pageUrl=@found-in-db,pageUrl=='.urlencode($pageUrlFoundInDb).',pageUrl!@not-found,pageUrl!@found';
- $segment = new Segment($segment, $idSites = array());
+ $segment = new Segment($segment, $idSites = array(), Date::factory('2020-02-02 02:00:00'));
$query = $segment->getSelectQuery($select, $from, $where, $bind);
@@ -1310,22 +1433,31 @@ public function test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_
LEFT JOIN " . Common::prefixTable('log_link_visit_action') . " AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
WHERE (HOUR(log_visit.visit_last_action_time) = ?
OR (1 = 0)) " . // pageUrl==xyz
- "AND ((1 = 1) " . // pageUrl!=abcdefg
+ "AND (( log_visit.idvisit NOT IN ( SELECT log_visit.idvisit FROM log_visit AS log_visit WHERE ( log_visit.visit_last_action_time >= ? ) AND ( (1 = 0) )) ) " . // pageUrl!=abcdefg
" OR ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) ) " . // pageUrl=@does-not-exist
- " OR ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) )" . // pageUrl=@found-in-db
- " OR log_link_visit_action.idaction_url = ?" . // pageUrl=='.urlencode($pageUrlFoundInDb)
- " OR ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name NOT LIKE CONCAT('%', ?, '%') AND type = 1 )) )" . // pageUrl!@not-found
- " OR ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name NOT LIKE CONCAT('%', ?, '%') AND type = 1 )) )" . // pageUrl!@found
+ " OR ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) ) " . // pageUrl=@found-in-db
+ " OR log_link_visit_action.idaction_url = ? " . // pageUrl=='.urlencode($pageUrlFoundInDb)
+ " OR ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM log_visit AS log_visit LEFT JOIN log_link_visit_action AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? ) AND ( ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) )
+ )) ) " . // pageUrl!@not-found
+ " OR ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM log_visit AS log_visit LEFT JOIN log_link_visit_action AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? ) AND ( ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) )
+ )) )" . // pageUrl!@found
" )
GROUP BY log_visit.idvisit
ORDER BY NULL
) AS log_inner",
"bind" => array(
12,
+ '2020-02-02 02:00:00',
"does-not-exist",
"found-in-db",
$actionIdFoundInDb,
+ '2020-02-02 02:00:00',
"not-found",
+ '2020-02-02 02:00:00',
"found",
));
@@ -1355,7 +1487,7 @@ public function test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_
* pageUrl!@found -- Matches none
*/
$segment = 'visitServerHour==12,pageUrl==xyz;pageUrl!=abcdefg,pageUrl=@does-not-exist,pageUrl=@found-in-db,pageUrl=='.urlencode($pageUrlFoundInDb).',pageUrl!@not-found,pageUrl!@found';
- $segment = new Segment($segment, $idSites = array());
+ $segment = new Segment($segment, $idSites = array(), Date::factory('2020-02-02 02:00:00'));
$query = $segment->getSelectQuery($select, $from, $where, $bind);
@@ -1373,7 +1505,7 @@ public function test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_
WHERE (HOUR(log_visit.visit_last_action_time) = ?
OR (1 = 0))" . // pageUrl==xyz
"
- AND ((1 = 1) " . // pageUrl!=abcdefg
+ AND (( log_visit.idvisit NOT IN ( SELECT log_visit.idvisit FROM " . Common::prefixTable('log_visit') . " AS log_visit WHERE ( log_visit.visit_last_action_time >= ? ) AND ( (1 = 0) )) )" . // pageUrl!=abcdefg
"
OR (1 = 0) " . // pageUrl=@does-not-exist
"
@@ -1381,22 +1513,35 @@ public function test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_
"
OR log_link_visit_action.idaction_url = ?" . // pageUrl=='.urlencode($pageUrlFoundInDb)
"
- OR ( log_link_visit_action.idaction_url IN (?,?,?) )" . // pageUrl!@not-found
+ OR ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM " . Common::prefixTable('log_visit') . " AS log_visit
+ LEFT JOIN " . Common::prefixTable('log_link_visit_action') . " AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? ) AND ( ( log_link_visit_action.idaction_url IN (?) )
+ )) )" . // pageUrl!@not-found
"
- OR (1 = 0) " . // pageUrl!@found
+ OR ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit FROM " . Common::prefixTable('log_visit') . " AS log_visit
+ LEFT JOIN " . Common::prefixTable('log_link_visit_action') . " AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? ) AND ( ( log_link_visit_action.idaction_url IN (?,?,?,?) )
+ )) ) " . // pageUrl!@found
")
GROUP BY log_visit.idvisit
ORDER BY NULL
) AS log_inner",
"bind" => array(
12,
+ '2020-02-02 02:00:00',
1, // pageUrl=@found-in-db
2, // pageUrl=@found-in-db
3, // pageUrl=@found-in-db
$actionIdFoundInDb, // pageUrl=='.urlencode($pageUrlFoundInDb)
- 1, // pageUrl!@not-found
- 2, // pageUrl!@not-found
- 3, // pageUrl!@not-found
+ '2020-02-02 02:00:00',
+ 4, // pageUrl!@not-found
+ '2020-02-02 02:00:00',
+ 1, // pageUrl!@found
+ 2, // pageUrl!@found
+ 3, // pageUrl!@found
+ 4, // pageUrl!@found
));
$cache = StaticContainer::get('Piwik\Tracker\TableLogAction\Cache');
@@ -1411,13 +1556,13 @@ public function test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_
$this->assertCacheWasHit($hits = 0);
$this->test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_AND_withCacheSave();
- $this->assertCacheWasHit($hits = 8);
+ $this->assertCacheWasHit($hits = 20);
$this->test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_AND_withCacheSave();
- $this->assertCacheWasHit($hits = 20);
+ $this->assertCacheWasHit($hits = 44);
$this->test_getSelectQuery_whenPageUrlDoesNotExist_asBothStatements_OR_AND_withCacheSave();
- $this->assertCacheWasHit($hits = 32);
+ $this->assertCacheWasHit($hits = 68);
}
@@ -1437,10 +1582,10 @@ public function test_getSelectQuery_withTwoSegments_subqueryNotCached_whenResult
/**
* pageUrl=@found-in-db-bis -- Will be cached
- * pageUrl!@not-found -- Too big to cache
+ * siteSearchCategory!@not-found -- Too big to cache
*/
- $segment = 'pageUrl=@found-in-db-bis;pageUrl!@not-found';
- $segment = new Segment($segment, $idSites = array());
+ $segment = 'pageUrl=@found-in-db-bis;siteSearchCategory!@not-found';
+ $segment = new Segment($segment, $idSites = array(), Date::factory('2020-02-02 02:00:00'));
$query = $segment->getSelectQuery($select, $from, $where, $bind);
$this->assertQueryDoesNotFail($query);
@@ -1459,13 +1604,18 @@ public function test_getSelectQuery_withTwoSegments_subqueryNotCached_whenResult
WHERE
( log_link_visit_action.idaction_url IN (?) )" . // pageUrl=@found-in-db-bis
"
- AND ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name NOT LIKE CONCAT('%', ?, '%') AND type = 1 )) ) " . // pageUrl!@not-found
+ AND ( log_visit.idvisit NOT IN (
+ SELECT log_visit.idvisit
+ FROM log_visit AS log_visit
+ LEFT JOIN log_link_visit_action AS log_link_visit_action ON log_link_visit_action.idvisit = log_visit.idvisit
+ WHERE ( log_visit.visit_last_action_time >= ? ) AND ( log_link_visit_action.search_cat LIKE ? )) ) " . // siteSearchCategory!@not-found
"GROUP BY log_visit.idvisit
ORDER BY NULL
) AS log_inner",
"bind" => array(
2, // pageUrl=@found-in-db-bis
- "not-found", // pageUrl!@not-found
+ '2020-02-02 02:00:00',
+ "%not-found%", // siteSearchCategory!@not-found
));
$cache = StaticContainer::get('Piwik\Tracker\TableLogAction\Cache');
@@ -1481,11 +1631,11 @@ public function test_getSelectQuery_withTwoSegments_partiallyCached()
// this will create the caches for both segments
$this->test_getSelectQuery_withTwoSegments_subqueryNotCached_whenResultsetTooLarge();
- $this->assertCacheWasHit($hits = 4);
+ $this->assertCacheWasHit($hits = 2);
// this will hit caches for both segments
$this->test_getSelectQuery_withTwoSegments_subqueryNotCached_whenResultsetTooLarge();
- $this->assertCacheWasHit($hits = 10);
+ $this->assertCacheWasHit($hits = 5);
}
// se https://github.com/piwik/piwik/issues/9194
@@ -1615,7 +1765,7 @@ public function test_getSelectQuery_whenQueryingLogConversionWithSegmentThatUses
SELECT log_inner.idgoal AS `idgoal`, count(*) AS `1`, count(distinct log_inner.idvisit) AS `3`, ROUND(SUM(log_inner.revenue),2) AS `2`
FROM (
SELECT log_conversion.idgoal, log_conversion.idvisit, log_conversion.revenue
- FROM log_conversion AS log_conversion
+ FROM $logConversionTable AS log_conversion
LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action ON log_link_visit_action.idvisit = log_conversion.idvisit
LEFT JOIN $logVisitTable AS log_visit ON log_visit.idvisit = log_conversion.idvisit
WHERE ( log_conversion.server_time >= ?
@@ -1658,6 +1808,7 @@ private function insertActions()
// Adding some other actions to make test case more realistic
$this->insertPageUrlAsAction('example.net/found-in-db-bis');
$this->insertPageUrlAsAction('example.net/found-in-db-ter');
+ $this->insertPageUrlAsAction('example.net/page-not-found');
return array($pageUrlFoundInDb, $actionIdFoundInDb);
}
diff --git a/tests/PHPUnit/System/ManyVisitorsOneWebsiteTest.php b/tests/PHPUnit/System/ManyVisitorsOneWebsiteTest.php
index 56dcdeee3f3..46e3cd24c08 100644
--- a/tests/PHPUnit/System/ManyVisitorsOneWebsiteTest.php
+++ b/tests/PHPUnit/System/ManyVisitorsOneWebsiteTest.php
@@ -148,6 +148,23 @@ public function getApiForTesting()
'otherRequestParameters' => array('filter_offset' => '4', 'filter_limit' => 3)
));
+ // #13785
+ // check that not contains / not equals action segments filter away all visits having any matching action
+ $apiToTest[] = array('Live.getLastVisitsDetails', array(
+ 'idSite' => $idSite,
+ 'date' => $dateString,
+ 'periods' => 'month',
+ 'testSuffix' => '_pageurlNotContainsSegment',
+ 'segment' => 'pageUrl!@quest'
+ ));
+ $apiToTest[] = array('Live.getLastVisitsDetails', array(
+ 'idSite' => $idSite,
+ 'date' => $dateString,
+ 'periods' => 'month',
+ 'testSuffix' => '_siteSearchCategoryNotEqualsSegment',
+ 'segment' => 'siteSearchCategory!=CAT'
+ ));
+
// #8324
// testing filter_excludelowpop and filter_excludelowpop_value
$apiToTest[] = array('UserCountry.getCountry', array(
diff --git a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_pageurlNotContainsSegment__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_pageurlNotContainsSegment__Live.getLastVisitsDetails_month.xml
new file mode 100644
index 00000000000..01d74e66512
--- /dev/null
+++ b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_pageurlNotContainsSegment__Live.getLastVisitsDetails_month.xml
@@ -0,0 +1,1565 @@
+
+
+
+ 1
+ 35
+ 194.57.91.215
+
+ 5bc9628006479118
+
+
+ action
+ http://piwik.net/grue/lair
+ It's pitch black...
+ 2
+
+
+ 95
+
+ 1
+ It's pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ goal
+ all
+ 1
+
+ 5
+ 95
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+ userid.email@example.org
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ search
+ Search Engines
+ Google
+ wikileaks ftw
+
+ http://google.com/?q=Wikileaks FTW
+ http://google.com
+ plugins/Morpheus/icons/dist/searchEngines/google.com.png
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ WebKit
+ WebKit (Safari, Chrome)
+ Safari
+ Safari
+ plugins/Morpheus/icons/dist/browsers/SF.png
+ SF
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ North America
+ amn
+ United States
+ us
+ plugins/Morpheus/icons/dist/flags/us.png
+ California
+ CA
+ not a city
+ not a city, California, United States
+ 1
+ 2
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+
+
+ 1
+ 17
+ 1.2.4.8
+
+ a36244db4114afa7
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 45
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 8
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 8
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 45
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Unknown
+ unk
+ Unknown
+ xx
+ plugins/Morpheus/icons/dist/flags/xx.png
+
+
+
+ Unknown
+
+
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 8
+
+
+ Cvar 5 name
+ Cvar5 value is 8
+
+
+
+
+ 1
+ 15
+ 1.2.4.7
+
+ 28a7ee52024f3a89
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 40
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 7
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 7
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 40
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 3
+ none
+
+ 1
+ 86400
+ 0
+
+ 1
+ 1s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ North Macedonia
+ mk
+ plugins/Morpheus/icons/dist/flags/mk.png
+ Gevgelija
+ 18
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Gevgelija, North Macedonia
+
+
+ 12:34:06
+ 12
+ 0
+ 82800
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 7
+
+
+ Cvar 5 name
+ Cvar5 value is 7
+
+
+
+
+ 1
+ 13
+ 1.2.4.6
+
+ 289e2fcbb06929fa
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 34
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 6
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 6
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 34
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ Russia
+ ru
+ plugins/Morpheus/icons/dist/flags/ru.png
+ Sankt-Peterburg
+ SPE
+ Hluboká nad Vltavou
+ Hluboká nad Vltavou, Sankt-Peterburg, Russia
+
+
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 6
+
+
+ Cvar 5 name
+ Cvar5 value is 6
+
+
+
+
+ 1
+ 11
+ 1.2.4.5
+
+ 3e5f540b8952a4ab
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 29
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 5
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 5
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 29
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 3
+ none
+
+ 1
+ 86400
+ 0
+
+ 1
+ 1s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ Russia
+ ru
+ plugins/Morpheus/icons/dist/flags/ru.png
+ Sankt-Peterburg
+ SPE
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Sankt-Peterburg, Russia
+
+
+ 12:34:06
+ 12
+ 0
+ 82800
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 5
+
+
+ Cvar 5 name
+ Cvar5 value is 5
+
+
+
+
+ 1
+ 9
+ 1.2.4.4
+
+ 17b5ac19cce8a192
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 23
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 4
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 4
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 23
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ United Kingdom
+ gb
+ plugins/Morpheus/icons/dist/flags/gb.png
+ Kent
+ KEN
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Kent, United Kingdom
+
+
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 4
+
+
+ Cvar 5 name
+ Cvar5 value is 4
+
+
+
+
+ 1
+ 7
+ 1.2.4.3
+
+ 9b641f2d195745f4
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 18
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 3
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 3
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 18
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 3
+ none
+
+ 1
+ 86400
+ 0
+
+ 1
+ 1s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ United Kingdom
+ gb
+ plugins/Morpheus/icons/dist/flags/gb.png
+ London, City of
+ LND
+ London
+ London, London, City of, United Kingdom
+
+
+ 12:34:06
+ 12
+ 0
+ 82800
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 3
+
+
+ Cvar 5 name
+ Cvar5 value is 3
+
+
+
+
+ 1
+ 29
+ 113.62.1.1
+
+ d5a95c7fe2a8286d
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 79
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 3
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 3
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 79
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 3
+ none
+
+ 1
+ 86400
+ 0
+
+ 1
+ 1s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+
+ Unknown
+ Tablet
+ plugins/Morpheus/icons/dist/devices/tablet.png
+ Sony
+ Xperia Tablet S
+ Android 4.1
+ Android
+ plugins/Morpheus/icons/dist/os/AND.png
+ AND
+ 4.1
+ Blink
+ Blink (Chrome, Opera)
+ Chrome 34.0
+ Chrome
+ plugins/Morpheus/icons/dist/browsers/CH.png
+ CH
+ 34.0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Asia
+ asi
+ China
+ cn
+ plugins/Morpheus/icons/dist/flags/cn.png
+ Xizang Zizhiqu
+ XZ
+ Lhasa
+ Lhasa, Xizang Zizhiqu, China
+ 29.650000
+ 91.100000
+ 12:34:06
+ 12
+ 0
+ 82800
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 3
+
+
+ Cvar 5 name
+ Cvar5 value is 3
+
+
+
+
+ 1
+ 5
+ 1.2.4.2
+
+ 85aaa85a2071daf5
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 12
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 2
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 2
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 12
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ United Kingdom
+ gb
+ plugins/Morpheus/icons/dist/flags/gb.png
+ Warwickshire
+ WAR
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Warwickshire, United Kingdom
+ 124.456000
+ 22.231000
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 2
+
+
+ Cvar 5 name
+ Cvar5 value is 2
+
+
+
+
+ 1
+ 27
+ 2003:f6:93bf:26f:9ec7:a6ff:fe29:27df
+
+ b6f1d5120b2b15a2
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 73
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 2
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 2
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 73
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+
+ Unknown
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Dell
+ Generic Desktop
+ Windows 7
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ 7
+ Trident
+ Trident (IE)
+ Internet Explorer 11.0
+ Internet Explorer
+ plugins/Morpheus/icons/dist/browsers/IE.png
+ IE
+ 11.0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ North America
+ amn
+ United States
+ us
+ plugins/Morpheus/icons/dist/flags/us.png
+
+
+
+ United States
+ 38
+ -97
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 2
+
+
+ Cvar 5 name
+ Cvar5 value is 2
+
+
+
+
\ No newline at end of file
diff --git a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_siteSearchCategoryNotEqualsSegment__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_siteSearchCategoryNotEqualsSegment__Live.getLastVisitsDetails_month.xml
new file mode 100644
index 00000000000..b376ceea5b4
--- /dev/null
+++ b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_siteSearchCategoryNotEqualsSegment__Live.getLastVisitsDetails_month.xml
@@ -0,0 +1,1817 @@
+
+
+
+ 1
+ 35
+ 194.57.91.215
+
+ 5bc9628006479118
+
+
+ action
+ http://piwik.net/grue/lair
+ It's pitch black...
+ 2
+
+
+ 95
+
+ 1
+ It's pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ goal
+ all
+ 1
+
+ 5
+ 95
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+ userid.email@example.org
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ search
+ Search Engines
+ Google
+ wikileaks ftw
+
+ http://google.com/?q=Wikileaks FTW
+ http://google.com
+ plugins/Morpheus/icons/dist/searchEngines/google.com.png
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ WebKit
+ WebKit (Safari, Chrome)
+ Safari
+ Safari
+ plugins/Morpheus/icons/dist/browsers/SF.png
+ SF
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ North America
+ amn
+ United States
+ us
+ plugins/Morpheus/icons/dist/flags/us.png
+ California
+ CA
+ not a city
+ not a city, California, United States
+ 1
+ 2
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+
+
+ 1
+ 17
+ 1.2.4.8
+
+ a36244db4114afa7
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 45
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 8
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 8
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 45
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Unknown
+ unk
+ Unknown
+ xx
+ plugins/Morpheus/icons/dist/flags/xx.png
+
+
+
+ Unknown
+
+
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 8
+
+
+ Cvar 5 name
+ Cvar5 value is 8
+
+
+
+
+ 1
+ 16
+ 1.2.4.7
+
+ 28a7ee52024f3a89
+
+
+ action
+ http://piwik.net/space/quest/iv
+ Space Quest XII
+ 4
+
+
+ 41
+
+ 180
+ 3 min 0s
+ 1
+ Space Quest XII
+ http://piwik.net/space/quest/iv
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ goal
+ all
+ 1
+
+ 5
+ 41
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ goal
+ two
+ 2
+
+ 5
+
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ two ($5 revenue)
+
+
+
+ download
+ http://example.org/path/file7.zip
+
+ 42
+
+
+ 42
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/download.png
+ plugins/Morpheus/images/download.svg
+ Download
+ http://example.org/path/file7.zip
+
+ 0 M
+
+
+ outlink
+ http://example-outlink.org/7.html
+
+ 43
+
+
+ 43
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/link.png
+ plugins/Morpheus/images/link.svg
+ Outlink
+ http://example-outlink.org/7.html
+
+ 0 M
+
+
+ event
+ http://piwik.net/space/quest/iv
+ 8
+
+
+ 44
+ Cat7
+ Action7
+
+ 1
+
+ plugins/Morpheus/images/event.png
+ plugins/Morpheus/images/event.svg
+ Event
+ Category: "Cat7', Action: "Action7"
+ Name7
+ 352.678
+ 0 M
+
+
+ 2
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 4
+ none
+
+ 1
+ 90000
+ 0
+
+ 1621
+ 27 min 1s
+ 0
+ 4
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ Europe
+ eur
+ North Macedonia
+ mk
+ plugins/Morpheus/icons/dist/flags/mk.png
+ Gevgelija
+ 18
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Gevgelija, North Macedonia
+
+
+ 12:34:06
+ 12
+ 0
+ 3600
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 7
+
+
+ Cvar 5 name
+ Cvar5 value is 7
+
+
+
+
+ 1
+ 15
+ 1.2.4.7
+
+ 28a7ee52024f3a89
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 40
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 7
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 7
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 40
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 3
+ none
+
+ 1
+ 86400
+ 0
+
+ 1
+ 1s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ North Macedonia
+ mk
+ plugins/Morpheus/icons/dist/flags/mk.png
+ Gevgelija
+ 18
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Gevgelija, North Macedonia
+
+
+ 12:34:06
+ 12
+ 0
+ 82800
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 7
+
+
+ Cvar 5 name
+ Cvar5 value is 7
+
+
+
+
+ 1
+ 13
+ 1.2.4.6
+
+ 289e2fcbb06929fa
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 34
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 6
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 6
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 34
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ Russia
+ ru
+ plugins/Morpheus/icons/dist/flags/ru.png
+ Sankt-Peterburg
+ SPE
+ Hluboká nad Vltavou
+ Hluboká nad Vltavou, Sankt-Peterburg, Russia
+
+
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 6
+
+
+ Cvar 5 name
+ Cvar5 value is 6
+
+
+
+
+ 1
+ 12
+ 1.2.4.5
+
+ 3e5f540b8952a4ab
+
+
+ action
+ http://piwik.net/space/quest/iv
+ Space Quest XII
+ 4
+
+
+ 30
+
+ 180
+ 3 min 0s
+ 1
+ Space Quest XII
+ http://piwik.net/space/quest/iv
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ goal
+ all
+ 1
+
+ 5
+ 30
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ goal
+ two
+ 2
+
+ 5
+
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ two ($5 revenue)
+
+
+
+ download
+ http://example.org/path/file5.zip
+
+ 32
+
+
+ 31
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/download.png
+ plugins/Morpheus/images/download.svg
+ Download
+ http://example.org/path/file5.zip
+
+ 0 M
+
+
+ outlink
+ http://example-outlink.org/5.html
+
+ 33
+
+
+ 32
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/link.png
+ plugins/Morpheus/images/link.svg
+ Outlink
+ http://example-outlink.org/5.html
+
+ 0 M
+
+
+ event
+ http://piwik.net/space/quest/iv
+ 8
+
+
+ 33
+ Cat5
+ Action5
+
+ 1
+
+ plugins/Morpheus/images/event.png
+ plugins/Morpheus/images/event.svg
+ Event
+ Category: "Cat5', Action: "Action5"
+ Name5
+ 350.678
+ 0 M
+
+
+ 2
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 4
+ none
+
+ 1
+ 90000
+ 0
+
+ 1621
+ 27 min 1s
+ 0
+ 4
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ Europe
+ eur
+ Russia
+ ru
+ plugins/Morpheus/icons/dist/flags/ru.png
+ Sankt-Peterburg
+ SPE
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Sankt-Peterburg, Russia
+
+
+ 12:34:06
+ 12
+ 0
+ 3600
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 5
+
+
+ Cvar 5 name
+ Cvar5 value is 5
+
+
+
+
+ 1
+ 11
+ 1.2.4.5
+
+ 3e5f540b8952a4ab
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 29
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 5
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 5
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 29
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 3
+ none
+
+ 1
+ 86400
+ 0
+
+ 1
+ 1s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ Russia
+ ru
+ plugins/Morpheus/icons/dist/flags/ru.png
+ Sankt-Peterburg
+ SPE
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Sankt-Peterburg, Russia
+
+
+ 12:34:06
+ 12
+ 0
+ 82800
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 5
+
+
+ Cvar 5 name
+ Cvar5 value is 5
+
+
+
+
+ 1
+ 9
+ 1.2.4.4
+
+ 17b5ac19cce8a192
+
+
+ action
+ http://piwik.net/grue/lair
+ It's <script> pitch black...
+ 2
+
+
+ 23
+
+ 1
+ It's <script> pitch black...
+ http://piwik.net/grue/lair
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ Cvar 2 PAGE name
+ Cvar2 PAGE value is 4
+
+
+ Cvar 5 PAGE name
+ Cvar5 PAGE value is 4
+
+
+
+
+ goal
+ all
+ 1
+
+ 5
+ 23
+
+ http://piwik.net/grue/lair
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ 1
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ new
+
+ 1
+ plugins/Morpheus/images/goal.svg
+ 1
+ none
+
+ 0
+ 0
+ 0
+
+ 0
+ 0s
+ 0
+ 1
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ Europe
+ eur
+ United Kingdom
+ gb
+ plugins/Morpheus/icons/dist/flags/gb.png
+ Kent
+ KEN
+ Stratford-upon-Avon
+ Stratford-upon-Avon, Kent, United Kingdom
+
+
+ 12:34:06
+ 12
+ 0
+ 0
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 4
+
+
+ Cvar 5 name
+ Cvar5 value is 4
+
+
+
+
+ 1
+ 8
+ 1.2.4.3
+
+ 9b641f2d195745f4
+
+
+ action
+ http://piwik.net/space/quest/iv
+ Space Quest XII
+ 4
+
+
+ 19
+
+ 180
+ 3 min 0s
+ 1
+ Space Quest XII
+ http://piwik.net/space/quest/iv
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ goal
+ all
+ 1
+
+ 5
+ 19
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ goal
+ two
+ 2
+
+ 5
+
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ two ($5 revenue)
+
+
+
+ download
+ http://example.org/path/file3.zip
+
+ 22
+
+
+ 20
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/download.png
+ plugins/Morpheus/images/download.svg
+ Download
+ http://example.org/path/file3.zip
+
+ 0 M
+
+
+ outlink
+ http://example-outlink.org/3.html
+
+ 23
+
+
+ 21
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/link.png
+ plugins/Morpheus/images/link.svg
+ Outlink
+ http://example-outlink.org/3.html
+
+ 0 M
+
+
+ event
+ http://piwik.net/space/quest/iv
+ 8
+
+
+ 22
+ Cat3
+ Action3
+
+ 1
+
+ plugins/Morpheus/images/event.png
+ plugins/Morpheus/images/event.svg
+ Event
+ Category: "Cat3', Action: "Action3"
+ Name3
+ 348.678
+ 0 M
+
+
+ 2
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 4
+ none
+
+ 1
+ 90000
+ 0
+
+ 1621
+ 27 min 1s
+ 0
+ 4
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+ fr
+ French
+ Desktop
+ plugins/Morpheus/icons/dist/devices/desktop.png
+ Unknown
+ Generic Desktop
+ Windows XP
+ Windows
+ plugins/Morpheus/icons/dist/os/WIN.png
+ WIN
+ XP
+ Gecko
+ Gecko (Firefox)
+ Firefox 3.6
+ Firefox
+ plugins/Morpheus/icons/dist/browsers/FF.png
+ FF
+ 3.6
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ Europe
+ eur
+ United Kingdom
+ gb
+ plugins/Morpheus/icons/dist/flags/gb.png
+ London, City of
+ LND
+ London
+ London, London, City of, United Kingdom
+
+
+ 12:34:06
+ 12
+ 0
+ 3600
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+ Cvar 1 name
+ Cvar1 value is 3
+
+
+ Cvar 5 name
+ Cvar5 value is 3
+
+
+
+
+ 1
+ 30
+ 113.62.1.1
+
+ d5a95c7fe2a8286d
+
+
+ action
+ http://piwik.net/space/quest/iv
+ Space Quest XII
+ 4
+
+
+ 80
+
+ 180
+ 3 min 0s
+ 1
+ Space Quest XII
+ http://piwik.net/space/quest/iv
+
+ plugins/Morpheus/images/action.svg
+
+ 0 M
+
+
+ goal
+ all
+ 1
+
+ 5
+ 80
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ all ($5 revenue)
+
+
+
+ goal
+ two
+ 2
+
+ 5
+
+
+ http://piwik.net/space/quest/iv
+ plugins/Morpheus/images/goal.png
+ plugins/Morpheus/images/goal.svg
+ Goal conversion
+ two ($5 revenue)
+
+
+
+ download
+ http://example.org/path/file3.zip
+
+ 22
+
+
+ 81
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/download.png
+ plugins/Morpheus/images/download.svg
+ Download
+ http://example.org/path/file3.zip
+
+ 0 M
+
+
+ outlink
+ http://example-outlink.org/3.html
+
+ 23
+
+
+ 82
+
+ 180
+ 3 min 0s
+ 1
+ plugins/Morpheus/images/link.png
+ plugins/Morpheus/images/link.svg
+ Outlink
+ http://example-outlink.org/3.html
+
+ 0 M
+
+
+ event
+ http://piwik.net/space/quest/iv
+ 8
+
+
+ 83
+ Cat3
+ Action3
+
+ 1
+
+ plugins/Morpheus/images/event.png
+ plugins/Morpheus/images/event.svg
+ Event
+ Category: "Cat3', Action: "Action3"
+ Name3
+ 348.678
+ 0 M
+
+
+ 2
+ USD
+ $
+
+
+
+
+ Site 1
+
+
+
+
+
+
+
+ returning
+ plugins/Live/images/returningVisitor.png
+ 1
+ plugins/Morpheus/images/goal.svg
+ 4
+ none
+
+ 1
+ 90000
+ 0
+
+ 1621
+ 27 min 1s
+ 0
+ 4
+ 1
+ direct
+ Direct Entry
+
+
+
+
+
+
+
+
+
+ Unknown
+ Tablet
+ plugins/Morpheus/icons/dist/devices/tablet.png
+ Sony
+ Xperia Tablet S
+ Android 4.1
+ Android
+ plugins/Morpheus/icons/dist/os/AND.png
+ AND
+ 4.1
+ Blink
+ Blink (Chrome, Opera)
+ Chrome 34.0
+ Chrome
+ plugins/Morpheus/icons/dist/browsers/CH.png
+ CH
+ 34.0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ Asia
+ asi
+ China
+ cn
+ plugins/Morpheus/icons/dist/flags/cn.png
+ Xizang Zizhiqu
+ XZ
+ Lhasa
+ Lhasa, Xizang Zizhiqu, China
+ 29.650000
+ 91.100000
+ 12:34:06
+ 12
+ 0
+ 3600
+ 1024x768
+ cookie, flash, java
+
+
+ plugins/Morpheus/icons/dist/plugins/cookie.png
+ cookie
+
+
+ plugins/Morpheus/icons/dist/plugins/flash.png
+ flash
+
+
+ plugins/Morpheus/icons/dist/plugins/java.png
+ java
+
+
+
+
+
+
\ No newline at end of file