Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Actions')
-rw-r--r--plugins/Actions/API.php991
-rw-r--r--plugins/Actions/Actions.php1099
-rw-r--r--plugins/Actions/Archiving.php950
-rw-r--r--plugins/Actions/ArchivingHelper.php939
-rw-r--r--plugins/Actions/Controller.php1007
-rw-r--r--plugins/Actions/templates/indexSiteSearch.tpl20
6 files changed, 2455 insertions, 2551 deletions
diff --git a/plugins/Actions/API.php b/plugins/Actions/API.php
index bb0367c742..060912f19f 100644
--- a/plugins/Actions/API.php
+++ b/plugins/Actions/API.php
@@ -1,10 +1,10 @@
<?php
/**
* Piwik - Open source web analytics
- *
+ *
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
+ *
* @category Piwik_Plugins
* @package Piwik_Actions
*/
@@ -12,543 +12,518 @@
/**
* The Actions API lets you request reports for all your Visitor Actions: Page URLs, Page titles (Piwik Events),
* File Downloads and Clicks on external websites.
- *
+ *
* For example, "getPageTitles" will return all your page titles along with standard <a href='http://piwik.org/docs/analytics-api/reference/#toc-metric-definitions' target='_blank'>Actions metrics</a> for each row.
- *
- * It is also possible to request data for a specific Page Title with "getPageTitle"
- * and setting the parameter pageName to the page title you wish to request.
- * Similarly, you can request metrics for a given Page URL via "getPageUrl", a Download file via "getDownload"
+ *
+ * It is also possible to request data for a specific Page Title with "getPageTitle"
+ * and setting the parameter pageName to the page title you wish to request.
+ * Similarly, you can request metrics for a given Page URL via "getPageUrl", a Download file via "getDownload"
* and an outlink via "getOutlink".
- *
+ *
* Note: pageName, pageUrl, outlinkUrl, downloadUrl parameters must be URL encoded before you call the API.
* @package Piwik_Actions
*/
class Piwik_Actions_API
{
- static private $instance = null;
-
- /**
- * @return Piwik_Actions_API
- */
- static public function getInstance()
- {
- if (self::$instance == null)
- {
- self::$instance = new self;
- }
- return self::$instance;
- }
-
-
- /**
- * Backward compatibility. Fallsback to getPageTitles() instead.
- * @deprecated Deprecated since Piwik 0.5
- * @ignore
- *
- * @param int $idSite
- * @param string $period
- * @param $date
- * @param bool $segment
- * @param bool $expanded
- * @param bool|int $idSubtable
- * @return Piwik_DataTable|Piwik_DataTable_Array
- */
- public function getActions( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- return $this->getPageTitles( $idSite, $period, $date, $segment, $expanded, $idSubtable );
- }
-
- /**
- * Returns the list of metrics (pages, downloads, outlinks)
- *
- * @param int $idSite
- * @param string $period
- * @param string $date
- * @param bool|string $segment
- * @param bool|array $columns
- * @return Piwik_DataTable
- */
- public function get( $idSite, $period, $date, $segment = false, $columns = false)
- {
- Piwik::checkUserHasViewAccess( $idSite );
- $archive = Piwik_Archive::build( $idSite, $period, $date, $segment );
-
- $metrics = array(
- 'Actions_nb_pageviews' => 'nb_pageviews',
- 'Actions_nb_uniq_pageviews' => 'nb_uniq_pageviews',
- 'Actions_nb_downloads' => 'nb_downloads',
- 'Actions_nb_uniq_downloads' => 'nb_uniq_downloads',
- 'Actions_nb_outlinks' => 'nb_outlinks',
- 'Actions_nb_uniq_outlinks' => 'nb_uniq_outlinks',
- 'Actions_nb_searches' => 'nb_searches',
- 'Actions_nb_keywords' => 'nb_keywords',
- );
-
- // get requested columns
- $columns = Piwik::getArrayFromApiParameter($columns);
- if(!empty($columns))
- {
- // get the columns that are available and requested
- $columns = array_intersect($columns, array_values($metrics));
- $columns = array_values($columns); // make sure indexes are right
- $nameReplace = array();
- foreach ($columns as $i => $column)
- {
- $fullColumn = array_search($column, $metrics);
- $columns[$i] = $fullColumn;
- $nameReplace[$fullColumn] = $column;
- }
- }
- else
- {
- // get all columns
- $columns = array_keys($metrics);
- $nameReplace = &$metrics;
- }
-
- $table = $archive->getDataTableFromNumeric($columns);
-
- // replace labels (remove Actions_)
- $table->filter('ReplaceColumnNames', array($nameReplace));
-
- return $table;
- }
+ static private $instance = null;
/**
- * @param int $idSite
- * @param string $period
- * @param Piwik_Date $date
- * @param bool $segment
- * @param bool $expanded
- * @param bool $idSubtable
+ * @return Piwik_Actions_API
+ */
+ static public function getInstance()
+ {
+ if (self::$instance == null) {
+ self::$instance = new self;
+ }
+ return self::$instance;
+ }
+
+
+ /**
+ * Backward compatibility. Fallsback to getPageTitles() instead.
+ * @deprecated Deprecated since Piwik 0.5
+ * @ignore
*
+ * @param int $idSite
+ * @param string $period
+ * @param $date
+ * @param bool $segment
+ * @param bool $expanded
+ * @param bool|int $idSubtable
* @return Piwik_DataTable|Piwik_DataTable_Array
*/
- public function getPageUrls( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_actions_url', $idSite, $period, $date, $segment, $expanded, $idSubtable );
- $this->filterPageDatatable($dataTable);
- $this->filterActionsDataTable($dataTable, $expanded);
- return $dataTable;
- }
+ public function getActions($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ return $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
+ }
/**
- * @param int $idSite
- * @param string $period
- * @param Piwik_Date $date
- * @param bool $segment
- * @param bool $expanded
- * @param bool $idSubtable
+ * Returns the list of metrics (pages, downloads, outlinks)
+ *
+ * @param int $idSite
+ * @param string $period
+ * @param string $date
+ * @param bool|string $segment
+ * @param bool|array $columns
+ * @return Piwik_DataTable
+ */
+ public function get($idSite, $period, $date, $segment = false, $columns = false)
+ {
+ Piwik::checkUserHasViewAccess($idSite);
+ $archive = Piwik_Archive::build($idSite, $period, $date, $segment);
+
+ $metrics = array(
+ 'Actions_nb_pageviews' => 'nb_pageviews',
+ 'Actions_nb_uniq_pageviews' => 'nb_uniq_pageviews',
+ 'Actions_nb_downloads' => 'nb_downloads',
+ 'Actions_nb_uniq_downloads' => 'nb_uniq_downloads',
+ 'Actions_nb_outlinks' => 'nb_outlinks',
+ 'Actions_nb_uniq_outlinks' => 'nb_uniq_outlinks',
+ 'Actions_nb_searches' => 'nb_searches',
+ 'Actions_nb_keywords' => 'nb_keywords',
+ );
+
+ // get requested columns
+ $columns = Piwik::getArrayFromApiParameter($columns);
+ if (!empty($columns)) {
+ // get the columns that are available and requested
+ $columns = array_intersect($columns, array_values($metrics));
+ $columns = array_values($columns); // make sure indexes are right
+ $nameReplace = array();
+ foreach ($columns as $i => $column) {
+ $fullColumn = array_search($column, $metrics);
+ $columns[$i] = $fullColumn;
+ $nameReplace[$fullColumn] = $column;
+ }
+ } else {
+ // get all columns
+ $columns = array_keys($metrics);
+ $nameReplace = & $metrics;
+ }
+
+ $table = $archive->getDataTableFromNumeric($columns);
+
+ // replace labels (remove Actions_)
+ $table->filter('ReplaceColumnNames', array($nameReplace));
+
+ return $table;
+ }
+
+ /**
+ * @param int $idSite
+ * @param string $period
+ * @param Piwik_Date $date
+ * @param bool $segment
+ * @param bool $expanded
+ * @param bool $idSubtable
+ *
+ * @return Piwik_DataTable|Piwik_DataTable_Array
+ */
+ public function getPageUrls($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_actions_url', $idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterPageDatatable($dataTable);
+ $this->filterActionsDataTable($dataTable, $expanded);
+ return $dataTable;
+ }
+
+ /**
+ * @param int $idSite
+ * @param string $period
+ * @param Piwik_Date $date
+ * @param bool $segment
+ * @param bool $expanded
+ * @param bool $idSubtable
*
* @return Piwik_DataTable|Piwik_DataTable_Array
*/
- public function getPageUrlsFollowingSiteSearch( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- $dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable);
- $this->keepPagesFollowingSearch($dataTable);
- return $dataTable;
- }
+ public function getPageUrlsFollowingSiteSearch($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->keepPagesFollowingSearch($dataTable);
+ return $dataTable;
+ }
/**
- * @param int $idSite
- * @param string $period
- * @param Piwik_Date $date
- * @param bool $segment
- * @param bool $expanded
- * @param bool $idSubtable
+ * @param int $idSite
+ * @param string $period
+ * @param Piwik_Date $date
+ * @param bool $segment
+ * @param bool $expanded
+ * @param bool $idSubtable
*
* @return Piwik_DataTable|Piwik_DataTable_Array
*/
- public function getPageTitlesFollowingSiteSearch( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- $dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
- $this->keepPagesFollowingSearch($dataTable);
- return $dataTable;
- }
+ public function getPageTitlesFollowingSiteSearch($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->keepPagesFollowingSearch($dataTable);
+ return $dataTable;
+ }
/**
* @param Piwik_DataTable $dataTable
*/
protected function keepPagesFollowingSearch($dataTable)
- {
- // Keep only pages which are following site search
- $dataTable->filter('ColumnCallbackDeleteRow', array(
- 'nb_hits_following_search',
- create_function('$value', 'return $value > 0;')
- ));
- }
-
- /**
- * Returns a DataTable with analytics information for every unique entry page URL, for
- * the specified site, period & segment.
- */
- public function getEntryPageUrls( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- $dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable);
- $this->filterNonEntryActions($dataTable);
- return $dataTable;
- }
-
- /**
- * Returns a DataTable with analytics information for every unique exit page URL, for
- * the specified site, period & segment.
- */
- public function getExitPageUrls( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- $dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable);
- $this->filterNonExitActions($dataTable);
- return $dataTable;
- }
-
- public function getPageUrl( $pageUrl, $idSite, $period, $date, $segment = false)
- {
- $callBackParameters = array('Actions_actions_url', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false );
- $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $pageUrl, Piwik_Tracker_Action::TYPE_ACTION_URL);
- $this->filterPageDatatable($dataTable);
- $this->filterActionsDataTable($dataTable);
- return $dataTable;
- }
-
- public function getPageTitles( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
- {
- $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_actions', $idSite, $period, $date, $segment, $expanded, $idSubtable);
- $this->filterPageDatatable($dataTable);
- $this->filterActionsDataTable($dataTable, $expanded);
- return $dataTable;
- }
-
- /**
- * Returns a Piwik_DataTable with analytics information for every unique entry page title
- * for the given site, time period & segment.
- */
- public function getEntryPageTitles( $idSite, $period, $date, $segment = false, $expanded = false,
- $idSubtable = false )
- {
- $dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
- $this->filterNonEntryActions($dataTable);
- return $dataTable;
- }
-
- /**
- * Returns a Piwik_DataTable with analytics information for every unique exit page title
- * for the given site, time period & segment.
- */
- public function getExitPageTitles( $idSite, $period, $date, $segment = false, $expanded = false,
- $idSubtable = false )
- {
- $dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
- $this->filterNonExitActions($dataTable);
- return $dataTable;
- }
-
- public function getPageTitle( $pageName, $idSite, $period, $date, $segment = false)
- {
- $callBackParameters = array('Actions_actions', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false );
- $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $pageName, Piwik_Tracker_Action::TYPE_ACTION_NAME);
- $this->filterPageDatatable($dataTable);
- $this->filterActionsDataTable($dataTable);
- return $dataTable;
- }
-
- public function getDownloads( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_downloads', $idSite, $period, $date, $segment, $expanded, $idSubtable );
- $this->filterActionsDataTable($dataTable, $expanded);
- return $dataTable;
- }
-
- public function getDownload( $downloadUrl, $idSite, $period, $date, $segment = false)
- {
- $callBackParameters = array('Actions_downloads', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false );
- $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $downloadUrl, Piwik_Tracker_Action::TYPE_DOWNLOAD);
- $this->filterActionsDataTable($dataTable);
- return $dataTable;
- }
-
- public function getOutlinks( $idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false )
- {
- $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_outlink', $idSite, $period, $date, $segment, $expanded, $idSubtable );
- $this->filterActionsDataTable($dataTable, $expanded);
- return $dataTable;
- }
-
- public function getOutlink( $outlinkUrl, $idSite, $period, $date, $segment = false)
- {
- $callBackParameters = array('Actions_outlink', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false );
- $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $outlinkUrl, Piwik_Tracker_Action::TYPE_OUTLINK);
- $this->filterActionsDataTable($dataTable);
- return $dataTable;
- }
-
- public function getSiteSearchKeywords( $idSite, $period, $date, $segment = false )
- {
- $dataTable = $this->getSiteSearchKeywordsRaw($idSite, $period, $date, $segment);
- $dataTable->deleteColumn(Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT);
- $this->filterPageDatatable($dataTable);
- $this->filterActionsDataTable($dataTable);
- $this->addPagesPerSearchColumn($dataTable);
- return $dataTable;
- }
-
- //Visitors can search, and then click "next" to view more results. This is the average number of search results pages viewed for this keyword.
- public function addPagesPerSearchColumn($dataTable, $columnToRead = 'nb_hits')
- {
- $dataTable->filter('ColumnCallbackAddColumnQuotient', array('nb_pages_per_search', $columnToRead, 'nb_visits', $precision = 1));
- }
-
- protected function getSiteSearchKeywordsRaw($idSite, $period, $date, $segment)
- {
- $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_sitesearch', $idSite, $period, $date, $segment, $expanded = false);
- return $dataTable;
- }
-
- public function getSiteSearchNoResultKeywords( $idSite, $period, $date, $segment = false )
- {
- $dataTable = $this->getSiteSearchKeywordsRaw($idSite, $period, $date, $segment);
- // Delete all rows that have some results
- $dataTable->filter('ColumnCallbackDeleteRow',
- array(
- Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT,
- create_function ( '$value', 'return $value >= 1;')
- ));
- $dataTable->deleteRow(Piwik_DataTable::ID_SUMMARY_ROW);
- $dataTable->deleteColumn(Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT);
- $this->filterPageDatatable($dataTable);
- $this->filterActionsDataTable($dataTable);
- $this->addPagesPerSearchColumn($dataTable);
- return $dataTable;
- }
+ {
+ // Keep only pages which are following site search
+ $dataTable->filter('ColumnCallbackDeleteRow', array(
+ 'nb_hits_following_search',
+ create_function('$value', 'return $value > 0;')
+ ));
+ }
+
+ /**
+ * Returns a DataTable with analytics information for every unique entry page URL, for
+ * the specified site, period & segment.
+ */
+ public function getEntryPageUrls($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterNonEntryActions($dataTable);
+ return $dataTable;
+ }
/**
- * @param int $idSite
- * @param string $period
- * @param Piwik_Date $date
- * @param bool $segment
+ * Returns a DataTable with analytics information for every unique exit page URL, for
+ * the specified site, period & segment.
+ */
+ public function getExitPageUrls($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterNonExitActions($dataTable);
+ return $dataTable;
+ }
+
+ public function getPageUrl($pageUrl, $idSite, $period, $date, $segment = false)
+ {
+ $callBackParameters = array('Actions_actions_url', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false);
+ $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $pageUrl, Piwik_Tracker_Action::TYPE_ACTION_URL);
+ $this->filterPageDatatable($dataTable);
+ $this->filterActionsDataTable($dataTable);
+ return $dataTable;
+ }
+
+ public function getPageTitles($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_actions', $idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterPageDatatable($dataTable);
+ $this->filterActionsDataTable($dataTable, $expanded);
+ return $dataTable;
+ }
+
+ /**
+ * Returns a Piwik_DataTable with analytics information for every unique entry page title
+ * for the given site, time period & segment.
+ */
+ public function getEntryPageTitles($idSite, $period, $date, $segment = false, $expanded = false,
+ $idSubtable = false)
+ {
+ $dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterNonEntryActions($dataTable);
+ return $dataTable;
+ }
+
+ /**
+ * Returns a Piwik_DataTable with analytics information for every unique exit page title
+ * for the given site, time period & segment.
+ */
+ public function getExitPageTitles($idSite, $period, $date, $segment = false, $expanded = false,
+ $idSubtable = false)
+ {
+ $dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterNonExitActions($dataTable);
+ return $dataTable;
+ }
+
+ public function getPageTitle($pageName, $idSite, $period, $date, $segment = false)
+ {
+ $callBackParameters = array('Actions_actions', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false);
+ $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $pageName, Piwik_Tracker_Action::TYPE_ACTION_NAME);
+ $this->filterPageDatatable($dataTable);
+ $this->filterActionsDataTable($dataTable);
+ return $dataTable;
+ }
+
+ public function getDownloads($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_downloads', $idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterActionsDataTable($dataTable, $expanded);
+ return $dataTable;
+ }
+
+ public function getDownload($downloadUrl, $idSite, $period, $date, $segment = false)
+ {
+ $callBackParameters = array('Actions_downloads', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false);
+ $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $downloadUrl, Piwik_Tracker_Action::TYPE_DOWNLOAD);
+ $this->filterActionsDataTable($dataTable);
+ return $dataTable;
+ }
+
+ public function getOutlinks($idSite, $period, $date, $segment = false, $expanded = false, $idSubtable = false)
+ {
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_outlink', $idSite, $period, $date, $segment, $expanded, $idSubtable);
+ $this->filterActionsDataTable($dataTable, $expanded);
+ return $dataTable;
+ }
+
+ public function getOutlink($outlinkUrl, $idSite, $period, $date, $segment = false)
+ {
+ $callBackParameters = array('Actions_outlink', $idSite, $period, $date, $segment, $expanded = false, $idSubtable = false);
+ $dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $outlinkUrl, Piwik_Tracker_Action::TYPE_OUTLINK);
+ $this->filterActionsDataTable($dataTable);
+ return $dataTable;
+ }
+
+ public function getSiteSearchKeywords($idSite, $period, $date, $segment = false)
+ {
+ $dataTable = $this->getSiteSearchKeywordsRaw($idSite, $period, $date, $segment);
+ $dataTable->deleteColumn(Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT);
+ $this->filterPageDatatable($dataTable);
+ $this->filterActionsDataTable($dataTable);
+ $this->addPagesPerSearchColumn($dataTable);
+ return $dataTable;
+ }
+
+ //Visitors can search, and then click "next" to view more results. This is the average number of search results pages viewed for this keyword.
+ public function addPagesPerSearchColumn($dataTable, $columnToRead = 'nb_hits')
+ {
+ $dataTable->filter('ColumnCallbackAddColumnQuotient', array('nb_pages_per_search', $columnToRead, 'nb_visits', $precision = 1));
+ }
+
+ protected function getSiteSearchKeywordsRaw($idSite, $period, $date, $segment)
+ {
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_sitesearch', $idSite, $period, $date, $segment, $expanded = false);
+ return $dataTable;
+ }
+
+ public function getSiteSearchNoResultKeywords($idSite, $period, $date, $segment = false)
+ {
+ $dataTable = $this->getSiteSearchKeywordsRaw($idSite, $period, $date, $segment);
+ // Delete all rows that have some results
+ $dataTable->filter('ColumnCallbackDeleteRow',
+ array(
+ Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT,
+ create_function('$value', 'return $value >= 1;')
+ ));
+ $dataTable->deleteRow(Piwik_DataTable::ID_SUMMARY_ROW);
+ $dataTable->deleteColumn(Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT);
+ $this->filterPageDatatable($dataTable);
+ $this->filterActionsDataTable($dataTable);
+ $this->addPagesPerSearchColumn($dataTable);
+ return $dataTable;
+ }
+
+ /**
+ * @param int $idSite
+ * @param string $period
+ * @param Piwik_Date $date
+ * @param bool $segment
*
* @return Piwik_DataTable|Piwik_DataTable_Array
*/
- public function getSiteSearchCategories( $idSite, $period, $date, $segment = false )
- {
- Piwik_Actions::checkCustomVariablesPluginEnabled();
- $customVariables = Piwik_CustomVariables_API::getInstance()->getCustomVariables($idSite, $period, $date, $segment, $expanded = false, $_leavePiwikCoreVariables = true);
-
- $customVarNameToLookFor = Piwik_Tracker_Action::CVAR_KEY_SEARCH_CATEGORY;
-
- $dataTable = new Piwik_DataTable();
- // Handle case where date=last30&period=day
- // TODO: this logic should really be refactored somewhere, this is ugly!
- if($customVariables instanceof Piwik_DataTable_Array)
- {
- $dataTable = $customVariables->getEmptyClone();
-
- $customVariableDatatables = $customVariables->getArray();
- $dataTables = $dataTable->getArray();
- foreach($customVariableDatatables as $key => $customVariableTableForDate)
- {
- // we do not enter the IF, in the case idSite=1,3 AND period=day&date=datefrom,dateto,
- if(isset($customVariableTableForDate->metadata['period']))
- {
- $row = $customVariableTableForDate->getRowFromLabel($customVarNameToLookFor);
- if($row)
- {
- $dateRewrite = $customVariableTableForDate->metadata['period']->getDateStart()->toString();
- $idSubtable = $row->getIdSubDataTable();
- $categories = Piwik_CustomVariables_API::getInstance()->getCustomVariablesValuesFromNameId($idSite, $period, $dateRewrite, $idSubtable, $segment);
- $dataTable->addTable($categories, $key);
- }
- }
- }
- }
- elseif($customVariables instanceof Piwik_DataTable)
- {
- $row = $customVariables->getRowFromLabel($customVarNameToLookFor);
- if($row)
- {
- $idSubtable = $row->getIdSubDataTable();
- $dataTable = Piwik_CustomVariables_API::getInstance()->getCustomVariablesValuesFromNameId($idSite, $period, $date, $idSubtable, $segment);
- }
- }
- $this->filterActionsDataTable($dataTable);
- $this->addPagesPerSearchColumn($dataTable, $columnToRead = 'nb_actions');
- return $dataTable;
- }
-
- /**
- * Will search in the DataTable for a Label matching the searched string
- * and return only the matching row, or an empty datatable
- */
- protected function getFilterPageDatatableSearch($callBackParameters, $search, $actionType, $table = false,
- $searchTree = false)
- {
- if ($searchTree === false)
- {
- // build the query parts that are searched inside the tree
- if($actionType == Piwik_Tracker_Action::TYPE_ACTION_NAME)
- {
- $searchedString = Piwik_Common::unsanitizeInputValue($search);
- }
- else
- {
- $idSite = $callBackParameters[1];
- try {
- $searchedString = Piwik_Tracker_Action::excludeQueryParametersFromUrl($search, $idSite);
- } catch(Exception $e) {
- $searchedString = $search;
- }
- }
- Piwik_Actions_ArchivingHelper::reloadConfig();
- $searchTree = Piwik_Actions_ArchivingHelper::getActionExplodedNames($searchedString, $actionType);
- }
-
- if ($table === false)
- {
- // fetch the data table
- $table = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
-
- if ($table instanceof Piwik_DataTable_Array)
- {
- // search an array of tables, e.g. when using date=last30
- // note that if the root is an array, we filter all children
- // if an array occurs inside the nested table, we only look for the first match (see below)
- $newTableArray = $table->getEmptyClone();
-
- foreach ($table->getArray() as $label => $subTable)
- {
- $newSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
-
- $newTableArray->addTable($newSubTable, $label);
- }
-
- return $newTableArray;
- }
-
- }
-
- return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
- }
-
- /**
- * This looks very similar to LabelFilter.php should it be refactored somehow? FIXME
- */
- protected function doFilterPageDatatableSearch($callBackParameters, $table, $searchTree)
- {
- // filter a data table array
- if ($table instanceof Piwik_DataTable_Array)
- {
- foreach ($table->getArray() as $subTable)
- {
- $filteredSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
-
- if ($filteredSubTable->getRowsCount() > 0)
- {
- // match found in a sub table, return and stop searching the others
- return $filteredSubTable;
- }
- }
-
- // nothing found in all sub tables
- return new Piwik_DataTable;
- }
-
- // filter regular data table
- if ($table instanceof Piwik_DataTable)
- {
- // search for the first part of the tree search
- $search = array_shift($searchTree);
- $row = $table->getRowFromLabel($search);
- if ($row === false)
- {
- // not found
- $result = new Piwik_DataTable;
- $result->metadata = $table->metadata;
- return $result;
- }
-
- // end of tree search reached
- if (count($searchTree) == 0)
- {
- $result = new Piwik_DataTable();
- $result->addRow($row);
- $result->metadata = $table->metadata;
- return $result;
- }
-
- // match found on this level and more levels remaining: go deeper
- $idSubTable = $row->getIdSubDataTable();
- $callBackParameters[6] = $idSubTable;
- $table = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
- return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
- }
-
- throw new Exception("For this API function, DataTable ".get_class($table)." is not supported");
- }
-
- /**
- * Common filters for Page URLs and Page Titles
- */
- protected function filterPageDatatable($dataTable)
- {
- // Average time on page = total time on page / number visits on that page
- $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_time_on_page', 'sum_time_spent', 'nb_visits', 0));
-
- // Bounce rate = single page visits on this page / visits started on this page
- $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('bounce_rate', 'entry_bounce_count', 'entry_nb_visits', 0));
-
- // % Exit = Number of visits that finished on this page / visits on this page
- $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('exit_rate', 'exit_nb_visits', 'nb_visits', 0));
-
- // Handle performance analytics
- $hasTimeGeneration = (array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION)) > 0);
- if ($hasTimeGeneration) {
- // Average generation time = total generation time / number of pageviews
- $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_time_generation', 'sum_time_generation', 'nb_hits_with_time_generation', 3));
- } else {
- // No generation time: remove it from the API output and add it to empty_columns metadata, so that
- // the columns can also be removed from the view
- $dataTable->filter('ColumnDelete', array(array(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION, Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION)));
- if ($dataTable instanceof Piwik_DataTable) {
- $emptyColumns = $dataTable->getMetadata(Piwik_DataTable::EMPTY_COLUMNS_METADATA_NAME);
- if (!is_array($emptyColumns)) {
- $emptyColumns = array();
- }
- $emptyColumns[] = 'sum_time_generation';
- $emptyColumns[] = 'avg_time_generation';
- $dataTable->setMetadata(Piwik_DataTable::EMPTY_COLUMNS_METADATA_NAME, $emptyColumns);
- }
- }
- }
-
- /**
- * Common filters for all Actions API getters
- */
- protected function filterActionsDataTable($dataTable, $expanded = false)
- {
- // Must be applied before Sort in this case, since the DataTable can contain both int and strings indexes
- // (in the transition period between pre 1.2 and post 1.2 datatable structure)
- $dataTable->filter('ReplaceColumnNames');
- $dataTable->filter('Sort', array('nb_visits', 'desc', $naturalSort = false, $expanded));
-
- $dataTable->queueFilter('ReplaceSummaryRowLabel');
- }
-
- /**
- * Removes DataTable rows referencing actions that were never the first action of a visit.
- *
- * @param Piwik_DataTable $dataTable
- */
- private function filterNonEntryActions( $dataTable )
- {
- $dataTable->filter('ColumnCallbackDeleteRow', array('entry_nb_visits', 'strlen'));
- }
-
- /**
- * Removes DataTable rows referencing actions that were never the last action of a visit.
- *
- * @param Piwik_DataTable $dataTable
- */
- private function filterNonExitActions( $dataTable )
- {
- $dataTable->filter('ColumnCallbackDeleteRow', array('exit_nb_visits', 'strlen'));
- }
+ public function getSiteSearchCategories($idSite, $period, $date, $segment = false)
+ {
+ Piwik_Actions::checkCustomVariablesPluginEnabled();
+ $customVariables = Piwik_CustomVariables_API::getInstance()->getCustomVariables($idSite, $period, $date, $segment, $expanded = false, $_leavePiwikCoreVariables = true);
+
+ $customVarNameToLookFor = Piwik_Tracker_Action::CVAR_KEY_SEARCH_CATEGORY;
+
+ $dataTable = new Piwik_DataTable();
+ // Handle case where date=last30&period=day
+ // TODO: this logic should really be refactored somewhere, this is ugly!
+ if ($customVariables instanceof Piwik_DataTable_Array) {
+ $dataTable = $customVariables->getEmptyClone();
+
+ $customVariableDatatables = $customVariables->getArray();
+ $dataTables = $dataTable->getArray();
+ foreach ($customVariableDatatables as $key => $customVariableTableForDate) {
+ // we do not enter the IF, in the case idSite=1,3 AND period=day&date=datefrom,dateto,
+ if (isset($customVariableTableForDate->metadata['period'])) {
+ $row = $customVariableTableForDate->getRowFromLabel($customVarNameToLookFor);
+ if ($row) {
+ $dateRewrite = $customVariableTableForDate->metadata['period']->getDateStart()->toString();
+ $idSubtable = $row->getIdSubDataTable();
+ $categories = Piwik_CustomVariables_API::getInstance()->getCustomVariablesValuesFromNameId($idSite, $period, $dateRewrite, $idSubtable, $segment);
+ $dataTable->addTable($categories, $key);
+ }
+ }
+ }
+ } elseif ($customVariables instanceof Piwik_DataTable) {
+ $row = $customVariables->getRowFromLabel($customVarNameToLookFor);
+ if ($row) {
+ $idSubtable = $row->getIdSubDataTable();
+ $dataTable = Piwik_CustomVariables_API::getInstance()->getCustomVariablesValuesFromNameId($idSite, $period, $date, $idSubtable, $segment);
+ }
+ }
+ $this->filterActionsDataTable($dataTable);
+ $this->addPagesPerSearchColumn($dataTable, $columnToRead = 'nb_actions');
+ return $dataTable;
+ }
+
+ /**
+ * Will search in the DataTable for a Label matching the searched string
+ * and return only the matching row, or an empty datatable
+ */
+ protected function getFilterPageDatatableSearch($callBackParameters, $search, $actionType, $table = false,
+ $searchTree = false)
+ {
+ if ($searchTree === false) {
+ // build the query parts that are searched inside the tree
+ if ($actionType == Piwik_Tracker_Action::TYPE_ACTION_NAME) {
+ $searchedString = Piwik_Common::unsanitizeInputValue($search);
+ } else {
+ $idSite = $callBackParameters[1];
+ try {
+ $searchedString = Piwik_Tracker_Action::excludeQueryParametersFromUrl($search, $idSite);
+ } catch (Exception $e) {
+ $searchedString = $search;
+ }
+ }
+ Piwik_Actions_ArchivingHelper::reloadConfig();
+ $searchTree = Piwik_Actions_ArchivingHelper::getActionExplodedNames($searchedString, $actionType);
+ }
+
+ if ($table === false) {
+ // fetch the data table
+ $table = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
+
+ if ($table instanceof Piwik_DataTable_Array) {
+ // search an array of tables, e.g. when using date=last30
+ // note that if the root is an array, we filter all children
+ // if an array occurs inside the nested table, we only look for the first match (see below)
+ $newTableArray = $table->getEmptyClone();
+
+ foreach ($table->getArray() as $label => $subTable) {
+ $newSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
+
+ $newTableArray->addTable($newSubTable, $label);
+ }
+
+ return $newTableArray;
+ }
+
+ }
+
+ return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
+ }
+
+ /**
+ * This looks very similar to LabelFilter.php should it be refactored somehow? FIXME
+ */
+ protected function doFilterPageDatatableSearch($callBackParameters, $table, $searchTree)
+ {
+ // filter a data table array
+ if ($table instanceof Piwik_DataTable_Array) {
+ foreach ($table->getArray() as $subTable) {
+ $filteredSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
+
+ if ($filteredSubTable->getRowsCount() > 0) {
+ // match found in a sub table, return and stop searching the others
+ return $filteredSubTable;
+ }
+ }
+
+ // nothing found in all sub tables
+ return new Piwik_DataTable;
+ }
+
+ // filter regular data table
+ if ($table instanceof Piwik_DataTable) {
+ // search for the first part of the tree search
+ $search = array_shift($searchTree);
+ $row = $table->getRowFromLabel($search);
+ if ($row === false) {
+ // not found
+ $result = new Piwik_DataTable;
+ $result->metadata = $table->metadata;
+ return $result;
+ }
+
+ // end of tree search reached
+ if (count($searchTree) == 0) {
+ $result = new Piwik_DataTable();
+ $result->addRow($row);
+ $result->metadata = $table->metadata;
+ return $result;
+ }
+
+ // match found on this level and more levels remaining: go deeper
+ $idSubTable = $row->getIdSubDataTable();
+ $callBackParameters[6] = $idSubTable;
+ $table = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
+ return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
+ }
+
+ throw new Exception("For this API function, DataTable " . get_class($table) . " is not supported");
+ }
+
+ /**
+ * Common filters for Page URLs and Page Titles
+ */
+ protected function filterPageDatatable($dataTable)
+ {
+ // Average time on page = total time on page / number visits on that page
+ $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_time_on_page', 'sum_time_spent', 'nb_visits', 0));
+
+ // Bounce rate = single page visits on this page / visits started on this page
+ $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('bounce_rate', 'entry_bounce_count', 'entry_nb_visits', 0));
+
+ // % Exit = Number of visits that finished on this page / visits on this page
+ $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('exit_rate', 'exit_nb_visits', 'nb_visits', 0));
+
+ // Handle performance analytics
+ $hasTimeGeneration = (array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION)) > 0);
+ if ($hasTimeGeneration) {
+ // Average generation time = total generation time / number of pageviews
+ $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_time_generation', 'sum_time_generation', 'nb_hits_with_time_generation', 3));
+ } else {
+ // No generation time: remove it from the API output and add it to empty_columns metadata, so that
+ // the columns can also be removed from the view
+ $dataTable->filter('ColumnDelete', array(array(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION, Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION)));
+ if ($dataTable instanceof Piwik_DataTable) {
+ $emptyColumns = $dataTable->getMetadata(Piwik_DataTable::EMPTY_COLUMNS_METADATA_NAME);
+ if (!is_array($emptyColumns)) {
+ $emptyColumns = array();
+ }
+ $emptyColumns[] = 'sum_time_generation';
+ $emptyColumns[] = 'avg_time_generation';
+ $dataTable->setMetadata(Piwik_DataTable::EMPTY_COLUMNS_METADATA_NAME, $emptyColumns);
+ }
+ }
+ }
+
+ /**
+ * Common filters for all Actions API getters
+ */
+ protected function filterActionsDataTable($dataTable, $expanded = false)
+ {
+ // Must be applied before Sort in this case, since the DataTable can contain both int and strings indexes
+ // (in the transition period between pre 1.2 and post 1.2 datatable structure)
+ $dataTable->filter('ReplaceColumnNames');
+ $dataTable->filter('Sort', array('nb_visits', 'desc', $naturalSort = false, $expanded));
+
+ $dataTable->queueFilter('ReplaceSummaryRowLabel');
+ }
+
+ /**
+ * Removes DataTable rows referencing actions that were never the first action of a visit.
+ *
+ * @param Piwik_DataTable $dataTable
+ */
+ private function filterNonEntryActions($dataTable)
+ {
+ $dataTable->filter('ColumnCallbackDeleteRow', array('entry_nb_visits', 'strlen'));
+ }
+
+ /**
+ * Removes DataTable rows referencing actions that were never the last action of a visit.
+ *
+ * @param Piwik_DataTable $dataTable
+ */
+ private function filterNonExitActions($dataTable)
+ {
+ $dataTable->filter('ColumnCallbackDeleteRow', array('exit_nb_visits', 'strlen'));
+ }
}
diff --git a/plugins/Actions/Actions.php b/plugins/Actions/Actions.php
index 230968e66f..635b0d95c4 100644
--- a/plugins/Actions/Actions.php
+++ b/plugins/Actions/Actions.php
@@ -8,7 +8,7 @@
* @category Piwik_Plugins
* @package Piwik_Actions
*/
-
+
/**
* Actions plugin
*
@@ -18,592 +18,585 @@
*/
class Piwik_Actions extends Piwik_Plugin
{
- public function getInformation()
- {
- $info = array(
- 'description' => Piwik_Translate('Actions_PluginDescription'),
- 'author' => 'Piwik',
- 'author_homepage' => 'http://piwik.org/',
- 'version' => Piwik_Version::VERSION,
- );
- return $info;
- }
-
-
- public function getListHooksRegistered()
- {
- $hooks = array(
- 'ArchiveProcessing_Day.compute' => 'archiveDay',
- 'ArchiveProcessing_Period.compute' => 'archivePeriod',
- 'WidgetsList.add' => 'addWidgets',
- 'Menu.add' => 'addMenus',
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentsMetadata' => 'getSegmentsMetadata',
- );
- return $hooks;
- }
-
- /**
- * @param Piwik_Event_Notification $notification notification object
- */
- public function getSegmentsMetadata($notification)
- {
- $segments =& $notification->getNotificationObject();
- $sqlFilter = array($this, 'getIdActionFromSegment');
-
- // entry and exit pages of visit
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Actions_Actions',
- 'name' => 'Actions_ColumnEntryPageURL',
- 'segment' => 'entryPageUrl',
- 'sqlSegment' => 'log_visit.visit_entry_idaction_url',
- 'sqlFilter' => $sqlFilter,
+ public function getInformation()
+ {
+ $info = array(
+ 'description' => Piwik_Translate('Actions_PluginDescription'),
+ 'author' => 'Piwik',
+ 'author_homepage' => 'http://piwik.org/',
+ 'version' => Piwik_Version::VERSION,
+ );
+ return $info;
+ }
+
+
+ public function getListHooksRegistered()
+ {
+ $hooks = array(
+ 'ArchiveProcessing_Day.compute' => 'archiveDay',
+ 'ArchiveProcessing_Period.compute' => 'archivePeriod',
+ 'WidgetsList.add' => 'addWidgets',
+ 'Menu.add' => 'addMenus',
+ 'API.getReportMetadata' => 'getReportMetadata',
+ 'API.getSegmentsMetadata' => 'getSegmentsMetadata',
+ );
+ return $hooks;
+ }
+
+ /**
+ * @param Piwik_Event_Notification $notification notification object
+ */
+ public function getSegmentsMetadata($notification)
+ {
+ $segments =& $notification->getNotificationObject();
+ $sqlFilter = array($this, 'getIdActionFromSegment');
+
+ // entry and exit pages of visit
+ $segments[] = array(
+ 'type' => 'dimension',
+ 'category' => 'Actions_Actions',
+ 'name' => 'Actions_ColumnEntryPageURL',
+ 'segment' => 'entryPageUrl',
+ 'sqlSegment' => 'log_visit.visit_entry_idaction_url',
+ 'sqlFilter' => $sqlFilter,
);
$segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Actions_Actions',
- 'name' => 'Actions_ColumnEntryPageTitle',
- 'segment' => 'entryPageTitle',
- 'sqlSegment' => 'log_visit.visit_entry_idaction_name',
- 'sqlFilter' => $sqlFilter,
+ 'type' => 'dimension',
+ 'category' => 'Actions_Actions',
+ 'name' => 'Actions_ColumnEntryPageTitle',
+ 'segment' => 'entryPageTitle',
+ 'sqlSegment' => 'log_visit.visit_entry_idaction_name',
+ 'sqlFilter' => $sqlFilter,
);
$segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Actions_Actions',
- 'name' => 'Actions_ColumnExitPageURL',
- 'segment' => 'exitPageUrl',
- 'sqlSegment' => 'log_visit.visit_exit_idaction_url',
- 'sqlFilter' => $sqlFilter,
+ 'type' => 'dimension',
+ 'category' => 'Actions_Actions',
+ 'name' => 'Actions_ColumnExitPageURL',
+ 'segment' => 'exitPageUrl',
+ 'sqlSegment' => 'log_visit.visit_exit_idaction_url',
+ 'sqlFilter' => $sqlFilter,
);
$segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Actions_Actions',
- 'name' => 'Actions_ColumnExitPageTitle',
- 'segment' => 'exitPageTitle',
- 'sqlSegment' => 'log_visit.visit_exit_idaction_name',
- 'sqlFilter' => $sqlFilter,
+ 'type' => 'dimension',
+ 'category' => 'Actions_Actions',
+ 'name' => 'Actions_ColumnExitPageTitle',
+ 'segment' => 'exitPageTitle',
+ 'sqlSegment' => 'log_visit.visit_exit_idaction_name',
+ 'sqlFilter' => $sqlFilter,
);
-
+
// single pages
$segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Actions_Actions',
- 'name' => 'Actions_ColumnPageURL',
- 'segment' => 'pageUrl',
- 'sqlSegment' => 'log_link_visit_action.idaction_url',
- 'sqlFilter' => $sqlFilter,
- 'acceptedValues' => "All these segments must be URL encoded, for example: ".urlencode('http://example.com/path/page?query'),
+ 'type' => 'dimension',
+ 'category' => 'Actions_Actions',
+ 'name' => 'Actions_ColumnPageURL',
+ 'segment' => 'pageUrl',
+ 'sqlSegment' => 'log_link_visit_action.idaction_url',
+ 'sqlFilter' => $sqlFilter,
+ 'acceptedValues' => "All these segments must be URL encoded, for example: " . urlencode('http://example.com/path/page?query'),
);
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Actions_Actions',
- 'name' => 'Actions_ColumnPageName',
- 'segment' => 'pageTitle',
- 'sqlSegment' => 'log_link_visit_action.idaction_name',
- 'sqlFilter' => $sqlFilter,
- );
- // TODO here could add keyword segment and hack $sqlFilter to make it select the right idaction
- }
-
- /**
- * Convert segment expression to an action ID or an SQL expression.
- *
- * This method is used as a sqlFilter-callback for the segments of this plugin.
- * Usually, these callbacks only return a value that should be compared to the
- * column in the database. In this case, that doesn't work since multiple IDs
- * can match an expression (e.g. "pageUrl=@foo").
- * @param string $string
- * @param string $sqlField
- * @param string $matchType
- * @throws Exception
- * @return array|int|string
- */
- public function getIdActionFromSegment($string, $sqlField, $matchType='==')
- {
- // Field is visit_*_idaction_url or visit_*_idaction_name
- $actionType = strpos($sqlField, '_name') === false
- ? Piwik_Tracker_Action::TYPE_ACTION_URL
- : Piwik_Tracker_Action::TYPE_ACTION_NAME;
-
- if ($actionType == Piwik_Tracker_Action::TYPE_ACTION_URL)
- {
- // for urls trim protocol and www because it is not recorded in the db
- $string = preg_replace('@^http[s]?://(www\.)?@i', '', $string);
- }
-
+ $segments[] = array(
+ 'type' => 'dimension',
+ 'category' => 'Actions_Actions',
+ 'name' => 'Actions_ColumnPageName',
+ 'segment' => 'pageTitle',
+ 'sqlSegment' => 'log_link_visit_action.idaction_name',
+ 'sqlFilter' => $sqlFilter,
+ );
+ // TODO here could add keyword segment and hack $sqlFilter to make it select the right idaction
+ }
+
+ /**
+ * Convert segment expression to an action ID or an SQL expression.
+ *
+ * This method is used as a sqlFilter-callback for the segments of this plugin.
+ * Usually, these callbacks only return a value that should be compared to the
+ * column in the database. In this case, that doesn't work since multiple IDs
+ * can match an expression (e.g. "pageUrl=@foo").
+ * @param string $string
+ * @param string $sqlField
+ * @param string $matchType
+ * @throws Exception
+ * @return array|int|string
+ */
+ public function getIdActionFromSegment($string, $sqlField, $matchType = '==')
+ {
+ // Field is visit_*_idaction_url or visit_*_idaction_name
+ $actionType = strpos($sqlField, '_name') === false
+ ? Piwik_Tracker_Action::TYPE_ACTION_URL
+ : Piwik_Tracker_Action::TYPE_ACTION_NAME;
+
+ if ($actionType == Piwik_Tracker_Action::TYPE_ACTION_URL) {
+ // for urls trim protocol and www because it is not recorded in the db
+ $string = preg_replace('@^http[s]?://(www\.)?@i', '', $string);
+ }
+
// exact matches work by returning the id directly
- if ($matchType == Piwik_SegmentExpression::MATCH_EQUAL
- || $matchType == Piwik_SegmentExpression::MATCH_NOT_EQUAL)
- {
+ if ($matchType == Piwik_SegmentExpression::MATCH_EQUAL
+ || $matchType == Piwik_SegmentExpression::MATCH_NOT_EQUAL
+ ) {
$sql = Piwik_Tracker_Action::getSqlSelectActionId();
$bind = array($string, $string, $actionType);
$idAction = Piwik_FetchOne($sql, $bind);
// if the action is not found, we hack -100 to ensure it tries to match against an integer
// otherwise binding idaction_name to "false" returns some rows for some reasons (in case &segment=pageTitle==Větrnásssssss)
- if(empty($idAction))
- {
+ if (empty($idAction)) {
$idAction = -100;
}
return $idAction;
}
-
+
// now, we handle the cases =@ (contains) and !@ (does not contain)
-
+
// build the expression based on the match type
- $sql = 'SELECT idaction FROM '.Piwik_Common::prefixTable('log_action').' WHERE ';
- switch ($matchType)
- {
+ $sql = 'SELECT idaction FROM ' . Piwik_Common::prefixTable('log_action') . ' WHERE ';
+ switch ($matchType) {
case '=@':
// use concat to make sure, no %s occurs because some plugins use %s in their sql
- $sql .= '( name LIKE CONCAT("%", ?, "%") AND type = '.$actionType.' )';
+ $sql .= '( name LIKE CONCAT("%", ?, "%") AND type = ' . $actionType . ' )';
break;
case '!@':
- $sql .= '( name NOT LIKE CONCAT("%", ?, "%") AND type = '.$actionType.' )';
+ $sql .= '( name NOT LIKE CONCAT("%", ?, "%") AND type = ' . $actionType . ' )';
break;
default:
throw new Exception("This match type is not available for action-segments.");
break;
}
-
+
return array(
// mark that the returned value is an sql-expression instead of a literal value
- 'SQL' => $sql,
- 'bind' => $string
+ 'SQL' => $sql,
+ 'bind' => $string
);
- }
-
- /**
- * Returns metadata for available reports
- *
- * @param Piwik_Event_Notification $notification notification object
- */
- public function getReportMetadata($notification)
- {
- $reports = &$notification->getNotificationObject();
-
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_Actions') . ' - ' . Piwik_Translate('General_MainMetrics'),
- 'module' => 'Actions',
- 'action' => 'get',
- 'metrics' => array(
- 'nb_pageviews' => Piwik_Translate('General_ColumnPageviews'),
- 'nb_uniq_pageviews' => Piwik_Translate('General_ColumnUniquePageviews'),
- 'nb_downloads' => Piwik_Translate('Actions_ColumnDownloads'),
- 'nb_uniq_downloads' => Piwik_Translate('Actions_ColumnUniqueDownloads'),
- 'nb_outlinks' => Piwik_Translate('Actions_ColumnOutlinks'),
- 'nb_uniq_outlinks' => Piwik_Translate('Actions_ColumnUniqueOutlinks'),
- 'nb_searches' => Piwik_Translate('Actions_ColumnSearches'),
- 'nb_keywords' => Piwik_Translate('Actions_ColumnSiteSearchKeywords'),
- ),
- 'metricsDocumentation' => array(
- 'nb_pageviews' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
- 'nb_uniq_pageviews' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
- 'nb_downloads' => Piwik_Translate('Actions_ColumnClicksDocumentation'),
- 'nb_uniq_downloads' => Piwik_Translate('Actions_ColumnUniqueClicksDocumentation'),
- 'nb_outlinks' => Piwik_Translate('Actions_ColumnClicksDocumentation'),
- 'nb_uniq_outlinks' => Piwik_Translate('Actions_ColumnUniqueClicksDocumentation'),
- 'nb_searches' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
+ }
+
+ /**
+ * Returns metadata for available reports
+ *
+ * @param Piwik_Event_Notification $notification notification object
+ */
+ public function getReportMetadata($notification)
+ {
+ $reports = & $notification->getNotificationObject();
+
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_Actions') . ' - ' . Piwik_Translate('General_MainMetrics'),
+ 'module' => 'Actions',
+ 'action' => 'get',
+ 'metrics' => array(
+ 'nb_pageviews' => Piwik_Translate('General_ColumnPageviews'),
+ 'nb_uniq_pageviews' => Piwik_Translate('General_ColumnUniquePageviews'),
+ 'nb_downloads' => Piwik_Translate('Actions_ColumnDownloads'),
+ 'nb_uniq_downloads' => Piwik_Translate('Actions_ColumnUniqueDownloads'),
+ 'nb_outlinks' => Piwik_Translate('Actions_ColumnOutlinks'),
+ 'nb_uniq_outlinks' => Piwik_Translate('Actions_ColumnUniqueOutlinks'),
+ 'nb_searches' => Piwik_Translate('Actions_ColumnSearches'),
+ 'nb_keywords' => Piwik_Translate('Actions_ColumnSiteSearchKeywords'),
+ ),
+ 'metricsDocumentation' => array(
+ 'nb_pageviews' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
+ 'nb_uniq_pageviews' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
+ 'nb_downloads' => Piwik_Translate('Actions_ColumnClicksDocumentation'),
+ 'nb_uniq_downloads' => Piwik_Translate('Actions_ColumnUniqueClicksDocumentation'),
+ 'nb_outlinks' => Piwik_Translate('Actions_ColumnClicksDocumentation'),
+ 'nb_uniq_outlinks' => Piwik_Translate('Actions_ColumnUniqueClicksDocumentation'),
+ 'nb_searches' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
// 'nb_keywords' => Piwik_Translate('Actions_ColumnSiteSearchKeywords'),
- ),
- 'processedMetrics' => false,
- 'order' => 1
- );
-
- $metrics = array(
- 'nb_hits' => Piwik_Translate('General_ColumnPageviews'),
- 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviews'),
- 'bounce_rate' => Piwik_Translate('General_ColumnBounceRate'),
- 'avg_time_on_page' => Piwik_Translate('General_ColumnAverageTimeOnPage'),
- 'exit_rate' => Piwik_Translate('General_ColumnExitRate'),
- 'avg_time_generation' => Piwik_Translate('General_ColumnAverageGenerationTime')
- );
-
- $documentation = array(
- 'nb_hits' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
- 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
- 'bounce_rate' => Piwik_Translate('General_ColumnPageBounceRateDocumentation'),
- 'avg_time_on_page' => Piwik_Translate('General_ColumnAverageTimeOnPageDocumentation'),
- 'exit_rate' => Piwik_Translate('General_ColumnExitRateDocumentation'),
- 'avg_time_generation' => Piwik_Translate('General_ColumnAverageGenerationTimeDocumentation'),
- );
-
- // pages report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_PageUrls'),
- 'module' => 'Actions',
- 'action' => 'getPageUrls',
- 'dimension' => Piwik_Translate('Actions_ColumnPageURL'),
- 'metrics' => $metrics,
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik_Translate('Actions_PagesReportDocumentation', '<br />')
- .'<br />'.Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getPageUrls',
- 'order' => 2
- );
-
- // entry pages report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_SubmenuPagesEntry'),
- 'module' => 'Actions',
- 'action' => 'getEntryPageUrls',
- 'dimension' => Piwik_Translate('Actions_ColumnPageURL'),
- 'metrics' => array(
- 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrances'),
- 'entry_bounce_count' => Piwik_Translate('General_ColumnBounces'),
- 'bounce_rate' => Piwik_Translate('General_ColumnBounceRate'),
- ),
- 'metricsDocumentation' => array(
- 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrancesDocumentation'),
- 'entry_bounce_count' => Piwik_Translate('General_ColumnBouncesDocumentation'),
- 'bounce_rate' => Piwik_Translate('General_ColumnBounceRateForPageDocumentation')
- ),
- 'documentation' => Piwik_Translate('Actions_EntryPagesReportDocumentation', '<br />')
- .' '.Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getEntryPageUrls',
- 'order' => 3
- );
-
- // exit pages report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_SubmenuPagesExit'),
- 'module' => 'Actions',
- 'action' => 'getExitPageUrls',
- 'dimension' => Piwik_Translate('Actions_ColumnPageURL'),
- 'metrics' => array(
- 'exit_nb_visits' => Piwik_Translate('General_ColumnExits'),
- 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviews'),
- 'exit_rate' => Piwik_Translate('General_ColumnExitRate')
- ),
- 'metricsDocumentation' => array(
- 'exit_nb_visits' => Piwik_Translate('General_ColumnExitsDocumentation'),
- 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
- 'exit_rate' => Piwik_Translate('General_ColumnExitRateDocumentation')
- ),
- 'documentation' => Piwik_Translate('Actions_ExitPagesReportDocumentation', '<br />')
- .' '.Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getExitPageUrls',
- 'order' => 4
- );
-
- // page titles report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_SubmenuPageTitles'),
- 'module' => 'Actions',
- 'action' => 'getPageTitles',
- 'dimension' => Piwik_Translate('Actions_ColumnPageName'),
- 'metrics' => $metrics,
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik_Translate('Actions_PageTitlesReportDocumentation', array('<br />', htmlentities('<title>'))),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getPageTitles',
- 'order' => 5,
-
- );
-
- // entry page titles report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_EntryPageTitles'),
- 'module' => 'Actions',
- 'action' => 'getEntryPageTitles',
- 'dimension' => Piwik_Translate('Actions_ColumnPageName'),
- 'metrics' => array(
- 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrances'),
- 'entry_bounce_count' => Piwik_Translate('General_ColumnBounces'),
- 'bounce_rate' => Piwik_Translate('General_ColumnBounceRate'),
- ),
- 'metricsDocumentation' => array(
- 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrancesDocumentation'),
- 'entry_bounce_count' => Piwik_Translate('General_ColumnBouncesDocumentation'),
- 'bounce_rate' => Piwik_Translate('General_ColumnBounceRateForPageDocumentation')
- ),
- 'documentation' => Piwik_Translate('Actions_ExitPageTitlesReportDocumentation', '<br />')
- .' '.Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getEntryPageTitles',
- 'order' => 6
- );
-
- // exit page titles report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_ExitPageTitles'),
- 'module' => 'Actions',
- 'action' => 'getExitPageTitles',
- 'dimension' => Piwik_Translate('Actions_ColumnPageName'),
- 'metrics' => array(
- 'exit_nb_visits' => Piwik_Translate('General_ColumnExits'),
- 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviews'),
- 'exit_rate' => Piwik_Translate('General_ColumnExitRate')
- ),
- 'metricsDocumentation' => array(
- 'exit_nb_visits' => Piwik_Translate('General_ColumnExitsDocumentation'),
- 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
- 'exit_rate' => Piwik_Translate('General_ColumnExitRateDocumentation')
- ),
- 'documentation' => Piwik_Translate('Actions_EntryPageTitlesReportDocumentation', '<br />')
- .' '.Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getExitPageTitles',
- 'order' => 7
- );
-
- $documentation = array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnUniqueClicksDocumentation'),
- 'nb_hits' => Piwik_Translate('Actions_ColumnClicksDocumentation')
- );
-
- // outlinks report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_SubmenuOutlinks'),
- 'module' => 'Actions',
- 'action' => 'getOutlinks',
- 'dimension' => Piwik_Translate('Actions_ColumnClickedURL'),
- 'metrics' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnUniqueClicks'),
- 'nb_hits' => Piwik_Translate('Actions_ColumnClicks')
- ),
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik_Translate('Actions_OutlinksReportDocumentation').' '
- .Piwik_Translate('Actions_OutlinkDocumentation').'<br />'
- .Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getOutlinks',
- 'order' => 8,
- );
-
- // downloads report
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_Actions'),
- 'name' => Piwik_Translate('Actions_SubmenuDownloads'),
- 'module' => 'Actions',
- 'action' => 'getDownloads',
- 'dimension' => Piwik_Translate('Actions_ColumnDownloadURL'),
- 'metrics' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnUniqueDownloads'),
- 'nb_hits' => Piwik_Translate('Actions_ColumnDownloads')
- ),
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik_Translate('Actions_DownloadsReportDocumentation', '<br />'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getDownloads',
- 'order' => 9,
- );
-
- if($this->isSiteSearchEnabled())
- {
- // Search Keywords
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik_Translate('Actions_WidgetSearchKeywords'),
- 'module' => 'Actions',
- 'action' => 'getSiteSearchKeywords',
- 'dimension' => Piwik_Translate('Actions_ColumnSearchKeyword'),
- 'metrics' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnSearches'),
- 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearch'),
- 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExits'),
- ),
- 'metricsDocumentation' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
- 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearchDocumentation'),
- 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExitsDocumentation'),
- ),
- 'documentation' => Piwik_Translate('Actions_SiteSearchKeywordsDocumentation') . '<br/><br/>' . Piwik_Translate('Actions_SiteSearchIntro') . '<br/><br/>'
- . '<a href="http://piwik.org/docs/site-search/" target="_blank">'. Piwik_Translate('Actions_LearnMoreAboutSiteSearchLink') . '</a>',
- 'processedMetrics' => false,
- 'order' => 15
- );
- // No Result Search Keywords
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik_Translate('Actions_WidgetSearchNoResultKeywords'),
- 'module' => 'Actions',
- 'action' => 'getSiteSearchNoResultKeywords',
- 'dimension' => Piwik_Translate('Actions_ColumnNoResultKeyword'),
- 'metrics' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnSearches'),
- 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExits'),
- ),
- 'metricsDocumentation' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
- 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExitsDocumentation'),
- ),
- 'documentation' => Piwik_Translate('Actions_SiteSearchIntro'). '<br /><br />' . Piwik_Translate('Actions_SiteSearchKeywordsNoResultDocumentation'),
- 'processedMetrics' => false,
- 'order' => 16
- );
-
- if(self::isCustomVariablesPluginsEnabled()) {
- // Search Categories
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik_Translate('Actions_WidgetSearchCategories'),
- 'module' => 'Actions',
- 'action' => 'getSiteSearchCategories',
- 'dimension' => Piwik_Translate('Actions_ColumnSearchCategory'),
- 'metrics' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnSearches'),
- 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearch'),
- 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExits'),
- ),
- 'metricsDocumentation' => array(
- 'nb_visits' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
- 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearchDocumentation'),
- 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExitsDocumentation'),
- ),
- 'documentation' => Piwik_Translate('Actions_SiteSearchCategories1') . '<br/>' . Piwik_Translate('Actions_SiteSearchCategories2'),
- 'processedMetrics' => false,
- 'order' => 17
- );
- }
-
- $documentation = Piwik_Translate('Actions_SiteSearchFollowingPagesDoc') .'<br/>'.Piwik_Translate('General_UsePlusMinusIconsDocumentation');
- // Pages URLs following Search
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik_Translate('Actions_WidgetPageUrlsFollowingSearch'),
- 'module' => 'Actions',
- 'action' => 'getPageUrlsFollowingSiteSearch',
- 'dimension' => Piwik_Translate('General_ColumnDestinationPage'),
- 'metrics' => array(
- 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearch'),
- 'nb_hits' => Piwik_Translate('General_ColumnTotalPageviews'),
- ),
- 'metricsDocumentation' => array(
- 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearchDocumentation'),
- 'nb_hits' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
- ),
- 'documentation' => $documentation,
- 'processedMetrics' => false,
- 'order' => 18
- );
- // Pages Titles following Search
- $reports[] = array(
- 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik_Translate('Actions_WidgetPageTitlesFollowingSearch'),
- 'module' => 'Actions',
- 'action' => 'getPageTitlesFollowingSiteSearch',
- 'dimension' => Piwik_Translate('General_ColumnDestinationPage'),
- 'metrics' => array(
- 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearch'),
- 'nb_hits' => Piwik_Translate('General_ColumnTotalPageviews'),
- ),
- 'metricsDocumentation' => array(
- 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearchDocumentation'),
- 'nb_hits' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
- ),
- 'documentation' => $documentation,
- 'processedMetrics' => false,
- 'order' => 19
- );
- }
- }
-
- function addWidgets()
- {
- Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuPages', 'Actions', 'getPageUrls');
- Piwik_AddWidget( 'Actions_Actions', 'Actions_WidgetPageTitles', 'Actions', 'getPageTitles');
- Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuOutlinks', 'Actions', 'getOutlinks');
- Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuDownloads', 'Actions', 'getDownloads');
- Piwik_AddWidget( 'Actions_Actions', 'Actions_WidgetPagesEntry', 'Actions', 'getEntryPageUrls');
- Piwik_AddWidget( 'Actions_Actions', 'Actions_WidgetPagesExit', 'Actions', 'getExitPageUrls');
- Piwik_AddWidget( 'Actions_Actions', 'Actions_WidgetEntryPageTitles', 'Actions', 'getEntryPageTitles' );
- Piwik_AddWidget( 'Actions_Actions', 'Actions_WidgetExitPageTitles', 'Actions', 'getExitPageTitles' );
-
- if($this->isSiteSearchEnabled())
- {
- Piwik_AddWidget( 'Actions_SubmenuSitesearch', 'Actions_WidgetSearchKeywords', 'Actions', 'getSiteSearchKeywords');
-
- if(self::isCustomVariablesPluginsEnabled()) {
- Piwik_AddWidget( 'Actions_SubmenuSitesearch', 'Actions_WidgetSearchCategories', 'Actions', 'getSiteSearchCategories');
- }
- Piwik_AddWidget( 'Actions_SubmenuSitesearch', 'Actions_WidgetSearchNoResultKeywords', 'Actions', 'getSiteSearchNoResultKeywords');
- Piwik_AddWidget( 'Actions_SubmenuSitesearch', 'Actions_WidgetPageUrlsFollowingSearch', 'Actions', 'getPageUrlsFollowingSiteSearch');
- Piwik_AddWidget( 'Actions_SubmenuSitesearch', 'Actions_WidgetPageTitlesFollowingSearch', 'Actions', 'getPageTitlesFollowingSiteSearch');
- }
- }
-
- function addMenus()
- {
- Piwik_AddMenu('Actions_Actions', '', array('module' => 'Actions', 'action' => 'indexPageUrls'), true, 15);
- Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPages', array('module' => 'Actions', 'action' => 'indexPageUrls'), true, 1);
- Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPagesEntry', array('module' => 'Actions', 'action' => 'indexEntryPageUrls'), true, 2);
- Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPagesExit', array('module' => 'Actions', 'action' => 'indexExitPageUrls'), true, 3);
- Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPageTitles', array('module' => 'Actions', 'action' => 'indexPageTitles'), true, 4);
- Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuOutlinks', array('module' => 'Actions', 'action' => 'indexOutlinks'), true, 6);
- Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuDownloads', array('module' => 'Actions', 'action' => 'indexDownloads'), true, 7);
-
- if($this->isSiteSearchEnabled())
- {
- Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuSitesearch', array('module' => 'Actions', 'action' => 'indexSiteSearch'), true, 5);
- }
- }
-
- protected function isSiteSearchEnabled()
- {
- $idSite = Piwik_Common::getRequestVar('idSite', 0, 'int');
- if($idSite == 0 ) {
- return false;
- }
- return Piwik_Site::isSiteSearchEnabledFor($idSite);
- }
-
-
- /**
- * @param Piwik_Event_Notification $notification notification object
- * @return mixed
- */
- function archivePeriod( $notification )
- {
- $archiveProcessing = $notification->getNotificationObject();
-
- if(!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return;
-
- $actionsArchiving = new Piwik_Actions_Archiving($archiveProcessing->idsite);
- return $actionsArchiving->archivePeriod($archiveProcessing);
- }
-
- /**
- * Compute all the actions along with their hierarchies.
- *
- * For each action we process the "interest statistics" :
- * visits, unique visitors, bounce count, sum visit length.
- *
- * @param Piwik_Event_Notification $notification notification object
- */
- public function archiveDay( $notification )
- {
- /* @var $archiveProcessing Piwik_ArchiveProcessing_Day */
- $archiveProcessing = $notification->getNotificationObject();
-
- if(!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return;
-
- $actionsArchiving = new Piwik_Actions_Archiving($archiveProcessing->idsite);
- return $actionsArchiving->archiveDay($archiveProcessing);
- }
-
- static public function checkCustomVariablesPluginEnabled()
- {
- if(!self::isCustomVariablesPluginsEnabled())
- {
- throw new Exception("To Track Site Search Categories, please ask the Piwik Administrator to enable the 'Custom Variables' plugin in Settings > Plugins.");
- }
- }
-
- static protected function isCustomVariablesPluginsEnabled()
- {
- return Piwik_PluginsManager::getInstance()->isPluginActivated('CustomVariables');
- }
+ ),
+ 'processedMetrics' => false,
+ 'order' => 1
+ );
+
+ $metrics = array(
+ 'nb_hits' => Piwik_Translate('General_ColumnPageviews'),
+ 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviews'),
+ 'bounce_rate' => Piwik_Translate('General_ColumnBounceRate'),
+ 'avg_time_on_page' => Piwik_Translate('General_ColumnAverageTimeOnPage'),
+ 'exit_rate' => Piwik_Translate('General_ColumnExitRate'),
+ 'avg_time_generation' => Piwik_Translate('General_ColumnAverageGenerationTime')
+ );
+
+ $documentation = array(
+ 'nb_hits' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
+ 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
+ 'bounce_rate' => Piwik_Translate('General_ColumnPageBounceRateDocumentation'),
+ 'avg_time_on_page' => Piwik_Translate('General_ColumnAverageTimeOnPageDocumentation'),
+ 'exit_rate' => Piwik_Translate('General_ColumnExitRateDocumentation'),
+ 'avg_time_generation' => Piwik_Translate('General_ColumnAverageGenerationTimeDocumentation'),
+ );
+
+ // pages report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_PageUrls'),
+ 'module' => 'Actions',
+ 'action' => 'getPageUrls',
+ 'dimension' => Piwik_Translate('Actions_ColumnPageURL'),
+ 'metrics' => $metrics,
+ 'metricsDocumentation' => $documentation,
+ 'documentation' => Piwik_Translate('Actions_PagesReportDocumentation', '<br />')
+ . '<br />' . Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getPageUrls',
+ 'order' => 2
+ );
+
+ // entry pages report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_SubmenuPagesEntry'),
+ 'module' => 'Actions',
+ 'action' => 'getEntryPageUrls',
+ 'dimension' => Piwik_Translate('Actions_ColumnPageURL'),
+ 'metrics' => array(
+ 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrances'),
+ 'entry_bounce_count' => Piwik_Translate('General_ColumnBounces'),
+ 'bounce_rate' => Piwik_Translate('General_ColumnBounceRate'),
+ ),
+ 'metricsDocumentation' => array(
+ 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrancesDocumentation'),
+ 'entry_bounce_count' => Piwik_Translate('General_ColumnBouncesDocumentation'),
+ 'bounce_rate' => Piwik_Translate('General_ColumnBounceRateForPageDocumentation')
+ ),
+ 'documentation' => Piwik_Translate('Actions_EntryPagesReportDocumentation', '<br />')
+ . ' ' . Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getEntryPageUrls',
+ 'order' => 3
+ );
+
+ // exit pages report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_SubmenuPagesExit'),
+ 'module' => 'Actions',
+ 'action' => 'getExitPageUrls',
+ 'dimension' => Piwik_Translate('Actions_ColumnPageURL'),
+ 'metrics' => array(
+ 'exit_nb_visits' => Piwik_Translate('General_ColumnExits'),
+ 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviews'),
+ 'exit_rate' => Piwik_Translate('General_ColumnExitRate')
+ ),
+ 'metricsDocumentation' => array(
+ 'exit_nb_visits' => Piwik_Translate('General_ColumnExitsDocumentation'),
+ 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
+ 'exit_rate' => Piwik_Translate('General_ColumnExitRateDocumentation')
+ ),
+ 'documentation' => Piwik_Translate('Actions_ExitPagesReportDocumentation', '<br />')
+ . ' ' . Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getExitPageUrls',
+ 'order' => 4
+ );
+
+ // page titles report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_SubmenuPageTitles'),
+ 'module' => 'Actions',
+ 'action' => 'getPageTitles',
+ 'dimension' => Piwik_Translate('Actions_ColumnPageName'),
+ 'metrics' => $metrics,
+ 'metricsDocumentation' => $documentation,
+ 'documentation' => Piwik_Translate('Actions_PageTitlesReportDocumentation', array('<br />', htmlentities('<title>'))),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getPageTitles',
+ 'order' => 5,
+
+ );
+
+ // entry page titles report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_EntryPageTitles'),
+ 'module' => 'Actions',
+ 'action' => 'getEntryPageTitles',
+ 'dimension' => Piwik_Translate('Actions_ColumnPageName'),
+ 'metrics' => array(
+ 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrances'),
+ 'entry_bounce_count' => Piwik_Translate('General_ColumnBounces'),
+ 'bounce_rate' => Piwik_Translate('General_ColumnBounceRate'),
+ ),
+ 'metricsDocumentation' => array(
+ 'entry_nb_visits' => Piwik_Translate('General_ColumnEntrancesDocumentation'),
+ 'entry_bounce_count' => Piwik_Translate('General_ColumnBouncesDocumentation'),
+ 'bounce_rate' => Piwik_Translate('General_ColumnBounceRateForPageDocumentation')
+ ),
+ 'documentation' => Piwik_Translate('Actions_ExitPageTitlesReportDocumentation', '<br />')
+ . ' ' . Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getEntryPageTitles',
+ 'order' => 6
+ );
+
+ // exit page titles report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_ExitPageTitles'),
+ 'module' => 'Actions',
+ 'action' => 'getExitPageTitles',
+ 'dimension' => Piwik_Translate('Actions_ColumnPageName'),
+ 'metrics' => array(
+ 'exit_nb_visits' => Piwik_Translate('General_ColumnExits'),
+ 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviews'),
+ 'exit_rate' => Piwik_Translate('General_ColumnExitRate')
+ ),
+ 'metricsDocumentation' => array(
+ 'exit_nb_visits' => Piwik_Translate('General_ColumnExitsDocumentation'),
+ 'nb_visits' => Piwik_Translate('General_ColumnUniquePageviewsDocumentation'),
+ 'exit_rate' => Piwik_Translate('General_ColumnExitRateDocumentation')
+ ),
+ 'documentation' => Piwik_Translate('Actions_EntryPageTitlesReportDocumentation', '<br />')
+ . ' ' . Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getExitPageTitles',
+ 'order' => 7
+ );
+
+ $documentation = array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnUniqueClicksDocumentation'),
+ 'nb_hits' => Piwik_Translate('Actions_ColumnClicksDocumentation')
+ );
+
+ // outlinks report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_SubmenuOutlinks'),
+ 'module' => 'Actions',
+ 'action' => 'getOutlinks',
+ 'dimension' => Piwik_Translate('Actions_ColumnClickedURL'),
+ 'metrics' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnUniqueClicks'),
+ 'nb_hits' => Piwik_Translate('Actions_ColumnClicks')
+ ),
+ 'metricsDocumentation' => $documentation,
+ 'documentation' => Piwik_Translate('Actions_OutlinksReportDocumentation') . ' '
+ . Piwik_Translate('Actions_OutlinkDocumentation') . '<br />'
+ . Piwik_Translate('General_UsePlusMinusIconsDocumentation'),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getOutlinks',
+ 'order' => 8,
+ );
+
+ // downloads report
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_Actions'),
+ 'name' => Piwik_Translate('Actions_SubmenuDownloads'),
+ 'module' => 'Actions',
+ 'action' => 'getDownloads',
+ 'dimension' => Piwik_Translate('Actions_ColumnDownloadURL'),
+ 'metrics' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnUniqueDownloads'),
+ 'nb_hits' => Piwik_Translate('Actions_ColumnDownloads')
+ ),
+ 'metricsDocumentation' => $documentation,
+ 'documentation' => Piwik_Translate('Actions_DownloadsReportDocumentation', '<br />'),
+ 'processedMetrics' => false,
+ 'actionToLoadSubTables' => 'getDownloads',
+ 'order' => 9,
+ );
+
+ if ($this->isSiteSearchEnabled()) {
+ // Search Keywords
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
+ 'name' => Piwik_Translate('Actions_WidgetSearchKeywords'),
+ 'module' => 'Actions',
+ 'action' => 'getSiteSearchKeywords',
+ 'dimension' => Piwik_Translate('Actions_ColumnSearchKeyword'),
+ 'metrics' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnSearches'),
+ 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearch'),
+ 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExits'),
+ ),
+ 'metricsDocumentation' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
+ 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearchDocumentation'),
+ 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExitsDocumentation'),
+ ),
+ 'documentation' => Piwik_Translate('Actions_SiteSearchKeywordsDocumentation') . '<br/><br/>' . Piwik_Translate('Actions_SiteSearchIntro') . '<br/><br/>'
+ . '<a href="http://piwik.org/docs/site-search/" target="_blank">' . Piwik_Translate('Actions_LearnMoreAboutSiteSearchLink') . '</a>',
+ 'processedMetrics' => false,
+ 'order' => 15
+ );
+ // No Result Search Keywords
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
+ 'name' => Piwik_Translate('Actions_WidgetSearchNoResultKeywords'),
+ 'module' => 'Actions',
+ 'action' => 'getSiteSearchNoResultKeywords',
+ 'dimension' => Piwik_Translate('Actions_ColumnNoResultKeyword'),
+ 'metrics' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnSearches'),
+ 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExits'),
+ ),
+ 'metricsDocumentation' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
+ 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExitsDocumentation'),
+ ),
+ 'documentation' => Piwik_Translate('Actions_SiteSearchIntro') . '<br /><br />' . Piwik_Translate('Actions_SiteSearchKeywordsNoResultDocumentation'),
+ 'processedMetrics' => false,
+ 'order' => 16
+ );
+
+ if (self::isCustomVariablesPluginsEnabled()) {
+ // Search Categories
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
+ 'name' => Piwik_Translate('Actions_WidgetSearchCategories'),
+ 'module' => 'Actions',
+ 'action' => 'getSiteSearchCategories',
+ 'dimension' => Piwik_Translate('Actions_ColumnSearchCategory'),
+ 'metrics' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnSearches'),
+ 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearch'),
+ 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExits'),
+ ),
+ 'metricsDocumentation' => array(
+ 'nb_visits' => Piwik_Translate('Actions_ColumnSearchesDocumentation'),
+ 'nb_pages_per_search' => Piwik_Translate('Actions_ColumnPagesPerSearchDocumentation'),
+ 'exit_rate' => Piwik_Translate('Actions_ColumnSearchExitsDocumentation'),
+ ),
+ 'documentation' => Piwik_Translate('Actions_SiteSearchCategories1') . '<br/>' . Piwik_Translate('Actions_SiteSearchCategories2'),
+ 'processedMetrics' => false,
+ 'order' => 17
+ );
+ }
+
+ $documentation = Piwik_Translate('Actions_SiteSearchFollowingPagesDoc') . '<br/>' . Piwik_Translate('General_UsePlusMinusIconsDocumentation');
+ // Pages URLs following Search
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
+ 'name' => Piwik_Translate('Actions_WidgetPageUrlsFollowingSearch'),
+ 'module' => 'Actions',
+ 'action' => 'getPageUrlsFollowingSiteSearch',
+ 'dimension' => Piwik_Translate('General_ColumnDestinationPage'),
+ 'metrics' => array(
+ 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearch'),
+ 'nb_hits' => Piwik_Translate('General_ColumnTotalPageviews'),
+ ),
+ 'metricsDocumentation' => array(
+ 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearchDocumentation'),
+ 'nb_hits' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
+ ),
+ 'documentation' => $documentation,
+ 'processedMetrics' => false,
+ 'order' => 18
+ );
+ // Pages Titles following Search
+ $reports[] = array(
+ 'category' => Piwik_Translate('Actions_SubmenuSitesearch'),
+ 'name' => Piwik_Translate('Actions_WidgetPageTitlesFollowingSearch'),
+ 'module' => 'Actions',
+ 'action' => 'getPageTitlesFollowingSiteSearch',
+ 'dimension' => Piwik_Translate('General_ColumnDestinationPage'),
+ 'metrics' => array(
+ 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearch'),
+ 'nb_hits' => Piwik_Translate('General_ColumnTotalPageviews'),
+ ),
+ 'metricsDocumentation' => array(
+ 'nb_hits_following_search' => Piwik_Translate('General_ColumnViewedAfterSearchDocumentation'),
+ 'nb_hits' => Piwik_Translate('General_ColumnPageviewsDocumentation'),
+ ),
+ 'documentation' => $documentation,
+ 'processedMetrics' => false,
+ 'order' => 19
+ );
+ }
+ }
+
+ function addWidgets()
+ {
+ Piwik_AddWidget('Actions_Actions', 'Actions_SubmenuPages', 'Actions', 'getPageUrls');
+ Piwik_AddWidget('Actions_Actions', 'Actions_WidgetPageTitles', 'Actions', 'getPageTitles');
+ Piwik_AddWidget('Actions_Actions', 'Actions_SubmenuOutlinks', 'Actions', 'getOutlinks');
+ Piwik_AddWidget('Actions_Actions', 'Actions_SubmenuDownloads', 'Actions', 'getDownloads');
+ Piwik_AddWidget('Actions_Actions', 'Actions_WidgetPagesEntry', 'Actions', 'getEntryPageUrls');
+ Piwik_AddWidget('Actions_Actions', 'Actions_WidgetPagesExit', 'Actions', 'getExitPageUrls');
+ Piwik_AddWidget('Actions_Actions', 'Actions_WidgetEntryPageTitles', 'Actions', 'getEntryPageTitles');
+ Piwik_AddWidget('Actions_Actions', 'Actions_WidgetExitPageTitles', 'Actions', 'getExitPageTitles');
+
+ if ($this->isSiteSearchEnabled()) {
+ Piwik_AddWidget('Actions_SubmenuSitesearch', 'Actions_WidgetSearchKeywords', 'Actions', 'getSiteSearchKeywords');
+
+ if (self::isCustomVariablesPluginsEnabled()) {
+ Piwik_AddWidget('Actions_SubmenuSitesearch', 'Actions_WidgetSearchCategories', 'Actions', 'getSiteSearchCategories');
+ }
+ Piwik_AddWidget('Actions_SubmenuSitesearch', 'Actions_WidgetSearchNoResultKeywords', 'Actions', 'getSiteSearchNoResultKeywords');
+ Piwik_AddWidget('Actions_SubmenuSitesearch', 'Actions_WidgetPageUrlsFollowingSearch', 'Actions', 'getPageUrlsFollowingSiteSearch');
+ Piwik_AddWidget('Actions_SubmenuSitesearch', 'Actions_WidgetPageTitlesFollowingSearch', 'Actions', 'getPageTitlesFollowingSiteSearch');
+ }
+ }
+
+ function addMenus()
+ {
+ Piwik_AddMenu('Actions_Actions', '', array('module' => 'Actions', 'action' => 'indexPageUrls'), true, 15);
+ Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPages', array('module' => 'Actions', 'action' => 'indexPageUrls'), true, 1);
+ Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPagesEntry', array('module' => 'Actions', 'action' => 'indexEntryPageUrls'), true, 2);
+ Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPagesExit', array('module' => 'Actions', 'action' => 'indexExitPageUrls'), true, 3);
+ Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPageTitles', array('module' => 'Actions', 'action' => 'indexPageTitles'), true, 4);
+ Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuOutlinks', array('module' => 'Actions', 'action' => 'indexOutlinks'), true, 6);
+ Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuDownloads', array('module' => 'Actions', 'action' => 'indexDownloads'), true, 7);
+
+ if ($this->isSiteSearchEnabled()) {
+ Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuSitesearch', array('module' => 'Actions', 'action' => 'indexSiteSearch'), true, 5);
+ }
+ }
+
+ protected function isSiteSearchEnabled()
+ {
+ $idSite = Piwik_Common::getRequestVar('idSite', 0, 'int');
+ if ($idSite == 0) {
+ return false;
+ }
+ return Piwik_Site::isSiteSearchEnabledFor($idSite);
+ }
+
+
+ /**
+ * @param Piwik_Event_Notification $notification notification object
+ * @return mixed
+ */
+ function archivePeriod($notification)
+ {
+ $archiveProcessing = $notification->getNotificationObject();
+
+ if (!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return;
+
+ $actionsArchiving = new Piwik_Actions_Archiving($archiveProcessing->idsite);
+ return $actionsArchiving->archivePeriod($archiveProcessing);
+ }
+
+ /**
+ * Compute all the actions along with their hierarchies.
+ *
+ * For each action we process the "interest statistics" :
+ * visits, unique visitors, bounce count, sum visit length.
+ *
+ * @param Piwik_Event_Notification $notification notification object
+ */
+ public function archiveDay($notification)
+ {
+ /* @var $archiveProcessing Piwik_ArchiveProcessing_Day */
+ $archiveProcessing = $notification->getNotificationObject();
+
+ if (!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return;
+
+ $actionsArchiving = new Piwik_Actions_Archiving($archiveProcessing->idsite);
+ return $actionsArchiving->archiveDay($archiveProcessing);
+ }
+
+ static public function checkCustomVariablesPluginEnabled()
+ {
+ if (!self::isCustomVariablesPluginsEnabled()) {
+ throw new Exception("To Track Site Search Categories, please ask the Piwik Administrator to enable the 'Custom Variables' plugin in Settings > Plugins.");
+ }
+ }
+
+ static protected function isCustomVariablesPluginsEnabled()
+ {
+ return Piwik_PluginsManager::getInstance()->isPluginActivated('CustomVariables');
+ }
}
diff --git a/plugins/Actions/Archiving.php b/plugins/Actions/Archiving.php
index c0d36d1083..db71faf788 100644
--- a/plugins/Actions/Archiving.php
+++ b/plugins/Actions/Archiving.php
@@ -16,100 +16,100 @@
*/
class Piwik_Actions_Archiving
{
- protected $actionsTablesByType = null;
-
- public static $actionTypes = array(
- Piwik_Tracker_Action::TYPE_ACTION_URL,
- Piwik_Tracker_Action::TYPE_OUTLINK,
- Piwik_Tracker_Action::TYPE_DOWNLOAD,
- Piwik_Tracker_Action::TYPE_ACTION_NAME,
- Piwik_Tracker_Action::TYPE_SITE_SEARCH,
- );
-
- static protected $invalidSummedColumnNameToRenamedNameFromPeriodArchive = array(
- Piwik_Archive::INDEX_NB_UNIQ_VISITORS => Piwik_Archive::INDEX_SUM_DAILY_NB_UNIQ_VISITORS,
- Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS => Piwik_Archive::INDEX_PAGE_ENTRY_SUM_DAILY_NB_UNIQ_VISITORS,
- Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS => Piwik_Archive::INDEX_PAGE_EXIT_SUM_DAILY_NB_UNIQ_VISITORS,
- );
-
- static protected $invalidSummedColumnNameToDeleteFromDayArchive = array(
- Piwik_Archive::INDEX_NB_UNIQ_VISITORS,
- Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS,
- Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS,
- );
-
- protected $isSiteSearchEnabled = false;
-
- function __construct($idSite)
- {
- $this->isSiteSearchEnabled = Piwik_Site::isSiteSearchEnabledFor($idSite);
- }
-
- /**
- * Archives Actions reports for a Period
- * @param Piwik_ArchiveProcessing $archiveProcessing
- * @return bool
- */
- public function archivePeriod(Piwik_ArchiveProcessing $archiveProcessing)
- {
- Piwik_Actions_ArchivingHelper::reloadConfig();
- $dataTableToSum = array(
- 'Actions_actions',
- 'Actions_downloads',
- 'Actions_outlink',
- 'Actions_actions_url',
- 'Actions_sitesearch',
- );
- $nameToCount = $archiveProcessing->archiveDataTable($dataTableToSum,
- self::$invalidSummedColumnNameToRenamedNameFromPeriodArchive,
- Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero,
- Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable,
- Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation);
-
- $archiveProcessing->archiveNumericValuesSum(array(
- 'Actions_nb_pageviews',
- 'Actions_nb_uniq_pageviews',
- 'Actions_nb_downloads',
- 'Actions_nb_uniq_downloads',
- 'Actions_nb_outlinks',
- 'Actions_nb_uniq_outlinks',
- 'Actions_nb_searches',
- ));
-
- // Unique Keywords can't be summed, instead we take the RowsCount() of the keyword table
- $archiveProcessing->insertNumericRecord('Actions_nb_keywords', $nameToCount['Actions_sitesearch']['level0']);
- return true;
- }
-
- /**
- * Archives Actions reports for a Day
- *
- * @param Piwik_ArchiveProcessing $archiveProcessing
- * @return bool
- */
- public function archiveDay(Piwik_ArchiveProcessing $archiveProcessing)
- {
- $rankingQueryLimit = self::getRankingQueryLimit();
- Piwik_Actions_ArchivingHelper::reloadConfig();
-
- $this->initActionsTables();
- $this->archiveDayActions($archiveProcessing, $rankingQueryLimit);
- $this->archiveDayEntryActions($archiveProcessing, $rankingQueryLimit);
- $this->archiveDayExitActions($archiveProcessing, $rankingQueryLimit);
- $this->archiveDayActionsTime($archiveProcessing, $rankingQueryLimit);
-
- // Record the final datasets
- $this->archiveDayRecordInDatabase($archiveProcessing);
-
- return true;
- }
-
- /*
- * Page URLs and Page names, general stats
- */
- protected function archiveDayActions($archiveProcessing, $rankingQueryLimit)
- {
- $select = "log_action.name,
+ protected $actionsTablesByType = null;
+
+ public static $actionTypes = array(
+ Piwik_Tracker_Action::TYPE_ACTION_URL,
+ Piwik_Tracker_Action::TYPE_OUTLINK,
+ Piwik_Tracker_Action::TYPE_DOWNLOAD,
+ Piwik_Tracker_Action::TYPE_ACTION_NAME,
+ Piwik_Tracker_Action::TYPE_SITE_SEARCH,
+ );
+
+ static protected $invalidSummedColumnNameToRenamedNameFromPeriodArchive = array(
+ Piwik_Archive::INDEX_NB_UNIQ_VISITORS => Piwik_Archive::INDEX_SUM_DAILY_NB_UNIQ_VISITORS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS => Piwik_Archive::INDEX_PAGE_ENTRY_SUM_DAILY_NB_UNIQ_VISITORS,
+ Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS => Piwik_Archive::INDEX_PAGE_EXIT_SUM_DAILY_NB_UNIQ_VISITORS,
+ );
+
+ static protected $invalidSummedColumnNameToDeleteFromDayArchive = array(
+ Piwik_Archive::INDEX_NB_UNIQ_VISITORS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS,
+ Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS,
+ );
+
+ protected $isSiteSearchEnabled = false;
+
+ function __construct($idSite)
+ {
+ $this->isSiteSearchEnabled = Piwik_Site::isSiteSearchEnabledFor($idSite);
+ }
+
+ /**
+ * Archives Actions reports for a Period
+ * @param Piwik_ArchiveProcessing $archiveProcessing
+ * @return bool
+ */
+ public function archivePeriod(Piwik_ArchiveProcessing $archiveProcessing)
+ {
+ Piwik_Actions_ArchivingHelper::reloadConfig();
+ $dataTableToSum = array(
+ 'Actions_actions',
+ 'Actions_downloads',
+ 'Actions_outlink',
+ 'Actions_actions_url',
+ 'Actions_sitesearch',
+ );
+ $nameToCount = $archiveProcessing->archiveDataTable($dataTableToSum,
+ self::$invalidSummedColumnNameToRenamedNameFromPeriodArchive,
+ Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero,
+ Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable,
+ Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation);
+
+ $archiveProcessing->archiveNumericValuesSum(array(
+ 'Actions_nb_pageviews',
+ 'Actions_nb_uniq_pageviews',
+ 'Actions_nb_downloads',
+ 'Actions_nb_uniq_downloads',
+ 'Actions_nb_outlinks',
+ 'Actions_nb_uniq_outlinks',
+ 'Actions_nb_searches',
+ ));
+
+ // Unique Keywords can't be summed, instead we take the RowsCount() of the keyword table
+ $archiveProcessing->insertNumericRecord('Actions_nb_keywords', $nameToCount['Actions_sitesearch']['level0']);
+ return true;
+ }
+
+ /**
+ * Archives Actions reports for a Day
+ *
+ * @param Piwik_ArchiveProcessing $archiveProcessing
+ * @return bool
+ */
+ public function archiveDay(Piwik_ArchiveProcessing $archiveProcessing)
+ {
+ $rankingQueryLimit = self::getRankingQueryLimit();
+ Piwik_Actions_ArchivingHelper::reloadConfig();
+
+ $this->initActionsTables();
+ $this->archiveDayActions($archiveProcessing, $rankingQueryLimit);
+ $this->archiveDayEntryActions($archiveProcessing, $rankingQueryLimit);
+ $this->archiveDayExitActions($archiveProcessing, $rankingQueryLimit);
+ $this->archiveDayActionsTime($archiveProcessing, $rankingQueryLimit);
+
+ // Record the final datasets
+ $this->archiveDayRecordInDatabase($archiveProcessing);
+
+ return true;
+ }
+
+ /*
+ * Page URLs and Page names, general stats
+ */
+ protected function archiveDayActions($archiveProcessing, $rankingQueryLimit)
+ {
+ $select = "log_action.name,
log_action.type,
log_action.idaction,
log_action.url_prefix,
@@ -117,432 +117,422 @@ class Piwik_Actions_Archiving
count(distinct log_link_visit_action.idvisitor) as `" . Piwik_Archive::INDEX_NB_UNIQ_VISITORS . "`,
count(*) as `" . Piwik_Archive::INDEX_PAGE_NB_HITS . "`,
sum(
- case when " . Piwik_Tracker_Action::DB_COLUMN_TIME_GENERATION ." is null
+ case when " . Piwik_Tracker_Action::DB_COLUMN_TIME_GENERATION . " is null
then 0
- else " . Piwik_Tracker_Action::DB_COLUMN_TIME_GENERATION ."
+ else " . Piwik_Tracker_Action::DB_COLUMN_TIME_GENERATION . "
end
) / 1000 as `" . Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION . "`,
sum(
- case when " . Piwik_Tracker_Action::DB_COLUMN_TIME_GENERATION ." is null
+ case when " . Piwik_Tracker_Action::DB_COLUMN_TIME_GENERATION . " is null
then 0
else 1
end
) as `" . Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION . "`";
- $from = array(
- "log_link_visit_action",
- array(
- "table" => "log_action",
- "joinOn" => "log_link_visit_action.%s = log_action.idaction"
- )
- );
+ $from = array(
+ "log_link_visit_action",
+ array(
+ "table" => "log_action",
+ "joinOn" => "log_link_visit_action.%s = log_action.idaction"
+ )
+ );
- $where = "log_link_visit_action.server_time >= ?
+ $where = "log_link_visit_action.server_time >= ?
AND log_link_visit_action.server_time <= ?
AND log_link_visit_action.idsite = ?
AND log_link_visit_action.%s IS NOT NULL";
- $groupBy = "log_action.idaction";
- $orderBy = "`" . Piwik_Archive::INDEX_PAGE_NB_HITS . "` DESC, name ASC";
-
- $rankingQuery = false;
- if ($rankingQueryLimit > 0)
- {
- $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
- $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
- $rankingQuery->addLabelColumn(array('idaction', 'name'));
- $rankingQuery->addColumn(array('url_prefix', Piwik_Archive::INDEX_NB_UNIQ_VISITORS));
- $rankingQuery->addColumn(array(Piwik_Archive::INDEX_PAGE_NB_HITS, Piwik_Archive::INDEX_NB_VISITS), 'sum');
- if ($this->isSiteSearchEnabled())
- {
- $rankingQuery->addColumn(Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT, 'min');
- $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS, 'sum');
- }
- $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION, 'sum');
- $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION, 'sum');
- $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
- }
-
- // Special Magic to get
- // 1) No result Keywords
- // 2) For each page view, count number of times the referrer page was a Site Search
- if($this->isSiteSearchEnabled())
- {
- $selectFlagNoResultKeywords = ",
- CASE WHEN (MAX(log_link_visit_action.custom_var_v". Piwik_Tracker_Action::CVAR_INDEX_SEARCH_COUNT.") = 0 AND log_link_visit_action.custom_var_k". Piwik_Tracker_Action::CVAR_INDEX_SEARCH_COUNT." = '". Piwik_Tracker_Action::CVAR_KEY_SEARCH_COUNT. "') THEN 1 ELSE 0 END AS `" . Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT . "`";
-
- //we need an extra JOIN to know whether the referrer "idaction_name_ref" was a Site Search request
- $from[] = array(
- "table" => "log_action",
- "tableAlias" => "log_action_name_ref",
- "joinOn" => "log_link_visit_action.idaction_name_ref = log_action_name_ref.idaction"
- );
-
- $selectSiteSearchFollowingPages = ",
- SUM(CASE WHEN log_action_name_ref.type = " . Piwik_Tracker_Action::TYPE_SITE_SEARCH . " THEN 1 ELSE 0 END) AS `". Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS."`";
-
- $select .= $selectFlagNoResultKeywords
- . $selectSiteSearchFollowingPages;
- // Not working yet
+ $groupBy = "log_action.idaction";
+ $orderBy = "`" . Piwik_Archive::INDEX_PAGE_NB_HITS . "` DESC, name ASC";
+
+ $rankingQuery = false;
+ if ($rankingQueryLimit > 0) {
+ $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
+ $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
+ $rankingQuery->addLabelColumn(array('idaction', 'name'));
+ $rankingQuery->addColumn(array('url_prefix', Piwik_Archive::INDEX_NB_UNIQ_VISITORS));
+ $rankingQuery->addColumn(array(Piwik_Archive::INDEX_PAGE_NB_HITS, Piwik_Archive::INDEX_NB_VISITS), 'sum');
+ if ($this->isSiteSearchEnabled()) {
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT, 'min');
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS, 'sum');
+ }
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION, 'sum');
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION, 'sum');
+ $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
+ }
+
+ // Special Magic to get
+ // 1) No result Keywords
+ // 2) For each page view, count number of times the referrer page was a Site Search
+ if ($this->isSiteSearchEnabled()) {
+ $selectFlagNoResultKeywords = ",
+ CASE WHEN (MAX(log_link_visit_action.custom_var_v" . Piwik_Tracker_Action::CVAR_INDEX_SEARCH_COUNT . ") = 0 AND log_link_visit_action.custom_var_k" . Piwik_Tracker_Action::CVAR_INDEX_SEARCH_COUNT . " = '" . Piwik_Tracker_Action::CVAR_KEY_SEARCH_COUNT . "') THEN 1 ELSE 0 END AS `" . Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT . "`";
+
+ //we need an extra JOIN to know whether the referrer "idaction_name_ref" was a Site Search request
+ $from[] = array(
+ "table" => "log_action",
+ "tableAlias" => "log_action_name_ref",
+ "joinOn" => "log_link_visit_action.idaction_name_ref = log_action_name_ref.idaction"
+ );
+
+ $selectSiteSearchFollowingPages = ",
+ SUM(CASE WHEN log_action_name_ref.type = " . Piwik_Tracker_Action::TYPE_SITE_SEARCH . " THEN 1 ELSE 0 END) AS `" . Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS . "`";
+
+ $select .= $selectFlagNoResultKeywords
+ . $selectSiteSearchFollowingPages;
+ // Not working yet
// $selectRefPageIsStartingSiteSearch = ",
// SUM(CASE WHEN log_action_name_ref.type = " . Piwik_Tracker_Action::TYPE_ACTION_NAME . " THEN 1 ELSE 0 END) AS `". Piwik_Archive::INDEX_PAGE_STARTING_SITE_SEARCH_NB_HITS."`";
// . $selectRefPageIsStartingSiteSearch
// . ", idaction_url_ref, idaction_name_ref"
- }
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "idaction_name", $archiveProcessing, $rankingQuery);
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "idaction_url", $archiveProcessing, $rankingQuery);
- }
-
- /**
- * Entry actions for Page URLs and Page names
- */
- protected function archiveDayEntryActions($archiveProcessing, $rankingQueryLimit)
- {
- $rankingQuery = false;
- if ($rankingQueryLimit > 0) {
- $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
- $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
- $rankingQuery->addLabelColumn('idaction');
- $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS);
- $rankingQuery->addColumn(array(Piwik_Archive::INDEX_PAGE_ENTRY_NB_VISITS,
- Piwik_Archive::INDEX_PAGE_ENTRY_NB_ACTIONS,
- Piwik_Archive::INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH,
- Piwik_Archive::INDEX_PAGE_ENTRY_BOUNCE_COUNT), 'sum');
- $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
-
- $extraSelects = 'log_action.type, log_action.name,';
- $from = array(
- "log_visit",
- array(
- "table" => "log_action",
- "joinOn" => "log_visit.%s = log_action.idaction"
- )
- );
- $orderBy = "`" . Piwik_Archive::INDEX_PAGE_ENTRY_NB_ACTIONS . "` DESC, log_action.name ASC";
- } else {
- $extraSelects = false;
- $from = "log_visit";
- $orderBy = false;
- }
-
- $select = "log_visit.%s as idaction, $extraSelects
+ }
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "idaction_name", $archiveProcessing, $rankingQuery);
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "idaction_url", $archiveProcessing, $rankingQuery);
+ }
+
+ /**
+ * Entry actions for Page URLs and Page names
+ */
+ protected function archiveDayEntryActions($archiveProcessing, $rankingQueryLimit)
+ {
+ $rankingQuery = false;
+ if ($rankingQueryLimit > 0) {
+ $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
+ $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
+ $rankingQuery->addLabelColumn('idaction');
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS);
+ $rankingQuery->addColumn(array(Piwik_Archive::INDEX_PAGE_ENTRY_NB_VISITS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_NB_ACTIONS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH,
+ Piwik_Archive::INDEX_PAGE_ENTRY_BOUNCE_COUNT), 'sum');
+ $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
+
+ $extraSelects = 'log_action.type, log_action.name,';
+ $from = array(
+ "log_visit",
+ array(
+ "table" => "log_action",
+ "joinOn" => "log_visit.%s = log_action.idaction"
+ )
+ );
+ $orderBy = "`" . Piwik_Archive::INDEX_PAGE_ENTRY_NB_ACTIONS . "` DESC, log_action.name ASC";
+ } else {
+ $extraSelects = false;
+ $from = "log_visit";
+ $orderBy = false;
+ }
+
+ $select = "log_visit.%s as idaction, $extraSelects
count(distinct log_visit.idvisitor) as `" . Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS . "`,
count(*) as `" . Piwik_Archive::INDEX_PAGE_ENTRY_NB_VISITS . "`,
sum(log_visit.visit_total_actions) as `" . Piwik_Archive::INDEX_PAGE_ENTRY_NB_ACTIONS . "`,
sum(log_visit.visit_total_time) as `" . Piwik_Archive::INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH . "`,
sum(case log_visit.visit_total_actions when 1 then 1 when 0 then 1 else 0 end) as `" . Piwik_Archive::INDEX_PAGE_ENTRY_BOUNCE_COUNT . "`";
- $where = "log_visit.visit_last_action_time >= ?
+ $where = "log_visit.visit_last_action_time >= ?
AND log_visit.visit_last_action_time <= ?
AND log_visit.idsite = ?
AND log_visit.%s > 0";
- $groupBy = "log_visit.%s, idaction";
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "visit_entry_idaction_url", $archiveProcessing, $rankingQuery);
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "visit_entry_idaction_name", $archiveProcessing, $rankingQuery);
- }
-
-
- /**
- * Time per action
- */
- protected function archiveDayActionsTime($archiveProcessing, $rankingQueryLimit)
- {
- $rankingQuery = false;
- if ($rankingQueryLimit > 0)
- {
- $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
- $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
- $rankingQuery->addLabelColumn('idaction');
- $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_SUM_TIME_SPENT, 'sum');
- $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
-
- $extraSelects = "log_action.type, log_action.name, count(*) as `" . Piwik_Archive::INDEX_PAGE_NB_HITS . "`,";
- $from = array(
- "log_link_visit_action",
- array(
- "table" => "log_action",
- "joinOn" => "log_link_visit_action.%s = log_action.idaction"
- )
- );
- $orderBy = "`" . Piwik_Archive::INDEX_PAGE_NB_HITS . "` DESC, log_action.name ASC";
- } else {
- $extraSelects = false;
- $from = "log_link_visit_action";
- $orderBy = false;
- }
-
- $select = "log_link_visit_action.%s as idaction, $extraSelects
+ $groupBy = "log_visit.%s, idaction";
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "visit_entry_idaction_url", $archiveProcessing, $rankingQuery);
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "visit_entry_idaction_name", $archiveProcessing, $rankingQuery);
+ }
+
+
+ /**
+ * Time per action
+ */
+ protected function archiveDayActionsTime($archiveProcessing, $rankingQueryLimit)
+ {
+ $rankingQuery = false;
+ if ($rankingQueryLimit > 0) {
+ $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
+ $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
+ $rankingQuery->addLabelColumn('idaction');
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_SUM_TIME_SPENT, 'sum');
+ $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
+
+ $extraSelects = "log_action.type, log_action.name, count(*) as `" . Piwik_Archive::INDEX_PAGE_NB_HITS . "`,";
+ $from = array(
+ "log_link_visit_action",
+ array(
+ "table" => "log_action",
+ "joinOn" => "log_link_visit_action.%s = log_action.idaction"
+ )
+ );
+ $orderBy = "`" . Piwik_Archive::INDEX_PAGE_NB_HITS . "` DESC, log_action.name ASC";
+ } else {
+ $extraSelects = false;
+ $from = "log_link_visit_action";
+ $orderBy = false;
+ }
+
+ $select = "log_link_visit_action.%s as idaction, $extraSelects
sum(log_link_visit_action.time_spent_ref_action) as `" . Piwik_Archive::INDEX_PAGE_SUM_TIME_SPENT . "`";
- $where = "log_link_visit_action.server_time >= ?
+ $where = "log_link_visit_action.server_time >= ?
AND log_link_visit_action.server_time <= ?
AND log_link_visit_action.idsite = ?
AND log_link_visit_action.time_spent_ref_action > 0
AND log_link_visit_action.%s > 0";
- $groupBy = "log_link_visit_action.%s, idaction";
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "idaction_url_ref", $archiveProcessing, $rankingQuery);
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "idaction_name_ref", $archiveProcessing, $rankingQuery);
- }
-
- /**
- * Exit actions
- */
- public function archiveDayExitActions($archiveProcessing, $rankingQueryLimit)
- {
- $rankingQuery = false;
- if ($rankingQueryLimit > 0) {
- $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
- $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
- $rankingQuery->addLabelColumn('idaction');
- $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS);
- $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_EXIT_NB_VISITS, 'sum');
- $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
-
- $extraSelects = 'log_action.type, log_action.name,';
- $from = array(
- "log_visit",
- array(
- "table" => "log_action",
- "joinOn" => "log_visit.%s = log_action.idaction"
- )
- );
- $orderBy = "`" . Piwik_Archive::INDEX_PAGE_EXIT_NB_VISITS . "` DESC, log_action.name ASC";
- } else {
- $extraSelects = false;
- $from = "log_visit";
- $orderBy = false;
- }
-
- $select = "log_visit.%s as idaction, $extraSelects
+ $groupBy = "log_link_visit_action.%s, idaction";
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "idaction_url_ref", $archiveProcessing, $rankingQuery);
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "idaction_name_ref", $archiveProcessing, $rankingQuery);
+ }
+
+ /**
+ * Exit actions
+ */
+ public function archiveDayExitActions($archiveProcessing, $rankingQueryLimit)
+ {
+ $rankingQuery = false;
+ if ($rankingQueryLimit > 0) {
+ $rankingQuery = new Piwik_RankingQuery($rankingQueryLimit);
+ $rankingQuery->setOthersLabel(Piwik_DataTable::LABEL_SUMMARY_ROW);
+ $rankingQuery->addLabelColumn('idaction');
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS);
+ $rankingQuery->addColumn(Piwik_Archive::INDEX_PAGE_EXIT_NB_VISITS, 'sum');
+ $rankingQuery->partitionResultIntoMultipleGroups('type', array_keys($this->actionsTablesByType));
+
+ $extraSelects = 'log_action.type, log_action.name,';
+ $from = array(
+ "log_visit",
+ array(
+ "table" => "log_action",
+ "joinOn" => "log_visit.%s = log_action.idaction"
+ )
+ );
+ $orderBy = "`" . Piwik_Archive::INDEX_PAGE_EXIT_NB_VISITS . "` DESC, log_action.name ASC";
+ } else {
+ $extraSelects = false;
+ $from = "log_visit";
+ $orderBy = false;
+ }
+
+ $select = "log_visit.%s as idaction, $extraSelects
count(distinct log_visit.idvisitor) as `" . Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS . "`,
count(*) as `" . Piwik_Archive::INDEX_PAGE_EXIT_NB_VISITS . "`";
- $where = "log_visit.visit_last_action_time >= ?
+ $where = "log_visit.visit_last_action_time >= ?
AND log_visit.visit_last_action_time <= ?
AND log_visit.idsite = ?
AND log_visit.%s > 0";
- $groupBy = "log_visit.%s, idaction";
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "visit_exit_idaction_url", $archiveProcessing, $rankingQuery);
-
- $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- "visit_exit_idaction_name", $archiveProcessing, $rankingQuery);
- return array($rankingQuery, $extraSelects, $from, $orderBy, $select, $where, $groupBy);
- }
-
-
- /**
- * Records in the DB the archived reports for Page views, Downloads, Outlinks, and Page titles
- *
- * @param $archiveProcessing
- */
- protected function archiveDayRecordInDatabase($archiveProcessing)
- {
- Piwik_Actions_ArchivingHelper::clearActionsCache();
-
- /** @var Piwik_DataTable $dataTable */
- $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION_URL];
- self::deleteInvalidSummedColumnsFromDataTable($dataTable);
- $s = $dataTable->getSerialized( Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation );
- $archiveProcessing->insertBlobRecord('Actions_actions_url', $s);
- $archiveProcessing->insertNumericRecord('Actions_nb_pageviews', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS)));
- $archiveProcessing->insertNumericRecord('Actions_nb_uniq_pageviews', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
- destroy($dataTable);
-
- $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_DOWNLOAD];
- self::deleteInvalidSummedColumnsFromDataTable($dataTable);
- $s = $dataTable->getSerialized(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation );
- $archiveProcessing->insertBlobRecord('Actions_downloads', $s);
- $archiveProcessing->insertNumericRecord('Actions_nb_downloads', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS)));
- $archiveProcessing->insertNumericRecord('Actions_nb_uniq_downloads', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
- destroy($dataTable);
-
- $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_OUTLINK];
- self::deleteInvalidSummedColumnsFromDataTable($dataTable);
- $s = $dataTable->getSerialized( Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation );
- $archiveProcessing->insertBlobRecord('Actions_outlink', $s);
- $archiveProcessing->insertNumericRecord('Actions_nb_outlinks', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS)));
- $archiveProcessing->insertNumericRecord('Actions_nb_uniq_outlinks', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
- destroy($dataTable);
-
- $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION_NAME];
- self::deleteInvalidSummedColumnsFromDataTable($dataTable);
- $s = $dataTable->getSerialized( Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation );
- $archiveProcessing->insertBlobRecord('Actions_actions', $s);
- destroy($dataTable);
-
- $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_SITE_SEARCH];
- self::deleteInvalidSummedColumnsFromDataTable($dataTable);
- $this->deleteUnusedColumnsFromKeywordsDataTable($dataTable);
- $s = $dataTable->getSerialized( Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation );
- $archiveProcessing->insertBlobRecord('Actions_sitesearch', $s);
- $archiveProcessing->insertNumericRecord('Actions_nb_searches', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
- $archiveProcessing->insertNumericRecord('Actions_nb_keywords', $dataTable->getRowsCount());
- destroy($dataTable);
-
- destroy($this->actionsTablesByType);
- }
-
- protected function deleteUnusedColumnsFromKeywordsDataTable($dataTable)
- {
- $columnsToDelete = array(
- Piwik_Archive::INDEX_NB_UNIQ_VISITORS,
- Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS,
- Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS,
- Piwik_Archive::INDEX_PAGE_ENTRY_NB_ACTIONS,
- Piwik_Archive::INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH,
- Piwik_Archive::INDEX_PAGE_ENTRY_NB_VISITS,
- Piwik_Archive::INDEX_PAGE_ENTRY_BOUNCE_COUNT,
- Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS,
- );
- $dataTable->deleteColumns($columnsToDelete);
- }
-
- static protected function removeEmptyColumns($dataTable)
- {
- // Delete all columns that have a value of zero
- $dataTable->filter('ColumnDelete', array(
- $columnsToRemove = array(Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS),
- $columnsToKeep = array(),
- $deleteIfZeroOnly = true
- ));
- }
-
-
- /**
- * Returns the limit to use with RankingQuery for this plugin.
- *
- * @return int
- */
- private static function getRankingQueryLimit()
- {
- $configGeneral = Piwik_Config::getInstance()->General;
- $configLimit = $configGeneral['archiving_ranking_query_row_limit'];
- return $configLimit == 0 ? 0 : max(
- $configLimit,
- $configGeneral['datatable_archiving_maximum_rows_actions'],
- $configGeneral['datatable_archiving_maximum_rows_subtable_actions']
- );
- }
-
-
- /**
- * @param $select
- * @param $from
- * @param $where
- * @param $orderBy
- * @param $groupBy
- * @param $sprintfField
- * @param Piwik_ArchiveProcessing $archiveProcessing
- * @param Piwik_RankingQuery|false $rankingQuery
- * @return int
- */
- protected function archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
- $sprintfField, $archiveProcessing, $rankingQuery = false)
- {
- // idaction field needs to be set in select clause before calling getSelectQuery().
- // if a complex segmentation join is needed, the field needs to be propagated
- // to the outer select. therefore, $segment needs to know about it.
- $select = sprintf($select, $sprintfField);
-
- $bind = array();
-
- // get query with segmentation
- $query = $archiveProcessing->getSegment()->getSelectQuery(
- $select, $from, $where, $bind, $orderBy, $groupBy);
-
- // extend bindings
- $bind = array_merge(array( $archiveProcessing->getStartDatetimeUTC(),
- $archiveProcessing->getEndDatetimeUTC(),
- $archiveProcessing->idsite
- ),
- $query['bind']
- );
-
- // replace the rest of the %s
- $querySql = str_replace("%s", $sprintfField, $query['sql']);
-
- // apply ranking query
- if ($rankingQuery)
- {
- $querySql = $rankingQuery->generateQuery($querySql);
- }
-
- // get result
- $resultSet = $archiveProcessing->db->query($querySql, $bind);
- $modified = Piwik_Actions_ArchivingHelper::updateActionsTableWithRowQuery($resultSet, $sprintfField, $this->actionsTablesByType);
- return $modified;
- }
-
-
- /**
- * For rows which have subtables (eg. directories with sub pages),
- * deletes columns which don't make sense when all values of sub pages are summed.
- *
- * @param $dataTable Piwik_DataTable
- */
- static public function deleteInvalidSummedColumnsFromDataTable($dataTable)
- {
- foreach($dataTable->getRows() as $id => $row)
- {
- if(($idSubtable = $row->getIdSubDataTable()) !== null
- || $id === Piwik_DataTable::ID_SUMMARY_ROW)
- {
- if ($idSubtable !== null)
- {
- $subtable = Piwik_DataTable_Manager::getInstance()->getTable($idSubtable);
- self::deleteInvalidSummedColumnsFromDataTable($subtable);
- }
-
- if ($row instanceof Piwik_DataTable_Row_DataTableSummary)
- {
- $row->recalculate();
- }
-
- foreach(self::$invalidSummedColumnNameToDeleteFromDayArchive as $name)
- {
- $row->deleteColumn($name);
- }
- }
- }
-
- // And this as well
- self::removeEmptyColumns($dataTable);
- }
-
- /**
- * Initializes the DataTables created by the archiveDay function.
- */
- private function initActionsTables()
- {
- $this->actionsTablesByType = array();
- foreach (self::$actionTypes as $type)
- {
- $dataTable = new Piwik_DataTable();
- $dataTable->setMaximumAllowedRows(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero);
-
- $this->actionsTablesByType[$type] = $dataTable;
- }
- }
-
- protected function isSiteSearchEnabled()
- {
- return $this->isSiteSearchEnabled;
- }
+ $groupBy = "log_visit.%s, idaction";
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "visit_exit_idaction_url", $archiveProcessing, $rankingQuery);
+
+ $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ "visit_exit_idaction_name", $archiveProcessing, $rankingQuery);
+ return array($rankingQuery, $extraSelects, $from, $orderBy, $select, $where, $groupBy);
+ }
+
+
+ /**
+ * Records in the DB the archived reports for Page views, Downloads, Outlinks, and Page titles
+ *
+ * @param $archiveProcessing
+ */
+ protected function archiveDayRecordInDatabase($archiveProcessing)
+ {
+ Piwik_Actions_ArchivingHelper::clearActionsCache();
+
+ /** @var Piwik_DataTable $dataTable */
+ $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION_URL];
+ self::deleteInvalidSummedColumnsFromDataTable($dataTable);
+ $s = $dataTable->getSerialized(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation);
+ $archiveProcessing->insertBlobRecord('Actions_actions_url', $s);
+ $archiveProcessing->insertNumericRecord('Actions_nb_pageviews', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS)));
+ $archiveProcessing->insertNumericRecord('Actions_nb_uniq_pageviews', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
+ destroy($dataTable);
+
+ $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_DOWNLOAD];
+ self::deleteInvalidSummedColumnsFromDataTable($dataTable);
+ $s = $dataTable->getSerialized(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation);
+ $archiveProcessing->insertBlobRecord('Actions_downloads', $s);
+ $archiveProcessing->insertNumericRecord('Actions_nb_downloads', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS)));
+ $archiveProcessing->insertNumericRecord('Actions_nb_uniq_downloads', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
+ destroy($dataTable);
+
+ $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_OUTLINK];
+ self::deleteInvalidSummedColumnsFromDataTable($dataTable);
+ $s = $dataTable->getSerialized(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation);
+ $archiveProcessing->insertBlobRecord('Actions_outlink', $s);
+ $archiveProcessing->insertNumericRecord('Actions_nb_outlinks', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS)));
+ $archiveProcessing->insertNumericRecord('Actions_nb_uniq_outlinks', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
+ destroy($dataTable);
+
+ $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION_NAME];
+ self::deleteInvalidSummedColumnsFromDataTable($dataTable);
+ $s = $dataTable->getSerialized(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation);
+ $archiveProcessing->insertBlobRecord('Actions_actions', $s);
+ destroy($dataTable);
+
+ $dataTable = $this->actionsTablesByType[Piwik_Tracker_Action::TYPE_SITE_SEARCH];
+ self::deleteInvalidSummedColumnsFromDataTable($dataTable);
+ $this->deleteUnusedColumnsFromKeywordsDataTable($dataTable);
+ $s = $dataTable->getSerialized(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero, Piwik_Actions_ArchivingHelper::$maximumRowsInSubDataTable, Piwik_Actions_ArchivingHelper::$columnToSortByBeforeTruncation);
+ $archiveProcessing->insertBlobRecord('Actions_sitesearch', $s);
+ $archiveProcessing->insertNumericRecord('Actions_nb_searches', array_sum($dataTable->getColumn(Piwik_Archive::INDEX_NB_VISITS)));
+ $archiveProcessing->insertNumericRecord('Actions_nb_keywords', $dataTable->getRowsCount());
+ destroy($dataTable);
+
+ destroy($this->actionsTablesByType);
+ }
+
+ protected function deleteUnusedColumnsFromKeywordsDataTable($dataTable)
+ {
+ $columnsToDelete = array(
+ Piwik_Archive::INDEX_NB_UNIQ_VISITORS,
+ Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_NB_ACTIONS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH,
+ Piwik_Archive::INDEX_PAGE_ENTRY_NB_VISITS,
+ Piwik_Archive::INDEX_PAGE_ENTRY_BOUNCE_COUNT,
+ Piwik_Archive::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS,
+ );
+ $dataTable->deleteColumns($columnsToDelete);
+ }
+
+ static protected function removeEmptyColumns($dataTable)
+ {
+ // Delete all columns that have a value of zero
+ $dataTable->filter('ColumnDelete', array(
+ $columnsToRemove = array(Piwik_Archive::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS),
+ $columnsToKeep = array(),
+ $deleteIfZeroOnly = true
+ ));
+ }
+
+
+ /**
+ * Returns the limit to use with RankingQuery for this plugin.
+ *
+ * @return int
+ */
+ private static function getRankingQueryLimit()
+ {
+ $configGeneral = Piwik_Config::getInstance()->General;
+ $configLimit = $configGeneral['archiving_ranking_query_row_limit'];
+ return $configLimit == 0 ? 0 : max(
+ $configLimit,
+ $configGeneral['datatable_archiving_maximum_rows_actions'],
+ $configGeneral['datatable_archiving_maximum_rows_subtable_actions']
+ );
+ }
+
+
+ /**
+ * @param $select
+ * @param $from
+ * @param $where
+ * @param $orderBy
+ * @param $groupBy
+ * @param $sprintfField
+ * @param Piwik_ArchiveProcessing $archiveProcessing
+ * @param Piwik_RankingQuery|false $rankingQuery
+ * @return int
+ */
+ protected function archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy,
+ $sprintfField, $archiveProcessing, $rankingQuery = false)
+ {
+ // idaction field needs to be set in select clause before calling getSelectQuery().
+ // if a complex segmentation join is needed, the field needs to be propagated
+ // to the outer select. therefore, $segment needs to know about it.
+ $select = sprintf($select, $sprintfField);
+
+ $bind = array();
+
+ // get query with segmentation
+ $query = $archiveProcessing->getSegment()->getSelectQuery(
+ $select, $from, $where, $bind, $orderBy, $groupBy);
+
+ // extend bindings
+ $bind = array_merge(array($archiveProcessing->getStartDatetimeUTC(),
+ $archiveProcessing->getEndDatetimeUTC(),
+ $archiveProcessing->idsite
+ ),
+ $query['bind']
+ );
+
+ // replace the rest of the %s
+ $querySql = str_replace("%s", $sprintfField, $query['sql']);
+
+ // apply ranking query
+ if ($rankingQuery) {
+ $querySql = $rankingQuery->generateQuery($querySql);
+ }
+
+ // get result
+ $resultSet = $archiveProcessing->db->query($querySql, $bind);
+ $modified = Piwik_Actions_ArchivingHelper::updateActionsTableWithRowQuery($resultSet, $sprintfField, $this->actionsTablesByType);
+ return $modified;
+ }
+
+
+ /**
+ * For rows which have subtables (eg. directories with sub pages),
+ * deletes columns which don't make sense when all values of sub pages are summed.
+ *
+ * @param $dataTable Piwik_DataTable
+ */
+ static public function deleteInvalidSummedColumnsFromDataTable($dataTable)
+ {
+ foreach ($dataTable->getRows() as $id => $row) {
+ if (($idSubtable = $row->getIdSubDataTable()) !== null
+ || $id === Piwik_DataTable::ID_SUMMARY_ROW
+ ) {
+ if ($idSubtable !== null) {
+ $subtable = Piwik_DataTable_Manager::getInstance()->getTable($idSubtable);
+ self::deleteInvalidSummedColumnsFromDataTable($subtable);
+ }
+
+ if ($row instanceof Piwik_DataTable_Row_DataTableSummary) {
+ $row->recalculate();
+ }
+
+ foreach (self::$invalidSummedColumnNameToDeleteFromDayArchive as $name) {
+ $row->deleteColumn($name);
+ }
+ }
+ }
+
+ // And this as well
+ self::removeEmptyColumns($dataTable);
+ }
+
+ /**
+ * Initializes the DataTables created by the archiveDay function.
+ */
+ private function initActionsTables()
+ {
+ $this->actionsTablesByType = array();
+ foreach (self::$actionTypes as $type) {
+ $dataTable = new Piwik_DataTable();
+ $dataTable->setMaximumAllowedRows(Piwik_Actions_ArchivingHelper::$maximumRowsInDataTableLevelZero);
+
+ $this->actionsTablesByType[$type] = $dataTable;
+ }
+ }
+
+ protected function isSiteSearchEnabled()
+ {
+ return $this->isSiteSearchEnabled;
+ }
}
diff --git a/plugins/Actions/ArchivingHelper.php b/plugins/Actions/ArchivingHelper.php
index 30fb58b555..739e8a2fef 100644
--- a/plugins/Actions/ArchivingHelper.php
+++ b/plugins/Actions/ArchivingHelper.php
@@ -19,495 +19,452 @@
class Piwik_Actions_ArchivingHelper
{
- const OTHERS_ROW_KEY = '';
-
- /**
- * @param Zend_Db_Statement|PDOStatement $query
- * @param string|bool $fieldQueried
- * @param array $actionsTablesByType
- * @return int
- */
- static public function updateActionsTableWithRowQuery($query, $fieldQueried, & $actionsTablesByType)
- {
- $rowsProcessed = 0;
- while( $row = $query->fetch() )
- {
- if(empty($row['idaction']))
- {
- $row['type'] = ($fieldQueried == 'idaction_url' ? Piwik_Tracker_Action::TYPE_ACTION_URL : Piwik_Tracker_Action::TYPE_ACTION_NAME);
- // This will be replaced with 'X not defined' later
- $row['name'] = '';
- // Yes, this is kind of a hack, so we don't mix 'page url not defined' with 'page title not defined' etc.
- $row['idaction'] = -$row['type'];
- }
-
- if($row['type'] != Piwik_Tracker_Action::TYPE_SITE_SEARCH)
- {
- unset($row[Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT]);
- }
-
- // This will appear as <url /> in the API, which is actually very important to keep
- // eg. When there's at least one row in a report that does not have a URL, not having this <url/> would break HTML/PDF reports.
- $url = '';
- if($row['type'] == Piwik_Tracker_Action::TYPE_SITE_SEARCH
- || $row['type'] == Piwik_Tracker_Action::TYPE_ACTION_NAME)
- {
- $url = null;
- }
- elseif(!empty($row['name'])
- && $row['name'] != Piwik_DataTable::LABEL_SUMMARY_ROW)
- {
- $url = Piwik_Tracker_Action::reconstructNormalizedUrl((string)$row['name'], $row['url_prefix']);
- }
-
- if(isset($row['name'])
- && isset($row['type']))
- {
- $actionName = $row['name'];
- $actionType = $row['type'];
- $urlPrefix = $row['url_prefix'];
- $idaction = $row['idaction'];
-
- // in some unknown case, the type field is NULL, as reported in #1082 - we ignore this page view
- if(empty($actionType))
- {
- if ($idaction != Piwik_DataTable::LABEL_SUMMARY_ROW)
- {
- self::setCachedActionRow($idaction, $actionType, false);
- }
- continue;
- }
-
- $actionRow = self::getActionRow($actionName, $actionType, $urlPrefix, $actionsTablesByType);
-
- self::setCachedActionRow($idaction, $actionType, $actionRow);
- }
- else
- {
- $actionRow = self::getCachedActionRow($row['idaction'], $row['type']);
-
- // Action processed as "to skip" for some reasons
- if($actionRow === false)
- {
- continue;
- }
- }
-
-
- if (is_null($actionRow))
- {
- continue;
- }
-
- // Here we do ensure that, the Metadata URL set for a given row, is the one from the Pageview with the most hits.
- // This is to ensure that when, different URLs are loaded with the same page name.
- // For example http://piwik.org and http://id.piwik.org are reported in Piwik > Actions > Pages with /index
- // But, we must make sure http://piwik.org is used to link & for transitions
- // Note: this code is partly duplicated from Piwik_DataTable_Row->sumRowMetadata()
- if( !is_null($url)
- && !$actionRow->isSummaryRow())
- {
- if(($existingUrl = $actionRow->getMetadata('url')) !== false)
- {
- if( !empty($row[Piwik_Archive::INDEX_PAGE_NB_HITS])
- && $row[Piwik_Archive::INDEX_PAGE_NB_HITS] > $actionRow->maxVisitsSummed)
- {
- $actionRow->setMetadata('url', $url);
- $actionRow->maxVisitsSummed = $row[Piwik_Archive::INDEX_PAGE_NB_HITS];
- }
- }
- else
- {
- $actionRow->setMetadata('url', $url);
- $actionRow->maxVisitsSummed = !empty($row[Piwik_Archive::INDEX_PAGE_NB_HITS]) ? $row[Piwik_Archive::INDEX_PAGE_NB_HITS] : 0;
- }
- }
-
- if ($row['type'] != Piwik_Tracker_Action::TYPE_ACTION_URL
- && $row['type'] != Piwik_Tracker_Action::TYPE_ACTION_NAME) {
- // only keep performance metrics when they're used (i.e. for URLs and page titles)
- if (array_key_exists(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION, $row)) {
- unset($row[Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION]);
- }
- if (array_key_exists(Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION, $row)) {
- unset($row[Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION]);
- }
- }
-
- unset($row['name']);
- unset($row['type']);
- unset($row['idaction']);
- unset($row['url_prefix']);
-
- foreach($row as $name => $value)
- {
- // in some edge cases, we have twice the same action name with 2 different idaction
- // - this happens when 2 visitors visit the same new page at the same time, and 2 actions get recorded for the same name
- // - this could also happen when 2 URLs end up having the same label (eg. 2 subdomains get aggregated to the "/index" page name)
- if(($alreadyValue = $actionRow->getColumn($name)) !== false)
- {
- $actionRow->setColumn($name, $alreadyValue+$value);
- }
- else
- {
- $actionRow->addColumn($name, $value);
- }
- }
-
- // if the exit_action was not recorded properly in the log_link_visit_action
- // there would be an error message when getting the nb_hits column
- // we must fake the record and add the columns
- if($actionRow->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS) === false)
- {
- // to test this code: delete the entries in log_link_action_visit for
- // a given exit_idaction_url
- foreach(self::getDefaultRow()->getColumns() as $name => $value)
- {
- $actionRow->addColumn($name, $value);
- }
- }
- $rowsProcessed++;
- }
-
- // just to make sure php copies the last $actionRow in the $parentTable array
- $actionRow =& $actionsTablesByType;
- return $rowsProcessed;
- }
-
- static public $maximumRowsInDataTableLevelZero;
- static public $maximumRowsInSubDataTable;
- static public $columnToSortByBeforeTruncation;
-
- static protected $actionUrlCategoryDelimiter = null;
- static protected $actionTitleCategoryDelimiter = null;
- static protected $defaultActionName = null;
- static protected $defaultActionNameWhenNotDefined = null;
- static protected $defaultActionUrlWhenNotDefined = null;
-
- static public function reloadConfig()
- {
- // for BC, we read the old style delimiter first (see #1067)Row
- $actionDelimiter = @Piwik_Config::getInstance()->General['action_category_delimiter'];
- if(empty($actionDelimiter))
- {
- self::$actionUrlCategoryDelimiter = Piwik_Config::getInstance()->General['action_url_category_delimiter'];
- self::$actionTitleCategoryDelimiter = Piwik_Config::getInstance()->General['action_title_category_delimiter'];
- }
- else
- {
- self::$actionUrlCategoryDelimiter = self::$actionTitleCategoryDelimiter = $actionDelimiter;
- }
-
- self::$defaultActionName = Piwik_Config::getInstance()->General['action_default_name'];
- self::$columnToSortByBeforeTruncation = Piwik_Archive::INDEX_NB_VISITS;
- self::$maximumRowsInDataTableLevelZero = Piwik_Config::getInstance()->General['datatable_archiving_maximum_rows_actions'];
- self::$maximumRowsInSubDataTable = Piwik_Config::getInstance()->General['datatable_archiving_maximum_rows_subtable_actions'];
-
- Piwik_DataTable::setMaximumDepthLevelAllowedAtLeast(self::getSubCategoryLevelLimit() + 1);
- }
-
-
- /**
- * The default row is used when archiving, if data is inconsistent in the DB,
- * there could be pages that have exit/entry hits, but don't yet
- * have a record in the table (or the record was truncated).
- *
- * @return Piwik_DataTable_Row
- */
- static private function getDefaultRow()
- {
- static $row = false;
- if($row === false) {
- // This row is used in the case where an action is know as an exit_action
- // but this action was not properly recorded when it was hit in the first place
- // so we add this fake row information to make sure there is a nb_hits, etc. column for every action
- $row = new Piwik_DataTable_Row(array(
- Piwik_DataTable_Row::COLUMNS => array(
- Piwik_Archive::INDEX_NB_VISITS => 1,
- Piwik_Archive::INDEX_NB_UNIQ_VISITORS => 1,
- Piwik_Archive::INDEX_PAGE_NB_HITS => 1,
- )));
- }
- return $row;
- }
-
- /**
- * Given a page name and type, builds a recursive datatable where
- * each level of the tree is a category, based on the page name split by a delimiter (slash / by default)
- *
- * @param string $actionName
- * @param int $actionType
- * @param int $urlPrefix
- * @param array $actionsTablesByType
- * @return Piwik_DataTable
- */
- protected static function getActionRow( $actionName, $actionType, $urlPrefix=null, &$actionsTablesByType )
- {
- // we work on the root table of the given TYPE (either ACTION_URL or DOWNLOAD or OUTLINK etc.)
- /* @var Piwik_DataTable $currentTable */
- $currentTable =& $actionsTablesByType[$actionType];
-
- // check for ranking query cut-off
- if ($actionName == Piwik_DataTable::LABEL_SUMMARY_ROW)
- {
- $summaryRow = $currentTable->getRowFromId(Piwik_DataTable::ID_SUMMARY_ROW);
- if ($summaryRow === false)
- {
- $summaryRow = $currentTable->addSummaryRow(self::createSummaryRow());
- }
- return $summaryRow;
- }
-
- // go to the level of the subcategory
- $actionExplodedNames = self::getActionExplodedNames($actionName, $actionType, $urlPrefix);
- list($row, $level) = $currentTable->walkPath(
- $actionExplodedNames, self::getDefaultRowColumns(), self::$maximumRowsInSubDataTable);
-
- return $row;
- }
-
- /**
- * Explodes action name into an array of elements.
- *
- * NOTE: before calling this function make sure Piwik_Actions_ArchivingHelper::reloadConfig(); is called
- *
- * for downloads:
- * we explode link http://piwik.org/some/path/piwik.zip into an array( 'piwik.org', '/some/path/piwik.zip' );
- *
- * for outlinks:
- * we explode link http://dev.piwik.org/some/path into an array( 'dev.piwik.org', '/some/path' );
- *
- * for action urls:
- * we explode link http://piwik.org/some/path into an array( 'some', 'path' );
- *
- * for action names:
- * we explode name 'Piwik / Category 1 / Category 2' into an array('Piwik', 'Category 1', 'Category 2');
- *
- * @param string action name
- * @param int action type
- * @param int url prefix (only used for TYPE_ACTION_URL)
- * @return array of exploded elements from $name
- */
- static public function getActionExplodedNames($name, $type, $urlPrefix=null)
- {
- // Site Search does not split Search keywords
- if($type == Piwik_Tracker_Action::TYPE_SITE_SEARCH)
- {
- return array($name);
- }
-
- $matches = array();
- $isUrl = false;
- $name = str_replace("\n", "", $name);
-
- $urlRegexAfterDomain = '([^/]+)[/]?([^#]*)[#]?(.*)';
- if ($urlPrefix === null)
- {
- // match url with protocol (used for outlinks / downloads)
- $urlRegex = '@^http[s]?://'.$urlRegexAfterDomain.'$@i';
- }
- else
- {
- // the name is a url that does not contain protocol and www anymore
- // we know that normalization has been done on db level because $urlPrefix is set
- $urlRegex = '@^'.$urlRegexAfterDomain.'$@i';
- }
-
- preg_match($urlRegex, $name, $matches);
- if( count($matches) )
- {
- $isUrl = true;
- $urlHost = $matches[1];
- $urlPath = $matches[2];
- $urlFragment = $matches[3];
- }
-
- if($type == Piwik_Tracker_Action::TYPE_DOWNLOAD
- || $type == Piwik_Tracker_Action::TYPE_OUTLINK)
- {
- if( $isUrl )
- {
- return array(trim($urlHost), '/' . trim($urlPath));
- }
- }
-
- if( $isUrl )
- {
- $name = $urlPath;
-
- if( $name === '' || substr($name, -1) == '/' )
- {
- $name .= self::$defaultActionName;
- }
- }
-
- if($type == Piwik_Tracker_Action::TYPE_ACTION_NAME)
- {
- $categoryDelimiter = self::$actionTitleCategoryDelimiter;
- }
- else
- {
- $categoryDelimiter = self::$actionUrlCategoryDelimiter;
- }
-
-
- if( $isUrl )
- {
- $urlFragment = Piwik_Tracker_Action::processUrlFragment($urlFragment);
- if(!empty($urlFragment)) {
- $name .= '#' . $urlFragment;
- }
- }
-
- if(empty($categoryDelimiter))
- {
- return array( trim($name) );
- }
-
- $split = explode($categoryDelimiter, $name, self::getSubCategoryLevelLimit());
-
- // trim every category and remove empty categories
- $split = array_map('trim', $split);
- $split = array_filter($split, 'strlen');
-
- // forces array key to start at 0
- $split = array_values($split);
-
- if( empty($split) )
- {
- $defaultName = self::getUnknownActionName($type);
- return array( trim($defaultName) );
- }
-
- $lastPageName = end($split);
- // we are careful to prefix the page URL / name with some value
- // so that if a page has the same name as a category
- // we don't merge both entries
- if($type != Piwik_Tracker_Action::TYPE_ACTION_NAME )
- {
- $lastPageName = '/' . $lastPageName;
- }
- else
- {
- $lastPageName = ' ' . $lastPageName;
- }
- $split[count($split)-1] = $lastPageName;
- return array_values( $split );
- }
-
- /**
- * Gets the key for the cache of action rows from an action ID and type.
- *
- * @param int $idAction
- * @param int $actionType
- * @return string|int
- */
- private static function getCachedActionRowKey( $idAction, $actionType )
- {
- return $idAction == Piwik_DataTable::LABEL_SUMMARY_ROW
- ? $actionType.'_others'
- : $idAction;
- }
-
- /**
- * Returns the configured sub-category level limit.
- *
- * @return int
- */
- public static function getSubCategoryLevelLimit()
- {
- return Piwik_Config::getInstance()->General['action_category_level_limit'];
- }
-
- /**
- * Returns default label for the action type
- *
- * @param $type
- * @return string
- */
- static public function getUnknownActionName($type)
- {
- if(empty(self::$defaultActionNameWhenNotDefined))
- {
- self::$defaultActionNameWhenNotDefined = Piwik_Translate('General_NotDefined', Piwik_Translate('Actions_ColumnPageName'));
- self::$defaultActionUrlWhenNotDefined = Piwik_Translate('General_NotDefined', Piwik_Translate('Actions_ColumnPageURL'));
- }
- if($type == Piwik_Tracker_Action::TYPE_ACTION_NAME)
- {
- return self::$defaultActionNameWhenNotDefined;
- }
- return self::$defaultActionUrlWhenNotDefined;
- }
-
- /**
- * Static cache to store Rows during processing
- */
- static protected $cacheParsedAction = array();
-
- public static function clearActionsCache()
- {
- self::$cacheParsedAction = array();
- }
-
- /**
- * Get cached action row by id & type. If $idAction is set to -1, the 'Others' row
- * for the specific action type will be returned.
- *
- * @param int $idAction
- * @param int $actionType
- * @return Piwik_DataTable_Row|false
- */
- private static function getCachedActionRow( $idAction, $actionType )
- {
- $cacheLabel = self::getCachedActionRowKey($idAction, $actionType);
-
- if (!isset(self::$cacheParsedAction[$cacheLabel]))
- {
- // This can happen when
- // - We select an entry page ID that was only seen yesterday, so wasn't selected in the first query
- // - We count time spent on a page, when this page was only seen yesterday
- return false;
- }
-
- return self::$cacheParsedAction[$cacheLabel];
- }
-
- /**
- * Set cached action row for an id & type.
- *
- * @param int $idAction
- * @param int $actionType
- * @param Piwik_DataTable_Row
- */
- private static function setCachedActionRow( $idAction, $actionType, $actionRow )
- {
- $cacheLabel = self::getCachedActionRowKey($idAction, $actionType);
- self::$cacheParsedAction[$cacheLabel] = $actionRow;
- }
-
- /**
- * Returns the default columns for a row in an Actions DataTable.
- *
- * @return array
- */
- private static function getDefaultRowColumns()
- {
- return array(Piwik_Archive::INDEX_NB_VISITS => 0,
- Piwik_Archive::INDEX_NB_UNIQ_VISITORS => 0,
- Piwik_Archive::INDEX_PAGE_NB_HITS => 0,
- Piwik_Archive::INDEX_PAGE_SUM_TIME_SPENT => 0);
- }
-
- /**
- * Creates a summary row for an Actions DataTable.
- *
- * @return Piwik_DataTable_Row
- */
- private static function createSummaryRow()
- {
- return new Piwik_DataTable_Row(array(
- Piwik_DataTable_Row::COLUMNS =>
- array('label' => Piwik_DataTable::LABEL_SUMMARY_ROW) + self::getDefaultRowColumns()
- ));
- }
+ const OTHERS_ROW_KEY = '';
+
+ /**
+ * @param Zend_Db_Statement|PDOStatement $query
+ * @param string|bool $fieldQueried
+ * @param array $actionsTablesByType
+ * @return int
+ */
+ static public function updateActionsTableWithRowQuery($query, $fieldQueried, & $actionsTablesByType)
+ {
+ $rowsProcessed = 0;
+ while ($row = $query->fetch()) {
+ if (empty($row['idaction'])) {
+ $row['type'] = ($fieldQueried == 'idaction_url' ? Piwik_Tracker_Action::TYPE_ACTION_URL : Piwik_Tracker_Action::TYPE_ACTION_NAME);
+ // This will be replaced with 'X not defined' later
+ $row['name'] = '';
+ // Yes, this is kind of a hack, so we don't mix 'page url not defined' with 'page title not defined' etc.
+ $row['idaction'] = -$row['type'];
+ }
+
+ if ($row['type'] != Piwik_Tracker_Action::TYPE_SITE_SEARCH) {
+ unset($row[Piwik_Archive::INDEX_SITE_SEARCH_HAS_NO_RESULT]);
+ }
+
+ // This will appear as <url /> in the API, which is actually very important to keep
+ // eg. When there's at least one row in a report that does not have a URL, not having this <url/> would break HTML/PDF reports.
+ $url = '';
+ if ($row['type'] == Piwik_Tracker_Action::TYPE_SITE_SEARCH
+ || $row['type'] == Piwik_Tracker_Action::TYPE_ACTION_NAME
+ ) {
+ $url = null;
+ } elseif (!empty($row['name'])
+ && $row['name'] != Piwik_DataTable::LABEL_SUMMARY_ROW
+ ) {
+ $url = Piwik_Tracker_Action::reconstructNormalizedUrl((string)$row['name'], $row['url_prefix']);
+ }
+
+ if (isset($row['name'])
+ && isset($row['type'])
+ ) {
+ $actionName = $row['name'];
+ $actionType = $row['type'];
+ $urlPrefix = $row['url_prefix'];
+ $idaction = $row['idaction'];
+
+ // in some unknown case, the type field is NULL, as reported in #1082 - we ignore this page view
+ if (empty($actionType)) {
+ if ($idaction != Piwik_DataTable::LABEL_SUMMARY_ROW) {
+ self::setCachedActionRow($idaction, $actionType, false);
+ }
+ continue;
+ }
+
+ $actionRow = self::getActionRow($actionName, $actionType, $urlPrefix, $actionsTablesByType);
+
+ self::setCachedActionRow($idaction, $actionType, $actionRow);
+ } else {
+ $actionRow = self::getCachedActionRow($row['idaction'], $row['type']);
+
+ // Action processed as "to skip" for some reasons
+ if ($actionRow === false) {
+ continue;
+ }
+ }
+
+
+ if (is_null($actionRow)) {
+ continue;
+ }
+
+ // Here we do ensure that, the Metadata URL set for a given row, is the one from the Pageview with the most hits.
+ // This is to ensure that when, different URLs are loaded with the same page name.
+ // For example http://piwik.org and http://id.piwik.org are reported in Piwik > Actions > Pages with /index
+ // But, we must make sure http://piwik.org is used to link & for transitions
+ // Note: this code is partly duplicated from Piwik_DataTable_Row->sumRowMetadata()
+ if (!is_null($url)
+ && !$actionRow->isSummaryRow()
+ ) {
+ if (($existingUrl = $actionRow->getMetadata('url')) !== false) {
+ if (!empty($row[Piwik_Archive::INDEX_PAGE_NB_HITS])
+ && $row[Piwik_Archive::INDEX_PAGE_NB_HITS] > $actionRow->maxVisitsSummed
+ ) {
+ $actionRow->setMetadata('url', $url);
+ $actionRow->maxVisitsSummed = $row[Piwik_Archive::INDEX_PAGE_NB_HITS];
+ }
+ } else {
+ $actionRow->setMetadata('url', $url);
+ $actionRow->maxVisitsSummed = !empty($row[Piwik_Archive::INDEX_PAGE_NB_HITS]) ? $row[Piwik_Archive::INDEX_PAGE_NB_HITS] : 0;
+ }
+ }
+
+ if ($row['type'] != Piwik_Tracker_Action::TYPE_ACTION_URL
+ && $row['type'] != Piwik_Tracker_Action::TYPE_ACTION_NAME
+ ) {
+ // only keep performance metrics when they're used (i.e. for URLs and page titles)
+ if (array_key_exists(Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION, $row)) {
+ unset($row[Piwik_Archive::INDEX_PAGE_SUM_TIME_GENERATION]);
+ }
+ if (array_key_exists(Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION, $row)) {
+ unset($row[Piwik_Archive::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION]);
+ }
+ }
+
+ unset($row['name']);
+ unset($row['type']);
+ unset($row['idaction']);
+ unset($row['url_prefix']);
+
+ foreach ($row as $name => $value) {
+ // in some edge cases, we have twice the same action name with 2 different idaction
+ // - this happens when 2 visitors visit the same new page at the same time, and 2 actions get recorded for the same name
+ // - this could also happen when 2 URLs end up having the same label (eg. 2 subdomains get aggregated to the "/index" page name)
+ if (($alreadyValue = $actionRow->getColumn($name)) !== false) {
+ $actionRow->setColumn($name, $alreadyValue + $value);
+ } else {
+ $actionRow->addColumn($name, $value);
+ }
+ }
+
+ // if the exit_action was not recorded properly in the log_link_visit_action
+ // there would be an error message when getting the nb_hits column
+ // we must fake the record and add the columns
+ if ($actionRow->getColumn(Piwik_Archive::INDEX_PAGE_NB_HITS) === false) {
+ // to test this code: delete the entries in log_link_action_visit for
+ // a given exit_idaction_url
+ foreach (self::getDefaultRow()->getColumns() as $name => $value) {
+ $actionRow->addColumn($name, $value);
+ }
+ }
+ $rowsProcessed++;
+ }
+
+ // just to make sure php copies the last $actionRow in the $parentTable array
+ $actionRow =& $actionsTablesByType;
+ return $rowsProcessed;
+ }
+
+ static public $maximumRowsInDataTableLevelZero;
+ static public $maximumRowsInSubDataTable;
+ static public $columnToSortByBeforeTruncation;
+
+ static protected $actionUrlCategoryDelimiter = null;
+ static protected $actionTitleCategoryDelimiter = null;
+ static protected $defaultActionName = null;
+ static protected $defaultActionNameWhenNotDefined = null;
+ static protected $defaultActionUrlWhenNotDefined = null;
+
+ static public function reloadConfig()
+ {
+ // for BC, we read the old style delimiter first (see #1067)Row
+ $actionDelimiter = @Piwik_Config::getInstance()->General['action_category_delimiter'];
+ if (empty($actionDelimiter)) {
+ self::$actionUrlCategoryDelimiter = Piwik_Config::getInstance()->General['action_url_category_delimiter'];
+ self::$actionTitleCategoryDelimiter = Piwik_Config::getInstance()->General['action_title_category_delimiter'];
+ } else {
+ self::$actionUrlCategoryDelimiter = self::$actionTitleCategoryDelimiter = $actionDelimiter;
+ }
+
+ self::$defaultActionName = Piwik_Config::getInstance()->General['action_default_name'];
+ self::$columnToSortByBeforeTruncation = Piwik_Archive::INDEX_NB_VISITS;
+ self::$maximumRowsInDataTableLevelZero = Piwik_Config::getInstance()->General['datatable_archiving_maximum_rows_actions'];
+ self::$maximumRowsInSubDataTable = Piwik_Config::getInstance()->General['datatable_archiving_maximum_rows_subtable_actions'];
+
+ Piwik_DataTable::setMaximumDepthLevelAllowedAtLeast(self::getSubCategoryLevelLimit() + 1);
+ }
+
+
+ /**
+ * The default row is used when archiving, if data is inconsistent in the DB,
+ * there could be pages that have exit/entry hits, but don't yet
+ * have a record in the table (or the record was truncated).
+ *
+ * @return Piwik_DataTable_Row
+ */
+ static private function getDefaultRow()
+ {
+ static $row = false;
+ if ($row === false) {
+ // This row is used in the case where an action is know as an exit_action
+ // but this action was not properly recorded when it was hit in the first place
+ // so we add this fake row information to make sure there is a nb_hits, etc. column for every action
+ $row = new Piwik_DataTable_Row(array(
+ Piwik_DataTable_Row::COLUMNS => array(
+ Piwik_Archive::INDEX_NB_VISITS => 1,
+ Piwik_Archive::INDEX_NB_UNIQ_VISITORS => 1,
+ Piwik_Archive::INDEX_PAGE_NB_HITS => 1,
+ )));
+ }
+ return $row;
+ }
+
+ /**
+ * Given a page name and type, builds a recursive datatable where
+ * each level of the tree is a category, based on the page name split by a delimiter (slash / by default)
+ *
+ * @param string $actionName
+ * @param int $actionType
+ * @param int $urlPrefix
+ * @param array $actionsTablesByType
+ * @return Piwik_DataTable
+ */
+ protected static function getActionRow($actionName, $actionType, $urlPrefix = null, &$actionsTablesByType)
+ {
+ // we work on the root table of the given TYPE (either ACTION_URL or DOWNLOAD or OUTLINK etc.)
+ /* @var Piwik_DataTable $currentTable */
+ $currentTable =& $actionsTablesByType[$actionType];
+
+ // check for ranking query cut-off
+ if ($actionName == Piwik_DataTable::LABEL_SUMMARY_ROW) {
+ $summaryRow = $currentTable->getRowFromId(Piwik_DataTable::ID_SUMMARY_ROW);
+ if ($summaryRow === false) {
+ $summaryRow = $currentTable->addSummaryRow(self::createSummaryRow());
+ }
+ return $summaryRow;
+ }
+
+ // go to the level of the subcategory
+ $actionExplodedNames = self::getActionExplodedNames($actionName, $actionType, $urlPrefix);
+ list($row, $level) = $currentTable->walkPath(
+ $actionExplodedNames, self::getDefaultRowColumns(), self::$maximumRowsInSubDataTable);
+
+ return $row;
+ }
+
+ /**
+ * Explodes action name into an array of elements.
+ *
+ * NOTE: before calling this function make sure Piwik_Actions_ArchivingHelper::reloadConfig(); is called
+ *
+ * for downloads:
+ * we explode link http://piwik.org/some/path/piwik.zip into an array( 'piwik.org', '/some/path/piwik.zip' );
+ *
+ * for outlinks:
+ * we explode link http://dev.piwik.org/some/path into an array( 'dev.piwik.org', '/some/path' );
+ *
+ * for action urls:
+ * we explode link http://piwik.org/some/path into an array( 'some', 'path' );
+ *
+ * for action names:
+ * we explode name 'Piwik / Category 1 / Category 2' into an array('Piwik', 'Category 1', 'Category 2');
+ *
+ * @param string action name
+ * @param int action type
+ * @param int url prefix (only used for TYPE_ACTION_URL)
+ * @return array of exploded elements from $name
+ */
+ static public function getActionExplodedNames($name, $type, $urlPrefix = null)
+ {
+ // Site Search does not split Search keywords
+ if ($type == Piwik_Tracker_Action::TYPE_SITE_SEARCH) {
+ return array($name);
+ }
+
+ $matches = array();
+ $isUrl = false;
+ $name = str_replace("\n", "", $name);
+
+ $urlRegexAfterDomain = '([^/]+)[/]?([^#]*)[#]?(.*)';
+ if ($urlPrefix === null) {
+ // match url with protocol (used for outlinks / downloads)
+ $urlRegex = '@^http[s]?://' . $urlRegexAfterDomain . '$@i';
+ } else {
+ // the name is a url that does not contain protocol and www anymore
+ // we know that normalization has been done on db level because $urlPrefix is set
+ $urlRegex = '@^' . $urlRegexAfterDomain . '$@i';
+ }
+
+ preg_match($urlRegex, $name, $matches);
+ if (count($matches)) {
+ $isUrl = true;
+ $urlHost = $matches[1];
+ $urlPath = $matches[2];
+ $urlFragment = $matches[3];
+ }
+
+ if ($type == Piwik_Tracker_Action::TYPE_DOWNLOAD
+ || $type == Piwik_Tracker_Action::TYPE_OUTLINK
+ ) {
+ if ($isUrl) {
+ return array(trim($urlHost), '/' . trim($urlPath));
+ }
+ }
+
+ if ($isUrl) {
+ $name = $urlPath;
+
+ if ($name === '' || substr($name, -1) == '/') {
+ $name .= self::$defaultActionName;
+ }
+ }
+
+ if ($type == Piwik_Tracker_Action::TYPE_ACTION_NAME) {
+ $categoryDelimiter = self::$actionTitleCategoryDelimiter;
+ } else {
+ $categoryDelimiter = self::$actionUrlCategoryDelimiter;
+ }
+
+
+ if ($isUrl) {
+ $urlFragment = Piwik_Tracker_Action::processUrlFragment($urlFragment);
+ if (!empty($urlFragment)) {
+ $name .= '#' . $urlFragment;
+ }
+ }
+
+ if (empty($categoryDelimiter)) {
+ return array(trim($name));
+ }
+
+ $split = explode($categoryDelimiter, $name, self::getSubCategoryLevelLimit());
+
+ // trim every category and remove empty categories
+ $split = array_map('trim', $split);
+ $split = array_filter($split, 'strlen');
+
+ // forces array key to start at 0
+ $split = array_values($split);
+
+ if (empty($split)) {
+ $defaultName = self::getUnknownActionName($type);
+ return array(trim($defaultName));
+ }
+
+ $lastPageName = end($split);
+ // we are careful to prefix the page URL / name with some value
+ // so that if a page has the same name as a category
+ // we don't merge both entries
+ if ($type != Piwik_Tracker_Action::TYPE_ACTION_NAME) {
+ $lastPageName = '/' . $lastPageName;
+ } else {
+ $lastPageName = ' ' . $lastPageName;
+ }
+ $split[count($split) - 1] = $lastPageName;
+ return array_values($split);
+ }
+
+ /**
+ * Gets the key for the cache of action rows from an action ID and type.
+ *
+ * @param int $idAction
+ * @param int $actionType
+ * @return string|int
+ */
+ private static function getCachedActionRowKey($idAction, $actionType)
+ {
+ return $idAction == Piwik_DataTable::LABEL_SUMMARY_ROW
+ ? $actionType . '_others'
+ : $idAction;
+ }
+
+ /**
+ * Returns the configured sub-category level limit.
+ *
+ * @return int
+ */
+ public static function getSubCategoryLevelLimit()
+ {
+ return Piwik_Config::getInstance()->General['action_category_level_limit'];
+ }
+
+ /**
+ * Returns default label for the action type
+ *
+ * @param $type
+ * @return string
+ */
+ static public function getUnknownActionName($type)
+ {
+ if (empty(self::$defaultActionNameWhenNotDefined)) {
+ self::$defaultActionNameWhenNotDefined = Piwik_Translate('General_NotDefined', Piwik_Translate('Actions_ColumnPageName'));
+ self::$defaultActionUrlWhenNotDefined = Piwik_Translate('General_NotDefined', Piwik_Translate('Actions_ColumnPageURL'));
+ }
+ if ($type == Piwik_Tracker_Action::TYPE_ACTION_NAME) {
+ return self::$defaultActionNameWhenNotDefined;
+ }
+ return self::$defaultActionUrlWhenNotDefined;
+ }
+
+ /**
+ * Static cache to store Rows during processing
+ */
+ static protected $cacheParsedAction = array();
+
+ public static function clearActionsCache()
+ {
+ self::$cacheParsedAction = array();
+ }
+
+ /**
+ * Get cached action row by id & type. If $idAction is set to -1, the 'Others' row
+ * for the specific action type will be returned.
+ *
+ * @param int $idAction
+ * @param int $actionType
+ * @return Piwik_DataTable_Row|false
+ */
+ private static function getCachedActionRow($idAction, $actionType)
+ {
+ $cacheLabel = self::getCachedActionRowKey($idAction, $actionType);
+
+ if (!isset(self::$cacheParsedAction[$cacheLabel])) {
+ // This can happen when
+ // - We select an entry page ID that was only seen yesterday, so wasn't selected in the first query
+ // - We count time spent on a page, when this page was only seen yesterday
+ return false;
+ }
+
+ return self::$cacheParsedAction[$cacheLabel];
+ }
+
+ /**
+ * Set cached action row for an id & type.
+ *
+ * @param int $idAction
+ * @param int $actionType
+ * @param Piwik_DataTable_Row
+ */
+ private static function setCachedActionRow($idAction, $actionType, $actionRow)
+ {
+ $cacheLabel = self::getCachedActionRowKey($idAction, $actionType);
+ self::$cacheParsedAction[$cacheLabel] = $actionRow;
+ }
+
+ /**
+ * Returns the default columns for a row in an Actions DataTable.
+ *
+ * @return array
+ */
+ private static function getDefaultRowColumns()
+ {
+ return array(Piwik_Archive::INDEX_NB_VISITS => 0,
+ Piwik_Archive::INDEX_NB_UNIQ_VISITORS => 0,
+ Piwik_Archive::INDEX_PAGE_NB_HITS => 0,
+ Piwik_Archive::INDEX_PAGE_SUM_TIME_SPENT => 0);
+ }
+
+ /**
+ * Creates a summary row for an Actions DataTable.
+ *
+ * @return Piwik_DataTable_Row
+ */
+ private static function createSummaryRow()
+ {
+ return new Piwik_DataTable_Row(array(
+ Piwik_DataTable_Row::COLUMNS =>
+ array('label' => Piwik_DataTable::LABEL_SUMMARY_ROW) + self::getDefaultRowColumns()
+ ));
+ }
}
diff --git a/plugins/Actions/Controller.php b/plugins/Actions/Controller.php
index 00eb49a804..aed8efd683 100644
--- a/plugins/Actions/Controller.php
+++ b/plugins/Actions/Controller.php
@@ -16,513 +16,502 @@
*/
class Piwik_Actions_Controller extends Piwik_Controller
{
- const ACTIONS_REPORT_ROWS_DISPLAY = 100;
-
- protected function getPageUrlsView($currentAction, $controllerActionSubtable, $apiAction)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init($this->pluginName, $currentAction, $apiAction, $controllerActionSubtable);
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageURL'));
- return $view;
- }
-
- /**
- * PAGES
- * @param bool $fetch
- * @return string
- */
-
- public function indexPageUrls($fetch = false)
- {
- return Piwik_View::singleReport(
- Piwik_Translate('Actions_SubmenuPages'),
- $this->getPageUrls(true), $fetch);
- }
-
- public function getPageUrls($fetch = false)
- {
- $view = $this->getPageUrlsView(__FUNCTION__, 'getPageUrls', 'Actions.getPageUrls');
- $this->configureViewPages($view);
- $this->configureViewActions($view);
- return $this->renderView($view, $fetch);
- }
-
- protected function configureViewPages($view)
- {
- $view->setColumnsToDisplay( array('label','nb_hits','nb_visits', 'bounce_rate', 'avg_time_on_page', 'exit_rate', 'avg_time_generation') );
- }
-
- /**
- * ENTRY PAGES
- * @param bool $fetch
- * @return string|void
- */
- public function indexEntryPageUrls($fetch = false)
- {
- return Piwik_View::singleReport(
- Piwik_Translate('Actions_SubmenuPagesEntry'),
- $this->getEntryPageUrls(true), $fetch);
- }
-
- public function getEntryPageUrls($fetch = false)
- {
- $view = $this->getPageUrlsView(__FUNCTION__, 'getEntryPageUrls', 'Actions.getEntryPageUrls');
- $this->configureViewEntryPageUrls($view);
- $this->configureViewActions($view);
- return $this->renderView($view, $fetch);
- }
-
- protected function configureViewEntryPageUrls($view)
- {
- $view->setSortedColumn('entry_nb_visits');
- $view->setColumnsToDisplay( array('label','entry_nb_visits', 'entry_bounce_count', 'bounce_rate') );
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnEntryPageURL'));
- $view->setColumnTranslation('entry_bounce_count', Piwik_Translate('General_ColumnBounces'));
- $view->setColumnTranslation('entry_nb_visits', Piwik_Translate('General_ColumnEntrances'));
- $view->addRelatedReports(Piwik_Translate('Actions_SubmenuPagesEntry'), array(
- 'Actions.getEntryPageTitles' => Piwik_Translate('Actions_EntryPageTitles')
- ));
- $view->setReportUrl('Actions', $this->getEntryPageUrlActionForLink());
- }
-
- /*
- * EXIT PAGES
- */
- public function indexExitPageUrls($fetch = false)
- {
- return Piwik_View::singleReport(
- Piwik_Translate('Actions_SubmenuPagesExit'),
- $this->getExitPageUrls(true), $fetch);
- }
-
- public function getExitPageUrls($fetch = false)
- {
- $view = $this->getPageUrlsView(__FUNCTION__, 'getExitPageUrls', 'Actions.getExitPageUrls');
- $this->configureViewExitPageUrls($view);
- $this->configureViewActions($view);
- return $this->renderView($view, $fetch);
- }
-
- protected function configureViewExitPageUrls($view)
- {
- $view->setSortedColumn('exit_nb_visits');
- $view->setColumnsToDisplay( array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate') );
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnExitPageURL'));
- $view->setColumnTranslation('exit_nb_visits', Piwik_Translate('General_ColumnExits'));
- $view->addRelatedReports(Piwik_Translate('Actions_SubmenuPagesExit'), array(
- 'Actions.getExitPageTitles' => Piwik_Translate('Actions_ExitPageTitles')
- ));
- $view->setReportUrl('Actions', $this->getExitPageUrlActionForLink());
- }
-
- /*
- * SITE SEARCH
- */
- public function indexSiteSearch()
- {
- $view = Piwik_View::factory('indexSiteSearch');
-
- $view->keywords = $this->getSiteSearchKeywords( true );
- $view->noResultKeywords = $this->getSiteSearchNoResultKeywords( true );
- $view->pagesUrlsFollowingSiteSearch = $this->getPageUrlsFollowingSiteSearch( true );
-
- $categoryTrackingEnabled = Piwik_PluginsManager::getInstance()->isPluginActivated('CustomVariables');
- if($categoryTrackingEnabled)
- {
- $view->categories = $this->getSiteSearchCategories( true );
- }
-
- echo $view->render();
- }
-
- public function getSiteSearchKeywords($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName, __FUNCTION__, 'Actions.getSiteSearchKeywords' );
- $this->configureViewSiteSearchKeywords($view);
- return $this->renderView($view, $fetch);
- }
-
- public function getSiteSearchNoResultKeywords($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName, __FUNCTION__, 'Actions.getSiteSearchNoResultKeywords' );
- $this->configureViewSiteSearchKeywords($view);
- $view->setColumnsToDisplay(array('label', 'nb_visits', 'exit_rate'));
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnNoResultKeyword'));
- return $this->renderView($view, $fetch);
- }
-
- public function configureViewSiteSearchKeywords(Piwik_ViewDataTable $view)
- {
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnSearchKeyword'));
- $view->setColumnsToDisplay(array('label', 'nb_visits', 'nb_pages_per_search', 'exit_rate'));
- $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnSearches'));
- $view->setColumnTranslation('exit_rate', str_replace("% ", "%&nbsp;", Piwik_Translate('Actions_ColumnSearchExits')));
- $view->setColumnTranslation('nb_pages_per_search', Piwik_Translate('Actions_ColumnPagesPerSearch'));
- $view->disableShowBarChart();
- $view->disableShowAllColumns();
- }
-
- public function getSiteSearchCategories($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName, __FUNCTION__, 'Actions.getSiteSearchCategories' );
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnSearchCategory'));
- $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnSearches'));
- $view->setColumnsToDisplay( array('label','nb_visits', 'nb_pages_per_search') );
- $view->setColumnTranslation('nb_pages_per_search', Piwik_Translate('Actions_ColumnPagesPerSearch'));
- $view->disableShowAllColumns();
- $view->disableShowBarChart();
- $view->disableRowEvolution();
- return $this->renderView($view, $fetch);
- }
-
-
- public function getPageUrlsFollowingSiteSearch($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName, __FUNCTION__, 'Actions.getPageUrlsFollowingSiteSearch', 'getPageUrlsFollowingSiteSearch' );
- $view->addRelatedReports(Piwik_Translate('Actions_WidgetPageUrlsFollowingSearch'), array(
- 'Actions.getPageTitlesFollowingSiteSearch' => Piwik_Translate('Actions_WidgetPageTitlesFollowingSearch'),
- ));
- $view = $this->configureViewPagesFollowingSiteSearch($view);
- return $this->renderView($view, $fetch);
- }
-
- public function getPageTitlesFollowingSiteSearch($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName, __FUNCTION__, 'Actions.getPageTitlesFollowingSiteSearch', 'getPageTitlesFollowingSiteSearch' );
- $view->addRelatedReports(Piwik_Translate('Actions_WidgetPageTitlesFollowingSearch'), array(
- 'Actions.getPageUrlsFollowingSiteSearch' => Piwik_Translate('Actions_WidgetPageUrlsFollowingSearch'),
- ));
- $view = $this->configureViewPagesFollowingSiteSearch($view);
- return $this->renderView($view, $fetch);
- }
-
- public function configureViewPagesFollowingSiteSearch($view)
- {
- $view->setColumnsToDisplay(array('label', 'nb_hits_following_search', 'nb_hits'));
- $view->setColumnTranslation('nb_hits_following_search', Piwik_Translate('General_ColumnViewedAfterSearch'));
- $view->setColumnTranslation('label', Piwik_Translate('General_ColumnDestinationPage'));
- $view->setSortedColumn('nb_hits_following_search');
- $view->setColumnTranslation('nb_hits', Piwik_Translate('General_ColumnTotalPageviews'));
- $view->disableExcludeLowPopulation();
- $view = $this->configureViewActions($view, $doSetTranslations = false);
- return $view;
- }
-
- /*
- * PAGE TITLES
- */
- public function indexPageTitles($fetch = false)
- {
- return Piwik_View::singleReport(
- Piwik_Translate('Actions_SubmenuPageTitles'),
- $this->getPageTitles(true), $fetch);
- }
-
- public function getPageTitles($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName,
- __FUNCTION__,
- 'Actions.getPageTitles',
- 'getPageTitlesSubDataTable' );
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageName'));
- $view->addRelatedReports(Piwik_Translate('Actions_SubmenuPageTitles'), array(
- 'Actions.getEntryPageTitles' => Piwik_Translate('Actions_EntryPageTitles'),
- 'Actions.getExitPageTitles' => Piwik_Translate('Actions_ExitPageTitles'),
- ));
- $view->setReportUrl('Actions', $this->getPageTitlesActionForLink());
- $this->configureViewPages($view);
- $this->configureViewActions($view);
- return $this->renderView($view, $fetch);
- }
-
- public function getPageTitlesSubDataTable($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName,
- __FUNCTION__,
- 'Actions.getPageTitles',
- 'getPageTitlesSubDataTable' );
- $this->configureViewPages($view);
- $this->configureViewActions($view);
- return $this->renderView($view, $fetch);
- }
-
- /**
- * Echos or returns a report displaying analytics data for every unique entry
- * page title.
- *
- * @param bool $fetch True to return the view as a string, false to echo it.
- * @return string
- */
- public function getEntryPageTitles( $fetch = false )
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init($this->pluginName, __FUNCTION__, 'Actions.getEntryPageTitles', __FUNCTION__);
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnEntryPageTitle'));
- $view->setColumnTranslation('entry_bounce_count', Piwik_Translate('General_ColumnBounces'));
- $view->setColumnTranslation('entry_nb_visits', Piwik_Translate('General_ColumnEntrances'));
- $view->setColumnsToDisplay( array('label','entry_nb_visits', 'entry_bounce_count', 'bounce_rate') );
-
- $entryPageUrlAction = $this->getEntryPageUrlActionForLink();
- $view->addRelatedReports(Piwik_Translate('Actions_EntryPageTitles'), array(
- 'Actions.getPageTitles' => Piwik_Translate('Actions_SubmenuPageTitles'),
- "Actions.$entryPageUrlAction" => Piwik_Translate('Actions_SubmenuPagesEntry'),
- ));
-
- $this->configureViewActions($view);
-
- return $this->renderView($view, $fetch);
- }
-
- /**
- * Echos or returns a report displaying analytics data for every unique exit
- * page title.
- *
- * @param bool $fetch True to return the view as a string, false to echo it.
- * @return string
- */
- public function getExitPageTitles( $fetch = false )
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init($this->pluginName, __FUNCTION__, 'Actions.getExitPageTitles', __FUNCTION__);
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnExitPageTitle'));
- $view->setColumnTranslation('exit_nb_visits', Piwik_Translate('General_ColumnExits'));
- $view->setColumnsToDisplay( array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate') );
-
- $exitPageUrlAction = $this->getExitPageUrlActionForLink();
- $view->addRelatedReports(Piwik_Translate('Actions_ExitPageTitles'), array(
- 'Actions.getPageTitles' => Piwik_Translate('Actions_SubmenuPageTitles'),
- "Actions.$exitPageUrlAction" => Piwik_Translate('Actions_SubmenuPagesExit'),
- ));
-
- $this->configureViewActions($view);
-
- return $this->renderView($view, $fetch);
- }
-
- /*
- * DOWNLOADS
- */
-
- public function indexDownloads($fetch = false)
- {
- return Piwik_View::singleReport(
- Piwik_Translate('Actions_SubmenuDownloads'),
- $this->getDownloads(true), $fetch);
- }
-
- public function getDownloads($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName,
- __FUNCTION__,
- 'Actions.getDownloads',
- 'getDownloadsSubDataTable' );
-
- $this->configureViewDownloads($view);
- return $this->renderView($view, $fetch);
- }
-
- public function getDownloadsSubDataTable($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName,
- __FUNCTION__,
- 'Actions.getDownloads',
- 'getDownloadsSubDataTable');
- $this->configureViewDownloads($view);
- return $this->renderView($view, $fetch);
- }
-
-
- /*
- * OUTLINKS
- */
-
- public function indexOutlinks($fetch = false)
- {
- return Piwik_View::singleReport(
- Piwik_Translate('Actions_SubmenuOutlinks'),
- $this->getOutlinks(true), $fetch);
- }
-
- public function getOutlinks($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName,
- __FUNCTION__,
- 'Actions.getOutlinks',
- 'getOutlinksSubDataTable' );
- $this->configureViewOutlinks($view);
- return $this->renderView($view, $fetch);
- }
-
- public function getOutlinksSubDataTable($fetch = false)
- {
- $view = Piwik_ViewDataTable::factory();
- $view->init( $this->pluginName,
- __FUNCTION__,
- 'Actions.getOutlinks',
- 'getOutlinksSubDataTable');
- $this->configureViewOutlinks($view);
- return $this->renderView($view, $fetch);
- }
-
- /*
- * Page titles & Page URLs reports
- */
- protected function configureViewActions($view, $doSetTranslations = true)
- {
- if($doSetTranslations)
- {
- $view->setColumnTranslation('nb_hits', Piwik_Translate('General_ColumnPageviews'));
- $view->setColumnTranslation('nb_visits', Piwik_Translate('General_ColumnUniquePageviews'));
- $view->setColumnTranslation('avg_time_on_page', Piwik_Translate('General_ColumnAverageTimeOnPage'));
- $view->setColumnTranslation('bounce_rate', Piwik_Translate('General_ColumnBounceRate'));
- $view->setColumnTranslation('exit_rate', Piwik_Translate('General_ColumnExitRate'));
- $view->setColumnTranslation('avg_time_generation', Piwik_Translate('General_ColumnAverageGenerationTime'));
- $view->queueFilter('ColumnCallbackReplace', array('avg_time_on_page', array('Piwik', 'getPrettyTimeFromSeconds')));
- $view->queueFilter('ColumnCallbackReplace', array('avg_time_generation',
- create_function('$averageTimeOnSite', 'return $averageTimeOnSite ? Piwik::getPrettyTimeFromSeconds($averageTimeOnSite, true, true, false) : "-";')));
- }
-
- if(Piwik_Common::getRequestVar('enable_filter_excludelowpop', '0', 'string' ) != '0')
- {
- // computing minimum value to exclude
- $visitsInfo = Piwik_VisitsSummary_Controller::getVisitsSummary();
- $visitsInfo = $visitsInfo->getFirstRow();
- $nbActions = $visitsInfo->getColumn('nb_actions');
- $nbActionsLowPopulationThreshold = floor(0.02 * $nbActions); // 2 percent of the total number of actions
- // we remove 1 to make sure some actions/downloads are displayed in the case we have a very few of them
- // and each of them has 1 or 2 hits...
- $nbActionsLowPopulationThreshold = min($visitsInfo->getColumn('max_actions')-1, $nbActionsLowPopulationThreshold-1);
-
- $view->setExcludeLowPopulation( 'nb_hits', $nbActionsLowPopulationThreshold );
- }
-
- $this->configureGenericViewActions($view);
- return $view;
- }
-
- /*
- * Downloads report
- */
- protected function configureViewDownloads($view)
- {
- $view->setColumnsToDisplay( array('label','nb_visits','nb_hits') );
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnDownloadURL'));
- $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnUniqueDownloads'));
- $view->setColumnTranslation('nb_hits', Piwik_Translate('Actions_ColumnDownloads'));
- $view->disableExcludeLowPopulation();
- $this->configureGenericViewActions($view);
- }
-
- /*
- * Outlinks report
- */
- protected function configureViewOutlinks($view)
- {
- $view->setColumnsToDisplay( array('label','nb_visits','nb_hits') );
- $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnClickedURL'));
- $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnUniqueClicks'));
- $view->setColumnTranslation('nb_hits', Piwik_Translate('Actions_ColumnClicks'));
- $view->disableExcludeLowPopulation();
- $this->configureGenericViewActions($view);
- }
-
- /*
- * Common to all Actions reports, how to use the custom Actions Datatable html
- */
- protected function configureGenericViewActions($view)
- {
- $view->setTemplate('CoreHome/templates/datatable_actions.tpl');
- if(Piwik_Common::getRequestVar('idSubtable', -1) != -1)
- {
- $view->setTemplate('CoreHome/templates/datatable_actions_subdatable.tpl');
- }
- $currentlySearching = $view->setSearchRecursive();
- if($currentlySearching)
- {
- $view->setTemplate('CoreHome/templates/datatable_actions_recursive.tpl');
- }
- // disable Footer icons
- $view->disableShowAllViewsIcons();
- $view->disableShowAllColumns();
-
- $view->setLimit( self::ACTIONS_REPORT_ROWS_DISPLAY );
-
- // if the flat parameter is not provided, make sure it is set to 0 in the URL,
- // so users can see that they can set it to 1 (see #3365)
- if (Piwik_Common::getRequestVar('flat', false) === false)
- {
- $view->setCustomParameter('flat', 0);
- }
-
- $view->main();
- // we need to rewrite the phpArray so it contains all the recursive arrays
- if($currentlySearching)
- {
- $phpArrayRecursive = $this->getArrayFromRecursiveDataTable($view->getDataTable());
- $view->getView()->arrayDataTable = $phpArrayRecursive;
- }
- }
-
- protected function getArrayFromRecursiveDataTable( $dataTable, $depth = 0 )
- {
- $table = array();
- foreach($dataTable->getRows() as $row)
- {
- $phpArray = array();
- if(($idSubtable = $row->getIdSubDataTable()) !== null)
- {
- $subTable = Piwik_DataTable_Manager::getInstance()->getTable( $idSubtable );
-
- if($subTable->getRowsCount() > 0)
- {
- $phpArray = $this->getArrayFromRecursiveDataTable( $subTable, $depth + 1 );
- }
- }
-
- $newRow = array(
- 'level' => $depth,
- 'columns' => $row->getColumns(),
- 'metadata' => $row->getMetadata(),
- 'idsubdatatable' => $row->getIdSubDataTable()
- );
- $table[] = $newRow;
- if(count($phpArray) > 0)
- {
- $table = array_merge( $table, $phpArray);
- }
- }
- return $table;
- }
-
- /** Returns action to use when linking to the exit page URLs report. */
- private function getExitPageUrlActionForLink()
- {
- // link to the page not, just the report, but only if not a widget
- return Piwik_Common::getRequestVar('widget', 0) == 0 ? 'indexExitPageUrls' : 'getExitPageUrls';
- }
-
-
- /** Returns action to use when linking to the entry page URLs report. */
- private function getEntryPageUrlActionForLink()
- {
- // link to the page not, just the report, but only if not a widget
- return Piwik_Common::getRequestVar('widget', 0) == 0 ? 'indexEntryPageUrls' : 'getEntryPageUrls';
- }
-
- /** Returns action to use when linking to the page titles report. */
- private function getPageTitlesActionForLink()
- {
- // link to the page not, just the report, but only if not a widget
- return Piwik_Common::getRequestVar('widget', 0) == 0 ? 'indexPageTitles' : 'getPageTitles';
- }
+ const ACTIONS_REPORT_ROWS_DISPLAY = 100;
+
+ protected function getPageUrlsView($currentAction, $controllerActionSubtable, $apiAction)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, $currentAction, $apiAction, $controllerActionSubtable);
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageURL'));
+ return $view;
+ }
+
+ /**
+ * PAGES
+ * @param bool $fetch
+ * @return string
+ */
+
+ public function indexPageUrls($fetch = false)
+ {
+ return Piwik_View::singleReport(
+ Piwik_Translate('Actions_SubmenuPages'),
+ $this->getPageUrls(true), $fetch);
+ }
+
+ public function getPageUrls($fetch = false)
+ {
+ $view = $this->getPageUrlsView(__FUNCTION__, 'getPageUrls', 'Actions.getPageUrls');
+ $this->configureViewPages($view);
+ $this->configureViewActions($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ protected function configureViewPages($view)
+ {
+ $view->setColumnsToDisplay(array('label', 'nb_hits', 'nb_visits', 'bounce_rate', 'avg_time_on_page', 'exit_rate', 'avg_time_generation'));
+ }
+
+ /**
+ * ENTRY PAGES
+ * @param bool $fetch
+ * @return string|void
+ */
+ public function indexEntryPageUrls($fetch = false)
+ {
+ return Piwik_View::singleReport(
+ Piwik_Translate('Actions_SubmenuPagesEntry'),
+ $this->getEntryPageUrls(true), $fetch);
+ }
+
+ public function getEntryPageUrls($fetch = false)
+ {
+ $view = $this->getPageUrlsView(__FUNCTION__, 'getEntryPageUrls', 'Actions.getEntryPageUrls');
+ $this->configureViewEntryPageUrls($view);
+ $this->configureViewActions($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ protected function configureViewEntryPageUrls($view)
+ {
+ $view->setSortedColumn('entry_nb_visits');
+ $view->setColumnsToDisplay(array('label', 'entry_nb_visits', 'entry_bounce_count', 'bounce_rate'));
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnEntryPageURL'));
+ $view->setColumnTranslation('entry_bounce_count', Piwik_Translate('General_ColumnBounces'));
+ $view->setColumnTranslation('entry_nb_visits', Piwik_Translate('General_ColumnEntrances'));
+ $view->addRelatedReports(Piwik_Translate('Actions_SubmenuPagesEntry'), array(
+ 'Actions.getEntryPageTitles' => Piwik_Translate('Actions_EntryPageTitles')
+ ));
+ $view->setReportUrl('Actions', $this->getEntryPageUrlActionForLink());
+ }
+
+ /*
+ * EXIT PAGES
+ */
+ public function indexExitPageUrls($fetch = false)
+ {
+ return Piwik_View::singleReport(
+ Piwik_Translate('Actions_SubmenuPagesExit'),
+ $this->getExitPageUrls(true), $fetch);
+ }
+
+ public function getExitPageUrls($fetch = false)
+ {
+ $view = $this->getPageUrlsView(__FUNCTION__, 'getExitPageUrls', 'Actions.getExitPageUrls');
+ $this->configureViewExitPageUrls($view);
+ $this->configureViewActions($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ protected function configureViewExitPageUrls($view)
+ {
+ $view->setSortedColumn('exit_nb_visits');
+ $view->setColumnsToDisplay(array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate'));
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnExitPageURL'));
+ $view->setColumnTranslation('exit_nb_visits', Piwik_Translate('General_ColumnExits'));
+ $view->addRelatedReports(Piwik_Translate('Actions_SubmenuPagesExit'), array(
+ 'Actions.getExitPageTitles' => Piwik_Translate('Actions_ExitPageTitles')
+ ));
+ $view->setReportUrl('Actions', $this->getExitPageUrlActionForLink());
+ }
+
+ /*
+ * SITE SEARCH
+ */
+ public function indexSiteSearch()
+ {
+ $view = Piwik_View::factory('indexSiteSearch');
+
+ $view->keywords = $this->getSiteSearchKeywords(true);
+ $view->noResultKeywords = $this->getSiteSearchNoResultKeywords(true);
+ $view->pagesUrlsFollowingSiteSearch = $this->getPageUrlsFollowingSiteSearch(true);
+
+ $categoryTrackingEnabled = Piwik_PluginsManager::getInstance()->isPluginActivated('CustomVariables');
+ if ($categoryTrackingEnabled) {
+ $view->categories = $this->getSiteSearchCategories(true);
+ }
+
+ echo $view->render();
+ }
+
+ public function getSiteSearchKeywords($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, __FUNCTION__, 'Actions.getSiteSearchKeywords');
+ $this->configureViewSiteSearchKeywords($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ public function getSiteSearchNoResultKeywords($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, __FUNCTION__, 'Actions.getSiteSearchNoResultKeywords');
+ $this->configureViewSiteSearchKeywords($view);
+ $view->setColumnsToDisplay(array('label', 'nb_visits', 'exit_rate'));
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnNoResultKeyword'));
+ return $this->renderView($view, $fetch);
+ }
+
+ public function configureViewSiteSearchKeywords(Piwik_ViewDataTable $view)
+ {
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnSearchKeyword'));
+ $view->setColumnsToDisplay(array('label', 'nb_visits', 'nb_pages_per_search', 'exit_rate'));
+ $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnSearches'));
+ $view->setColumnTranslation('exit_rate', str_replace("% ", "%&nbsp;", Piwik_Translate('Actions_ColumnSearchExits')));
+ $view->setColumnTranslation('nb_pages_per_search', Piwik_Translate('Actions_ColumnPagesPerSearch'));
+ $view->disableShowBarChart();
+ $view->disableShowAllColumns();
+ }
+
+ public function getSiteSearchCategories($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, __FUNCTION__, 'Actions.getSiteSearchCategories');
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnSearchCategory'));
+ $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnSearches'));
+ $view->setColumnsToDisplay(array('label', 'nb_visits', 'nb_pages_per_search'));
+ $view->setColumnTranslation('nb_pages_per_search', Piwik_Translate('Actions_ColumnPagesPerSearch'));
+ $view->disableShowAllColumns();
+ $view->disableShowBarChart();
+ $view->disableRowEvolution();
+ return $this->renderView($view, $fetch);
+ }
+
+
+ public function getPageUrlsFollowingSiteSearch($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, __FUNCTION__, 'Actions.getPageUrlsFollowingSiteSearch', 'getPageUrlsFollowingSiteSearch');
+ $view->addRelatedReports(Piwik_Translate('Actions_WidgetPageUrlsFollowingSearch'), array(
+ 'Actions.getPageTitlesFollowingSiteSearch' => Piwik_Translate('Actions_WidgetPageTitlesFollowingSearch'),
+ ));
+ $view = $this->configureViewPagesFollowingSiteSearch($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ public function getPageTitlesFollowingSiteSearch($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, __FUNCTION__, 'Actions.getPageTitlesFollowingSiteSearch', 'getPageTitlesFollowingSiteSearch');
+ $view->addRelatedReports(Piwik_Translate('Actions_WidgetPageTitlesFollowingSearch'), array(
+ 'Actions.getPageUrlsFollowingSiteSearch' => Piwik_Translate('Actions_WidgetPageUrlsFollowingSearch'),
+ ));
+ $view = $this->configureViewPagesFollowingSiteSearch($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ public function configureViewPagesFollowingSiteSearch($view)
+ {
+ $view->setColumnsToDisplay(array('label', 'nb_hits_following_search', 'nb_hits'));
+ $view->setColumnTranslation('nb_hits_following_search', Piwik_Translate('General_ColumnViewedAfterSearch'));
+ $view->setColumnTranslation('label', Piwik_Translate('General_ColumnDestinationPage'));
+ $view->setSortedColumn('nb_hits_following_search');
+ $view->setColumnTranslation('nb_hits', Piwik_Translate('General_ColumnTotalPageviews'));
+ $view->disableExcludeLowPopulation();
+ $view = $this->configureViewActions($view, $doSetTranslations = false);
+ return $view;
+ }
+
+ /*
+ * PAGE TITLES
+ */
+ public function indexPageTitles($fetch = false)
+ {
+ return Piwik_View::singleReport(
+ Piwik_Translate('Actions_SubmenuPageTitles'),
+ $this->getPageTitles(true), $fetch);
+ }
+
+ public function getPageTitles($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName,
+ __FUNCTION__,
+ 'Actions.getPageTitles',
+ 'getPageTitlesSubDataTable');
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageName'));
+ $view->addRelatedReports(Piwik_Translate('Actions_SubmenuPageTitles'), array(
+ 'Actions.getEntryPageTitles' => Piwik_Translate('Actions_EntryPageTitles'),
+ 'Actions.getExitPageTitles' => Piwik_Translate('Actions_ExitPageTitles'),
+ ));
+ $view->setReportUrl('Actions', $this->getPageTitlesActionForLink());
+ $this->configureViewPages($view);
+ $this->configureViewActions($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ public function getPageTitlesSubDataTable($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName,
+ __FUNCTION__,
+ 'Actions.getPageTitles',
+ 'getPageTitlesSubDataTable');
+ $this->configureViewPages($view);
+ $this->configureViewActions($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ /**
+ * Echos or returns a report displaying analytics data for every unique entry
+ * page title.
+ *
+ * @param bool $fetch True to return the view as a string, false to echo it.
+ * @return string
+ */
+ public function getEntryPageTitles($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, __FUNCTION__, 'Actions.getEntryPageTitles', __FUNCTION__);
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnEntryPageTitle'));
+ $view->setColumnTranslation('entry_bounce_count', Piwik_Translate('General_ColumnBounces'));
+ $view->setColumnTranslation('entry_nb_visits', Piwik_Translate('General_ColumnEntrances'));
+ $view->setColumnsToDisplay(array('label', 'entry_nb_visits', 'entry_bounce_count', 'bounce_rate'));
+
+ $entryPageUrlAction = $this->getEntryPageUrlActionForLink();
+ $view->addRelatedReports(Piwik_Translate('Actions_EntryPageTitles'), array(
+ 'Actions.getPageTitles' => Piwik_Translate('Actions_SubmenuPageTitles'),
+ "Actions.$entryPageUrlAction" => Piwik_Translate('Actions_SubmenuPagesEntry'),
+ ));
+
+ $this->configureViewActions($view);
+
+ return $this->renderView($view, $fetch);
+ }
+
+ /**
+ * Echos or returns a report displaying analytics data for every unique exit
+ * page title.
+ *
+ * @param bool $fetch True to return the view as a string, false to echo it.
+ * @return string
+ */
+ public function getExitPageTitles($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName, __FUNCTION__, 'Actions.getExitPageTitles', __FUNCTION__);
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnExitPageTitle'));
+ $view->setColumnTranslation('exit_nb_visits', Piwik_Translate('General_ColumnExits'));
+ $view->setColumnsToDisplay(array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate'));
+
+ $exitPageUrlAction = $this->getExitPageUrlActionForLink();
+ $view->addRelatedReports(Piwik_Translate('Actions_ExitPageTitles'), array(
+ 'Actions.getPageTitles' => Piwik_Translate('Actions_SubmenuPageTitles'),
+ "Actions.$exitPageUrlAction" => Piwik_Translate('Actions_SubmenuPagesExit'),
+ ));
+
+ $this->configureViewActions($view);
+
+ return $this->renderView($view, $fetch);
+ }
+
+ /*
+ * DOWNLOADS
+ */
+
+ public function indexDownloads($fetch = false)
+ {
+ return Piwik_View::singleReport(
+ Piwik_Translate('Actions_SubmenuDownloads'),
+ $this->getDownloads(true), $fetch);
+ }
+
+ public function getDownloads($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName,
+ __FUNCTION__,
+ 'Actions.getDownloads',
+ 'getDownloadsSubDataTable');
+
+ $this->configureViewDownloads($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ public function getDownloadsSubDataTable($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName,
+ __FUNCTION__,
+ 'Actions.getDownloads',
+ 'getDownloadsSubDataTable');
+ $this->configureViewDownloads($view);
+ return $this->renderView($view, $fetch);
+ }
+
+
+ /*
+ * OUTLINKS
+ */
+
+ public function indexOutlinks($fetch = false)
+ {
+ return Piwik_View::singleReport(
+ Piwik_Translate('Actions_SubmenuOutlinks'),
+ $this->getOutlinks(true), $fetch);
+ }
+
+ public function getOutlinks($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName,
+ __FUNCTION__,
+ 'Actions.getOutlinks',
+ 'getOutlinksSubDataTable');
+ $this->configureViewOutlinks($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ public function getOutlinksSubDataTable($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init($this->pluginName,
+ __FUNCTION__,
+ 'Actions.getOutlinks',
+ 'getOutlinksSubDataTable');
+ $this->configureViewOutlinks($view);
+ return $this->renderView($view, $fetch);
+ }
+
+ /*
+ * Page titles & Page URLs reports
+ */
+ protected function configureViewActions($view, $doSetTranslations = true)
+ {
+ if ($doSetTranslations) {
+ $view->setColumnTranslation('nb_hits', Piwik_Translate('General_ColumnPageviews'));
+ $view->setColumnTranslation('nb_visits', Piwik_Translate('General_ColumnUniquePageviews'));
+ $view->setColumnTranslation('avg_time_on_page', Piwik_Translate('General_ColumnAverageTimeOnPage'));
+ $view->setColumnTranslation('bounce_rate', Piwik_Translate('General_ColumnBounceRate'));
+ $view->setColumnTranslation('exit_rate', Piwik_Translate('General_ColumnExitRate'));
+ $view->setColumnTranslation('avg_time_generation', Piwik_Translate('General_ColumnAverageGenerationTime'));
+ $view->queueFilter('ColumnCallbackReplace', array('avg_time_on_page', array('Piwik', 'getPrettyTimeFromSeconds')));
+ $view->queueFilter('ColumnCallbackReplace', array('avg_time_generation',
+ create_function('$averageTimeOnSite', 'return $averageTimeOnSite ? Piwik::getPrettyTimeFromSeconds($averageTimeOnSite, true, true, false) : "-";')));
+ }
+
+ if (Piwik_Common::getRequestVar('enable_filter_excludelowpop', '0', 'string') != '0') {
+ // computing minimum value to exclude
+ $visitsInfo = Piwik_VisitsSummary_Controller::getVisitsSummary();
+ $visitsInfo = $visitsInfo->getFirstRow();
+ $nbActions = $visitsInfo->getColumn('nb_actions');
+ $nbActionsLowPopulationThreshold = floor(0.02 * $nbActions); // 2 percent of the total number of actions
+ // we remove 1 to make sure some actions/downloads are displayed in the case we have a very few of them
+ // and each of them has 1 or 2 hits...
+ $nbActionsLowPopulationThreshold = min($visitsInfo->getColumn('max_actions') - 1, $nbActionsLowPopulationThreshold - 1);
+
+ $view->setExcludeLowPopulation('nb_hits', $nbActionsLowPopulationThreshold);
+ }
+
+ $this->configureGenericViewActions($view);
+ return $view;
+ }
+
+ /*
+ * Downloads report
+ */
+ protected function configureViewDownloads($view)
+ {
+ $view->setColumnsToDisplay(array('label', 'nb_visits', 'nb_hits'));
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnDownloadURL'));
+ $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnUniqueDownloads'));
+ $view->setColumnTranslation('nb_hits', Piwik_Translate('Actions_ColumnDownloads'));
+ $view->disableExcludeLowPopulation();
+ $this->configureGenericViewActions($view);
+ }
+
+ /*
+ * Outlinks report
+ */
+ protected function configureViewOutlinks($view)
+ {
+ $view->setColumnsToDisplay(array('label', 'nb_visits', 'nb_hits'));
+ $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnClickedURL'));
+ $view->setColumnTranslation('nb_visits', Piwik_Translate('Actions_ColumnUniqueClicks'));
+ $view->setColumnTranslation('nb_hits', Piwik_Translate('Actions_ColumnClicks'));
+ $view->disableExcludeLowPopulation();
+ $this->configureGenericViewActions($view);
+ }
+
+ /*
+ * Common to all Actions reports, how to use the custom Actions Datatable html
+ */
+ protected function configureGenericViewActions($view)
+ {
+ $view->setTemplate('CoreHome/templates/datatable_actions.tpl');
+ if (Piwik_Common::getRequestVar('idSubtable', -1) != -1) {
+ $view->setTemplate('CoreHome/templates/datatable_actions_subdatable.tpl');
+ }
+ $currentlySearching = $view->setSearchRecursive();
+ if ($currentlySearching) {
+ $view->setTemplate('CoreHome/templates/datatable_actions_recursive.tpl');
+ }
+ // disable Footer icons
+ $view->disableShowAllViewsIcons();
+ $view->disableShowAllColumns();
+
+ $view->setLimit(self::ACTIONS_REPORT_ROWS_DISPLAY);
+
+ // if the flat parameter is not provided, make sure it is set to 0 in the URL,
+ // so users can see that they can set it to 1 (see #3365)
+ if (Piwik_Common::getRequestVar('flat', false) === false) {
+ $view->setCustomParameter('flat', 0);
+ }
+
+ $view->main();
+ // we need to rewrite the phpArray so it contains all the recursive arrays
+ if ($currentlySearching) {
+ $phpArrayRecursive = $this->getArrayFromRecursiveDataTable($view->getDataTable());
+ $view->getView()->arrayDataTable = $phpArrayRecursive;
+ }
+ }
+
+ protected function getArrayFromRecursiveDataTable($dataTable, $depth = 0)
+ {
+ $table = array();
+ foreach ($dataTable->getRows() as $row) {
+ $phpArray = array();
+ if (($idSubtable = $row->getIdSubDataTable()) !== null) {
+ $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubtable);
+
+ if ($subTable->getRowsCount() > 0) {
+ $phpArray = $this->getArrayFromRecursiveDataTable($subTable, $depth + 1);
+ }
+ }
+
+ $newRow = array(
+ 'level' => $depth,
+ 'columns' => $row->getColumns(),
+ 'metadata' => $row->getMetadata(),
+ 'idsubdatatable' => $row->getIdSubDataTable()
+ );
+ $table[] = $newRow;
+ if (count($phpArray) > 0) {
+ $table = array_merge($table, $phpArray);
+ }
+ }
+ return $table;
+ }
+
+ /** Returns action to use when linking to the exit page URLs report. */
+ private function getExitPageUrlActionForLink()
+ {
+ // link to the page not, just the report, but only if not a widget
+ return Piwik_Common::getRequestVar('widget', 0) == 0 ? 'indexExitPageUrls' : 'getExitPageUrls';
+ }
+
+
+ /** Returns action to use when linking to the entry page URLs report. */
+ private function getEntryPageUrlActionForLink()
+ {
+ // link to the page not, just the report, but only if not a widget
+ return Piwik_Common::getRequestVar('widget', 0) == 0 ? 'indexEntryPageUrls' : 'getEntryPageUrls';
+ }
+
+ /** Returns action to use when linking to the page titles report. */
+ private function getPageTitlesActionForLink()
+ {
+ // link to the page not, just the report, but only if not a widget
+ return Piwik_Common::getRequestVar('widget', 0) == 0 ? 'indexPageTitles' : 'getPageTitles';
+ }
}
diff --git a/plugins/Actions/templates/indexSiteSearch.tpl b/plugins/Actions/templates/indexSiteSearch.tpl
index 3af0d5c0a4..a692fdd697 100644
--- a/plugins/Actions/templates/indexSiteSearch.tpl
+++ b/plugins/Actions/templates/indexSiteSearch.tpl
@@ -1,19 +1,19 @@
<div id='leftcolumn'>
- <h2>{'Actions_WidgetSearchKeywords'|translate}</h2>
-{$keywords}
+ <h2>{'Actions_WidgetSearchKeywords'|translate}</h2>
+ {$keywords}
- <h2>{'Actions_WidgetSearchNoResultKeywords'|translate}</h2>
-{$noResultKeywords}
+ <h2>{'Actions_WidgetSearchNoResultKeywords'|translate}</h2>
+ {$noResultKeywords}
-{if isset($categories)}
- <h2>{'Actions_WidgetSearchCategories'|translate}</h2>
-{$categories}
-{/if}
+ {if isset($categories)}
+ <h2>{'Actions_WidgetSearchCategories'|translate}</h2>
+ {$categories}
+ {/if}
</div>
<div id='rightcolumn'>
- <h2>{'Actions_WidgetPageUrlsFollowingSearch'|translate}</h2>
-{$pagesUrlsFollowingSiteSearch}
+ <h2>{'Actions_WidgetPageUrlsFollowingSearch'|translate}</h2>
+ {$pagesUrlsFollowingSiteSearch}
</div>