From b686ab1a8bfaf8ef6262cd2b9df0b26c2861c668 Mon Sep 17 00:00:00 2001
From: diosmosis <benaka@piwik.pro>
Date: Wed, 9 Sep 2015 16:00:40 -0700
Subject: [PATCH] Refs #8630, when detecing campaign info in Referrers check
 _rcn and _rck query parameters.

---
 plugins/Referrers/Columns/Base.php            | 44 +++++++++--
 ...sCustomVariablesCampaignsNotHeuristics.php | 27 +++++++
 ...ignsForceUsingVisitIdNotHeuristicsTest.php |  3 +
 ...gnTracking__Referrers.getCampaigns_day.xml | 77 ++++++++++++++++++-
 ...ampaignTracking__VisitsSummary.get_day.xml | 16 ++--
 5 files changed, 147 insertions(+), 20 deletions(-)

diff --git a/plugins/Referrers/Columns/Base.php b/plugins/Referrers/Columns/Base.php
index ab6090e78e..78fe27516c 100644
--- a/plugins/Referrers/Columns/Base.php
+++ b/plugins/Referrers/Columns/Base.php
@@ -66,7 +66,7 @@ abstract class Base extends VisitDimension
      * @param int $idSite
      * @return array
      */
-    protected function getReferrerInformation($referrerUrl, $currentUrl, $idSite)
+    protected function getReferrerInformation($referrerUrl, $currentUrl, $idSite, Request $request)
     {
         $cacheKey = $referrerUrl . $currentUrl . $idSite;
 
@@ -98,7 +98,7 @@ abstract class Base extends VisitDimension
             $this->referrerHost = $this->referrerUrlParse['host'];
         }
 
-        $referrerDetected = $this->detectReferrerCampaign();
+        $referrerDetected = $this->detectReferrerCampaign($request);
 
         if (!$referrerDetected) {
             if ($this->detectReferrerDirectEntry()
@@ -130,7 +130,7 @@ abstract class Base extends VisitDimension
         $referrerUrl = $request->getParam('urlref');
         $currentUrl  = $request->getParam('url');
 
-        return $this->getReferrerInformation($referrerUrl, $currentUrl, $request->getIdSite());
+        return $this->getReferrerInformation($referrerUrl, $currentUrl, $request->getIdSite(), $request);
     }
 
     /**
@@ -222,6 +222,25 @@ abstract class Base extends VisitDimension
         }
     }
 
+
+    protected function detectReferrerCampaignFromTrackerParams(Request $request)
+    {
+        $campaignName = $this->getReferrerCampaignQueryParam($request, '_rcn');
+        if (empty($campaignName)) {
+            return false;
+        }
+
+        $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_CAMPAIGN;
+        $this->nameReferrerAnalyzed = $campaignName;
+
+        $keyword = $this->getReferrerCampaignQueryParam($request, '_rck');
+        if (!empty($keyword)) {
+            $this->keywordReferrerAnalyzed = $keyword;
+        }
+
+        return true;
+    }
+
     /**
      * We have previously tried to detect the campaign variables in the URL
      * so at this stage, if the referrer host is the current host,
@@ -301,9 +320,13 @@ abstract class Base extends VisitDimension
     /**
      * @return bool
      */
-    protected function detectReferrerCampaign()
+    protected function detectReferrerCampaign(Request $request)
     {
-        $this->detectReferrerCampaignFromLandingUrl();
+        $isCampaign = $this->detectReferrerCampaignFromTrackerParams($request);
+        if (!$isCampaign) {
+            $this->detectReferrerCampaignFromLandingUrl();
+        }
+
         $this->detectCampaignKeywordFromReferrerUrl();
 
         if ($this->typeReferrerAnalyzed != Common::REFERRER_TYPE_CAMPAIGN) {
@@ -329,8 +352,8 @@ abstract class Base extends VisitDimension
     {
         $referrerTimestamp       = $request->getParam('_refts');
         $referrerUrl             = $request->getParam('_ref');
-        $referrerCampaignName    = trim(urldecode($request->getParam('_rcn')));
-        $referrerCampaignKeyword = trim(urldecode($request->getParam('_rck')));
+        $referrerCampaignName    = $this->getReferrerCampaignQueryParam($request, '_rcn');
+        $referrerCampaignKeyword = $this->getReferrerCampaignQueryParam($request, '_rck');
 
         // Attributing the correct Referrer to this conversion.
         // Priority order is as follows:
@@ -365,7 +388,7 @@ abstract class Base extends VisitDimension
         elseif (!empty($referrerUrl)) {
 
             $idSite   = $request->getIdSite();
-            $referrer = $this->getReferrerInformation($referrerUrl, $currentUrl = '', $idSite);
+            $referrer = $this->getReferrerInformation($referrerUrl, $currentUrl = '', $idSite, $request);
 
             // if the parsed referrer is interesting enough, ie. website or search engine
             if (in_array($referrer['referer_type'], array(Common::REFERRER_TYPE_SEARCH_ENGINE, Common::REFERRER_TYPE_WEBSITE))) {
@@ -432,4 +455,9 @@ abstract class Base extends VisitDimension
     {
         return $visitor->getVisitorColumn('referer_type') == $referrerType;
     }
+
+    protected function getReferrerCampaignQueryParam(Request $request, $paramName)
+    {
+        return trim(urldecode($request->getParam($paramName)));
+    }
 }
diff --git a/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php b/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php
index 5c3dcc553e..8ba755fabd 100644
--- a/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php
+++ b/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php
@@ -51,6 +51,10 @@ class SomeVisitsCustomVariablesCampaignsNotHeuristics extends Fixture
         if (!self::goalExists($idSite = 1, $idGoal = 1)) {
             API::getInstance()->addGoal($this->idSite, 'triggered js', 'manually', '', '');
         }
+
+        if (!self::goalExists($idSite = 1, $idGoal = 2)) {
+            API::getInstance()->addGoal($this->idSite, 'view act', 'url', 'http://mutantregistration.com/act.html', 'exact');
+        }
     }
 
     private function trackVisits()
@@ -177,6 +181,29 @@ class SomeVisitsCustomVariablesCampaignsNotHeuristics extends Fixture
         $t4->setUrlReferrer('http://mutantregistration.com');
         $t4->setUrl('http://example.org/index.html');
         self::checkResponse($t4->doTrackPageView('העלא וועלט'));
+
+        // test campaigns that are specified through _rcn
+        $t5 = self::getTracker($idSite, $dateTime);
+        $t5->setUrlReferrer('http://xavierinstitute.org');
+        $t5->setUrl('http://mutantregistration.com/act.html');
+        $t5->setAttributionInfo(json_encode(array('Gifted Search'))); // rcn supplied, nothing else
+        self::checkResponse($t5->doTrackPageView('Mutant Registration'));
+
+        $t5->setForceVisitDateTime(Date::factory($dateTime)->addHour(1)->getDatetime());
+        $t5->setUrlReferrer('http://mutantrights.org');
+        $t5->setUrl('http://asteroidm.com');
+        // all params suppplied, one that differs from url referrer
+        $t5->setAttributionInfo(json_encode(array('Recruiting Drive', 'am i a mutant?',
+            Date::factory($dateTime)->addHour(1)->getDatetime(), 'http://sentinelwatch.org')));
+        self::checkResponse($t5->doTrackPageView('Fighting Back'));
+
+        $t5->setForceVisitDateTime(Date::factory($dateTime)->addHour(2)->getDatetime());
+        $t5->setUrlReferrer('http://apocalypsenow.org');
+        $t5->setUrl('http://mutantrights.org');
+        // params supplied, for existing campaign
+        $t5->setAttributionInfo(json_encode(array('GA Campaign', 'some keyword',
+            Date::factory($dateTime)->addHour(2)->getDatetime())));
+        self::checkResponse($t5->doTrackPageView('Mutant Registration'));
     }
 
     // see updateDomainHash() in piwik.js
diff --git a/tests/PHPUnit/System/TrackCustomVariablesAndCampaignsForceUsingVisitIdNotHeuristicsTest.php b/tests/PHPUnit/System/TrackCustomVariablesAndCampaignsForceUsingVisitIdNotHeuristicsTest.php
index 2a08882e8d..27d19c09cc 100755
--- a/tests/PHPUnit/System/TrackCustomVariablesAndCampaignsForceUsingVisitIdNotHeuristicsTest.php
+++ b/tests/PHPUnit/System/TrackCustomVariablesAndCampaignsForceUsingVisitIdNotHeuristicsTest.php
@@ -19,6 +19,9 @@ use Piwik\Tests\Fixtures\SomeVisitsCustomVariablesCampaignsNotHeuristics;
  */
 class TrackCustomVariablesAndCampaignsForceUsingVisitIdNotHeuristicsTest extends SystemTestCase
 {
+    /**
+     * @var SomeVisitsCustomVariablesCampaignsNotHeuristics
+     */
     public static $fixture = null; // initialized below class definition
 
     /**
diff --git a/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__Referrers.getCampaigns_day.xml b/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__Referrers.getCampaigns_day.xml
index 981347b803..d774bbe438 100644
--- a/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__Referrers.getCampaigns_day.xml
+++ b/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__Referrers.getCampaigns_day.xml
@@ -2,13 +2,13 @@
 <result>
 	<row>
 		<label>ga campaign</label>
-		<nb_uniq_visitors>4</nb_uniq_visitors>
-		<nb_visits>4</nb_visits>
-		<nb_actions>4</nb_actions>
+		<nb_uniq_visitors>5</nb_uniq_visitors>
+		<nb_visits>5</nb_visits>
+		<nb_actions>5</nb_actions>
 		<nb_users>0</nb_users>
 		<max_actions>1</max_actions>
 		<sum_visit_length>1084</sum_visit_length>
-		<bounce_count>4</bounce_count>
+		<bounce_count>5</bounce_count>
 		<goals>
 			<row idgoal='1'>
 				<nb_conversions>1</nb_conversions>
@@ -39,6 +39,17 @@
 				<nb_conversions>1</nb_conversions>
 				<revenue>42.26</revenue>
 			</row>
+			<row>
+				<label>some keyword</label>
+				<nb_uniq_visitors>1</nb_uniq_visitors>
+				<nb_visits>1</nb_visits>
+				<nb_actions>1</nb_actions>
+				<nb_users>0</nb_users>
+				<max_actions>1</max_actions>
+				<sum_visit_length>0</sum_visit_length>
+				<bounce_count>1</bounce_count>
+				<nb_visits_converted>0</nb_visits_converted>
+			</row>
 			<row>
 				<label>thing1.com</label>
 				<nb_uniq_visitors>1</nb_uniq_visitors>
@@ -231,4 +242,62 @@
 			</row>
 		</subtable>
 	</row>
+	<row>
+		<label>gifted search</label>
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<nb_actions>1</nb_actions>
+		<nb_users>0</nb_users>
+		<max_actions>1</max_actions>
+		<sum_visit_length>1</sum_visit_length>
+		<bounce_count>1</bounce_count>
+		<goals>
+			<row idgoal='2'>
+				<nb_conversions>1</nb_conversions>
+				<nb_visits_converted>1</nb_visits_converted>
+				<revenue>0</revenue>
+			</row>
+		</goals>
+		<nb_conversions>1</nb_conversions>
+		<revenue>0</revenue>
+		<segment>referrerType==campaign;referrerName==gifted+search</segment>
+		<subtable>
+			<row>
+				<label>xavierinstitute.org</label>
+				<nb_uniq_visitors>1</nb_uniq_visitors>
+				<nb_visits>1</nb_visits>
+				<nb_actions>1</nb_actions>
+				<nb_users>0</nb_users>
+				<max_actions>1</max_actions>
+				<sum_visit_length>1</sum_visit_length>
+				<bounce_count>1</bounce_count>
+				<nb_visits_converted>1</nb_visits_converted>
+			</row>
+		</subtable>
+	</row>
+	<row>
+		<label>recruiting drive</label>
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<nb_actions>1</nb_actions>
+		<nb_users>0</nb_users>
+		<max_actions>1</max_actions>
+		<sum_visit_length>0</sum_visit_length>
+		<bounce_count>1</bounce_count>
+		<nb_visits_converted>0</nb_visits_converted>
+		<segment>referrerType==campaign;referrerName==recruiting+drive</segment>
+		<subtable>
+			<row>
+				<label>am i a mutant?</label>
+				<nb_uniq_visitors>1</nb_uniq_visitors>
+				<nb_visits>1</nb_visits>
+				<nb_actions>1</nb_actions>
+				<nb_users>0</nb_users>
+				<max_actions>1</max_actions>
+				<sum_visit_length>0</sum_visit_length>
+				<bounce_count>1</bounce_count>
+				<nb_visits_converted>0</nb_visits_converted>
+			</row>
+		</subtable>
+	</row>
 </result>
\ No newline at end of file
diff --git a/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__VisitsSummary.get_day.xml b/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__VisitsSummary.get_day.xml
index 3e911d8174..34d6d3b5a0 100644
--- a/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/System/expected/test_PiwikTracker_trackForceUsingVisitId_insteadOfHeuristics_alsoTestsCampaignTracking__VisitsSummary.get_day.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <result>
-	<nb_uniq_visitors>3</nb_uniq_visitors>
+	<nb_uniq_visitors>4</nb_uniq_visitors>
 	<nb_users>0</nb_users>
-	<nb_visits>15</nb_visits>
-	<nb_actions>14</nb_actions>
-	<nb_visits_converted>3</nb_visits_converted>
-	<bounce_count>14</bounce_count>
-	<sum_visit_length>1448</sum_visit_length>
+	<nb_visits>18</nb_visits>
+	<nb_actions>17</nb_actions>
+	<nb_visits_converted>4</nb_visits_converted>
+	<bounce_count>17</bounce_count>
+	<sum_visit_length>1449</sum_visit_length>
 	<max_actions>2</max_actions>
-	<bounce_rate>93%</bounce_rate>
+	<bounce_rate>94%</bounce_rate>
 	<nb_actions_per_visit>0.9</nb_actions_per_visit>
-	<avg_time_on_site>97</avg_time_on_site>
+	<avg_time_on_site>81</avg_time_on_site>
 </result>
\ No newline at end of file
-- 
GitLab