diff --git a/core/Filechecks.php b/core/Filechecks.php
index acf09fb8403..0ab5e79334e 100644
--- a/core/Filechecks.php
+++ b/core/Filechecks.php
@@ -186,11 +186,11 @@ public static function getErrorMessageMissingPermissions($path)
$message = "Please check that the web server has enough permission to write to these files/directories:
";
if (SettingsServer::isWindows()) {
- $message .= "On Windows, check that the folder is not read only and is writable.
+ $message .= "On Windows, check that the folder is not read only and is writable.\n
You can try to execute:
";
} else {
$message .= "For example, on a Linux server if your Apache httpd user
- is www-data, you can try to execute:
"
+ is www-data, you can try to execute:
\n"
. "chown -R www-data:www-data " . $path . "
";
}
@@ -208,7 +208,7 @@ public static function getErrorMessageMissingPermissions($path)
private static function getMakeWritableCommand($realpath)
{
if (SettingsServer::isWindows()) {
- return "cacls $realpath /t /g " . get_current_user() . ":f
";
+ return "cacls $realpath /t /g " . get_current_user() . ":f
\n";
}
return "chmod -R 0755 $realpath
";
}
diff --git a/core/Log.php b/core/Log.php
index 3c3d06eb890..0f883ab631c 100644
--- a/core/Log.php
+++ b/core/Log.php
@@ -351,7 +351,10 @@ private function logToFile($level, $tag, $datetime, $message)
return;
}
- file_put_contents($this->logToFilePath, $message . "\n", FILE_APPEND);
+ if(!file_put_contents($this->logToFilePath, $message . "\n", FILE_APPEND)) {
+ $message = Filechecks::getErrorMessageMissingPermissions($this->logToFilePath);
+ throw new \Exception( $message );
+ }
}
private function logToScreen($level, $tag, $datetime, $message)
diff --git a/core/Tracker.php b/core/Tracker.php
index f4618ee3b37..c6ba93ebb65 100644
--- a/core/Tracker.php
+++ b/core/Tracker.php
@@ -191,7 +191,7 @@ private function authenticateBulkTrackingRequests($rawData)
if (isset($jsonData['requests'])) {
$this->requests = $jsonData['requests'];
}
- $tokenAuth = Common::getRequestVar('token_auth', false, null, $jsonData);
+ $tokenAuth = Common::getRequestVar('token_auth', false, 'string', $jsonData);
if (empty($tokenAuth)) {
throw new Exception("token_auth must be specified when using Bulk Tracking Import. See Tracking Doc");
}
@@ -244,6 +244,9 @@ public function main($args = null)
$this->initOutputBuffer();
if (!empty($this->requests)) {
+ // Request needs the Db to authenticate (if cache files not available)
+ self::connectDatabaseIfNotConnected();
+
foreach ($this->requests as $params) {
$request = new Request($params, $tokenAuth);
$isAuthenticated = $request->isAuthenticated();
@@ -252,7 +255,6 @@ public function main($args = null)
try {
if ($this->isVisitValid()) {
- self::connectDatabaseIfNotConnected();
$visit = $this->getNewVisitObject();
$request->setForcedVisitorId(self::$forcedVisitorId);
diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php
index d875ced45f3..c5bfa782dc9 100644
--- a/core/Tracker/Action.php
+++ b/core/Tracker/Action.php
@@ -17,8 +17,7 @@
use Piwik\Tracker;
/**
- * Handles an action (page view, download or outlink) by the visitor.
- * Parses the action name and URL from the request array, then records the action in the log table.
+ *
*
* @package Piwik
* @subpackage Tracker
@@ -27,7 +26,12 @@ class Action implements ActionInterface
{
const DB_COLUMN_CUSTOM_FLOAT = 'custom_float';
- static public function make(Request $request)
+ /**
+ *
+ * @param Request $request
+ * @return ActionClickUrl|ActionPageview|ActionSiteSearch
+ */
+ static public function factory(Request $request)
{
$downloadUrl = $request->getParam('download');
if (!empty($downloadUrl)) {
@@ -54,8 +58,8 @@ static public function make(Request $request)
protected $request;
private $idLinkVisitAction;
- private $idActionName = false;
- private $idActionUrl = false;
+
+ protected $actionIdsCached = array();
private $actionName;
private $actionType;
@@ -67,7 +71,6 @@ public function __construct($type, Request $request)
$this->request = $request;
}
-
/**
* Returns URL of the page currently being tracked, or the file being downloaded, or the outlink being clicked
*
@@ -88,25 +91,23 @@ public function getActionType()
return $this->actionType;
}
- protected function getActionNameType()
- {
- return ActionInterface::TYPE_PAGE_TITLE;
- }
-
public function getIdActionUrl()
{
- $idUrl = $this->idActionUrl;
+ $idUrl = $this->actionIdsCached['idaction_url'];
// note; idaction_url = 0 is displayed as "Page URL Not Defined"
return (int)$idUrl;
}
public function getIdActionName()
{
- return $this->idActionName;
+ if(!isset($this->actionIdsCached['idaction_name'])) {
+ return false;
+ }
+ return $this->actionIdsCached['idaction_name'];
}
// custom_float column
- public function getActionCustomValue()
+ public function getCustomFloatValue()
{
return false;
}
@@ -154,6 +155,36 @@ protected function setActionUrl($url)
$this->actionUrl = $url;
}
+ public function getCustomVariables()
+ {
+ $customVariables = $this->request->getCustomVariables($scope = 'page');
+ return $customVariables;
+ }
+
+ protected function getActionsToLookup()
+ {
+ return array(
+ 'idaction_name' => $this->getNameAndType(),
+ 'idaction_url' => $this->getUrlAndType()
+ );
+ }
+
+ protected function getNameAndType()
+ {
+ return array($this->getActionName(), ActionInterface::TYPE_PAGE_TITLE, $prefix = false);
+ }
+
+ protected function getUrlAndType()
+ {
+ $url = $this->getActionUrl();
+ 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 false;
+ }
+
public static function getTypeAsString($type)
{
$class = new \ReflectionClass("\\Piwik\\Tracker\\ActionInterface");
@@ -175,37 +206,20 @@ public static function getTypeAsString($type)
* The methods takes care of creating a new record(s) in the action table if the existing
* action name and action url doesn't exist yet.
*/
- function loadIdActionNameAndUrl()
+ public function loadIdsFromLogActionTable()
{
- if ($this->idActionUrl !== false
- && $this->idActionName !== false
- ) {
- return;
- }
- $actions = array();
+ $actions = $this->getActionsToLookup();
+ $actions = array_filter($actions, 'count');
- $actionNameAndType = $this->getNameAndType();
- if($actionNameAndType) {
- $actions[] = $actionNameAndType;
+ if(empty($actions)
+ || !empty($this->actionIdsCached)) {
+ return false;
}
- $actionUrlAndType = $this->getUrlAndType();
- if($actionUrlAndType) {
- $actions[] = $actionUrlAndType;
+ $loadedActionIds = TableLogAction::loadIdsAction($actions);
- }
-
- $loadedActionIds = TableActionIds::loadActionId($actions);
-
- foreach ($loadedActionIds as $loadedActionId) {
- var_dump($loadedActionId);
- list($name, $type, $prefixId, $actionId) = $loadedActionId;
- if ($type == $this->getActionNameType()) {
- $this->idActionName = $actionId;
- } else {
- $this->idActionUrl = $actionId;
- }
- }
+ $this->actionIdsCached = $loadedActionIds;
+ return $this->actionIdsCached;
}
/**
@@ -220,7 +234,7 @@ function loadIdActionNameAndUrl()
*/
public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idReferrerActionName, $timeSpentReferrerAction)
{
- $this->loadIdActionNameAndUrl();
+ $this->loadIdsFromLogActionTable();
$idActionName = in_array($this->getActionType(), array(Tracker\Action::TYPE_PAGE_TITLE,
Tracker\Action::TYPE_PAGE_URL,
@@ -241,7 +255,7 @@ public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idRefe
'time_spent_ref_action' => $timeSpentReferrerAction
);
- $customValue = $this->getActionCustomValue();
+ $customValue = $this->getCustomFloatValue();
if (!empty($customValue)) {
$insert[self::DB_COLUMN_CUSTOM_FLOAT] = $customValue;
}
@@ -280,6 +294,7 @@ public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idRefe
'idReferrerActionName' => $idReferrerActionName,
'timeSpentReferrerAction' => $timeSpentReferrerAction,
);
+ Common::printDebug("Inserted new action:");
Common::printDebug($insertWithoutNulls);
/**
@@ -289,31 +304,6 @@ public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idRefe
Piwik::postEvent('Tracker.recordAction', array($trackerAction = $this, $info));
}
- public function getCustomVariables()
- {
- $customVariables = $this->request->getCustomVariables($scope = 'page');
- return $customVariables;
- }
-
- protected function getNameAndType()
- {
- $nameType = $this->getActionNameType();
- if (!is_null($nameType)) {
- return array($this->getActionName(), $nameType, $prefix = false);
- }
- return false;
- }
-
- protected function getUrlAndType()
- {
- $url = $this->getActionUrl();
- 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 false;
- }
}
diff --git a/core/Tracker/ActionClickUrl.php b/core/Tracker/ActionClickUrl.php
index 3a7e68a1bcf..82d6c312ccc 100644
--- a/core/Tracker/ActionClickUrl.php
+++ b/core/Tracker/ActionClickUrl.php
@@ -27,9 +27,15 @@ function __construct($type, $url, Request $request)
$this->setActionUrl($url);
}
- function getActionNameType()
+ protected function getActionsToLookup()
{
- return null;
+ $actions = parent::getActionsToLookup();
+ // set the right type
+ $actions['idaction_url'][1] = $this->getActionType();
+
+ return array(
+ 'idaction_url' => $actions['idaction_url']
+ );
}
function writeDebugInfo()
diff --git a/core/Tracker/ActionPageview.php b/core/Tracker/ActionPageview.php
index ec1e865bb7a..a05db93556e 100644
--- a/core/Tracker/ActionPageview.php
+++ b/core/Tracker/ActionPageview.php
@@ -15,6 +15,11 @@
use Piwik\Config;
+/**
+ * This class represents a page view, tracking URL, page title and generation time.
+ *
+ * @package Piwik\Tracker
+ */
class ActionPageview extends Action
{
protected $timeGeneration = false;
@@ -32,7 +37,7 @@ function __construct($url, Request $request)
$this->timeGeneration = $this->request->getPageGenerationTime();
}
- function getActionCustomValue()
+ function getCustomFloatValue()
{
return $this->request->getPageGenerationTime();
}
diff --git a/core/Tracker/ActionSiteSearch.php b/core/Tracker/ActionSiteSearch.php
index ee380be9791..fc9e6e374cb 100644
--- a/core/Tracker/ActionSiteSearch.php
+++ b/core/Tracker/ActionSiteSearch.php
@@ -16,14 +16,24 @@
use Piwik\Tracker;
use Piwik\UrlHelper;
+/**
+ * This class represents a search on the site.
+ * - Its name is the search keyword
+ * - by default the URL is not recorded (since it's not used)
+ * - tracks site search result count and site search category as custom variables
+ *
+ * @package Piwik\Tracker
+ */
class ActionSiteSearch extends Action
{
+ private $searchCategory = false;
+ private $searchCount = false;
+
const CVAR_KEY_SEARCH_CATEGORY = '_pk_scat';
const CVAR_KEY_SEARCH_COUNT = '_pk_scount';
const CVAR_INDEX_SEARCH_CATEGORY = '4';
const CVAR_INDEX_SEARCH_COUNT = '5';
- private $searchCategory = false;
- private $searchCount = false;
+
function __construct($url, Request $request)
{
@@ -31,7 +41,25 @@ function __construct($url, Request $request)
$this->originalUrl = $url;
}
- function getActionCustomValue()
+ protected function getActionsToLookup()
+ {
+ return array(
+ 'idaction_name' => array($this->getActionName(), ActionInterface::TYPE_SITE_SEARCH, $prefix = false),
+ 'idaction_url' => $this->getUrlAndType()
+ );
+ }
+
+ 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)
+ if (empty(Config::getInstance()->Tracker['action_sitesearch_record_url'])) {
+ return null;
+ }
+ return parent::getIdActionUrl();
+ }
+
+ public function getCustomFloatValue()
{
return $this->request->getPageGenerationTime();
}
@@ -58,21 +86,6 @@ function isSearchDetected()
return true;
}
- // FIXMEA replace by getNameAndType
- protected function getActionNameType()
- {
- return ActionInterface::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)
- if (empty(Config::getInstance()->Tracker['action_sitesearch_record_url'])) {
- return null;
- }
- return parent::getIdActionUrl();
- }
public function getCustomVariables()
{
@@ -96,11 +109,6 @@ public function getCustomVariables()
return $customVariables;
}
- public function isSiteSearchDetected($originalUrl)
- {
- return true;
- }
-
protected function detectSiteSearchFromUrl($website, $parsedUrl)
{
$doRemoveSearchParametersFromUrl = false;
diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php
index 793bb8107ac..0c5e1f330d0 100644
--- a/core/Tracker/GoalManager.php
+++ b/core/Tracker/GoalManager.php
@@ -630,28 +630,25 @@ protected function getCleanedEcommerceItems($items)
$actionsToLookupAllItems = array_merge($actionsToLookupAllItems, $actionsToLookup);
}
- // add prefixId = false expected by loadActionId()
+ // add prefixId = false expected by loadIdsFromLogActionTable()
foreach($actionsToLookupAllItems as &$actionToLookup) {
$actionToLookup[] = false;
}
- $actionsLookedUp = TableActionIds::loadActionId($actionsToLookupAllItems);
-
- // id action is returned as the last element of the array
- $keyIdAction = 3;
+ $actionsLookedUp = TableLogAction::loadIdsAction($actionsToLookupAllItems);
// Replace SKU, name & category by their ID action
foreach ($cleanedItems as $index => &$item) {
// SKU
- $item[0] = $actionsLookedUp[$index * $columnsInEachRow + 0][$keyIdAction];
+ $item[0] = $actionsLookedUp[$index * $columnsInEachRow + 0];
// Name
- $item[1] = $actionsLookedUp[$index * $columnsInEachRow + 1][$keyIdAction];
+ $item[1] = $actionsLookedUp[$index * $columnsInEachRow + 1];
// Categories
- $item[2] = $actionsLookedUp[$index * $columnsInEachRow + 2][$keyIdAction];
- $item[3] = $actionsLookedUp[$index * $columnsInEachRow + 3][$keyIdAction];
- $item[4] = $actionsLookedUp[$index * $columnsInEachRow + 4][$keyIdAction];
- $item[5] = $actionsLookedUp[$index * $columnsInEachRow + 5][$keyIdAction];
- $item[6] = $actionsLookedUp[$index * $columnsInEachRow + 6][$keyIdAction];
+ $item[2] = $actionsLookedUp[$index * $columnsInEachRow + 2];
+ $item[3] = $actionsLookedUp[$index * $columnsInEachRow + 3];
+ $item[4] = $actionsLookedUp[$index * $columnsInEachRow + 4];
+ $item[5] = $actionsLookedUp[$index * $columnsInEachRow + 5];
+ $item[6] = $actionsLookedUp[$index * $columnsInEachRow + 6];
}
return $cleanedItems;
}
diff --git a/core/Tracker/PageUrl.php b/core/Tracker/PageUrl.php
index dc3073b3af5..e0defd4cda9 100644
--- a/core/Tracker/PageUrl.php
+++ b/core/Tracker/PageUrl.php
@@ -35,7 +35,7 @@ class PageUrl
/**
* Given the Input URL, will exclude all query parameters set for this site
- * Note: Site Search parameters are excluded in isSiteSearchDetected()
+ *
* @static
* @param $originalUrl
* @param $idSite
diff --git a/core/Tracker/Request.php b/core/Tracker/Request.php
index 013bcb18da8..2eb72bb5d6d 100644
--- a/core/Tracker/Request.php
+++ b/core/Tracker/Request.php
@@ -75,7 +75,7 @@ protected function authenticateTrackingApi($tokenAuthFromBulkRequest)
{
$shouldAuthenticate = Config::getInstance()->Tracker['tracking_requests_require_authentication'];
if ($shouldAuthenticate) {
- $tokenAuth = $tokenAuthFromBulkRequest || Common::getRequestVar('token_auth', false, 'string', $this->params);
+ $tokenAuth = $tokenAuthFromBulkRequest ? $tokenAuthFromBulkRequest : Common::getRequestVar('token_auth', false, 'string', $this->params);
try {
$idSite = $this->getIdSite();
$this->isAuthenticated = $this->authenticateSuperUserOrAdmin($tokenAuth, $idSite);
@@ -94,12 +94,12 @@ protected function authenticateTrackingApi($tokenAuthFromBulkRequest)
public static function authenticateSuperUserOrAdmin($tokenAuth, $idSite)
{
- if (!$tokenAuth) {
+ if (empty($tokenAuth)) {
return false;
}
$superUserLogin = Config::getInstance()->superuser['login'];
$superUserPassword = Config::getInstance()->superuser['password'];
- if (md5($superUserLogin . $superUserPassword) == $tokenAuth) {
+ if (md5($superUserLogin . $superUserPassword) === $tokenAuth) {
return true;
}
@@ -528,7 +528,6 @@ public function getParamsCount()
return count($this->params);
}
-
const GENERATION_TIME_MS_MAXIMUM = 3600000; // 1 hour
public function getPageGenerationTime()
diff --git a/core/Tracker/TableActionIds.php b/core/Tracker/TableLogAction.php
similarity index 56%
rename from core/Tracker/TableActionIds.php
rename to core/Tracker/TableLogAction.php
index ab64fa34fd9..25b838787c9 100644
--- a/core/Tracker/TableActionIds.php
+++ b/core/Tracker/TableLogAction.php
@@ -14,9 +14,17 @@
use Piwik\Common;
use Piwik\Tracker;
-class TableActionIds
-{
+/**
+ * This class is used to query Action IDs from the log_action table.
+ *
+ * A pageview, outlink, download or site search are made of several "Action IDs"
+ * For example pageview is idaction_url and idaction_name.
+ *
+ * @package Piwik\Tracker
+ */
+class TableLogAction
+{
public static function getSqlSelectActionId()
{
$sql = "SELECT idaction, type, name
@@ -33,16 +41,47 @@ public static function getSqlSelectActionId()
* This is used to record Page URLs, Page Titles, Ecommerce items SKUs, item names, item categories
*
* If the action name does not exist in the lookup table, it will INSERT it
- * @param array $actionNamesAndTypes Array of one or many (name,type)
- * @return array Returns the input array, with the idaction appended ie. Array of one or many (name,type,idaction)
+ * @param array $actionsNameAndType Array of one or many (name,type)
+ * @return array Returns the an array (Field name => idaction)
*/
- public static function loadActionId($actionNamesAndTypes)
+ public static function loadIdsAction($actionsNameAndType)
{
- // First, we try and select the actions that are already recorded
- $sql = TableActionIds::getSqlSelectActionId();
+ $actionIds = self::queryIdsAction($actionsNameAndType);
+
+ list($queriedIds, $fieldNamesToInsert) = self::processIdsToInsert($actionsNameAndType, $actionIds);
+
+ $insertedIds = self::insertNewIdsAction($actionsNameAndType, $fieldNamesToInsert);
+
+ $queriedIds = $queriedIds + $insertedIds;
+
+ return $queriedIds;
+ }
+
+ protected static function insertNewIdsAction($actionsNameAndType, $fieldNamesToInsert)
+ {
+ $sql = "INSERT INTO " . Common::prefixTable('log_action') .
+ "( name, hash, type, url_prefix ) VALUES (?,CRC32(?),?,?)";
+ // Then, we insert all new actions in the lookup table
+ $inserted = array();
+ foreach ($fieldNamesToInsert as $fieldName) {
+ list($name, $type, $urlPrefix) = $actionsNameAndType[$fieldName];
+
+ Tracker::getDatabase()->query($sql, array($name, $name, $type, $urlPrefix));
+ $actionId = Tracker::getDatabase()->lastInsertId();
+
+ $inserted[$fieldName] = $actionId;
+
+ Common::printDebug("Recorded a new action (" . Action::getTypeAsString($type) . ") in the lookup table: " . $name . " (idaction = " . $actionId . ")");
+ }
+ return $inserted;
+ }
+
+ protected static function queryIdsAction($actionsNameAndType)
+ {
+ $sql = TableLogAction::getSqlSelectActionId();
$bind = array();
$i = 0;
- foreach ($actionNamesAndTypes as &$actionNameType) {
+ foreach ($actionsNameAndType as &$actionNameType) {
list($name, $type, $urlPrefix) = $actionNameType;
if (empty($name)) {
continue;
@@ -57,16 +96,21 @@ public static function loadActionId($actionNamesAndTypes)
}
// Case URL & Title are empty
if (empty($bind)) {
- return $actionNamesAndTypes;
+ return false;
}
$actionIds = Tracker::getDatabase()->fetchAll($sql, $bind);
+ return $actionIds;
+ }
+ protected static function processIdsToInsert($actionsNameAndType, $actionIds)
+ {
// For the Actions found in the lookup table, add the idaction in the array,
// If not found in lookup table, queue for INSERT
- $actionsToInsert = array();
- foreach ($actionNamesAndTypes as $index => &$actionNameType) {
- list($name, $type, $urlPrefix) = $actionNameType;
+ $fieldNamesToInsert = $fieldNameToActionId = array();
+ foreach ($actionsNameAndType as $fieldName => &$actionNameType) {
+ @list($name, $type, $urlPrefix) = $actionNameType;
if (empty($name)) {
+ $fieldNameToActionId[$fieldName] = false;
continue;
}
@@ -76,28 +120,16 @@ public static function loadActionId($actionNamesAndTypes)
&& $type == $row['type']
) {
$found = true;
- $actionNameType[] = $row['idaction'];
+
+ $fieldNameToActionId[$fieldName] = $row['idaction'];
continue;
}
}
if (!$found) {
- $actionsToInsert[] = $index;
+ $fieldNamesToInsert[] = $fieldName;
}
}
-
- $sql = "INSERT INTO " . Common::prefixTable('log_action') .
- "( name, hash, type, url_prefix ) VALUES (?,CRC32(?),?,?)";
- // Then, we insert all new actions in the lookup table
- foreach ($actionsToInsert as $actionToInsert) {
- list($name, $type, $urlPrefix) = $actionNamesAndTypes[$actionToInsert];
-
- Tracker::getDatabase()->query($sql, array($name, $name, $type, $urlPrefix));
- $actionId = Tracker::getDatabase()->lastInsertId();
- Common::printDebug("Recorded a new action (" . Action::getTypeAsString($type) . ") in the lookup table: " . $name . " (idaction = " . $actionId . ")");
-
- $keyIdAction = 3;
- $actionNamesAndTypes[$actionToInsert][$keyIdAction] = $actionId;
- }
- return $actionNamesAndTypes;
+ return array($fieldNameToActionId, $fieldNamesToInsert);
}
-}
\ No newline at end of file
+}
+
diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php
index be9ce912d7b..7772d3be99a 100644
--- a/core/Tracker/Visit.php
+++ b/core/Tracker/Visit.php
@@ -128,14 +128,14 @@ public function handle()
}
} // normal page view, potentially triggering a URL matching goal
else {
- $action = Action::make($this->request);
+ $action = Action::factory($this->request);
$action->writeDebugInfo();
$someGoalsConverted = $this->goalManager->detectGoalsMatchingUrl($this->request->getIdSite(), $action);
$visitIsConverted = $someGoalsConverted;
- $action->loadIdActionNameAndUrl();
+ $action->loadIdsFromLogActionTable();
}
// the visitor and session
diff --git a/core/ViewDataTable/Manager.php b/core/ViewDataTable/Manager.php
index 48d77eec148..de3f0ad7950 100644
--- a/core/ViewDataTable/Manager.php
+++ b/core/ViewDataTable/Manager.php
@@ -27,7 +27,6 @@
*/
class Manager
{
-
/**
* Returns the viewDataTable IDs of a visualization's class lineage.
*
diff --git a/piwik.php b/piwik.php
index 36201b00616..f805fee9d3f 100644
--- a/piwik.php
+++ b/piwik.php
@@ -56,7 +56,7 @@
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Visit.php';
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/TableActionIds.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/ActionPageview.php';
diff --git a/plugins/Actions/Actions.php b/plugins/Actions/Actions.php
index 3d4cddd3881..ca4e9daa392 100644
--- a/plugins/Actions/Actions.php
+++ b/plugins/Actions/Actions.php
@@ -22,7 +22,7 @@
use Piwik\SegmentExpression;
use Piwik\Site;
use Piwik\Tracker\Action;
-use Piwik\Tracker\TableActionIds;
+use Piwik\Tracker\TableLogAction;
use Piwik\ViewDataTable\Request as ViewDataTableRequest;
use Piwik\WidgetsList;
@@ -177,7 +177,7 @@ public function getIdActionFromSegment($valueToMatch, $sqlField, $matchType, $se
if ($matchType == SegmentExpression::MATCH_EQUAL
|| $matchType == SegmentExpression::MATCH_NOT_EQUAL
) {
- $sql = TableActionIds::getSqlSelectActionId();
+ $sql = TableLogAction::getSqlSelectActionId();
$bind = array($valueToMatch, $valueToMatch, $actionType);
$idAction = Db::fetchOne($sql, $bind);
// if the action is not found, we hack -100 to ensure it tries to match against an integer
diff --git a/plugins/Actions/ArchivingHelper.php b/plugins/Actions/ArchivingHelper.php
index e4eb4a313ef..0921452fe4c 100644
--- a/plugins/Actions/ArchivingHelper.php
+++ b/plugins/Actions/ArchivingHelper.php
@@ -65,8 +65,7 @@ static public function updateActionsTableWithRowQuery($query, $fieldQueried, & $
) {
$url = null;
} elseif (!empty($row['name'])
- && $row['name'] != DataTable::LABEL_SUMMARY_ROW
- ) {
+ && $row['name'] != DataTable::LABEL_SUMMARY_ROW) {
$url = PageUrl::reconstructNormalizedUrl((string)$row['name'], $row['url_prefix']);
}
@@ -389,7 +388,7 @@ protected static function getActionRow($actionName, $actionType, $urlPrefix = nu
* we explode link http://piwik.org/some/path into an array( 'some', 'path' );
*
* for action names:
- * we explode name 'Piwik / Category 1 / Category 2' into an array('\Piwik\Piwik', 'Category 1', 'Category 2');
+ * we explode name 'Piwik / Category 1 / Category 2' into an array('Piwik', 'Category 1', 'Category 2');
*
* @param string $name action name
* @param int $type action type
@@ -403,69 +402,10 @@ static public function getActionExplodedNames($name, $type, $urlPrefix = null)
return array($name);
}
- $matches = array();
- $isUrl = false;
$name = str_replace("\n", "", $name);
- $urlRegexAfterDomain = '([^/]+)[/]?([^#]*)[#]?(.*)';
- if ($urlPrefix === null) {
- // match url with protocol (used for outlinks / downloads)
- $urlRegex = '@^http[s]?://' . $urlRegexAfterDomain . '$@i';
- } else {
- // the name is a url that does not contain protocol and www anymore
- // we know that normalization has been done on db level because $urlPrefix is set
- $urlRegex = '@^' . $urlRegexAfterDomain . '$@i';
- }
-
- preg_match($urlRegex, $name, $matches);
- if (count($matches)) {
- $isUrl = true;
- $urlHost = $matches[1];
- $urlPath = $matches[2];
- $urlFragment = $matches[3];
- }
-
- if ($type == Action::TYPE_DOWNLOAD
- || $type == Action::TYPE_OUTLINK
- ) {
- if ($isUrl) {
- return array(trim($urlHost), '/' . trim($urlPath));
- }
- }
-
- if ($isUrl) {
- $name = $urlPath;
-
- if ($name === '' || substr($name, -1) == '/') {
- $name .= self::$defaultActionName;
- }
- }
-
- if ($type == Action::TYPE_PAGE_TITLE) {
- $categoryDelimiter = self::$actionTitleCategoryDelimiter;
- } else {
- $categoryDelimiter = self::$actionUrlCategoryDelimiter;
- }
-
- if ($isUrl) {
- $urlFragment = PageUrl::processUrlFragment($urlFragment);
- if (!empty($urlFragment)) {
- $name .= '#' . $urlFragment;
- }
- }
-
- if (empty($categoryDelimiter)) {
- return array(trim($name));
- }
-
- $split = explode($categoryDelimiter, $name, self::getSubCategoryLevelLimit());
-
- // trim every category and remove empty categories
- $split = array_map('trim', $split);
- $split = array_filter($split, 'strlen');
-
- // forces array key to start at 0
- $split = array_values($split);
+ $name = self::parseNameFromPageUrl($name, $type, $urlPrefix);
+ $split = self::splitNameByDelimiter($name, $type);
if (empty($split)) {
$defaultName = self::getUnknownActionName($type);
@@ -597,4 +537,72 @@ private static function createSummaryRow()
array('label' => DataTable::LABEL_SUMMARY_ROW) + self::getDefaultRowColumns()
));
}
+
+ protected static function splitNameByDelimiter($name, $type)
+ {
+ if(is_array($name)) {
+ return $name;
+ }
+ if ($type == Action::TYPE_PAGE_TITLE) {
+ $categoryDelimiter = self::$actionTitleCategoryDelimiter;
+ } else {
+ $categoryDelimiter = self::$actionUrlCategoryDelimiter;
+ }
+
+ if (empty($categoryDelimiter)) {
+ return array(trim($name));
+ }
+
+ $split = explode($categoryDelimiter, $name, self::getSubCategoryLevelLimit());
+
+ // trim every category and remove empty categories
+ $split = array_map('trim', $split);
+ $split = array_filter($split, 'strlen');
+
+ // forces array key to start at 0
+ $split = array_values($split);
+
+ return $split;
+ }
+
+ protected static function parseNameFromPageUrl($name, $type, $urlPrefix)
+ {
+ if($type == Action::TYPE_PAGE_TITLE) {
+ return $name;
+ }
+ $urlRegexAfterDomain = '([^/]+)[/]?([^#]*)[#]?(.*)';
+ if ($urlPrefix === null) {
+ // match url with protocol (used for outlinks / downloads)
+ $urlRegex = '@^http[s]?://' . $urlRegexAfterDomain . '$@i';
+ } else {
+ // the name is a url that does not contain protocol and www anymore
+ // we know that normalization has been done on db level because $urlPrefix is set
+ $urlRegex = '@^' . $urlRegexAfterDomain . '$@i';
+ }
+
+ $matches = array();
+ preg_match($urlRegex, $name, $matches);
+ if (!count($matches)) {
+ return $name;
+ }
+ $urlHost = $matches[1];
+ $urlPath = $matches[2];
+ $urlFragment = $matches[3];
+
+ if (in_array($type, array(Action::TYPE_DOWNLOAD, Action::TYPE_OUTLINK))) {
+ return array(trim($urlHost), trim($urlPath));
+ }
+
+ $name = $urlPath;
+ if ($name === '' || substr($name, -1) == '/') {
+ $name .= self::$defaultActionName;
+ }
+
+ $urlFragment = PageUrl::processUrlFragment($urlFragment);
+ if (!empty($urlFragment)) {
+ $name .= '#' . $urlFragment;
+ }
+
+ return $name;
+ }
}
diff --git a/plugins/CoreVisualizations/Visualizations/Cloud.php b/plugins/CoreVisualizations/Visualizations/Cloud.php
index f75e30ba346..a5d157e6601 100644
--- a/plugins/CoreVisualizations/Visualizations/Cloud.php
+++ b/plugins/CoreVisualizations/Visualizations/Cloud.php
@@ -101,7 +101,7 @@ public function addWord($word, $value = 1)
}
}
- public function getCloudValues()
+ private function getCloudValues()
{
$this->shuffleCloud();
diff --git a/plugins/Transitions/API.php b/plugins/Transitions/API.php
index 793d46a1509..618e50505c9 100644
--- a/plugins/Transitions/API.php
+++ b/plugins/Transitions/API.php
@@ -58,12 +58,11 @@ public function getTransitionsForPageUrl($pageUrl, $idSite, $period, $date, $seg
* @param bool $segment
* @param bool $limitBeforeGrouping
* @param string $parts
- * @param bool $returnNormalizedUrls
* @return array
* @throws Exception
*/
public function getTransitionsForAction($actionName, $actionType, $idSite, $period, $date,
- $segment = false, $limitBeforeGrouping = false, $parts = 'all', $returnNormalizedUrls = false)
+ $segment = false, $limitBeforeGrouping = false, $parts = 'all')
{
Piwik::checkUserHasViewAccess($idSite);
@@ -84,9 +83,6 @@ public function getTransitionsForAction($actionName, $actionType, $idSite, $peri
'date' => Day::advancedFactory($period->getLabel(), $date)->getLocalizedShortString()
);
- // add data to the report
- $this->returnNormalizedUrls();
-
$partsArray = explode(',', $parts);
if ($parts == 'all' || in_array('internalReferrers', $partsArray)) {
@@ -226,13 +222,12 @@ private function addFollowingActions($logAggregator, &$report, $idaction, $actio
* @param $includeLoops
* @return array(followingPages:DataTable, outlinks:DataTable, downloads:DataTable)
*/
- public function queryFollowingActions($idaction, $actionType, LogAggregator $logAggregator,
+ protected function queryFollowingActions($idaction, $actionType, LogAggregator $logAggregator,
$limitBeforeGrouping = false, $includeLoops = false)
{
$types = array();
- $isTitle = ($actionType == 'title');
- if (!$isTitle) {
+ if ($actionType != 'title') {
// specific setup for page urls
$types[Action::TYPE_PAGE_URL] = 'followingPages';
$dimension = 'IF( idaction_url IS NULL, idaction_name, idaction_url )';
@@ -296,37 +291,11 @@ public function queryFollowingActions($idaction, $actionType, LogAggregator $log
$metrics = array(Metrics::INDEX_NB_ACTIONS);
$data = $logAggregator->queryActionsByDimension(array($dimension), $where, $selects, $metrics, $rankingQuery, $joinLogActionColumn);
- $this->totalTransitionsToFollowingActions = 0;
- $dataTables = array();
- foreach ($types as $type => $recordName) {
- $dataTable = new DataTable;
- if (isset($data[$type])) {
- foreach ($data[$type] as &$record) {
- $actions = intval($record[Metrics::INDEX_NB_ACTIONS]);
- $dataTable->addRow(new Row(array(
- Row::COLUMNS => array(
- 'label' => $this->getPageLabel($record, $isTitle),
- Metrics::INDEX_NB_ACTIONS => $actions
- )
- )));
- $this->totalTransitionsToFollowingActions += $actions;
- }
- }
- $dataTables[$recordName] = $dataTable;
- }
+ $dataTables = $this->makeDataTablesFollowingActions($types, $data);
return $dataTables;
}
- /**
- * After calling this method, the query*()-Methods will return urls in their
- * normalized form (without the prefix reconstructed)
- */
- public function returnNormalizedUrls()
- {
- $this->returnNormalizedUrls = true;
- }
-
/**
* Get information about external referrers (i.e. search engines, websites & campaigns)
*
@@ -336,7 +305,7 @@ public function returnNormalizedUrls()
* @param $limitBeforeGrouping
* @return DataTable
*/
- public function queryExternalReferrers($idaction, $actionType, $logAggregator, $limitBeforeGrouping = false)
+ protected function queryExternalReferrers($idaction, $actionType, $logAggregator, $limitBeforeGrouping = false)
{
$rankingQuery = new RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping);
@@ -410,17 +379,20 @@ public function queryExternalReferrers($idaction, $actionType, $logAggregator, $
*/
protected function queryInternalReferrers($idaction, $actionType, $logAggregator, $limitBeforeGrouping = false)
{
+ $keyIsOther = 0;
+ $keyIsPageUrlAction = 1;
+ $keyIsSiteSearchAction = 2;
+
$rankingQuery = new RankingQuery($limitBeforeGrouping ? $limitBeforeGrouping : $this->limitBeforeGrouping);
$rankingQuery->addLabelColumn(array('name', 'url_prefix'));
$rankingQuery->setColumnToMarkExcludedRows('is_self');
- $rankingQuery->partitionResultIntoMultipleGroups('action_partition', array(0, 1, 2));
+ $rankingQuery->partitionResultIntoMultipleGroups('action_partition', array($keyIsOther, $keyIsPageUrlAction, $keyIsSiteSearchAction));
$type = $this->getColumnTypeSuffix($actionType);
$mainActionType = Action::TYPE_PAGE_URL;
$dimension = 'idaction_url_ref';
- $isTitle = $actionType == 'title';
- if ($isTitle) {
+ if ($actionType == 'title') {
$mainActionType = Action::TYPE_PAGE_TITLE;
$dimension = 'idaction_name_ref';
}
@@ -430,9 +402,9 @@ protected function queryInternalReferrers($idaction, $actionType, $logAggregator
'log_action.url_prefix',
'CASE WHEN log_link_visit_action.idaction_' . $type . '_ref = ' . intval($idaction) . ' THEN 1 ELSE 0 END AS `is_self`',
'CASE
- WHEN log_action.type = ' . $mainActionType . ' THEN 1
- WHEN log_action.type = ' . Action::TYPE_SITE_SEARCH . ' THEN 2
- ELSE 0
+ WHEN log_action.type = ' . $mainActionType . ' THEN ' . $keyIsPageUrlAction . '
+ WHEN log_action.type = ' . Action::TYPE_SITE_SEARCH . ' THEN ' . $keyIsSiteSearchAction .'
+ ELSE ' . $keyIsOther . '
END AS `action_partition`'
);
@@ -453,12 +425,12 @@ protected function queryInternalReferrers($idaction, $actionType, $logAggregator
$loops = 0;
$nbPageviews = 0;
$previousPagesDataTable = new DataTable;
- if (isset($data['result'][1])) {
- foreach ($data['result'][1] as &$page) {
+ if (isset($data['result'][$keyIsPageUrlAction])) {
+ foreach ($data['result'][$keyIsPageUrlAction] as &$page) {
$nbActions = intval($page[Metrics::INDEX_NB_ACTIONS]);
$previousPagesDataTable->addRow(new Row(array(
Row::COLUMNS => array(
- 'label' => $this->getPageLabel($page, $isTitle),
+ 'label' => $this->getPageLabel($page, Action::TYPE_PAGE_URL),
Metrics::INDEX_NB_ACTIONS => $nbActions
)
)));
@@ -467,8 +439,8 @@ protected function queryInternalReferrers($idaction, $actionType, $logAggregator
}
$previousSearchesDataTable = new DataTable;
- if (isset($data['result'][2])) {
- foreach ($data['result'][2] as &$search) {
+ if (isset($data['result'][$keyIsSiteSearchAction])) {
+ foreach ($data['result'][$keyIsSiteSearchAction] as &$search) {
$nbActions = intval($search[Metrics::INDEX_NB_ACTIONS]);
$previousSearchesDataTable->addRow(new Row(array(
Row::COLUMNS => array(
@@ -499,21 +471,21 @@ protected function queryInternalReferrers($idaction, $actionType, $logAggregator
);
}
- private function getPageLabel(&$pageRecord, $isTitle)
+ private function getPageLabel(&$pageRecord, $type)
{
- if ($isTitle) {
+ if ($type == Action::TYPE_PAGE_TITLE) {
$label = $pageRecord['name'];
if (empty($label)) {
- $label = ArchivingHelper::getUnknownActionName(
- Action::TYPE_PAGE_TITLE);
+ $label = ArchivingHelper::getUnknownActionName(Action::TYPE_PAGE_TITLE);
}
return $label;
- } else if ($this->returnNormalizedUrls) {
- return $pageRecord['name'];
- } else {
- return PageUrl::reconstructNormalizedUrl(
- $pageRecord['name'], $pageRecord['url_prefix']);
}
+
+ if ($type == Action::TYPE_OUTLINK || $type == Action::TYPE_DOWNLOAD) {
+ return PageUrl::reconstructNormalizedUrl($pageRecord['name'], $pageRecord['url_prefix']);
+ }
+
+ return $pageRecord['name'];
}
private function getColumnTypeSuffix($actionType)
@@ -527,8 +499,6 @@ private function getColumnTypeSuffix($actionType)
private $limitBeforeGrouping = 5;
private $totalTransitionsToFollowingActions = 0;
- private $returnNormalizedUrls = false;
-
/**
* Get the sum of all transitions to following actions (pages, outlinks, downloads).
* Only works if queryFollowingActions() has been used directly before.
@@ -614,4 +584,27 @@ public function getTranslations()
$controller = new Controller();
return $controller->getTranslations();
}
+
+ protected function makeDataTablesFollowingActions($types, $data)
+ {
+ $this->totalTransitionsToFollowingActions = 0;
+ $dataTables = array();
+ foreach ($types as $type => $recordName) {
+ $dataTable = new DataTable;
+ if (isset($data[$type])) {
+ foreach ($data[$type] as &$record) {
+ $actions = intval($record[Metrics::INDEX_NB_ACTIONS]);
+ $dataTable->addRow(new Row(array(
+ Row::COLUMNS => array(
+ 'label' => $this->getPageLabel($record, $type),
+ Metrics::INDEX_NB_ACTIONS => $actions
+ )
+ )));
+ $this->totalTransitionsToFollowingActions += $actions;
+ }
+ }
+ $dataTables[$recordName] = $dataTable;
+ }
+ return $dataTables;
+ }
}
\ No newline at end of file
diff --git a/tests/PHPUnit/BaseFixture.php b/tests/PHPUnit/BaseFixture.php
index e05c6ad6c07..a386123bd2b 100644
--- a/tests/PHPUnit/BaseFixture.php
+++ b/tests/PHPUnit/BaseFixture.php
@@ -180,8 +180,11 @@ public static function checkResponse($response)
*/
public static function checkBulkTrackingResponse($response) {
$data = json_decode($response, true);
- if (!is_array($data)) {
- echo "Bulk tracking response is not an array: " . var_export($data, true) . "\n";
+ if (!is_array($data) || empty($response)) {
+ throw new Exception("Bulk tracking response (".$response.") is not an array: " . var_export($data, true) . "\n");
+ }
+ if(!isset($data['status'])) {
+ throw new Exception("Returned data didn't have a status: " . var_export($data,true));
}
self::assertArrayHasKey('status', $data);
self::assertEquals('success', $data['status']);
diff --git a/tests/PHPUnit/Core/Tracker/ActionTest.php b/tests/PHPUnit/Core/Tracker/ActionTest.php
index b7f65897982..d3d0e59da84 100644
--- a/tests/PHPUnit/Core/Tracker/ActionTest.php
+++ b/tests/PHPUnit/Core/Tracker/ActionTest.php
@@ -4,6 +4,7 @@
use Piwik\Plugins\SitesManager\API;
use Piwik\Tracker\Action;
use Piwik\Tracker\PageUrl;
+use Piwik\Tracker\TableLogAction;
use Piwik\Tracker\Request;
use Piwik\Translate;
@@ -26,6 +27,8 @@ public function setUp()
\Piwik\Plugin\Manager::getInstance()->loadPlugins(array('SitesManager'));
Translate::loadEnglishTranslation();
+
+ \Piwik\Tracker::connectDatabaseIfNotConnected();
}
protected function setUpRootAccess()
@@ -190,10 +193,10 @@ public function getExtractUrlData()
'url' => 'http://example.org',
'type' => Action::TYPE_OUTLINK),
),
- // outlinks with custom name
+ // outlinks with custom name -> no custom name
array(
'request' => array('link' => 'http://example.org', 'action_name' => 'Example.org'),
- 'expected' => array('name' => 'Example.org',
+ 'expected' => array('name' => null,
'url' => 'http://example.org',
'type' => Action::TYPE_OUTLINK),
),
@@ -205,10 +208,10 @@ public function getExtractUrlData()
'type' => Action::TYPE_OUTLINK),
),
- // trim the custom name
+ // no custom name
array(
'request' => array('link' => ' http://example.org/Category/Test/ ', 'action_name' => ' Example dot org '),
- 'expected' => array('name' => 'Example dot org',
+ 'expected' => array('name' => null,
'url' => 'http://example.org/Category/Test/',
'type' => Action::TYPE_OUTLINK),
),
@@ -221,10 +224,10 @@ public function getExtractUrlData()
'type' => Action::TYPE_DOWNLOAD),
),
- // downloads with custom name
+ // downloads with custom name -> no custom name
array(
'request' => array('download' => 'http://example.org/*$test.zip', 'action_name' => 'Download test.zip'),
- 'expected' => array('name' => 'Download test.zip',
+ 'expected' => array('name' => null,
'url' => 'http://example.org/*$test.zip',
'type' => Action::TYPE_DOWNLOAD),
),
@@ -361,16 +364,15 @@ public function testExtractUrlAndActionNameFromRequest($request, $expected)
$idSite = API::getInstance()->addSite("site1", array('http://example.org'));
$request['idsite'] = $idSite;
$request = new Request($request);
- $action = new Test_Piwik_TrackerAction_extractUrlAndActionNameFromRequest($request);
- $this->assertEquals($action->public_extractUrlAndActionNameFromRequest(), $expected);
- }
-}
+ $action = Action::factory($request);
-class Test_Piwik_TrackerAction_extractUrlAndActionNameFromRequest extends Action
-{
- public function public_extractUrlAndActionNameFromRequest()
- {
- return $this->extractUrlAndActionNameFromRequest();
+ $processed = array(
+ 'name' => $action->getActionName(),
+ 'url' => $action->getActionUrl(),
+ 'type' => $action->getActionType(),
+ );
+
+ $this->assertEquals($processed, $expected);
}
}
diff --git a/tests/PHPUnit/Fixtures/ThreeSitesWithManyVisitsWithSiteSearch.php b/tests/PHPUnit/Fixtures/ThreeSitesWithManyVisitsWithSiteSearch.php
index cecddf208aa..0280e3661f3 100644
--- a/tests/PHPUnit/Fixtures/ThreeSitesWithManyVisitsWithSiteSearch.php
+++ b/tests/PHPUnit/Fixtures/ThreeSitesWithManyVisitsWithSiteSearch.php
@@ -141,27 +141,6 @@ protected function recordVisitorsSite1()
self::checkResponse($visitorB->doTrackPageView('Site Search results'));
}
- protected function recordVisitorSite3()
- { // -
- // Third new visitor on Idsite 3
- $visitor = self::getTracker($this->idSite3, $this->dateTime, $defaultInit = true);
- $visitor->setResolution(1801, 1301);
-
- $visitor->setForceVisitDateTime(Date::factory($this->dateTime)->addHour(0.2)->getDatetime());
- $visitor->setUrl('http://example.org/index.htm?q=Search 1&IsPageView=1');
- $visitor->setCustomVariable(1, 'test cvar name', 'test cvar value');
- self::checkResponse($visitor->doTrackPageView('IsPageView'));
-
- $visitor->setForceVisitDateTime(Date::factory($this->dateTime)->addHour(0.35)->getDatetime());
- $visitor->setUrl('http://example.org/index.htm?gkwd=test not a keyword&gcat=Cat not but not keyword, so this is not search');
- self::checkResponse($visitor->doTrackPageView('This is a pageview, not a Search'));
-
- // Testing UTF8 Title & URL
- $crazyTitle = '%2C%20%C3%8Dslenska%2C%20Italiano%2C%20%E6%97%A5%E6%9C%AC%E8%AA%9E%2C%20%E1%83%A5%E1%83%90%E1%83%A0%E1%83%97%E1%83%A3%E1%83%9A%E1%83%98%2C%20%ED%95%9C%EA%B5%AD%EC%96%B4%2C%20Lietuvi%C5%B3%2C%20Latvie%C5%A1u%2C%20Norsk%20(bokm%C3%A5l)%2C%20Nederlands%2C%20Norsk%20(nynorsk)%2C%20Polski%2C%20Portugu%C3%AAs%20brasileiro%2C%20Portugu%C3%AAs%2C%20Rom%C3%A2n%C4%83%2C%20%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%2C%20Slovensky%2C%20Sloven%C5%A1%C4%8Dina%2C%20Shqip%2C%20Srpski%2C%20Svenska%2C%20%E0%B0%A4%E0%B1%86%E0%B0%B2%E0%B1%81%E0%B0%97%E0%B1%81%2C%20%E0%B8%A0%E0%B8%B2%E0%B8%A9%E0%B8%B2%E0%B9%84%E0%B8%97%E0%B8%A2%2C%20T%C3%BCrk%C3%A7e%2C%20%D0%A3%D0%BA%D1%80%D0%B0%D1%97%D0%BD%D1%81%D1%8C%D0%BA%D0%B0%2C%20%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%2C%20%E7%B9%81%E9%AB%94%E4%B8%AD%E6%96%87.';
- $visitor->setUrl('http://example.org/index.htm?' . $crazyTitle);
- self::checkResponse($visitor->doTrackPageView('Pageview: ' . $crazyTitle));
- }
-
protected function recordVisitorSite2()
{
$visitor = self::getTracker($this->idSite2, $this->dateTime, $defaultInit = true);
@@ -189,5 +168,28 @@ protected function recordVisitorSite2()
self::checkResponse($visitor->doTrackSiteSearch("No Result Keyword!", "Bad No Result Category bis :(", $count = 0));
return array($defaultInit, $visitor);
}
+
+
+ protected function recordVisitorSite3()
+ {
+ // Third new visitor on Idsite 3
+ $visitor = self::getTracker($this->idSite3, $this->dateTime, $defaultInit = true);
+ $visitor->setResolution(1801, 1301);
+
+ $visitor->setForceVisitDateTime(Date::factory($this->dateTime)->addHour(0.2)->getDatetime());
+ $visitor->setUrl('http://example.org/index.htm?q=Search 1&IsPageView=1');
+ $visitor->setCustomVariable(1, 'test cvar name', 'test cvar value');
+ self::checkResponse($visitor->doTrackPageView('IsPageView'));
+
+ $visitor->setForceVisitDateTime(Date::factory($this->dateTime)->addHour(0.35)->getDatetime());
+ $visitor->setUrl('http://example.org/index.htm?gkwd=test not a keyword&gcat=Cat not but not keyword, so this is not search');
+ self::checkResponse($visitor->doTrackPageView('This is a pageview, not a Search'));
+
+ // Testing UTF8 Title & URL
+ $crazyTitle = '%2C%20%C3%8Dslenska%2C%20Italiano%2C%20%E6%97%A5%E6%9C%AC%E8%AA%9E%2C%20%E1%83%A5%E1%83%90%E1%83%A0%E1%83%97%E1%83%A3%E1%83%9A%E1%83%98%2C%20%ED%95%9C%EA%B5%AD%EC%96%B4%2C%20Lietuvi%C5%B3%2C%20Latvie%C5%A1u%2C%20Norsk%20(bokm%C3%A5l)%2C%20Nederlands%2C%20Norsk%20(nynorsk)%2C%20Polski%2C%20Portugu%C3%AAs%20brasileiro%2C%20Portugu%C3%AAs%2C%20Rom%C3%A2n%C4%83%2C%20%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%2C%20Slovensky%2C%20Sloven%C5%A1%C4%8Dina%2C%20Shqip%2C%20Srpski%2C%20Svenska%2C%20%E0%B0%A4%E0%B1%86%E0%B0%B2%E0%B1%81%E0%B0%97%E0%B1%81%2C%20%E0%B8%A0%E0%B8%B2%E0%B8%A9%E0%B8%B2%E0%B9%84%E0%B8%97%E0%B8%A2%2C%20T%C3%BCrk%C3%A7e%2C%20%D0%A3%D0%BA%D1%80%D0%B0%D1%97%D0%BD%D1%81%D1%8C%D0%BA%D0%B0%2C%20%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%2C%20%E7%B9%81%E9%AB%94%E4%B8%AD%E6%96%87.';
+ $visitor->setUrl('http://example.org/index.htm?' . $crazyTitle);
+ self::checkResponse($visitor->doTrackPageView('Pageview: ' . $crazyTitle));
+ }
+
}
diff --git a/tests/PHPUnit/UI b/tests/PHPUnit/UI
index 64f408608a9..b42f538c500 160000
--- a/tests/PHPUnit/UI
+++ b/tests/PHPUnit/UI
@@ -1 +1 @@
-Subproject commit 64f408608a90fb6d199698b34f053de2a7aa0ba0
+Subproject commit b42f538c5002b787cf99b759fe9ad6f059233f32
diff --git a/tests/PHPUnit/bootstrap.php b/tests/PHPUnit/bootstrap.php
index f1a7c5f8aff..004c41a706b 100644
--- a/tests/PHPUnit/bootstrap.php
+++ b/tests/PHPUnit/bootstrap.php
@@ -1,8 +1,8 @@