diff --git a/core/API/DocumentationGenerator.php b/core/API/DocumentationGenerator.php index 6ed73e1f7a93b9e134d567130f19588e7855dff2..fb26a886e5f067cecfdaa48ec257cc2cdd0ed7e8 100644 --- a/core/API/DocumentationGenerator.php +++ b/core/API/DocumentationGenerator.php @@ -192,15 +192,15 @@ class Piwik_API_DocumentationGenerator $aParameters['flat'] = false; $aParameters['include_aggregate_rows'] = false; $aParameters['filter_truncate'] = false; - + $moduleName = Piwik_API_Proxy::getInstance()->getModuleNameFromClassName($class); - $urlExample = '?module=API&method='.$moduleName.'.'.$methodName.'&'; - foreach($aParameters as $nameVariable=> $defaultValue) + $aParameters = array_merge(array('module' => 'API', 'method' => $moduleName.'.'.$methodName), $aParameters); + + foreach($aParameters as $nameVariable => &$defaultValue) { if(isset($knowExampleDefaultParametersValues[$nameVariable])) { - $exampleValue = $knowExampleDefaultParametersValues[$nameVariable]; - $urlExample .= $nameVariable . '=' . $exampleValue . '&'; + $defaultValue = $knowExampleDefaultParametersValues[$nameVariable]; } // if there isn't a default value for a given parameter, // we need a 'know default value' or we can't generate the link @@ -209,7 +209,7 @@ class Piwik_API_DocumentationGenerator return false; } } - return substr($urlExample,0,-1); + return '?'.Piwik_Url::getQueryStringFromParameters($aParameters); } diff --git a/core/DataTable/Renderer/Xml.php b/core/DataTable/Renderer/Xml.php index 01e127a11c123d73bd277b755d47ce28003fe2f0..74bb78be41e90859cb8e31f3b83632a12cafa91e 100644 --- a/core/DataTable/Renderer/Xml.php +++ b/core/DataTable/Renderer/Xml.php @@ -323,7 +323,7 @@ class Piwik_DataTable_Renderer_Xml extends Piwik_DataTable_Renderer if(count($row) === 1 && key($row) === 0) { - $value = current($row); + $value = self::formatValueXml(current($row)); $out .= $prefixLine . $value; } else diff --git a/core/Tracker.php b/core/Tracker.php index 19f4c66920607393e03d0db1fe5b24b46d21cfd3..7e76a2362a4527dc69b7c2392f7ce41d1d77d345 100644 --- a/core/Tracker.php +++ b/core/Tracker.php @@ -47,11 +47,61 @@ class Piwik_Tracker static protected $forcedVisitorId = null; static protected $pluginsNotToLoad = array(); + + /** + * The set of visits to track. + * + * @var array + */ + private $requests = array(); + + /** + * The token auth supplied with a bulk visits POST. + * + * @var string + */ + private $tokenAuth = null; public function __construct($args = null) { - $this->request = $args ? $args : $_GET + $_POST; + if (!empty($args) || !empty($_GET) || !empty($_POST)) + { + $this->requests = $args ? $args : array($_GET + $_POST); + } + else + { + // doing bulk tracking. POST data can be array of string URLs or array of arrays w/ visit info + $rawData = file_get_contents("php://input"); + $jsonData = Piwik_Common::json_decode($rawData, $assoc = true); + + if (isset($jsonData['requests'])) + { + $this->requests = $jsonData['requests']; + } + + $this->tokenAuth = Piwik_Common::getRequestVar('token_auth', false, null, $jsonData); + + if (!empty($this->requests)) + { + foreach ($this->requests as &$request) + { + // if a string is sent, we assume its a URL and try to parse it + if (is_string($request)) + { + $params = array(); + + $url = @parse_url($request); + if (!empty($url)) + { + @parse_str($url['query'], $params); + $request = $params; + } + } + } + } + } } + public static function setForceIp($ipString) { self::$forcedIpString = $ipString; @@ -99,19 +149,40 @@ class Piwik_Tracker */ public function main() { - $this->init(); - - try { - if( $this->isVisitValid() ) + if (!empty($this->requests)) + { + // handle all visits + foreach ($this->requests as $request) { - self::connectDatabase(); - - $visit = $this->getNewVisitObject(); - $visit->setRequest($this->request); - $visit->handle(); - unset($visit); + $this->init($request); + + try + { + if ($this->isVisitValid()) + { + self::connectDatabaseIfNotConnected(); + + $visit = $this->getNewVisitObject(); + $visit->setRequest($request); + $visit->handle(); + unset($visit); + } + } catch (Piwik_Tracker_Db_Exception $e) { + printDebug("<b>".$e->getMessage()."</b>"); + } catch(Piwik_Tracker_Visit_Excluded $e) { + } catch(Exception $e) { + Piwik_Tracker_ExitWithException($e); + } } - + } + else + { + $this->handleEmptyRequest($_GET + $_POST); + } + + // run scheduled task + try + { // don't run scheduled tasks in CLI mode from Tracker, this is the case // where we bulk load logs & don't want to lose time with tasks if(!Piwik_Common::isPhpCliMode() @@ -119,13 +190,12 @@ class Piwik_Tracker { Piwik_Common::runScheduledTasks($now = $this->getCurrentTimestamp()); } - } catch (Piwik_Tracker_Db_Exception $e) { - printDebug("<b>".$e->getMessage()."</b>"); - } catch(Piwik_Tracker_Visit_Excluded $e) { - } catch(Exception $e) { + } + catch (Exception $e) + { Piwik_Tracker_ExitWithException($e); } - + $this->end(); } @@ -143,12 +213,12 @@ class Piwik_Tracker /** * Initialization */ - protected function init() + protected function init( $request ) { - $this->handleTrackingApi(); - $this->loadTrackerPlugins(); + $this->handleTrackingApi($request); + $this->loadTrackerPlugins($request); $this->handleDisabledTracker(); - $this->handleEmptyRequest(); + $this->handleEmptyRequest($request); printDebug("Current datetime: ".date("Y-m-d H:i:s", $this->getCurrentTimestamp())); } @@ -232,7 +302,7 @@ class Piwik_Tracker return $db; } - public static function connectDatabase() + public static function connectDatabaseIfNotConnected() { if( !is_null(self::$db)) { @@ -321,11 +391,11 @@ class Piwik_Tracker $this->stateValid = $value; } - protected function loadTrackerPlugins() + protected function loadTrackerPlugins( $request ) { // Adding &dp=1 will disable the provider plugin, if token_auth is used (used to speed up bulk imports) - if(isset($this->request['dp']) - && !empty($this->request['dp']) + if(isset($request['dp']) + && !empty($request['dp']) && $this->authenticated) { Piwik_Tracker::setPluginsNotToLoad(array('Provider')); @@ -347,9 +417,9 @@ class Piwik_Tracker } } - protected function handleEmptyRequest() + protected function handleEmptyRequest( $request ) { - $countParameters = count($this->request); + $countParameters = count($request); if($countParameters == 0) { $this->setState(self::STATE_EMPTY_REQUEST); @@ -369,9 +439,9 @@ class Piwik_Tracker } } - protected function authenticateSuperUserOrAdmin() + protected function authenticateSuperUserOrAdmin( $request ) { - $tokenAuth = Piwik_Common::getRequestVar('token_auth', false); + $tokenAuth = $this->getTokenAuth(); if( $tokenAuth ) { @@ -384,7 +454,7 @@ class Piwik_Tracker } // Now checking the list of admin token_auth cached in the Tracker config file - $idSite = Piwik_Common::getRequestVar('idsite', false, 'int', $this->request); + $idSite = Piwik_Common::getRequestVar('idsite', false, 'int', $request); if(!empty($idSite) && $idSite > 0) { @@ -400,17 +470,27 @@ class Piwik_Tracker } return false; } + + protected function getTokenAuth() + { + if (!is_null($this->tokenAuth)) + { + return $this->tokenAuth; + } + + return Piwik_Common::getRequestVar('token_auth', false); + } /** * This method allows to set custom IP + server time when using Tracking API. * These two attributes can be only set by the Super User (passing token_auth). */ - protected function handleTrackingApi() + protected function handleTrackingApi( $request ) { $shouldAuthenticate = Piwik_Config::getInstance()->Tracker['tracking_requests_require_authentication']; if($shouldAuthenticate) { - if(!$this->authenticateSuperUserOrAdmin()) + if(!$this->authenticateSuperUserOrAdmin($request)) { return; } @@ -422,21 +502,21 @@ class Piwik_Tracker } // Custom IP to use for this visitor - $customIp = Piwik_Common::getRequestVar('cip', false, 'string', $this->request); + $customIp = Piwik_Common::getRequestVar('cip', false, 'string', $request); if(!empty($customIp)) { $this->setForceIp($customIp); } // Custom server date time to use - $customDatetime = Piwik_Common::getRequestVar('cdt', false, 'string', $this->request); + $customDatetime = Piwik_Common::getRequestVar('cdt', false, 'string', $request); if(!empty($customDatetime)) { $this->setForceDateTime($customDatetime); } // Forced Visitor ID to record the visit / action - $customVisitorId = Piwik_Common::getRequestVar('cid', false, 'string', $this->request); + $customVisitorId = Piwik_Common::getRequestVar('cid', false, 'string', $request); if(!empty($customVisitorId)) { $this->setForceVisitorId($customVisitorId); diff --git a/libs/PiwikTracker/PiwikTracker.php b/libs/PiwikTracker/PiwikTracker.php index 445fac2700c23546111d492b6f47b3cd14f9c6ea..b516623fe2375cc1844e3171cb915d6da411b8c9 100644 --- a/libs/PiwikTracker/PiwikTracker.php +++ b/libs/PiwikTracker/PiwikTracker.php @@ -93,6 +93,8 @@ class PiwikTracker // Allow debug while blocking the request $this->requestTimeout = 600; + $this->doBulkRequests = false; + $this->storedTrackingActions = array(); } /** @@ -244,12 +246,20 @@ class PiwikTracker $this->userAgent = $userAgent; } - + /** + * Enables the bulk request feature. When used, each tracking action is stored until the + * doBulkTrack method is called. This method will send all tracking data at once. + */ + public function enableBulkTracking() + { + $this->doBulkRequests = true; + } + /** * Tracks a page view * * @param string $documentTitle Page title as it will appear in the Actions > Page titles report - * @return string Response + * @return string|true Response or true if using bulk requests. */ public function doTrackPageView( $documentTitle ) { @@ -262,7 +272,7 @@ class PiwikTracker * * @param int $idGoal Id Goal to record a conversion * @param float $revenue Revenue for this conversion - * @return string Response + * @return string|true Response or true if using bulk request */ public function doTrackGoal($idGoal, $revenue = false) { @@ -275,7 +285,7 @@ class PiwikTracker * * @param string $actionUrl URL of the download or outlink * @param string $actionType Type of the action: 'download' or 'link' - * @return string Response + * @return string|true Response or true if using bulk request */ public function doTrackAction($actionUrl, $actionType) { @@ -322,6 +332,34 @@ class PiwikTracker return $this->sendRequest($url); } + /** + * Sends all stored tracking actions at once. Only has an effect if bulk tracking is enabled. + * + * To enable bulk tracking, call enableBulkTracking(). + * + * @return string Response + */ + public function doBulkTrack() + { + if (empty($this->storedTrackingActions)) + { + return ''; + } + + $data = array('requests' => $this->storedTrackingActions); + if (!empty($this->token_auth)) + { + $data['token_auth'] = $this->token_auth; + } + + $postData = json_encode($data); + $response = $this->sendRequest($this->getBaseUrl(), 'POST', $postData, $force = true); + + $this->storedTrackingActions = array(); + + return $response; + } + /** * Tracks an Ecommerce order. * @@ -337,6 +375,7 @@ class PiwikTracker * @param float $tax (optional) Tax amount for this order * @param float $shipping (optional) Shipping amount for this order * @param float $discount (optional) Discounted amount in this order + * @return string|true Response or true if using bulk request */ public function doTrackEcommerceOrder($orderId, $grandTotal, $subTotal = false, $tax = false, $shipping = false, $discount = false) { @@ -735,8 +774,15 @@ class PiwikTracker /** * @ignore */ - protected function sendRequest($url) + protected function sendRequest( $url, $method = 'GET', $data = null, $force = false ) { + // if doing a bulk request, store the url + if ($this->doBulkRequests && !$force) + { + $this->storedTrackingActions[] = $url; + return true; + } + $response = ''; if(!$this->cookieSupport) @@ -745,8 +791,7 @@ class PiwikTracker } if(function_exists('curl_init')) { - $ch = curl_init(); - curl_setopt_array($ch, array( + $options = array( CURLOPT_URL => $url, CURLOPT_USERAGENT => $this->userAgent, CURLOPT_HEADER => true, @@ -755,8 +800,27 @@ class PiwikTracker CURLOPT_HTTPHEADER => array( 'Accept-Language: ' . $this->acceptLanguage, 'Cookie: '. $this->requestCookie, - ), - )); + )); + + switch ($method) + { + case 'POST': + $options[CURLOPT_POST] = TRUE; + break; + default: + break; + } + + // only supports JSON data + if (!empty($data)) + { + $options[CURLOPT_HTTPHEADER][] = 'Content-Type: application/json'; + $options[CURLOPT_HTTPHEADER][] = 'Expect:'; + $options[CURLOPT_POSTFIELDS] = $data; + } + + $ch = curl_init(); + curl_setopt_array($ch, $options); ob_start(); $response = @curl_exec($ch); ob_end_clean(); @@ -770,12 +834,21 @@ class PiwikTracker { $stream_options = array( 'http' => array( + 'method' => $method, 'user_agent' => $this->userAgent, 'header' => "Accept-Language: " . $this->acceptLanguage . "\r\n" . "Cookie: ".$this->requestCookie. "\r\n" , 'timeout' => $this->requestTimeout, // PHP 5.2.1 ) ); + + // only supports JSON data + if (!empty($data)) + { + $stream_options['http']['header'][] = 'Content-Type: application/json'; + $stream_options['http']['content'] = $data; + } + $ctx = stream_context_create($stream_options); $response = file_get_contents($url, 0, $ctx); $header = implode("\r\n", $http_response_header); @@ -816,9 +889,9 @@ class PiwikTracker } /** - * @ignore + * Returns the base URL for the piwik server. */ - protected function getRequest( $idSite ) + protected function getBaseUrl() { if(empty(self::$URL)) { @@ -829,8 +902,15 @@ class PiwikTracker { self::$URL .= '/piwik.php'; } - - $url = self::$URL . + return self::$URL; + } + + /** + * @ignore + */ + protected function getRequest( $idSite ) + { + $url = $this->getBaseUrl() . '?idsite=' . $idSite . '&rec=1' . '&apiv=' . self::VERSION . @@ -844,7 +924,7 @@ class PiwikTracker (!empty($this->ip) ? '&cip=' . $this->ip : '') . (!empty($this->forcedVisitorId) ? '&cid=' . $this->forcedVisitorId : '&_id=' . $this->visitorId) . (!empty($this->forcedDatetime) ? '&cdt=' . urlencode($this->forcedDatetime) : '') . - (!empty($this->token_auth) ? '&token_auth=' . urlencode($this->token_auth) : '') . + ((!empty($this->token_auth) && !$this->doBulkRequests) ? '&token_auth=' . urlencode($this->token_auth) : '') . // These parameters are set by the JS, but optional when using API (!empty($this->plugins) ? $this->plugins : '') . diff --git a/plugins/API/API.php b/plugins/API/API.php index 76e56137a18e88d7c66a657385ae44cc6d5a5cb8..03586f6c80a2910c4c23358d98c85dbe50a94cb3 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -1450,4 +1450,26 @@ class Piwik_API_API ); } + /** + * Performs multiple API requests at once and returns every result. + * + * @param array $urls The array of API requests. + */ + public function getBulkRequest( $urls ) + { + if (empty($urls)) + { + return array(); + } + + $urls = Piwik_Common::unsanitizeInputValues($urls); + + $result = array(); + foreach ($urls as $url) + { + $req = new Piwik_API_Request($url); + $result[] = $req->process(); + } + return $result; + } } diff --git a/tests/integration/EcommerceOrderWithItems.test.php b/tests/integration/EcommerceOrderWithItems.test.php index d1240e59df9d779ab061e1d2d5192d8c5a68e2bc..90b3171867bdf8f84ab95ffb0290429dd896c56d 100755 --- a/tests/integration/EcommerceOrderWithItems.test.php +++ b/tests/integration/EcommerceOrderWithItems.test.php @@ -130,7 +130,7 @@ class Test_Piwik_Integration_EcommerceOrderWithItems extends Test_Integration_Fa // test segment pageTitle array('VisitsSummary.get', array('idSite' => $this->idSite, 'date' => $this->dateTime, - 'periods' => array('day'), 'segment' => 'pageTitle==incredible%20title!', + 'periods' => array('day'), 'segment' => 'pageTitle==incredible title!', 'testSuffix' => '_SegmentPageTitleMatch')), // test Live! output is OK also for the visit that just bought something (other visits leave an abandoned cart) diff --git a/tests/integration/Integration.php b/tests/integration/Integration.php index d041dceaeb2e23ef0da3e2bc570cd3fa0ed4c3cc..f24a5358ce2f189f3eb3c1d672e57865a61e0987 100644 --- a/tests/integration/Integration.php +++ b/tests/integration/Integration.php @@ -532,10 +532,10 @@ abstract class Test_Integration extends Test_Database_Base // Used in Actions.getPageUrl, .getDownload, etc. // tied to Main.test.php doTest_oneVisitorTwoVisits // will need refactoring when these same API functions are tested in a new function - 'downloadUrl' => urlencode('http://piwik.org/path/again/latest.zip?phpsessid=this is ignored when searching'), - 'outlinkUrl' => urlencode('http://dev.piwik.org/svn'), - 'pageUrl' => urlencode('http://example.org/index.htm?sessionid=this is also ignored by default'), - 'pageName' => urlencode(' Checkout / Purchasing... '), + 'downloadUrl' => 'http://piwik.org/path/again/latest.zip?phpsessid=this is ignored when searching', + 'outlinkUrl' => 'http://dev.piwik.org/svn', + 'pageUrl' => 'http://example.org/index.htm?sessionid=this is also ignored by default', + 'pageName' => ' Checkout / Purchasing... ', // do not show the millisec timer in response or tests would always fail as value is changing 'showTimer' => 0, diff --git a/tests/integration/LabelFilter.test.php b/tests/integration/LabelFilter.test.php index b0b16cbf3071668acdcae47e3b5b75f7d30dfbbe..af487fa27dbe159910240d308741e985f4900979 100644 --- a/tests/integration/LabelFilter.test.php +++ b/tests/integration/LabelFilter.test.php @@ -42,7 +42,7 @@ class Test_Piwik_Integration_LabelFilter extends Test_Integration_Facade 'idSite' => $this->idSite, 'date' => $this->dateTime, 'otherRequestParameters' => array( - 'label' => urlencode($label), + 'label' => $label, 'expanded' => 0 ) )); @@ -55,7 +55,7 @@ class Test_Piwik_Integration_LabelFilter extends Test_Integration_Facade 'date' => $this->dateTime, 'otherRequestParameters' => array( 'date' => '2010-03-06,2010-03-08', - 'label' => urlencode($label), + 'label' => $label, 'expanded' => 0 ) )); @@ -67,7 +67,7 @@ class Test_Piwik_Integration_LabelFilter extends Test_Integration_Facade 'otherRequestParameters' => array( // encode once for test framework and once for the label filter. // note: title has no blank prefixed here. in the report it has. - 'label' => urlencode(urlencode('incredible title! <>,;')), + 'label' => urlencode('incredible title! <>,;'), 'expanded' => 0 ) )); @@ -79,9 +79,9 @@ class Test_Piwik_Integration_LabelFilter extends Test_Integration_Facade 'otherRequestParameters' => array( 'label' => ' '. // test trimming - urlencode(urlencode('incredible parent title! <>,;'). + urlencode('incredible parent title! <>,;'). '>'. - urlencode('subtitle <>,;')), + urlencode('subtitle <>,;'), 'expanded' => 0 ) )); @@ -92,13 +92,13 @@ class Test_Piwik_Integration_LabelFilter extends Test_Integration_Facade 'idSite' => $this->idSite, 'date' => $this->dateTime, 'otherRequestParameters' => array( - 'label' => urlencode('Google>'.urlencode($keyword)), + 'label' => 'Google>'.urlencode($keyword), 'expanded' => 0 ) ); $return[] = array('Referers.getSearchEngines', $searchEngineTest); - $searchEngineTest['otherRequestParameters']['label'] = urlencode('Google>'.urlencode(html_entity_decode($keyword))); + $searchEngineTest['otherRequestParameters']['label'] = 'Google>'.urlencode(html_entity_decode($keyword)); $return[] = array('Referers.getSearchEngines', $searchEngineTest); return $return; diff --git a/tests/integration/OneVisitorTwoVisits.test.php b/tests/integration/OneVisitorTwoVisits.test.php index 30548d9ffc786eb9b43f302367a2d5b51cef2504..952508779050a38ede6e22d04b0e89a8bdc34d47 100755 --- a/tests/integration/OneVisitorTwoVisits.test.php +++ b/tests/integration/OneVisitorTwoVisits.test.php @@ -25,6 +25,12 @@ class Test_Piwik_Integration_OneVisitorTwoVisits extends Test_Integration_Facade public function getApiToTest() { $enExtraParam = array('expanded' => 1, 'flat' => 1, 'include_aggregate_rows' => 0, 'translateColumnNames' => 1); + $bulkUrls = array( + "idSite={$this->idSite}&date=2010-03-06&format=json&expanded=1&period=day&method=VisitsSummary.get", + "idSite={$this->idSite}&date=2010-03-06&format=xml&expanded=1&period=day&method=VisitsSummary.get", + "idSite={$this->idSite}&date=2010-03-06&format=json&expanded=1&period=day&method=" + ."VisitorInterest.getNumberOfVisitsPerVisitDuration" + ); return array( array('all', array('idSite' => $this->idSite, 'date' => $this->dateTime)), @@ -34,6 +40,8 @@ class Test_Piwik_Integration_OneVisitorTwoVisits extends Test_Integration_Facade 'periods' => array('month'), 'setDateLastN' => true, 'otherRequestParameters' => $enExtraParam, 'language' => 'en', 'testSuffix' => '_csv')), + + array('API.getBulkRequest', array('otherRequestParameters' => array('urls' => $bulkUrls))), ); } diff --git a/tests/integration/RowEvolution.test.php b/tests/integration/RowEvolution.test.php index 76b06794319a257512d67a61a5afa5fbabe18fef..9439af41fc856b2de9c65389d56a1df5b441d5ec 100644 --- a/tests/integration/RowEvolution.test.php +++ b/tests/integration/RowEvolution.test.php @@ -27,7 +27,7 @@ class Test_Piwik_Integration_RowEvolution extends Test_Integration_Facade 'period' => 'day', 'apiModule' => 'Referers', 'apiAction' => 'getWebsites', - 'label' => urlencode('www.referrer2.com'), + 'label' => 'www.referrer2.com', 'expanded' => 0 ) ); @@ -37,20 +37,20 @@ class Test_Piwik_Integration_RowEvolution extends Test_Integration_Facade // Websites, hierarchical $config['testSuffix'] = '_referrer2'; $referrerLabel = urlencode('www.referrer0.com').'>'.urlencode('theReferrerPage1.html'); - $config['otherRequestParameters']['label'] = urlencode($referrerLabel); + $config['otherRequestParameters']['label'] = $referrerLabel; $return[] = array('API.getRowEvolution', $config); // Websites, multiple labels including one hierarchical $config['testSuffix'] = '_referrerMulti1'; $referrerLabel = urlencode($referrerLabel).','.urlencode('www.referrer2.com'); - $config['otherRequestParameters']['label'] = urlencode($referrerLabel); + $config['otherRequestParameters']['label'] = $referrerLabel; $return[] = array('API.getRowEvolution', $config); // Keywords, label containing > and , $config['otherRequestParameters']['apiAction'] = 'getKeywords'; $config['testSuffix'] = '_LabelReservedCharacters'; $keywords = urlencode($this->keywords[0]).','.urlencode($this->keywords[1]); - $config['otherRequestParameters']['label'] = urlencode($keywords); + $config['otherRequestParameters']['label'] = $keywords; $return[] = array('API.getRowEvolution', $config); // Keywords, hierarchical @@ -60,7 +60,7 @@ class Test_Piwik_Integration_RowEvolution extends Test_Integration_Facade .',Google>'.urlencode(strtolower($this->keywords[1])) .',Google>'.urlencode(strtolower($this->keywords[2])); // Test multiple labels search engines, Google should also have a 'logo' entry - $config['otherRequestParameters']['label'] = urlencode($keywords) . ",Google"; + $config['otherRequestParameters']['label'] = $keywords . ",Google"; $return[] = array('API.getRowEvolution', $config); // Actions > Pages titles, standard label @@ -68,13 +68,13 @@ class Test_Piwik_Integration_RowEvolution extends Test_Integration_Facade $config['periods'] = array('day', 'week'); $config['otherRequestParameters']['apiModule'] = 'Actions'; $config['otherRequestParameters']['apiAction'] = 'getPageTitles'; - $config['otherRequestParameters']['label'] = urlencode('incredible title 0'); + $config['otherRequestParameters']['label'] = 'incredible title 0'; $return[] = array('API.getRowEvolution', $config); // Actions > Page titles, multiple labels $config['testSuffix'] = '_pageTitlesMulti'; $label = urlencode('incredible title 0').','.urlencode('incredible title 2'); - $config['otherRequestParameters']['label'] = urlencode($label); + $config['otherRequestParameters']['label'] = $label; $return[] = array('API.getRowEvolution', $config); // Actions > Page URLS, hierarchical label @@ -83,7 +83,7 @@ class Test_Piwik_Integration_RowEvolution extends Test_Integration_Facade $config['otherRequestParameters']['date'] = '2010-03-01,2010-03-06'; $config['otherRequestParameters']['apiModule'] = 'Actions'; $config['otherRequestParameters']['apiAction'] = 'getPageUrls'; - $config['otherRequestParameters']['label'] = urlencode('my>dir>'.urlencode('/page3?foo=bar&baz=bar')); + $config['otherRequestParameters']['label'] = 'my>dir>'.urlencode('/page3?foo=bar&baz=bar'); $return[] = array('API.getRowEvolution', $config); return $return; diff --git a/tests/integration/TwoVisitors_TwoWebsites_DifferentDays.test.php b/tests/integration/TwoVisitors_TwoWebsites_DifferentDays.test.php index c698a4381e83335e0050730d996d9c0dc213392b..f6ccbd2305b99af1d61ef79c5509167cc8359479 100755 --- a/tests/integration/TwoVisitors_TwoWebsites_DifferentDays.test.php +++ b/tests/integration/TwoVisitors_TwoWebsites_DifferentDays.test.php @@ -122,10 +122,11 @@ class Test_Piwik_Integration_TwoVisitors_TwoWebsites_DifferentDays extends Test_ // testing with empty URL and empty page title $visitorA->setUrl(' '); $this->checkResponse($visitorA->doTrackPageView(' ')); - + // - // Second new visitor on Idsite 1: one page view $visitorB = $this->getTracker($idSite, $dateTime, $defaultInit = true); + $visitorB->enableBulkTracking(); $visitorB->setIp('100.52.156.83'); $visitorB->setResolution(800, 300); $visitorB->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(1)->getDatetime()); @@ -133,7 +134,7 @@ class Test_Piwik_Integration_TwoVisitors_TwoWebsites_DifferentDays extends Test_ $visitorB->setUserAgent('Opera/9.63 (Windows NT 5.1; U; en) Presto/2.1.1'); $visitorB->setUrl('http://example.org/products'); $visitorB->DEBUG_APPEND_URL = '&_idts='.Piwik_Date::factory($dateTime)->addHour(1)->getTimestamp(); - $this->checkResponse($visitorB->doTrackPageView('first page view')); + $this->assertTrue($visitorB->doTrackPageView('first page view')); // - // Second visitor again on Idsite 1: 2 page views 2 days later, 2010-01-05 @@ -144,21 +145,22 @@ class Test_Piwik_Integration_TwoVisitors_TwoWebsites_DifferentDays extends Test_ $visitorB->setUrlReferrer( 'http://referer.com/Other_Page.htm' ); $visitorB->setUrl('http://example.org/index.htm'); - $this->checkResponse($visitorB->doTrackPageView('second visitor/two days later/a new visit')); + $this->assertTrue($visitorB->doTrackPageView('second visitor/two days later/a new visit')); // Second page view 6 minutes later $visitorB->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(48)->addHour(0.1)->getDatetime()); $visitorB->setUrl('http://example.org/thankyou'); - $this->checkResponse($visitorB->doTrackPageView('second visitor/two days later/second page view')); + $this->assertTrue($visitorB->doTrackPageView('second visitor/two days later/second page view')); // testing a strange combination causing an error in r3767 $visitorB->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(48)->addHour(0.2)->getDatetime()); - $this->checkResponse($visitorB->doTrackAction('mailto:test@example.org', 'link')); + $this->assertTrue($visitorB->doTrackAction('mailto:test@example.org', 'link')); $visitorB->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(48)->addHour(0.25)->getDatetime()); - $this->checkResponse($visitorB->doTrackAction('mailto:test@example.org/strangelink', 'link')); + $this->assertTrue($visitorB->doTrackAction('mailto:test@example.org/strangelink', 'link')); // Actions.getPageTitle tested with this title $visitorB->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(48)->addHour(0.25)->getDatetime()); - $this->checkResponse($visitorB->doTrackPageView('Checkout / Purchasing...')); + $this->assertTrue($visitorB->doTrackPageView('Checkout / Purchasing...')); + $this->checkResponse($visitorB->doBulkTrack()); // - // First visitor on Idsite 2: one page view, with Website referer diff --git a/tests/integration/TwoVisitsWithCustomVariables_SegmentContains.test.php b/tests/integration/TwoVisitsWithCustomVariables_SegmentContains.test.php index 3f43d1a9c8077cc916e6dd51352d88eadfe7a8ff..194b1aaa4c13538d73cf5baa058affa02687bbf9 100644 --- a/tests/integration/TwoVisitsWithCustomVariables_SegmentContains.test.php +++ b/tests/integration/TwoVisitsWithCustomVariables_SegmentContains.test.php @@ -24,11 +24,11 @@ class Test_Piwik_Integration_TwoVisitsWithCustomVariables_SegmentContains extend $api = array('Actions.getPageUrls', 'Actions.getPageTitles', 'VisitsSummary.get'); $segmentsToTest = array( // array( SegmentString , TestSuffix , Array of API to test) - array("pageTitle=@".urlencode('*_)%'), '_SegmentPageTitleContainsStrangeCharacters', array('Actions.getPageTitles', 'VisitsSummary.get')), - array("pageUrl=@".urlencode('user/profile'), '_SegmentPageUrlContains', $api), - array("pageTitle=@Profile%20pa", '_SegmentPageTitleContains', $api), + array("pageTitle=@*_)%", '_SegmentPageTitleContainsStrangeCharacters', array('Actions.getPageTitles', 'VisitsSummary.get')), + array("pageUrl=@user/profile", '_SegmentPageUrlContains', $api), + array("pageTitle=@Profile pa", '_SegmentPageTitleContains', $api), array("pageUrl!@user/profile", '_SegmentPageUrlExcludes', $api), - array("pageTitle!@Profile%20pa", '_SegmentPageTitleExcludes', $api), + array("pageTitle!@Profile pa", '_SegmentPageTitleExcludes', $api), ); foreach($segmentsToTest as $segment) diff --git a/tests/integration/TwoVisitsWithCustomVariables_SegmentMatchALL_NoGoalData.test.php b/tests/integration/TwoVisitsWithCustomVariables_SegmentMatchALL_NoGoalData.test.php index e27ce6a3539582345427c688ff2ca6973d3fd2d1..a72f0613944de4b1bb2b1bf32ae8ab58a2960ad3 100755 --- a/tests/integration/TwoVisitsWithCustomVariables_SegmentMatchALL_NoGoalData.test.php +++ b/tests/integration/TwoVisitsWithCustomVariables_SegmentMatchALL_NoGoalData.test.php @@ -24,7 +24,7 @@ class Test_Piwik_Integration_TwoVisitsWithCustomVariables_SegmentMatchALL_NoGoal // Segment matching ALL // + adding DOES NOT CONTAIN segment always matched, to test this particular operator $resolution = $this->width.'x'.$this->height; - $segment = 'resolution=='.$resolution.';customVariableName1!@randomvalue%20does%20not%20exist'; + $segment = 'resolution=='.$resolution.';customVariableName1!@randomvalue does not exist'; return array( array($apiToCall, array('idSite' => 'all', 'date' => $this->dateTime, 'periods' => array('day', 'week'), diff --git a/tests/integration/proxy-piwik.php b/tests/integration/proxy-piwik.php index d0b7338f71e1b532cd3fcbd8ba56d47fb21dd999..e355081a19a4db5fccd1fccde0947edf64fb7a2f 100644 --- a/tests/integration/proxy-piwik.php +++ b/tests/integration/proxy-piwik.php @@ -27,6 +27,13 @@ Piwik_Config::getInstance()->PluginsInstalled['PluginsInstalled'] = array(); // Do not run scheduled tasks during tests Piwik_Config::getInstance()->Tracker['scheduled_tasks_min_interval'] = 0; +// if nothing found in _GET/_POST and we're doing a POST, assume bulk request. in which case, we have to bypass +// authentication +if (empty($_GET) && empty($_POST) && $_SERVER['REQUEST_METHOD'] == 'POST') +{ + Piwik_Config::getInstance()->Tracker['tracking_requests_require_authentication'] = 0; +} + // Tests can force the use of 3rd party cookie for ID visitor if(Piwik_Common::getRequestVar('forceUseThirdPartyCookie', false) == 1) {