diff options
author | Fabian Becker <halfdan@xnorfz.de> | 2013-06-22 23:47:29 +0400 |
---|---|---|
committer | Fabian Becker <halfdan@xnorfz.de> | 2013-06-22 23:47:29 +0400 |
commit | 165ac7aeec855234e8c60bd758fad39bd6659adf (patch) | |
tree | e42ace9f7f45e420f883245a8df1beefa8eac9b0 /plugins/Transitions | |
parent | 89d41940a87d449114f529df115b62d3987f88ce (diff) | |
parent | e2e5176279255b7ff2d80f0f511a1ef5f3748ebe (diff) |
Huge merge! Lets see how the tests run..
Merge branch 'master' into 2.x-twig
Conflicts:
core/ReportRenderer/Html.php
core/SmartyPlugins/function.ajaxLoadingDiv.php
plugins/CoreAdminHome/templates/jsTrackingGenerator.tpl
plugins/CoreHome/templates/donate.tpl
plugins/CoreHome/templates/html_report_header.tpl
plugins/CoreHome/templates/menu.tpl
plugins/CoreHome/templates/period_select.tpl
plugins/CoreHome/templates/reports_by_dimension.tpl
plugins/Feedback/templates/index.tpl
plugins/Goals/Controller.php
plugins/Goals/templates/overview.tpl
plugins/Live/API.php
plugins/Live/templates/lastVisits.tpl
plugins/Live/templates/visitorLog.tpl
plugins/MobileMessaging/templates/SMSReport.tpl
plugins/PDFReports/templates/add.tpl
plugins/PDFReports/templates/list.tpl
plugins/PDFReports/templates/report_parameters.tpl
plugins/SEO/templates/index.tpl
plugins/SegmentEditor/templates/selector.twig
plugins/UserCountry/javascripts/userCountry.js
plugins/Zeitgeist/stylesheets/common.css
tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest__UserCountry.getCity_month.xml
tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest__UserCountry.getCountry_month.xml
tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest__UserCountry.getRegion_month.xml
tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_segment_continent__UserCountry.getCountry_month.xml
Diffstat (limited to 'plugins/Transitions')
-rw-r--r-- | plugins/Transitions/API.php | 394 | ||||
-rw-r--r-- | plugins/Transitions/Transitions.php | 331 |
2 files changed, 355 insertions, 370 deletions
diff --git a/plugins/Transitions/API.php b/plugins/Transitions/API.php index 4457d71046..1c2934ca74 100644 --- a/plugins/Transitions/API.php +++ b/plugins/Transitions/API.php @@ -62,15 +62,14 @@ class Piwik_Transitions_API } // prepare archive processing that can be used by the archiving code - $archiveProcessing = new Piwik_ArchiveProcessing_Day(); - $archiveProcessing->setSite(new Piwik_Site($idSite)); - $archiveProcessing->setPeriod(Piwik_Period::advancedFactory($period, $date)); - $archiveProcessing->setSegment(new Piwik_Segment($segment, $idSite)); - $archiveProcessing->initForLiveUsage(); - + $segment = new Piwik_Segment($segment, $idSite); + $site = new Piwik_Site($idSite); + $period = Piwik_Period::advancedFactory($period, $date); + $archiveProcessor = new Piwik_ArchiveProcessor_Day($period, $site, $segment); + $logAggregator = $archiveProcessor->getLogAggregator(); // 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 @@ -82,23 +81,20 @@ class Piwik_Transitions_API $partsArray = explode(',', $parts); if ($parts == 'all' || in_array('internalReferrers', $partsArray)) { - $this->addInternalReferrers($transitionsArchiving, $archiveProcessing, $report, $idaction, - $actionType, $limitBeforeGrouping); + $this->addInternalReferrers($logAggregator, $report, $idaction, $actionType, $limitBeforeGrouping); } if ($parts == 'all' || in_array('followingActions', $partsArray)) { $includeLoops = $parts != 'all' && !in_array('internalReferrers', $partsArray); - $this->addFollowingActions($transitionsArchiving, $archiveProcessing, $report, $idaction, - $actionType, $limitBeforeGrouping, $includeLoops); + $this->addFollowingActions($logAggregator, $report, $idaction, $actionType, $limitBeforeGrouping, $includeLoops); } if ($parts == 'all' || in_array('externalReferrers', $partsArray)) { - $this->addExternalReferrers($transitionsArchiving, $archiveProcessing, $report, $idaction, - $actionType, $limitBeforeGrouping); + $this->addExternalReferrers($logAggregator, $report, $idaction, $actionType, $limitBeforeGrouping); } // derive the number of exits from the other metrics if ($parts == 'all') { $report['pageMetrics']['exits'] = $report['pageMetrics']['pageviews'] - - $transitionsArchiving->getTotalTransitionsToFollowingActions() + - $this->getTotalTransitionsToFollowingActions() - $report['pageMetrics']['loops']; } @@ -113,9 +109,9 @@ class Piwik_Transitions_API ); foreach ($reportNames as $reportName => $replaceLabel) { if (isset($report[$reportName])) { - $columnNames = array(Piwik_Archive::INDEX_NB_ACTIONS => 'referrals'); + $columnNames = array(Piwik_Metrics::INDEX_NB_ACTIONS => 'referrals'); if ($replaceLabel) { - $columnNames[Piwik_Archive::INDEX_NB_ACTIONS] = 'referrals'; + $columnNames[Piwik_Metrics::INDEX_NB_ACTIONS] = 'referrals'; } $report[$reportName]->filter('ReplaceColumnNames', array($columnNames)); } @@ -139,7 +135,7 @@ class Piwik_Transitions_API if ($id < 0) { // an example where this is needed is urls containing < or > $actionName = $originalActionName; - $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_url', Piwik_SegmentExpression::MATCH_EQUALs, 'pageUrl'); + $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_url', Piwik_SegmentExpression::MATCH_EQUAL, 'pageUrl'); } return $id; @@ -167,20 +163,17 @@ class Piwik_Transitions_API * Add the internal referrers to the report: * previous pages and previous site searches * - * @param Piwik_Transitions $transitionsArchiving - * @param $archiveProcessing + * @param Piwik_DataAccess_LogAggregator $logAggregator * @param $report * @param $idaction * @param string $actionType * @param $limitBeforeGrouping * @throws Exception */ - private function addInternalReferrers($transitionsArchiving, $archiveProcessing, &$report, - $idaction, $actionType, $limitBeforeGrouping) + private function addInternalReferrers($logAggregator, &$report, $idaction, $actionType, $limitBeforeGrouping) { - $data = $transitionsArchiving->queryInternalReferrers( - $idaction, $actionType, $archiveProcessing, $limitBeforeGrouping); + $data = $this->queryInternalReferrers($idaction, $actionType, $logAggregator, $limitBeforeGrouping); if ($data['pageviews'] == 0) { throw new Exception('NoDataForAction'); @@ -196,49 +189,375 @@ class Piwik_Transitions_API * Add the following actions to the report: * following pages, downloads, outlinks * - * @param Piwik_Transitions $transitionsArchiving - * @param $archiveProcessing + * @param Piwik_DataAccess_LogAggregator $logAggregator * @param $report * @param $idaction * @param string $actionType * @param $limitBeforeGrouping * @param boolean $includeLoops */ - private function addFollowingActions($transitionsArchiving, $archiveProcessing, &$report, - $idaction, $actionType, $limitBeforeGrouping, $includeLoops = false) + private function addFollowingActions($logAggregator, &$report, $idaction, $actionType, $limitBeforeGrouping, $includeLoops = false) { - $data = $transitionsArchiving->queryFollowingActions( - $idaction, $actionType, $archiveProcessing, $limitBeforeGrouping, $includeLoops); + $data = $this->queryFollowingActions( + $idaction, $actionType, $logAggregator, $limitBeforeGrouping, $includeLoops); foreach ($data as $tableName => $table) { $report[$tableName] = $table; } } + + + /** + * Get information about the following actions (following pages, site searches, outlinks, downloads) + * + * @param $idaction + * @param $actionType + * @param Piwik_DataAccess_LogAggregator $logAggregator + * @param $limitBeforeGrouping + * @param $includeLoops + * @return array(followingPages:Piwik_DataTable, outlinks:Piwik_DataTable, downloads:Piwik_DataTable) + */ + public function queryFollowingActions($idaction, $actionType, Piwik_DataAccess_LogAggregator $logAggregator, + $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_Metrics::INDEX_NB_ACTIONS); + $data = $logAggregator->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_Metrics::INDEX_NB_ACTIONS]); + $dataTable->addRow(new Piwik_DataTable_Row(array( + Piwik_DataTable_Row::COLUMNS => array( + 'label' => $this->getPageLabel($record, $isTitle), + Piwik_Metrics::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 $logAggregator + * @param $limitBeforeGrouping + * @return Piwik_DataTable + */ + public function queryExternalReferrers($idaction, $actionType, $logAggregator, + $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_Metrics::INDEX_NB_VISITS); + $data = $logAggregator->queryVisitsByDimension($dimensions, $where, $selects, $metrics, $rankingQuery); + + $referrerData = array(); + $referrerSubData = array(); + + foreach ($data as $referrerType => &$subData) { + $referrerData[$referrerType] = array(Piwik_Metrics::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_Metrics::INDEX_NB_VISITS] += $row[Piwik_Metrics::INDEX_NB_VISITS]; + + $label = $row['referrer_data']; + if ($label) { + $referrerSubData[$referrerType][$label] = array( + Piwik_Metrics::INDEX_NB_VISITS => $row[Piwik_Metrics::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 $logAggregator + * @param $limitBeforeGrouping + * @return array(previousPages:Piwik_DataTable, loops:integer) + */ + protected function queryInternalReferrers($idaction, $actionType, $logAggregator, + $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_Metrics::INDEX_NB_ACTIONS); + $data = $logAggregator->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_Metrics::INDEX_NB_ACTIONS]); + $previousPagesDataTable->addRow(new Piwik_DataTable_Row(array( + Piwik_DataTable_Row::COLUMNS => array( + 'label' => $this->getPageLabel($page, $isTitle), + Piwik_Metrics::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_Metrics::INDEX_NB_ACTIONS]); + $previousSearchesDataTable->addRow(new Piwik_DataTable_Row(array( + Piwik_DataTable_Row::COLUMNS => array( + 'label' => $search['name'], + Piwik_Metrics::INDEX_NB_ACTIONS => $nbActions + ) + ))); + $nbPageviews += $nbActions; + } + } + + if (isset($data['result'][0])) { + foreach ($data['result'][0] as &$referrer) { + $nbPageviews += intval($referrer[Piwik_Metrics::INDEX_NB_ACTIONS]); + } + } + + if (count($data['excludedFromLimit'])) { + $loops += intval($data['excludedFromLimit'][0][Piwik_Metrics::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 * - * @param Piwik_Transitions $transitionsArchiving - * @param $archiveProcessing + * @param Piwik_DataAccess_LogAggregator $logAggregator * @param $report * @param $idaction * @param string $actionType * @param $limitBeforeGrouping */ - private function addExternalReferrers($transitionsArchiving, $archiveProcessing, &$report, + private function addExternalReferrers($logAggregator, &$report, $idaction, $actionType, $limitBeforeGrouping) { - $data = $transitionsArchiving->queryExternalReferrers( - $idaction, $actionType, $archiveProcessing, $limitBeforeGrouping); + $data = $this->queryExternalReferrers( + $idaction, $actionType, $logAggregator, $limitBeforeGrouping); $report['pageMetrics']['entries'] = 0; $report['referrers'] = array(); foreach ($data->getRows() as $row) { $referrerId = $row->getColumn('label'); - $visits = $row->getColumn(Piwik_Archive::INDEX_NB_VISITS); + $visits = $row->getColumn(Piwik_Metrics::INDEX_NB_VISITS); if ($visits) { // load details (i.e. subtables) $details = array(); @@ -247,7 +566,7 @@ class Piwik_Transitions_API foreach ($subTable->getRows() as $subRow) { $details[] = array( 'label' => $subRow->getColumn('label'), - 'referrals' => $subRow->getColumn(Piwik_Archive::INDEX_NB_VISITS) + 'referrals' => $subRow->getColumn(Piwik_Metrics::INDEX_NB_VISITS) ); } } @@ -289,9 +608,6 @@ class Piwik_Transitions_API } } - /** - * @ignore - */ public function getTranslations() { $controller = new Piwik_Transitions_Controller(); diff --git a/plugins/Transitions/Transitions.php b/plugins/Transitions/Transitions.php index 0e43c1cef9..b503266fc3 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,331 +45,5 @@ class Piwik_Transitions extends Piwik_Plugin $jsFiles[] = 'plugins/Transitions/javascripts/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_ArchiveProcessing_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. - $dimension = 'referrer_data'; - $rankingQuery->addLabelColumn('referrer_data'); - $select = ' - 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, - referer_type'; - - // 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 - )); - - $orderBy = '`' . Piwik_Archive::INDEX_NB_VISITS . '` DESC'; - - $type = $this->getColumnTypeSuffix($actionType); - $where = 'visit_entry_idaction_' . $type . ' = ' . intval($idaction); - - $metrics = array(Piwik_Archive::INDEX_NB_VISITS); - $data = $archiveProcessing->queryVisitsByDimension($dimension, $where, $metrics, $orderBy, - $rankingQuery, $select, $selectGeneratesLabelColumn = true); - - $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::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] - ); - } - } - } - - return $archiveProcessing->getDataTableWithSubtablesFromArraysIndexedByLabel($referrerSubData, $referrerData); - } - - /** - * Get information about internal referrers (previous pages & loops, i.e. page refreshes) - * - * @param $idaction - * @param $actionType - * @param Piwik_ArchiveProcessing_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'; - } - - $addSelect = ' - 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); - } - - $orderBy = '`' . Piwik_Archive::INDEX_NB_ACTIONS . '` DESC'; - - $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS); - $data = $archiveProcessing->queryActionsByDimension($dimension, $where, $metrics, $orderBy, - $rankingQuery, $joinLogActionOn, $addSelect); - - $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_ArchiveProcessing_Day $archiveProcessing - * @param $limitBeforeGrouping - * @param $includeLoops - * @return array(followingPages:Piwik_DataTable, outlinks:Piwik_DataTable, downloads:Piwik_DataTable) - */ - public function queryFollowingActions($idaction, $actionType, Piwik_ArchiveProcessing_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; - $addSelect = '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 - '; - $addSelect = ' - 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) . ')'; - } - - $orderBy = '`' . Piwik_Archive::INDEX_NB_ACTIONS . '` DESC'; - - $metrics = array(Piwik_Archive::INDEX_NB_ACTIONS); - $data = $archiveProcessing->queryActionsByDimension($dimension, $where, $metrics, $orderBy, - $rankingQuery, $joinLogActionColumn, $addSelect); - - $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 |