diff options
-rw-r--r-- | js/piwik.js | 2 | ||||
-rw-r--r-- | libs/PiwikTracker/PiwikTracker.php | 96 | ||||
-rw-r--r-- | plugins/Contents/Archiver.php | 6 | ||||
-rw-r--r-- | tests/javascript/index.php | 25 |
4 files changed, 128 insertions, 1 deletions
diff --git a/js/piwik.js b/js/piwik.js index d230e07914..85ab872342 100644 --- a/js/piwik.js +++ b/js/piwik.js @@ -3333,7 +3333,7 @@ if (typeof Piwik !== 'object') { var linkParams = linkType + '=' + encodeWrapper(purify(url)); - var interaction = getContentInteractionToRequestIfPossible(linkParams, sourceElement, 'click', url); + var interaction = getContentInteractionToRequestIfPossible(sourceElement, 'click', url); if (interaction) { linkParams += '&' + interaction; diff --git a/libs/PiwikTracker/PiwikTracker.php b/libs/PiwikTracker/PiwikTracker.php index 3afc2db93a..e251e309f7 100644 --- a/libs/PiwikTracker/PiwikTracker.php +++ b/libs/PiwikTracker/PiwikTracker.php @@ -552,6 +552,36 @@ class PiwikTracker } /** + * Tracks a content impression + * + * @param string $contentName The name of the content. For instance 'Ad Foo Bar' + * @param string $contentPiece The actual content. For instance the path to an image, video, audio, any text + * @param string|false $contentTarget (optional) The target of the content. For instance the URL of a landing page. + * @return mixed Response string or true if using bulk requests. + */ + public function doTrackContentImpression($contentName, $contentPiece = 'Unknown', $contentTarget = false) + { + $url = $this->getUrlTrackContentImpression($contentName, $contentPiece, $contentTarget); + return $this->sendRequest($url); + } + + /** + * Tracks a content interaction. Make sure you have tracked a content impression using the same content name and + * content piece, otherwise it will not count. To do so you should call the method doTrackContentImpression(); + * + * @param string $interaction The name of the interaction with the content. For instance a 'click' + * @param string $contentName The name of the content. For instance 'Ad Foo Bar' + * @param string $contentPiece The actual content. For instance the path to an image, video, audio, any text + * @param string|false $contentTarget (optional) The target the content leading to when an interaction occurs. For instance the URL of a landing page. + * @return mixed Response string or true if using bulk requests. + */ + public function doTrackContentInteraction($interaction, $contentName, $contentPiece = 'Unknown', $contentTarget = false) + { + $url = $this->getUrlTrackContentInteraction($interaction, $contentName, $contentPiece, $contentTarget); + return $this->sendRequest($url); + } + + /** * Tracks an internal Site Search query, and optionally tracks the Search Category, and Search results Count. * These are used to populate reports in Actions > Site Search. * @@ -850,6 +880,72 @@ class PiwikTracker } /** + * Builds URL to track a content impression. + * + * @see doTrackContentImpression() + * @param string $contentName The name of the content. For instance 'Ad Foo Bar' + * @param string $contentPiece The actual content. For instance the path to an image, video, audio, any text + * @param string|false $contentTarget (optional) The target of the content. For instance the URL of a landing page. + * @throws Exception In case $contentName is empty + * @return string URL to piwik.php with all parameters set to track the pageview + */ + public function getUrlTrackContentImpression($contentName, $contentPiece, $contentTarget) + { + $url = $this->getRequest($this->idSite); + + if (strlen($contentName) == 0) { + throw new Exception("You must specify a content name"); + } + + $url .= 'c_n=' . urlencode($contentName); + + if (!empty($contentPiece) && strlen($contentPiece) > 0) { + $url .= '&c_p=' . urlencode($contentPiece); + } + if (!empty($contentTarget) && strlen($contentTarget) > 0) { + $url .= '&c_t=' . urlencode($contentTarget); + } + + return $url; + } + + /** + * Builds URL to track a content impression. + * + * @see doTrackContentInteraction() + * @param string $interaction The name of the interaction with the content. For instance a 'click' + * @param string $contentName The name of the content. For instance 'Ad Foo Bar' + * @param string $contentPiece The actual content. For instance the path to an image, video, audio, any text + * @param string|false $contentTarget (optional) The target the content leading to when an interaction occurs. For instance the URL of a landing page. + * @throws Exception In case $interaction or $contentName is empty + * @return string URL to piwik.php with all parameters set to track the pageview + */ + public function getUrlTrackContentInteraction($interaction, $contentName, $contentPiece, $contentTarget) + { + $url = $this->getRequest($this->idSite); + + if (strlen($interaction) == 0) { + throw new Exception("You must specify a name for the interaction"); + } + + if (strlen($contentName) == 0) { + throw new Exception("You must specify a content name"); + } + + $url .= 'c_i=' . urlencode($interaction); + $url .= 'c_n=' . urlencode($contentName); + + if (!empty($contentPiece) && strlen($contentPiece) > 0) { + $url .= '&c_p=' . urlencode($contentPiece); + } + if (!empty($contentTarget) && strlen($contentTarget) > 0) { + $url .= '&c_t=' . urlencode($contentTarget); + } + + return $url; + } + + /** * Builds URL to track a site search. * * @see doTrackSiteSearch() diff --git a/plugins/Contents/Archiver.php b/plugins/Contents/Archiver.php index debac613a9..55668b4c3a 100644 --- a/plugins/Contents/Archiver.php +++ b/plugins/Contents/Archiver.php @@ -265,6 +265,12 @@ class Archiver extends \Piwik\Plugin\Archiver continue; } + // content piece is optional + if ($subDimension == 'contentPiece' + && empty($subLabel)) { + $subLabel = self::CONTENT_PIECE_NOT_SET; + } + $dataArray->sumMetricsContentsImpressionPivot($mainLabel, $subLabel, $row); } } diff --git a/tests/javascript/index.php b/tests/javascript/index.php index 698ce3fec5..418150fc94 100644 --- a/tests/javascript/index.php +++ b/tests/javascript/index.php @@ -61,6 +61,14 @@ testTrackPageViewAsync(); height: 1px; width: 1px; } + .hideY { + overflow-x: hidden !important; + } + .ie #contenttest { + position: relative; + margin-left: 8px; + margin-right: 8px; + } </style> <script src="../../libs/jquery/jquery.js" type="text/javascript"></script> <script src="assets/qunit.js" type="text/javascript"></script> @@ -75,6 +83,10 @@ function _e(id){ if (document.all) return document.all[id]; } + function isIE () { + var myNav = navigator.userAgent.toLowerCase(); + return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false; + } function _s(selector) { // select node within content test scope $nodes = $('#contenttest ' + selector); @@ -287,6 +299,19 @@ function setupContentTrackingFixture(name, targetNode) { <div id="main" style="display:none;"></div> <script> + + if (isIE) { + (function () { + // otherwise because of position:absolute some nodes will be visible but should not... it will show scroll bars in IE + function fixWidthNode(tagName){ + var node = document.getElementsByTagName(tagName)[0]; + node.className = node.className + ' hideY ie'; + } + fixWidthNode('html'); + fixWidthNode('body'); + })(); + } + var hasLoaded = false; function PiwikTest() { hasLoaded = true; |