diff --git a/config/global.ini.php b/config/global.ini.php index a0ba449dbe078cebdb56dafd4a5f6c5bb4739b97..025e265787ddeaf895562c6f35a65167e030f9b2 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -289,14 +289,16 @@ scheduled_tasks_min_interval = 3600 ; name of the cookie to ignore visits ignore_visits_cookie_name = piwik_ignore -; variable name to track any campaign, for example CPC campaign +; Comma separated list of variable names that will be read to define a Campaign name, for example CPC campaign ; Example: If a visitor first visits 'index.php?piwik_campaign=Adwords-CPC' then it will be counted as a campaign referer named 'Adwords-CPC' -campaign_var_name = piwik_campaign +; Includes by default the GA style campaign parameters +campaign_var_name = "piwik_campaign,utm_campaign,utm_source,utm_medium" -; variable name to track any campaign keyword +; Comma separated list of variable names that will be read to track a Campaign Keyword ; Example: If a visitor first visits 'index.php?piwik_campaign=Adwords-CPC&piwik_kwd=My killer keyword' ; ; then it will be counted as a campaign referer named 'Adwords-CPC' with the keyword 'My killer keyword' -campaign_keyword_var_name = piwik_kwd +; Includes by default the GA style campaign keyword parameter utm_term +campaign_keyword_var_name = "piwik_kwd,utm_term" ; maximum length of a Page Title or a Page URL recorded in the log_action.name table page_maximum_length = 1024; diff --git a/core/Common.php b/core/Common.php index a9c5fcd65aca7a1e69bfe1208ec4157ac05afcf8..9a8eac85c4df97a8aca48c6796b517f15bbd5893 100644 --- a/core/Common.php +++ b/core/Common.php @@ -784,6 +784,46 @@ class Piwik_Common return $salt; } + /** + * Returns the list of Campaign parameter names that will be read to classify + * a visit as coming from a Campaign + * + * @return array array( + * 0 => array( ... ) // campaign names parameters + * 1 => array( ... ) // campaign keyword parameters + * ); + */ + static public function getCampaignParameters() + { + if(!empty($GLOBALS['PIWIK_TRACKER_MODE'])) + { + $return = array( + Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name'], + Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name'], + ); + } + else + { + $return = array( + Zend_Registry::get('config')->Tracker->campaign_var_name, + Zend_Registry::get('config')->Tracker->campaign_keyword_var_name, + ); + } + foreach($return as &$list) + { + if(strpos($list, ',') !== false) + { + $list = explode(',', $list); + } + else + { + $list = array($list); + } + } + array_walk_recursive($return, 'trim'); + return $return; + } + /** * Generate random string * diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php index 885c10ba8467ce2815cb1fbba0c7166bbb95ec0f..3efe824275065e77df7d06c8f003703d0259380d 100644 --- a/core/Tracker/Action.php +++ b/core/Tracker/Action.php @@ -134,9 +134,12 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface { return $originalUrl; } - $campaignTrackingParameters = array( - Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name'], - Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name']); + $campaignTrackingParameters = Piwik_Common::getCampaignParameters(); + + $campaignTrackingParameters = array_merge( + $campaignTrackingParameters[0], // campaign name parameters + $campaignTrackingParameters[1] // campaign keyword parameters + ); $excludedParameters = isset($website['excluded_parameters']) ? $website['excluded_parameters'] diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php index cb82d11d475dc50f2f36ba2135b0848069114e4d..f00fc5bd814ff7e5a9dfeadb047d8732484d3061 100644 --- a/core/Tracker/Visit.php +++ b/core/Tracker/Visit.php @@ -1286,22 +1286,33 @@ class Piwik_Tracker_Visit_Referer { if(isset($this->currentUrlParse['query'])) { - $campaignVariableName = Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name']; - $campaignName = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignVariableName); - - if( !empty($campaignName)) + $campaignParameters = Piwik_Common::getCampaignParameters(); + + $campaignNames = $campaignParameters[0]; + foreach($campaignNames as $campaignNameParameter) + { + $campaignName = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignNameParameter); + if( !empty($campaignName)) + { + break; + } + } + + if(!empty($campaignName)) { - $campaignKeywordVariableName = Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name']; - $campaignKeyword = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignKeywordVariableName); - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_CAMPAIGN; $this->nameRefererAnalyzed = $campaignName; - if(!empty($campaignKeyword)) + $campaignKeywords = $campaignParameters[1]; + foreach($campaignKeywords as $campaignKeywordParameter) { - $this->keywordRefererAnalyzed = $campaignKeyword; + $campaignKeyword = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignKeywordParameter); + if( !empty($campaignKeyword)) + { + $this->keywordRefererAnalyzed = $campaignKeyword; + break; + } } - return true; } } diff --git a/plugins/VisitorGenerator/Generator.php b/plugins/VisitorGenerator/Generator.php index b8997f33dff7cf4bb230011ae1968dd1b8456766..a608a96b686f3ced394233bca7879b6a19847549 100644 --- a/plugins/VisitorGenerator/Generator.php +++ b/plugins/VisitorGenerator/Generator.php @@ -283,7 +283,7 @@ class Piwik_VisitorGenerator_Generator // we get the variables name for the campaign parameters $campaigns = array( - Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name'] + 'piwik_campaign' ); // we generate a campaign in the URL in 3/18 % of the generated URls $this->addParam('piwik_vars_campaign', $campaigns); @@ -424,11 +424,10 @@ class Piwik_VisitorGenerator_Generator $url .= '?'. $urlVars . '=' . $urlValue; // for a campaign of the CPC kind, we sometimes generate a keyword - if($urlVars == Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name'] + if($urlVars == 'piwik_campaign' && mt_rand(0,1)==0) { - $url .= '&'. Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name'] - . '=' . $this->getRandomString(6,3,'ALL');; + $url .= '&piwik_campaign=' . $this->getRandomString(6,3,'ALL');; } } else diff --git a/tests/core/Tracker/Action.test.php b/tests/core/Tracker/Action.test.php index 00889a9cc2db3636eb2bedfc2d5b8aa0ff83da55..39f6174b010d3ba56ccd886ad48452f446897ca8 100644 --- a/tests/core/Tracker/Action.test.php +++ b/tests/core/Tracker/Action.test.php @@ -36,10 +36,8 @@ class Test_Piwik_TrackerAction extends Test_Database protected function getTestUrls() { - $campaignNameParam = Piwik_Tracker_Config::getInstance()->Tracker['campaign_var_name']; - $campaignKwdParam = Piwik_Tracker_Config::getInstance()->Tracker['campaign_keyword_var_name']; - $this->assertTrue(!empty($campaignNameParam)); - $this->assertTrue(!empty($campaignKwdParam)); + $campaignNameParam = 'piwik_campaign'; + $campaignKwdParam = 'piwik_kwd'; $urls = array( // a wrongly formatted url (parse_url returns false) @@ -50,6 +48,9 @@ class Test_Piwik_TrackerAction extends Test_Database // a standard url with excluded campaign parameters 'http://a.com/index?p1=v1&'.$campaignNameParam.'=Adwords-CPC&'.$campaignKwdParam.'=My killer keyword', + + // a standard url with excluded campaign parameters, GA style + 'http://a.com/index?p1=v1&utm_campaign=Adwords-CPC&utm_term=My killer keyword', // testing with capital parameter 'http://a.com/index?p1=v1&P2=v2&p3=v3', @@ -78,6 +79,7 @@ class Test_Piwik_TrackerAction extends Test_Database 'http:////wrongurl', 'http://username:password@hostname:80/path#anchor', 'http://a.com/index?p1=v1', + 'http://a.com/index?p1=v1', 'http://a.com/index?p1=v1&P2=v2&p3=v3', 'http://a.com/index?p1=v1&p2[]=v2a&p2[]=v2b&p2[]=v2c&p3=v3&p4=v4', @@ -110,6 +112,7 @@ class Test_Piwik_TrackerAction extends Test_Database 'http:////wrongurl', 'http://username:password@hostname:80/path#anchor', 'http://a.com/index?p1=v1', + 'http://a.com/index?p1=v1', 'http://a.com/index?p1=v1&p3=v3', 'http://a.com/index?p1=v1&p3=v3', 'http://a.com/index?p1=v1&p3=v3', @@ -139,6 +142,7 @@ class Test_Piwik_TrackerAction extends Test_Database 'http:////wrongurl', 'http://username:password@hostname:80/path#anchor', 'http://a.com/index?p1=v1', + 'http://a.com/index?p1=v1', 'http://a.com/index?p1=v1&p3=v3', 'http://a.com/index?p1=v1&p3=v3', 'http://a.com/index?p1=v1&p3=v3', diff --git a/tests/integration/Main.test.php b/tests/integration/Main.test.php index 857a59d8b7a8e64c121c88dc99ec175ad656504d..a0c2040aefb235da577239502fce75ab031747e2 100644 --- a/tests/integration/Main.test.php +++ b/tests/integration/Main.test.php @@ -394,7 +394,7 @@ class Test_Piwik_Integration_Main extends Test_Integration // Used to test actual referer + keyword position in Live! $visitorA->setUrlReferrer(urldecode('http://www.google.com/url?sa=t&source=web&cd=1&ved=0CB4QFjAA&url=http%3A%2F%2Fpiwik.org%2F&rct=j&q=this%20keyword%20should%20be%20ranked&ei=V8WfTePkKKLfiALrpZWGAw&usg=AFQjCNF_MGJRqKPvaKuUokHtZ3VvNG9ALw&sig2=BvKAdCtNixsmfNWXjsNyMw')); - // no campaign, but a search engine to attribute the goal conversion to + // no campaign, but a search engine to attribute the goal conversion _to $attribution = array( '', '', @@ -678,9 +678,12 @@ class Test_Piwik_Integration_Main extends Test_Integration ); } - function test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics() + function test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking() { - $this->setApiToCall( 'VisitsSummary.get' ); + $this->setApiToCall( array( + 'VisitsSummary.get', + 'Referers.getCampaigns' + )); $dateTime = '2009-01-04 00:11:42'; $idSite = $this->createWebsite($dateTime); $idGoal = Piwik_Goals_API::getInstance()->addGoal($idSite, 'triggered js', 'manually', '', ''); @@ -688,7 +691,7 @@ class Test_Piwik_Integration_Main extends Test_Integration $t = $this->getTracker($idSite, $dateTime, $defaultInit = true); // Record 1st page view - $t->setUrl( 'http://example.org/index.htm' ); + $t->setUrl( 'http://example.org/index.htm?utm_campaign=GA Campaign&piwik_kwd=Piwik kwd&utm_term=GA keyword SHOULD NOT DISPLAY' ); $this->checkResponse($t->doTrackPageView( 'incredible title!')); $visitorId = $t->getVisitorId(); diff --git a/tests/integration/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__Referers.getCampaigns_day.xml b/tests/integration/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__Referers.getCampaigns_day.xml new file mode 100644 index 0000000000000000000000000000000000000000..b8d8a98b4a6081a8a64ae83640dc837086196454 --- /dev/null +++ b/tests/integration/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__Referers.getCampaigns_day.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <label>GA Campaign</label> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + <max_actions>1</max_actions> + <sum_visit_length>1080</sum_visit_length> + <bounce_count>1</bounce_count> + <nb_visits_converted>1</nb_visits_converted> + <goals> + <row idgoal='1'> + <nb_conversions>1</nb_conversions> + <nb_visits_converted>1</nb_visits_converted> + <revenue>42.2560005188</revenue> + </row> + </goals> + <nb_conversions>1</nb_conversions> + <revenue>42.2560005188</revenue> + <subtable> + <row> + <label>Piwik kwd</label> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + <max_actions>1</max_actions> + <sum_visit_length>1080</sum_visit_length> + <bounce_count>1</bounce_count> + <nb_visits_converted>1</nb_visits_converted> + <goals> + <row idgoal='1'> + <nb_conversions>1</nb_conversions> + <nb_visits_converted>1</nb_visits_converted> + <revenue>42.2560005188</revenue> + </row> + </goals> + <nb_conversions>1</nb_conversions> + <revenue>42.2560005188</revenue> + </row> + </subtable> + </row> +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics__VisitsSummary.get_day.xml b/tests/integration/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__VisitsSummary.get_day.xml similarity index 100% rename from tests/integration/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics__VisitsSummary.get_day.xml rename to tests/integration/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__VisitsSummary.get_day.xml