From cb6ae9d57117f918e6ea2f689df4bd1c6134cc65 Mon Sep 17 00:00:00 2001 From: Thomas Steur Date: Tue, 17 Jun 2014 06:23:24 +0200 Subject: starting to move actions from tracker into plugins --- core/Db/Schema/Mysql.php | 7 +- core/Plugin/ActionDimension.php | 10 + core/Tracker/Action.php | 146 ++++++++++---- core/Tracker/ActionClickUrl.php | 63 ------ core/Tracker/ActionEvent.php | 78 -------- core/Tracker/ActionPageview.php | 12 +- core/Tracker/ActionSiteSearch.php | 254 ------------------------ core/Tracker/Visit.php | 13 +- piwik.php | 3 - plugins/API/API.php | 6 - plugins/Actions/API.php | 2 +- plugins/Actions/Actions.php | 2 +- plugins/Actions/Actions/ActionClickUrl.php | 71 +++++++ plugins/Actions/Actions/ActionDownloadUrl.php | 41 ++++ plugins/Actions/Actions/ActionSiteSearch.php | 260 +++++++++++++++++++++++++ plugins/Actions/Archiver.php | 2 +- plugins/Actions/Columns/ClickedUrl.php | 27 --- plugins/Actions/Columns/DownloadUrl.php | 27 --- plugins/Actions/Columns/PageTitle.php | 9 - plugins/Actions/Columns/ServerTime.php | 43 ++++ plugins/Actions/Columns/TimeSpentRefAction.php | 36 ++++ plugins/CustomVariables/API.php | 2 +- plugins/Events/Actions/ActionEvent.php | 73 +++++++ plugins/Events/Columns/EventAction.php | 25 +++ plugins/Events/Columns/EventCategory.php | 25 +++ plugins/Events/Columns/EventName.php | 24 +++ plugins/Live/Visitor.php | 6 +- plugins/UserCountry/Columns/Base.php | 1 - 28 files changed, 734 insertions(+), 534 deletions(-) delete mode 100644 core/Tracker/ActionClickUrl.php delete mode 100644 core/Tracker/ActionEvent.php delete mode 100644 core/Tracker/ActionSiteSearch.php create mode 100644 plugins/Actions/Actions/ActionClickUrl.php create mode 100644 plugins/Actions/Actions/ActionDownloadUrl.php create mode 100644 plugins/Actions/Actions/ActionSiteSearch.php create mode 100644 plugins/Actions/Columns/ServerTime.php create mode 100644 plugins/Actions/Columns/TimeSpentRefAction.php create mode 100644 plugins/Events/Actions/ActionEvent.php diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php index c3ce4307c1..f23321be43 100644 --- a/core/Db/Schema/Mysql.php +++ b/core/Db/Schema/Mysql.php @@ -233,18 +233,13 @@ class Mysql implements SchemaInterface idlink_va INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT, idsite int(10) UNSIGNED NOT NULL, idvisitor BINARY(8) NOT NULL, - server_time DATETIME NOT NULL, idvisit INTEGER(10) UNSIGNED NOT NULL, idaction_url_ref INTEGER(10) UNSIGNED NULL DEFAULT 0, idaction_name_ref INTEGER(10) UNSIGNED NOT NULL, - idaction_event_category INTEGER(10) UNSIGNED DEFAULT NULL, - idaction_event_action INTEGER(10) UNSIGNED DEFAULT NULL, - time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL, custom_float FLOAT NULL DEFAULT NULL, PRIMARY KEY(idlink_va), - INDEX index_idvisit(idvisit), - INDEX index_idsite_servertime ( idsite, server_time ) + INDEX index_idvisit(idvisit) ) ENGINE=$engine DEFAULT CHARSET=utf8 ", diff --git a/core/Plugin/ActionDimension.php b/core/Plugin/ActionDimension.php index f42dfb0eb2..507b2d804f 100644 --- a/core/Plugin/ActionDimension.php +++ b/core/Plugin/ActionDimension.php @@ -58,6 +58,15 @@ abstract class ActionDimension return false; } + /** + * @return string|int + * @throws \Exception in case not implemented + */ + public function getActionId() + { + throw new \Exception('You need to overwrite the getActionId method in case you implement the onLookupAction method in class: ' . get_class($this)); + } + protected function addSegment(Segment $segment) { $sqlSegment = $segment->getSqlSegment(); @@ -90,6 +99,7 @@ abstract class ActionDimension { $plugins = PluginManager::getInstance()->getLoadedPlugins(); $instances = array(); + foreach ($plugins as $plugin) { foreach (self::getDimensions($plugin) as $instance) { $instances[] = $instance; diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php index 63a93c1ec3..75ea3fd58f 100644 --- a/core/Tracker/Action.php +++ b/core/Tracker/Action.php @@ -12,6 +12,8 @@ namespace Piwik\Tracker; use Exception; use Piwik\Common; use Piwik\Piwik; +use Piwik\Plugin\ActionDimension; +use Piwik\Plugin\Manager; use Piwik\Tracker; /** @@ -36,37 +38,71 @@ abstract class Action const DB_COLUMN_CUSTOM_FLOAT = 'custom_float'; + private static $factoryPriority = array( + self::TYPE_PAGE_URL, self::TYPE_SITE_SEARCH, self::TYPE_EVENT, self::TYPE_OUTLINK, self::TYPE_DOWNLOAD + ); + /** * Makes the correct Action object based on the request. * * @param Request $request - * @return ActionClickUrl|ActionPageview|ActionSiteSearch + * @return Action */ static public function factory(Request $request) { - $downloadUrl = $request->getParam('download'); - if (!empty($downloadUrl)) { - return new ActionClickUrl(self::TYPE_DOWNLOAD, $downloadUrl, $request); + /** @var Action[] $actions */ + $actions = self::getAllActions($request); + + foreach ($actions as $actionType) { + if (empty($action)) { + $action = $actionType; + continue; + } + + $posPrevious = self::getPriority($action); + $posCurrent = self::getPriority($actionType); + + if ($posCurrent > $posPrevious) { + $action = $actionType; + } } - $outlinkUrl = $request->getParam('link'); - if (!empty($outlinkUrl)) { - return new ActionClickUrl(self::TYPE_OUTLINK, $outlinkUrl, $request); + if (!empty($action)) { + return $action; } - $url = $request->getParam('url'); + return new ActionPageview($request); + } + + private static function getPriority(Action $actionType) + { + $key = array_search($actionType->getActionType(), self::$factoryPriority); - $eventCategory = $request->getParam('e_c'); - $eventAction = $request->getParam('e_a'); - if(strlen($eventCategory) > 0 && strlen($eventAction) > 0 ) { - return new ActionEvent($eventCategory, $eventAction, $url, $request); + if (!$key) { + return -1; } + } - $action = new ActionSiteSearch($url, $request); - if ($action->isSearchDetected()) { - return $action; + public function shouldHandle() + { + return false; + } + + static private function getAllActions(Request $request) + { + $actions = Manager::getInstance()->findMultipleComponents('Actions', '\\Piwik\\Tracker\\Action'); + $instances = array(); + + foreach ($actions as $action) { + /** @var \Piwik\Tracker\Action $instance */ + $instance = new $action($request); + + if ($instance->shouldHandle($request)) { + $instances[] = $instance; + } } - return new ActionPageview($url, $request); + + return $instances; } /** @@ -83,7 +119,7 @@ abstract class Action public function __construct($type, Request $request) { $this->actionType = $type; - $this->request = $request; + $this->request = $request; } /** @@ -118,7 +154,6 @@ abstract class Action return false; } - protected function setActionName($name) { $name = PageUrl::cleanupString((string)$name); @@ -147,7 +182,7 @@ abstract class Action if (!empty($url)) { // normalize urls by stripping protocol and www $url = PageUrl::normalizeUrl($url); - return array($url['url'], Tracker\Action::TYPE_PAGE_URL, $url['prefixId']); + return array($url['url'], self::TYPE_PAGE_URL, $url['prefixId']); } return false; } @@ -159,7 +194,6 @@ abstract class Action return (int)$idUrl; } - public function getIdActionUrlForEntryAndExitIds() { return $this->getIdActionUrl(); @@ -223,10 +257,29 @@ abstract class Action if(!empty($this->actionIdsCached)) { return; } - $actions = $this->getActionsToLookup(); + + $actions = $this->getActionsToLookup(); + $dimensions = ActionDimension::getAllDimensions(); + + foreach ($dimensions as $dimension) { + if (method_exists($dimension, 'onLookupAction')) { + $field = $dimension->getFieldName(); + $value = $dimension->onLookupAction($this->request, $this); + + if (empty($field)) { + throw new Exception('Dimension ' . get_class($dimension) . ' does not define a field name'); + } + + if ($value !== false) { + $actions[$field] = array($value, $dimension->getActionId()); + Common::printDebug("$field = $value"); + } + } + } + $actions = array_filter($actions, 'count'); - if(empty($actions)) { + if (empty($actions)) { return; } @@ -239,34 +292,41 @@ abstract class Action /** * Records in the DB the association between the visit and this action. * - * @param int $idVisit is the ID of the current visit in the DB table log_visit - * @param $visitorIdCookie * @param int $idReferrerActionUrl is the ID of the last action done by the current visit. * @param $idReferrerActionName - * @param int $timeSpentReferrerAction is the number of seconds since the last action was done. - * It is directly related to idReferrerActionUrl. + * @param Visitor $visitor */ - public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idReferrerActionName, $timeSpentReferrerAction) + public function record(Visitor $visitor, $idReferrerActionUrl, $idReferrerActionName) { $this->loadIdsFromLogActionTable(); $visitAction = array( - 'idvisit' => $idVisit, - 'idsite' => $this->request->getIdSite(), - 'idvisitor' => $visitorIdCookie, - 'server_time' => Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()), - 'idaction_url' => $this->getIdActionUrl(), - 'idaction_url_ref' => $idReferrerActionUrl, - 'idaction_name_ref' => $idReferrerActionName, - 'time_spent_ref_action' => $timeSpentReferrerAction + 'idvisit' => $visitor->getVisitorColumn('idvisit'), + 'idsite' => $this->request->getIdSite(), + 'idvisitor' => $visitor->getVisitorColumn('idvisitor'), + 'idaction_url' => $this->getIdActionUrl(), + 'idaction_url_ref' => $idReferrerActionUrl, + 'idaction_name_ref' => $idReferrerActionName ); + $dimensions = ActionDimension::getAllDimensions(); + + foreach ($dimensions as $dimension) { + if (method_exists($dimension, 'onNewAction')) { + $value = $dimension->onNewAction($this->request, $this, $visitor); + + if ($value !== false) { + $visitAction[$dimension->getFieldName()] = $value; + } + } + } + // idaction_name is NULLable. we only set it when applicable - if($this->isActionHasActionName()) { + if ($this->isActionHasActionName()) { $visitAction['idaction_name'] = (int)$this->getIdActionName(); } - foreach($this->actionIdsCached as $field => $idAction) { + foreach ($this->actionIdsCached as $field => $idAction) { $visitAction[$field] = ($idAction === false) ? 0 : $idAction; } @@ -282,9 +342,9 @@ abstract class Action } $visitAction = array_merge($visitAction, $customVariables); - $fields = implode(", ", array_keys($visitAction)); - $bind = array_values($visitAction); - $values = Common::getSqlStringFieldsArray($visitAction); + $fields = implode(", ", array_keys($visitAction)); + $bind = array_values($visitAction); + $values = Common::getSqlStringFieldsArray($visitAction); $sql = "INSERT INTO " . Common::prefixTable('log_link_visit_action') . " ($fields) VALUES ($values)"; Tracker::getDatabase()->query($sql, $bind); @@ -310,8 +370,8 @@ abstract class Action */ protected function isActionHasActionName() { - return in_array($this->getActionType(), array(Tracker\Action::TYPE_PAGE_TITLE, - Tracker\Action::TYPE_PAGE_URL, - Tracker\Action::TYPE_SITE_SEARCH)); + return in_array($this->getActionType(), array(self::TYPE_PAGE_TITLE, + self::TYPE_PAGE_URL, + self::TYPE_SITE_SEARCH)); } } diff --git a/core/Tracker/ActionClickUrl.php b/core/Tracker/ActionClickUrl.php deleted file mode 100644 index 0eacedf1df..0000000000 --- a/core/Tracker/ActionClickUrl.php +++ /dev/null @@ -1,63 +0,0 @@ -setActionUrl($url); - } - - protected function getActionsToLookup() - { - return array( - // Note: we do not normalize download/oulink URL - 'idaction_url' => array($this->getActionUrl(), $this->getActionType()) - ); - } - - function writeDebugInfo() - { - parent::writeDebugInfo(); - - if (self::detectActionIsOutlinkOnAliasHost($this, $this->request->getIdSite())) { - Common::printDebug("INFO: The outlink URL host is one of the known host for this website. "); - } - } - - /** - * Detect whether action is an outlink given host aliases - * - * @param Action $action - * @return bool true if the outlink the visitor clicked on points to one of the known hosts for this website - */ - public static function detectActionIsOutlinkOnAliasHost(Action $action, $idSite) - { - if ($action->getActionType() != Action::TYPE_OUTLINK) { - return false; - } - $decodedActionUrl = $action->getActionUrl(); - $actionUrlParsed = @parse_url($decodedActionUrl); - if (!isset($actionUrlParsed['host'])) { - return false; - } - return Visit::isHostKnownAliasHost($actionUrlParsed['host'], $idSite); - } -} diff --git a/core/Tracker/ActionEvent.php b/core/Tracker/ActionEvent.php deleted file mode 100644 index 511cf7923c..0000000000 --- a/core/Tracker/ActionEvent.php +++ /dev/null @@ -1,78 +0,0 @@ -setActionUrl($url); - $this->eventCategory = trim($eventCategory); - $this->eventAction = trim($eventAction); - $this->eventName = trim($request->getParam('e_n')); - $this->eventValue = trim($request->getParam('e_v')); - } - - function getCustomFloatValue() - { - return $this->eventValue; - } - - protected function getActionsToLookup() - { - $actions = array( - 'idaction_url' => $this->getUrlAndType() - ); - - if(strlen($this->eventName) > 0) { - $actions['idaction_name'] = array($this->eventName, Action::TYPE_EVENT_NAME); - } - if(strlen($this->eventCategory) > 0) { - $actions['idaction_event_category'] = array($this->eventCategory, Action::TYPE_EVENT_CATEGORY); - } - if(strlen($this->eventAction) > 0) { - $actions['idaction_event_action'] = array($this->eventAction, Action::TYPE_EVENT_ACTION); - } - return $actions; - } - - // Do not track this Event URL as Entry/Exit Page URL (leave the existing entry/exit) - public function getIdActionUrlForEntryAndExitIds() - { - return false; - } - - // Do not track this Event Name as Entry/Exit Page Title (leave the existing entry/exit) - public function getIdActionNameForEntryAndExitIds() - { - return false; - } - - public function writeDebugInfo() - { - $write = parent::writeDebugInfo(); - if($write) { - Common::printDebug("Event Category = " . $this->eventCategory . ", - Event Action = " . $this->eventAction . ", - Event Name = " . $this->eventName . ", - Event Value = " . $this->getCustomFloatValue()); - } - return $write; - } - -} diff --git a/core/Tracker/ActionPageview.php b/core/Tracker/ActionPageview.php index 35cdb0edac..2eab5c95c9 100644 --- a/core/Tracker/ActionPageview.php +++ b/core/Tracker/ActionPageview.php @@ -20,10 +20,11 @@ class ActionPageview extends Action { protected $timeGeneration = false; - function __construct($url, Request $request) + function __construct(Request $request) { parent::__construct(Action::TYPE_PAGE_URL, $request); + $url = $request->getParam('url'); $this->setActionUrl($url); $actionName = $request->getParam('action_name'); @@ -41,12 +42,17 @@ class ActionPageview extends Action ); } - function getCustomFloatValue() + public function getCustomFloatValue() { return $this->request->getPageGenerationTime(); } - protected function cleanupActionName($actionName) + public function shouldHandle() + { + return true; + } + + private function cleanupActionName($actionName) { // get the delimiter, by default '/'; BC, we read the old action_category_delimiter first (see #1067) $actionCategoryDelimiter = isset(Config::getInstance()->General['action_category_delimiter']) diff --git a/core/Tracker/ActionSiteSearch.php b/core/Tracker/ActionSiteSearch.php deleted file mode 100644 index 369abda231..0000000000 --- a/core/Tracker/ActionSiteSearch.php +++ /dev/null @@ -1,254 +0,0 @@ -originalUrl = $url; - } - - protected function getActionsToLookup() - { - return array( - 'idaction_name' => array($this->getActionName(), Action::TYPE_SITE_SEARCH), - ); - } - - public function getIdActionUrl() - { - // Site Search, by default, will not track URL. We do not want URL to appear as "Page URL not defined" - // so we specifically set it to NULL in the table (the archiving query does IS NOT NULL) - return null; - } - - public function getCustomFloatValue() - { - return $this->request->getPageGenerationTime(); - } - - function isSearchDetected() - { - $siteSearch = $this->detectSiteSearch($this->originalUrl); - - if(empty($siteSearch)) { - return false; - } - - list($actionName, $url, $category, $count) = $siteSearch; - - if (!empty($category)) { - $this->searchCategory = trim($category); - } - if ($count !== false) { - $this->searchCount = $count; - } - $this->setActionName($actionName); - $this->setActionUrl($url); - - return true; - } - - - public function getCustomVariables() - { - $customVariables = parent::getCustomVariables(); - - // Enrich Site Search actions with Custom Variables, overwriting existing values - if (!empty($this->searchCategory)) { - if (!empty($customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_CATEGORY])) { - Common::printDebug("WARNING: Overwriting existing Custom Variable in slot " . self::CVAR_INDEX_SEARCH_CATEGORY . " for this page view"); - } - $customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_CATEGORY] = self::CVAR_KEY_SEARCH_CATEGORY; - $customVariables['custom_var_v' . self::CVAR_INDEX_SEARCH_CATEGORY] = Request::truncateCustomVariable($this->searchCategory); - } - if ($this->searchCount !== false) { - if (!empty($customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_COUNT])) { - Common::printDebug("WARNING: Overwriting existing Custom Variable in slot " . self::CVAR_INDEX_SEARCH_COUNT . " for this page view"); - } - $customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_COUNT] = self::CVAR_KEY_SEARCH_COUNT; - $customVariables['custom_var_v' . self::CVAR_INDEX_SEARCH_COUNT] = (int)$this->searchCount; - } - return $customVariables; - } - - protected function detectSiteSearchFromUrl($website, $parsedUrl) - { - $doRemoveSearchParametersFromUrl = true; - $separator = '&'; - $count = $actionName = $categoryName = false; - - $keywordParameters = isset($website['sitesearch_keyword_parameters']) - ? $website['sitesearch_keyword_parameters'] - : array(); - $queryString = (!empty($parsedUrl['query']) ? $parsedUrl['query'] : '') . (!empty($parsedUrl['fragment']) ? $separator . $parsedUrl['fragment'] : ''); - $parametersRaw = UrlHelper::getArrayFromQueryString($queryString); - - // strtolower the parameter names for smooth site search detection - $parameters = array(); - foreach ($parametersRaw as $k => $v) { - $parameters[Common::mb_strtolower($k)] = $v; - } - // decode values if they were sent from a client using another charset - $pageEncoding = $this->request->getParam('cs'); - PageUrl::reencodeParameters($parameters, $pageEncoding); - - // Detect Site Search keyword - foreach ($keywordParameters as $keywordParameterRaw) { - $keywordParameter = Common::mb_strtolower($keywordParameterRaw); - if (!empty($parameters[$keywordParameter])) { - $actionName = $parameters[$keywordParameter]; - break; - } - } - - if (empty($actionName)) { - return false; - } - - $categoryParameters = isset($website['sitesearch_category_parameters']) - ? $website['sitesearch_category_parameters'] - : array(); - - foreach ($categoryParameters as $categoryParameterRaw) { - $categoryParameter = Common::mb_strtolower($categoryParameterRaw); - if (!empty($parameters[$categoryParameter])) { - $categoryName = $parameters[$categoryParameter]; - break; - } - } - - if (isset($parameters['search_count']) - && $this->isValidSearchCount($parameters['search_count']) - ) { - $count = $parameters['search_count']; - } - // Remove search kwd from URL - if ($doRemoveSearchParametersFromUrl) { - // @see excludeQueryParametersFromUrl() - // Excluded the detected parameters from the URL - $parametersToExclude = array($categoryParameterRaw, $keywordParameterRaw); - if(isset($parsedUrl['query'])) { - $parsedUrl['query'] = UrlHelper::getQueryStringWithExcludedParameters(UrlHelper::getArrayFromQueryString($parsedUrl['query']), $parametersToExclude); - } - if(isset($parsedUrl['fragment'])) { - $parsedUrl['fragment'] = UrlHelper::getQueryStringWithExcludedParameters(UrlHelper::getArrayFromQueryString($parsedUrl['fragment']), $parametersToExclude); - } - } - $url = UrlHelper::getParseUrlReverse($parsedUrl); - if (is_array($actionName)) { - $actionName = reset($actionName); - } - $actionName = trim(urldecode($actionName)); - if (empty($actionName)) { - return false; - } - if (is_array($categoryName)) { - $categoryName = reset($categoryName); - } - $categoryName = trim(urldecode($categoryName)); - return array($url, $actionName, $categoryName, $count); - } - - protected function isValidSearchCount($count) - { - return is_numeric($count) && $count >= 0; - } - - protected function detectSiteSearch($originalUrl) - { - $website = Cache::getCacheWebsiteAttributes($this->request->getIdSite()); - if (empty($website['sitesearch'])) { - Common::printDebug("Internal 'Site Search' tracking is not enabled for this site. "); - return false; - } - - $actionName = $url = $categoryName = $count = false; - - $originalUrl = PageUrl::cleanupUrl($originalUrl); - - // Detect Site search from Tracking API parameters rather than URL - $searchKwd = $this->request->getParam('search'); - if (!empty($searchKwd)) { - $actionName = $searchKwd; - $isCategoryName = $this->request->getParam('search_cat'); - if (!empty($isCategoryName)) { - $categoryName = $isCategoryName; - } - $isCount = $this->request->getParam('search_count'); - if ($this->isValidSearchCount($isCount)) { - $count = $isCount; - } - } - - if (empty($actionName)) { - $parsedUrl = @parse_url($originalUrl); - - // Detect Site Search from URL query parameters - if (!empty($parsedUrl['query']) || !empty($parsedUrl['fragment'])) { - // array($url, $actionName, $categoryName, $count); - $searchInfo = $this->detectSiteSearchFromUrl($website, $parsedUrl); - if (!empty($searchInfo)) { - list ($url, $actionName, $categoryName, $count) = $searchInfo; - } - } - } - - $actionName = trim($actionName); - $categoryName = trim($categoryName); - - if (empty($actionName)) { - Common::printDebug("(this is not a Site Search request)"); - return false; - } - - Common::printDebug("Detected Site Search keyword '$actionName'. "); - if (!empty($categoryName)) { - Common::printDebug("- Detected Site Search Category '$categoryName'. "); - } - if ($count !== false) { - Common::printDebug("- Search Results Count was '$count'. "); - } - if ($url != $originalUrl) { - Common::printDebug("NOTE: The Page URL was changed / removed, during the Site Search detection, was '$originalUrl', now is '$url'"); - } - - return array( - $actionName, - $url, - $categoryName, - $count - ); - } - - -} diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php index 79cd857358..3a0ed0b575 100644 --- a/core/Tracker/Visit.php +++ b/core/Tracker/Visit.php @@ -167,12 +167,7 @@ class Visit implements VisitInterface try { $this->handleExistingVisit($visitor, $action, $visitIsConverted); if (!is_null($action)) { - $action->record($this->visitorInfo['idvisit'], - $this->visitorInfo['idvisitor'], - $idReferrerActionUrl, - $idReferrerActionName, - $this->visitorInfo['time_spent_ref_action'] - ); + $action->record($visitor, $idReferrerActionUrl, $idReferrerActionName); } } catch (VisitorNotFoundInDb $e) { @@ -203,7 +198,7 @@ class Visit implements VisitInterface ) { $this->handleNewVisit($visitor, $action, $visitIsConverted); if (!is_null($action)) { - $action->record($this->visitorInfo['idvisit'], $this->visitorInfo['idvisitor'], 0, 0, 0); + $action->record($visitor, 0, 0); } } @@ -240,7 +235,10 @@ class Visit implements VisitInterface $valuesToUpdate = $this->getExistingVisitFieldsToUpdate($visitor, $action, $visitIsConverted); + // TODO we should not have to sync this->visitorInfo and $visitor columns. + // TODO it should be its own dimension $this->visitorInfo['time_spent_ref_action'] = $this->getTimeSpentReferrerAction(); + $visitor->setVisitorColumn('time_spent_ref_action', $this->visitorInfo['time_spent_ref_action']); // update visitorInfo foreach ($valuesToUpdate AS $name => $value) { @@ -322,6 +320,7 @@ class Visit implements VisitInterface $idVisit = $this->insertNewVisit( $this->visitorInfo ); + $visitor->setVisitorColumn('idvisit', $idVisit); $this->visitorInfo['idvisit'] = $idVisit; $this->visitorInfo['visit_first_action_time'] = $this->request->getCurrentTimestamp(); $this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp(); diff --git a/piwik.php b/piwik.php index 18f5b22a54..40096c11ce 100644 --- a/piwik.php +++ b/piwik.php @@ -69,10 +69,7 @@ require_once PIWIK_INCLUDE_PATH . '/core/Tracker/GoalManager.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/PageUrl.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/TableLogAction.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Action.php'; -require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionClickUrl.php'; -require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionEvent.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionPageview.php'; -require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionSiteSearch.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Request.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Referrer.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/VisitExcluded.php'; diff --git a/plugins/API/API.php b/plugins/API/API.php index 76a2e7a600..212ef57d90 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -15,9 +15,6 @@ use Piwik\DataTable; use Piwik\DataTable\Filter\ColumnDelete; use Piwik\DataTable\Row; use Piwik\Date; -use Piwik\Filesystem; -use Piwik\Menu\MenuReporting; -use Piwik\Menu\MenuTop; use Piwik\Metrics; use Piwik\Period; use Piwik\Period\Range; @@ -25,11 +22,8 @@ use Piwik\Piwik; use Piwik\Plugin\ActionDimension; use Piwik\Plugin\VisitDimension; use Piwik\Plugins\CoreAdminHome\CustomLogo; -use Piwik\Tracker\Action; -use Piwik\Tracker\GoalManager; use Piwik\Translate; use Piwik\Version; -use Piwik\WidgetsList; require_once PIWIK_INCLUDE_PATH . '/core/Config.php'; diff --git a/plugins/Actions/API.php b/plugins/Actions/API.php index b7855ef8a9..0c253c85bc 100644 --- a/plugins/Actions/API.php +++ b/plugins/Actions/API.php @@ -17,8 +17,8 @@ use Piwik\Date; use Piwik\Metrics; use Piwik\Piwik; use Piwik\Plugins\CustomVariables\API as APICustomVariables; +use Piwik\Plugins\Actions\Actions\ActionSiteSearch; use Piwik\Tracker\Action; -use Piwik\Tracker\ActionSiteSearch; use Piwik\Tracker\PageUrl; /** diff --git a/plugins/Actions/Actions.php b/plugins/Actions/Actions.php index e1ef68fbed..934b911319 100644 --- a/plugins/Actions/Actions.php +++ b/plugins/Actions/Actions.php @@ -11,9 +11,9 @@ namespace Piwik\Plugins\Actions; use Piwik\ArchiveProcessor; use Piwik\Common; use Piwik\Db; +use Piwik\Site; use Piwik\Plugin\ViewDataTable; use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable; -use Piwik\Site; /** * Actions plugin diff --git a/plugins/Actions/Actions/ActionClickUrl.php b/plugins/Actions/Actions/ActionClickUrl.php new file mode 100644 index 0000000000..67ae28805f --- /dev/null +++ b/plugins/Actions/Actions/ActionClickUrl.php @@ -0,0 +1,71 @@ +setActionUrl($request->getParam('link')); + } + + public function shouldHandle() + { + $outlinkUrl = $this->request->getParam('link'); + + return !empty($outlinkUrl); + } + + protected function getActionsToLookup() + { + return array( + // Note: we do not normalize outlink URL + 'idaction_url' => array($this->getActionUrl(), $this->getActionType()) + ); + } + + public function writeDebugInfo() + { + parent::writeDebugInfo(); + + if ($this->detectActionIsOutlinkOnAliasHost($this, $this->request->getIdSite())) { + Common::printDebug("INFO: The outlink URL host is one of the known host for this website. "); + } + } + + /** + * Detect whether action is an outlink given host aliases + * + * @param Action $action + * @return bool true if the outlink the visitor clicked on points to one of the known hosts for this website + */ + protected function detectActionIsOutlinkOnAliasHost(Action $action, $idSite) + { + $decodedActionUrl = $action->getActionUrl(); + $actionUrlParsed = @parse_url($decodedActionUrl); + + if (!isset($actionUrlParsed['host'])) { + return false; + } + + return Visit::isHostKnownAliasHost($actionUrlParsed['host'], $idSite); + } +} diff --git a/plugins/Actions/Actions/ActionDownloadUrl.php b/plugins/Actions/Actions/ActionDownloadUrl.php new file mode 100644 index 0000000000..a33bed1765 --- /dev/null +++ b/plugins/Actions/Actions/ActionDownloadUrl.php @@ -0,0 +1,41 @@ +setActionUrl($request->getParam('download')); + } + + public function shouldHandle() + { + $downloadUrl = $this->request->getParam('download'); + + return !empty($downloadUrl); + } + + protected function getActionsToLookup() + { + return array( + // Note: we do not normalize download URL + 'idaction_url' => array($this->getActionUrl(), $this->getActionType()) + ); + } + +} diff --git a/plugins/Actions/Actions/ActionSiteSearch.php b/plugins/Actions/Actions/ActionSiteSearch.php new file mode 100644 index 0000000000..61646aa883 --- /dev/null +++ b/plugins/Actions/Actions/ActionSiteSearch.php @@ -0,0 +1,260 @@ +originalUrl = $request->getParam('url'); + } + + public function shouldHandle() + { + return $this->isSearchDetected(); + } + + protected function getActionsToLookup() + { + return array( + 'idaction_name' => array($this->getActionName(), Action::TYPE_SITE_SEARCH), + ); + } + + public function getIdActionUrl() + { + // Site Search, by default, will not track URL. We do not want URL to appear as "Page URL not defined" + // so we specifically set it to NULL in the table (the archiving query does IS NOT NULL) + return null; + } + + public function getCustomFloatValue() + { + return $this->request->getPageGenerationTime(); + } + + public function isSearchDetected() + { + $siteSearch = $this->detectSiteSearch($this->originalUrl); + + if(empty($siteSearch)) { + return false; + } + + list($actionName, $url, $category, $count) = $siteSearch; + + if (!empty($category)) { + $this->searchCategory = trim($category); + } + if ($count !== false) { + $this->searchCount = $count; + } + $this->setActionName($actionName); + $this->setActionUrl($url); + + return true; + } + + public function getCustomVariables() + { + $customVariables = parent::getCustomVariables(); + + // Enrich Site Search actions with Custom Variables, overwriting existing values + if (!empty($this->searchCategory)) { + if (!empty($customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_CATEGORY])) { + Common::printDebug("WARNING: Overwriting existing Custom Variable in slot " . self::CVAR_INDEX_SEARCH_CATEGORY . " for this page view"); + } + $customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_CATEGORY] = self::CVAR_KEY_SEARCH_CATEGORY; + $customVariables['custom_var_v' . self::CVAR_INDEX_SEARCH_CATEGORY] = Request::truncateCustomVariable($this->searchCategory); + } + if ($this->searchCount !== false) { + if (!empty($customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_COUNT])) { + Common::printDebug("WARNING: Overwriting existing Custom Variable in slot " . self::CVAR_INDEX_SEARCH_COUNT . " for this page view"); + } + $customVariables['custom_var_k' . self::CVAR_INDEX_SEARCH_COUNT] = self::CVAR_KEY_SEARCH_COUNT; + $customVariables['custom_var_v' . self::CVAR_INDEX_SEARCH_COUNT] = (int)$this->searchCount; + } + return $customVariables; + } + + protected function detectSiteSearchFromUrl($website, $parsedUrl) + { + $doRemoveSearchParametersFromUrl = true; + $separator = '&'; + $count = $actionName = $categoryName = false; + + $keywordParameters = isset($website['sitesearch_keyword_parameters']) + ? $website['sitesearch_keyword_parameters'] + : array(); + $queryString = (!empty($parsedUrl['query']) ? $parsedUrl['query'] : '') . (!empty($parsedUrl['fragment']) ? $separator . $parsedUrl['fragment'] : ''); + $parametersRaw = UrlHelper::getArrayFromQueryString($queryString); + + // strtolower the parameter names for smooth site search detection + $parameters = array(); + foreach ($parametersRaw as $k => $v) { + $parameters[Common::mb_strtolower($k)] = $v; + } + // decode values if they were sent from a client using another charset + $pageEncoding = $this->request->getParam('cs'); + PageUrl::reencodeParameters($parameters, $pageEncoding); + + // Detect Site Search keyword + foreach ($keywordParameters as $keywordParameterRaw) { + $keywordParameter = Common::mb_strtolower($keywordParameterRaw); + if (!empty($parameters[$keywordParameter])) { + $actionName = $parameters[$keywordParameter]; + break; + } + } + + if (empty($actionName)) { + return false; + } + + $categoryParameters = isset($website['sitesearch_category_parameters']) + ? $website['sitesearch_category_parameters'] + : array(); + + foreach ($categoryParameters as $categoryParameterRaw) { + $categoryParameter = Common::mb_strtolower($categoryParameterRaw); + if (!empty($parameters[$categoryParameter])) { + $categoryName = $parameters[$categoryParameter]; + break; + } + } + + if (isset($parameters['search_count']) + && $this->isValidSearchCount($parameters['search_count']) + ) { + $count = $parameters['search_count']; + } + // Remove search kwd from URL + if ($doRemoveSearchParametersFromUrl) { + // @see excludeQueryParametersFromUrl() + // Excluded the detected parameters from the URL + $parametersToExclude = array($categoryParameterRaw, $keywordParameterRaw); + if(isset($parsedUrl['query'])) { + $parsedUrl['query'] = UrlHelper::getQueryStringWithExcludedParameters(UrlHelper::getArrayFromQueryString($parsedUrl['query']), $parametersToExclude); + } + if(isset($parsedUrl['fragment'])) { + $parsedUrl['fragment'] = UrlHelper::getQueryStringWithExcludedParameters(UrlHelper::getArrayFromQueryString($parsedUrl['fragment']), $parametersToExclude); + } + } + $url = UrlHelper::getParseUrlReverse($parsedUrl); + if (is_array($actionName)) { + $actionName = reset($actionName); + } + $actionName = trim(urldecode($actionName)); + if (empty($actionName)) { + return false; + } + if (is_array($categoryName)) { + $categoryName = reset($categoryName); + } + $categoryName = trim(urldecode($categoryName)); + return array($url, $actionName, $categoryName, $count); + } + + protected function isValidSearchCount($count) + { + return is_numeric($count) && $count >= 0; + } + + protected function detectSiteSearch($originalUrl) + { + $website = Cache::getCacheWebsiteAttributes($this->request->getIdSite()); + if (empty($website['sitesearch'])) { + Common::printDebug("Internal 'Site Search' tracking is not enabled for this site. "); + return false; + } + + $actionName = $url = $categoryName = $count = false; + + $originalUrl = PageUrl::cleanupUrl($originalUrl); + + // Detect Site search from Tracking API parameters rather than URL + $searchKwd = $this->request->getParam('search'); + if (!empty($searchKwd)) { + $actionName = $searchKwd; + $isCategoryName = $this->request->getParam('search_cat'); + if (!empty($isCategoryName)) { + $categoryName = $isCategoryName; + } + $isCount = $this->request->getParam('search_count'); + if ($this->isValidSearchCount($isCount)) { + $count = $isCount; + } + } + + if (empty($actionName)) { + $parsedUrl = @parse_url($originalUrl); + + // Detect Site Search from URL query parameters + if (!empty($parsedUrl['query']) || !empty($parsedUrl['fragment'])) { + // array($url, $actionName, $categoryName, $count); + $searchInfo = $this->detectSiteSearchFromUrl($website, $parsedUrl); + if (!empty($searchInfo)) { + list ($url, $actionName, $categoryName, $count) = $searchInfo; + } + } + } + + $actionName = trim($actionName); + $categoryName = trim($categoryName); + + if (empty($actionName)) { + Common::printDebug("(this is not a Site Search request)"); + return false; + } + + Common::printDebug("Detected Site Search keyword '$actionName'. "); + if (!empty($categoryName)) { + Common::printDebug("- Detected Site Search Category '$categoryName'. "); + } + if ($count !== false) { + Common::printDebug("- Search Results Count was '$count'. "); + } + if ($url != $originalUrl) { + Common::printDebug("NOTE: The Page URL was changed / removed, during the Site Search detection, was '$originalUrl', now is '$url'"); + } + + return array( + $actionName, + $url, + $categoryName, + $count + ); + } + + +} diff --git a/plugins/Actions/Archiver.php b/plugins/Actions/Archiver.php index f7f839827b..cd977fd576 100644 --- a/plugins/Actions/Archiver.php +++ b/plugins/Actions/Archiver.php @@ -12,7 +12,7 @@ use Piwik\DataTable; use Piwik\Metrics; use Piwik\RankingQuery; use Piwik\Tracker\Action; -use Piwik\Tracker\ActionSiteSearch; +use Piwik\Plugins\Actions\Actions\ActionSiteSearch; /** * Class encapsulating logic to process Day/Period Archiving for the Actions reports diff --git a/plugins/Actions/Columns/ClickedUrl.php b/plugins/Actions/Columns/ClickedUrl.php index f5d14fb5df..60790e39ab 100644 --- a/plugins/Actions/Columns/ClickedUrl.php +++ b/plugins/Actions/Columns/ClickedUrl.php @@ -10,9 +10,6 @@ namespace Piwik\Plugins\Actions\Columns; use Piwik\Piwik; use Piwik\Plugin\ActionDimension; -use Piwik\Plugin\VisitDimension; -use Piwik\Tracker\Request; -use Piwik\Tracker\TableLogAction; class ClickedUrl extends ActionDimension { @@ -20,29 +17,5 @@ class ClickedUrl extends ActionDimension { return Piwik::translate('Actions_ColumnClickedURL'); } -/* - public function shouldHandleAction(Request $request) - { - $link = $request->getParam('link'); - - return !empty($link); - } - - public function getValue(Request $request) - { - $url = $request->getParam('link'); - $ids = TableLogAction::loadIdsAction(array('idaction_url' => array($url, $this->getActionId()))); - - if (empty($ids['idaction_url'])) { - return false; - } - - return (int) $ids['idaction_url']; - } - - public function getActionId() - { - return 2; - }*/ } diff --git a/plugins/Actions/Columns/DownloadUrl.php b/plugins/Actions/Columns/DownloadUrl.php index bfccd19d44..23b039b7a1 100644 --- a/plugins/Actions/Columns/DownloadUrl.php +++ b/plugins/Actions/Columns/DownloadUrl.php @@ -10,9 +10,6 @@ namespace Piwik\Plugins\Actions\Columns; use Piwik\Piwik; use Piwik\Plugin\ActionDimension; -use Piwik\Plugin\VisitDimension; -use Piwik\Tracker\Request; -use Piwik\Tracker\TableLogAction; class DownloadUrl extends ActionDimension { @@ -20,29 +17,5 @@ class DownloadUrl extends ActionDimension { return Piwik::translate('Actions_ColumnDownloadURL'); } -/* - public function shouldHandleAction(Request $request) - { - $download = $request->getParam('download'); - - return !empty($download); - } - - public function getValue(Request $request) - { - $url = $request->getParam('download'); - $ids = TableLogAction::loadIdsAction(array('idaction_url' => array($url, $this->getActionId()))); - - if (empty($ids['idaction_url'])) { - return false; - } - - return (int) $ids['idaction_url']; - } - - public function getActionId() - { - return 3; - }*/ } diff --git a/plugins/Actions/Columns/PageTitle.php b/plugins/Actions/Columns/PageTitle.php index 2b0385717b..5c4ff21372 100644 --- a/plugins/Actions/Columns/PageTitle.php +++ b/plugins/Actions/Columns/PageTitle.php @@ -30,14 +30,5 @@ class PageTitle extends ActionDimension { return Piwik::translate('Actions_ColumnPageName'); } -/* - public function shouldHandleAction(Request $request) - { - return true; - } - public function getActionId() - { - return 4; - }*/ } diff --git a/plugins/Actions/Columns/ServerTime.php b/plugins/Actions/Columns/ServerTime.php new file mode 100644 index 0000000000..802799bb25 --- /dev/null +++ b/plugins/Actions/Columns/ServerTime.php @@ -0,0 +1,43 @@ +getCurrentTimestamp(); + + return Tracker::getDatetimeFromTimestamp($timestamp); + } +} diff --git a/plugins/Actions/Columns/TimeSpentRefAction.php b/plugins/Actions/Columns/TimeSpentRefAction.php new file mode 100644 index 0000000000..44a1094348 --- /dev/null +++ b/plugins/Actions/Columns/TimeSpentRefAction.php @@ -0,0 +1,36 @@ +getVisitorColumn('time_spent_ref_action'); + + if (empty($timeSpent)) { + return 0; + } + + return $timeSpent; + } +} diff --git a/plugins/CustomVariables/API.php b/plugins/CustomVariables/API.php index b995cdcf8e..77df63861b 100644 --- a/plugins/CustomVariables/API.php +++ b/plugins/CustomVariables/API.php @@ -13,7 +13,7 @@ use Piwik\DataTable; use Piwik\Date; use Piwik\Metrics; use Piwik\Piwik; -use Piwik\Tracker\ActionSiteSearch; +use Piwik\Plugins\Actions\Actions\ActionSiteSearch; /** * The Custom Variables API lets you access reports for your Custom Variables names and values. diff --git a/plugins/Events/Actions/ActionEvent.php b/plugins/Events/Actions/ActionEvent.php new file mode 100644 index 0000000000..50b07b9350 --- /dev/null +++ b/plugins/Events/Actions/ActionEvent.php @@ -0,0 +1,73 @@ +getParam('url'); + + $this->setActionUrl($url); + $this->eventValue = trim($request->getParam('e_v')); + } + + public function shouldHandle() + { + $eventCategory = $this->request->getParam('e_c'); + $eventAction = $this->request->getParam('e_a'); + + return (strlen($eventCategory) > 0 && strlen($eventAction) > 0); + } + + public function getCustomFloatValue() + { + return $this->eventValue; + } + + protected function getActionsToLookup() + { + return array( + 'idaction_url' => $this->getUrlAndType() + ); + } + + // Do not track this Event URL as Entry/Exit Page URL (leave the existing entry/exit) + public function getIdActionUrlForEntryAndExitIds() + { + return false; + } + + // Do not track this Event Name as Entry/Exit Page Title (leave the existing entry/exit) + public function getIdActionNameForEntryAndExitIds() + { + return false; + } + + public function writeDebugInfo() + { + $write = parent::writeDebugInfo(); + if ($write) { + Common::printDebug("Event Value = " . $this->getCustomFloatValue()); + } + return $write; + } +} diff --git a/plugins/Events/Columns/EventAction.php b/plugins/Events/Columns/EventAction.php index ef831bb561..f65b4a6e3b 100644 --- a/plugins/Events/Columns/EventAction.php +++ b/plugins/Events/Columns/EventAction.php @@ -11,10 +11,14 @@ namespace Piwik\Plugins\Events\Columns; use Piwik\Piwik; use Piwik\Plugin\ActionDimension; use Piwik\Plugins\Events\Segment; +use Piwik\Plugins\Events\Actions\ActionEvent; +use Piwik\Tracker\Action; +use Piwik\Tracker\Request; class EventAction extends ActionDimension { protected $fieldName = 'idaction_event_action'; + protected $fieldType = 'INTEGER(10) UNSIGNED DEFAULT NULL'; protected function init() { @@ -28,4 +32,25 @@ class EventAction extends ActionDimension { return Piwik::translate('Events_EventAction'); } + + public function getActionId() + { + return Action::TYPE_EVENT_ACTION; + } + + public function onLookupAction(Request $request, Action $action) + { + if (!($action instanceof ActionEvent)) { + return false; + } + + $eventAction = $request->getParam('e_a'); + $eventAction = trim($eventAction); + + if (strlen($eventAction) > 0) { + return $eventAction; + } + + return false; + } } \ No newline at end of file diff --git a/plugins/Events/Columns/EventCategory.php b/plugins/Events/Columns/EventCategory.php index c9434a5a20..13e76f83a2 100644 --- a/plugins/Events/Columns/EventCategory.php +++ b/plugins/Events/Columns/EventCategory.php @@ -11,10 +11,14 @@ namespace Piwik\Plugins\Events\Columns; use Piwik\Piwik; use Piwik\Plugin\ActionDimension; use Piwik\Plugins\Events\Segment; +use Piwik\Plugins\Events\Actions\ActionEvent; +use Piwik\Tracker\Action; +use Piwik\Tracker\Request; class EventCategory extends ActionDimension { protected $fieldName = 'idaction_event_category'; + protected $fieldType = 'INTEGER(10) UNSIGNED DEFAULT NULL'; protected function init() { @@ -28,4 +32,25 @@ class EventCategory extends ActionDimension { return Piwik::translate('Events_EventCategory'); } + + public function getActionId() + { + return Action::TYPE_EVENT_CATEGORY; + } + + public function onLookupAction(Request $request, Action $action) + { + if (!($action instanceof ActionEvent)) { + return false; + } + + $eventCategory = $request->getParam('e_c'); + $eventCategory = trim($eventCategory); + + if (strlen($eventCategory) > 0) { + return $eventCategory; + } + + return false; + } } \ No newline at end of file diff --git a/plugins/Events/Columns/EventName.php b/plugins/Events/Columns/EventName.php index d3415391a1..c2f084d3cd 100644 --- a/plugins/Events/Columns/EventName.php +++ b/plugins/Events/Columns/EventName.php @@ -11,6 +11,9 @@ namespace Piwik\Plugins\Events\Columns; use Piwik\Piwik; use Piwik\Plugin\ActionDimension; use Piwik\Plugins\Events\Segment; +use Piwik\Plugins\Events\Actions\ActionEvent; +use Piwik\Tracker\Action; +use Piwik\Tracker\Request; class EventName extends ActionDimension { @@ -28,4 +31,25 @@ class EventName extends ActionDimension { return Piwik::translate('Events_EventName'); } + + public function getActionId() + { + return Action::TYPE_EVENT_NAME; + } + + public function onLookupAction(Request $request, Action $action) + { + if (!($action instanceof ActionEvent)) { + return false; + } + + $eventName = $request->getParam('e_n'); + $eventName = trim($eventName); + + if (strlen($eventName) > 0) { + return $eventName; + } + + return false; + } } \ No newline at end of file diff --git a/plugins/Live/Visitor.php b/plugins/Live/Visitor.php index b0adb4a08d..48769bb362 100644 --- a/plugins/Live/Visitor.php +++ b/plugins/Live/Visitor.php @@ -15,11 +15,11 @@ use Piwik\Date; use Piwik\Db; use Piwik\IP; use Piwik\Piwik; -use Piwik\Plugins\API\API as APIMetadata; use Piwik\Plugins\CoreHome\Columns\VisitGoalBuyer; use Piwik\Plugins\CustomVariables\CustomVariables; use Piwik\Plugins\Referrers\API as APIReferrers; use Piwik\Plugins\UserCountry\LocationProvider\GeoIp; +use Piwik\Plugins\Actions\Actions\ActionSiteSearch; use Piwik\Tracker; use Piwik\Tracker\Action; use Piwik\Tracker\GoalManager; @@ -971,8 +971,8 @@ class Visitor private static function getCustomVariablePrettyKey($key) { $rename = array( - Tracker\ActionSiteSearch::CVAR_KEY_SEARCH_CATEGORY => Piwik::translate('Actions_ColumnSearchCategory'), - Tracker\ActionSiteSearch::CVAR_KEY_SEARCH_COUNT => Piwik::translate('Actions_ColumnSearchResultsCount'), + ActionSiteSearch::CVAR_KEY_SEARCH_CATEGORY => Piwik::translate('Actions_ColumnSearchCategory'), + ActionSiteSearch::CVAR_KEY_SEARCH_COUNT => Piwik::translate('Actions_ColumnSearchResultsCount'), ); if (isset($rename[$key])) { return $rename[$key]; diff --git a/plugins/UserCountry/Columns/Base.php b/plugins/UserCountry/Columns/Base.php index 8bffc20028..dfe51fe4e7 100644 --- a/plugins/UserCountry/Columns/Base.php +++ b/plugins/UserCountry/Columns/Base.php @@ -15,7 +15,6 @@ use Piwik\Plugins\UserCountry\LocationProvider; use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig; use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider; use Piwik\IP; -use Piwik\Plugin\Manager; use Piwik\Tracker\Visitor; use Piwik\Tracker\Visit; use Piwik\Tracker\Request; -- cgit v1.2.3