Esempio n. 1
0
 public function outputResponse(Tracker $tracker)
 {
     if (!$tracker->shouldRecordStatistics()) {
         $this->outputApiResponse($tracker);
         Common::printDebug("Logging disabled, display transparent logo");
     } elseif (!$tracker->hasLoggedRequests()) {
         if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) {
             Common::sendResponseCode(400);
         }
         Common::printDebug("Empty request => Piwik page");
         echo "This resource is part of Piwik. Keep full control of your data with the leading free and open source <a href='https://piwik.org' target='_blank'>digital analytics platform</a> for web and mobile.";
     } else {
         $this->outputApiResponse($tracker);
         Common::printDebug("Nothing to notice => default behaviour");
     }
     Common::printDebug("End of the page.");
     if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() && TrackerDb::isProfilingEnabled()) {
         $db = Tracker::getDatabase();
         $db->recordProfiling();
         Profiler::displayDbTrackerProfile($db);
     }
     if ($tracker->isDebugModeEnabled()) {
         Common::printDebug($_COOKIE);
         Common::printDebug((string) $this->timer);
     }
 }
Esempio n. 2
0
 public function outputResponse(Tracker $tracker)
 {
     if (!$tracker->shouldRecordStatistics()) {
         $this->outputApiResponse($tracker);
         Common::printDebug("Logging disabled, display transparent logo");
     } elseif (!$tracker->hasLoggedRequests()) {
         if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) {
             Common::sendResponseCode(400);
         }
         Common::printDebug("Empty request => Piwik page");
         echo "<a href='/'>Piwik</a> is a free/libre web <a href='http://piwik.org'>analytics</a> that lets you keep control of your data.";
     } else {
         $this->outputApiResponse($tracker);
         Common::printDebug("Nothing to notice => default behaviour");
     }
     Common::printDebug("End of the page.");
     if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() && TrackerDb::isProfilingEnabled()) {
         $db = Tracker::getDatabase();
         $db->recordProfiling();
         Profiler::displayDbTrackerProfile($db);
     }
     if ($tracker->isDebugModeEnabled()) {
         Common::printDebug($_COOKIE);
         Common::printDebug((string) $this->timer);
     }
 }
Esempio n. 3
0
 public function outputResponse(Tracker $tracker)
 {
     if (!$tracker->shouldRecordStatistics()) {
         $this->outputApiResponse($tracker);
         Common::printDebug("Logging disabled, display transparent logo");
     } elseif (!$tracker->hasLoggedRequests()) {
         if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) {
             Common::sendResponseCode(400);
         }
         Common::printDebug("Empty request => Piwik page");
         //echo date('Y-m-d H:i:s');
     } else {
         $this->outputApiResponse($tracker);
         Common::printDebug("Nothing to notice => default behaviour");
     }
     Common::printDebug("End of the page.");
     if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() && TrackerDb::isProfilingEnabled()) {
         $db = Tracker::getDatabase();
         $db->recordProfiling();
         Profiler::displayDbTrackerProfile($db);
     }
     if ($tracker->isDebugModeEnabled()) {
         Common::printDebug($_COOKIE);
         Common::printDebug((string) $this->timer);
     }
 }
Esempio n. 4
0
 /**
  * Returns the database connection and creates it if it hasn't been already.
  *
  * @return \Piwik\Tracker\Db|\Piwik\Db\AdapterInterface|\Piwik\Db
  */
 public static function get()
 {
     if (SettingsServer::isTrackerApiRequest()) {
         return Tracker::getDatabase();
     }
     if (!self::hasDatabaseObject()) {
         self::createDatabaseObject();
     }
     return self::$connection;
 }
Esempio n. 5
0
 /**
  * Returns the database connection and creates it if it hasn't been already.
  *
  * @return \Piwik\Tracker\Db|\Piwik\Db\AdapterInterface|\Piwik\Db
  */
 public static function get()
 {
     if (!empty($GLOBALS['PIWIK_TRACKER_MODE'])) {
         return Tracker::getDatabase();
     }
     if (self::$connection === null) {
         self::createDatabaseObject();
     }
     return self::$connection;
 }
Esempio n. 6
0
 public function test_rowCount_whenUpdating_returnsAllMatchedRowsNotOnlyUpdatedRows()
 {
     $db = Tracker::getDatabase();
     // insert one record
     $db->query("INSERT INTO `" . Common::prefixTable('option') . "` VALUES ('rowid', '1', false)");
     // We will now UPDATE this table and check rowCount() value
     $sqlUpdate = "UPDATE `" . Common::prefixTable('option') . "` SET option_value = 2";
     // when no record was updated, return 0
     $result = $db->query($sqlUpdate . " WHERE option_name = 'NOT FOUND'");
     $this->assertSame(0, $db->rowCount($result));
     // when one record was found and updated, returns 1
     $result = $db->query($sqlUpdate . " WHERE option_name = 'rowid'");
     $this->assertSame(1, $db->rowCount($result));
     // when one record was found but NOT actually updated (as values have not changed), we make sure to return 1
     // testing for MYSQLI_CLIENT_FOUND_ROWS and MYSQL_ATTR_FOUND_ROWS
     $result = $db->query($sqlUpdate . " WHERE option_name = 'rowid'");
     $this->assertSame(1, $db->rowCount($result));
 }
Esempio n. 7
0
 /**
  * Print profiling report for the tracker
  *
  * @param \Piwik\Db $db Tracker database object (or null)
  */
 public static function displayDbTrackerProfile($db = null)
 {
     if (is_null($db)) {
         $db = Tracker::getDatabase();
     }
     $LogProfiling = Factory::getDAO('log_profiling', $db);
     $all = $LogProfiling->getAll();
     if ($all === false) {
         return;
     }
     uasort($all, 'self::maxSumMsFirst');
     $infoIndexedByQuery = array();
     foreach ($all as $infoQuery) {
         $query = $infoQuery['query'];
         $count = $infoQuery['count'];
         $sum_time_ms = $infoQuery['sum_time_ms'];
         $infoIndexedByQuery[$query] = array('count' => $count, 'sumTimeMs' => $sum_time_ms);
     }
     self::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery);
 }
Esempio n. 8
0
 private function assertActionEquals($expected, $idaction)
 {
     $actionName = Tracker::getDatabase()->fetchOne("SELECT name FROM " . Common::prefixTable('log_action') . " WHERE idaction = ?", array($idaction));
     $this->assertEquals($expected, $actionName);
 }
Esempio n. 9
0
 private function getDb()
 {
     return Tracker::getDatabase();
 }
Esempio n. 10
0
 protected function getDb()
 {
     return Tracker::getDatabase();
 }
Esempio n. 11
0
 private static function queryIdsAction($actionsNameAndType)
 {
     $sql = TableLogAction::getSqlSelectActionId();
     $bind = array();
     $i = 0;
     foreach ($actionsNameAndType as &$actionNameType) {
         list($name, $type, $urlPrefix) = $actionNameType;
         if (empty($name)) {
             continue;
         }
         if ($i > 0) {
             $sql .= " OR ( hash = CRC32(?) AND name = ? AND type = ? ) ";
         }
         $bind[] = $name;
         $bind[] = $name;
         $bind[] = $type;
         $i++;
     }
     // Case URL & Title are empty
     if (empty($bind)) {
         return false;
     }
     $actionIds = Tracker::getDatabase()->fetchAll($sql, $bind);
     return $actionIds;
 }
Esempio n. 12
0
 /**
  * Print profiling report for the tracker
  *
  * @param \Piwik\Db $db Tracker database object (or null)
  */
 public static function displayDbTrackerProfile($db = null)
 {
     if (is_null($db)) {
         $db = Tracker::getDatabase();
     }
     $tableName = Common::prefixTable('log_profiling');
     $all = $db->fetchAll('SELECT * FROM ' . $tableName);
     if ($all === false) {
         return;
     }
     uasort($all, 'self::maxSumMsFirst');
     $infoIndexedByQuery = array();
     foreach ($all as $infoQuery) {
         $query = $infoQuery['query'];
         $count = $infoQuery['count'];
         $sum_time_ms = $infoQuery['sum_time_ms'];
         $infoIndexedByQuery[$query] = array('count' => $count, 'sumTimeMs' => $sum_time_ms);
     }
     self::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery);
 }
Esempio n. 13
0
 protected function updateExistingConversion($newGoal, $updateWhere)
 {
     $updateParts = $sqlBind = $updateWhereParts = array();
     foreach ($newGoal as $name => $value) {
         $updateParts[] = $name . " = ?";
         $sqlBind[] = $value;
     }
     foreach ($updateWhere as $name => $value) {
         $updateWhereParts[] = $name . " = ?";
         $sqlBind[] = $value;
     }
     $sql = 'UPDATE  ' . Common::prefixTable('log_conversion') . "\n\t\t\t\t\tSET " . implode($updateParts, ', ') . "\n\t\t\t\t\t\tWHERE " . implode($updateWhereParts, ' AND ');
     try {
         Tracker::getDatabase()->query($sql, $sqlBind);
     } catch (Exception $e) {
         Common::printDebug("There was an error while updating the Conversion: " . $e->getMessage());
         return false;
     }
     return true;
 }
Esempio n. 14
0
 /**
  * This methods tries to see if the visitor has visited the website before.
  *
  * We have to split the visitor into one of the category
  * - Known visitor
  * - New visitor
  */
 public function recognize()
 {
     $this->setIsVisitorKnown(false);
     $configId = $this->configId;
     $idVisitor = $this->request->getVisitorId();
     $isVisitorIdToLookup = !empty($idVisitor);
     if ($isVisitorIdToLookup) {
         $this->visitorInfo['idvisitor'] = $idVisitor;
         Common::printDebug("Matching visitors with: visitorId=" . bin2hex($this->visitorInfo['idvisitor']) . " OR configId=" . bin2hex($configId));
     } else {
         Common::printDebug("Visitor doesn't have the piwik cookie...");
     }
     $selectCustomVariables = '';
     // No custom var were found in the request, so let's copy the previous one in a potential conversion later
     if (!$this->customVariables) {
         $maxCustomVariables = CustomVariables::getMaxCustomVariables();
         for ($index = 1; $index <= $maxCustomVariables; $index++) {
             $selectCustomVariables .= ', custom_var_k' . $index . ', custom_var_v' . $index;
         }
     }
     $persistedVisitAttributes = self::getVisitFieldsPersist();
     array_unshift($persistedVisitAttributes, 'visit_first_action_time');
     array_unshift($persistedVisitAttributes, 'visit_last_action_time');
     $persistedVisitAttributes = array_unique($persistedVisitAttributes);
     $selectFields = implode(", ", $persistedVisitAttributes);
     $select = "SELECT\n                        {$selectFields}\n                        {$selectCustomVariables}\n        ";
     $from = "FROM " . Common::prefixTable('log_visit');
     list($timeLookBack, $timeLookAhead) = $this->getWindowLookupThisVisit();
     $shouldMatchOneFieldOnly = $this->shouldLookupOneVisitorFieldOnly($isVisitorIdToLookup);
     // Two use cases:
     // 1) there is no visitor ID so we try to match only on config_id (heuristics)
     // 		Possible causes of no visitor ID: no browser cookie support, direct Tracking API request without visitor ID passed,
     //        importing server access logs with import_logs.py, etc.
     // 		In this case we use config_id heuristics to try find the visitor in tahhhe past. There is a risk to assign
     // 		this page view to the wrong visitor, but this is better than creating artificial visits.
     // 2) there is a visitor ID and we trust it (config setting trust_visitors_cookies, OR it was set using &cid= in tracking API),
     //      and in these cases, we force to look up this visitor id
     $whereCommon = "visit_last_action_time >= ? AND visit_last_action_time <= ? AND idsite = ?";
     $bindSql = array($timeLookBack, $timeLookAhead, $this->request->getIdSite());
     if ($shouldMatchOneFieldOnly) {
         if ($isVisitorIdToLookup) {
             $whereCommon .= ' AND idvisitor = ?';
             $bindSql[] = $this->visitorInfo['idvisitor'];
         } else {
             $whereCommon .= ' AND config_id = ?';
             $bindSql[] = $configId;
         }
         $sql = "{$select}\n            {$from}\n            WHERE " . $whereCommon . "\n            ORDER BY visit_last_action_time DESC\n            LIMIT 1";
     } else {
         // will use INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time)
         $where = ' AND config_id = ?';
         $bindSql[] = $configId;
         $sqlConfigId = "{$select} ,\n                0 as priority\n                {$from}\n                WHERE {$whereCommon} {$where}\n                ORDER BY visit_last_action_time DESC\n                LIMIT 1\n            ";
         // will use INDEX index_idsite_idvisitor (idsite, idvisitor)
         $bindSql[] = $timeLookBack;
         $bindSql[] = $timeLookAhead;
         $bindSql[] = $this->request->getIdSite();
         $where = ' AND idvisitor = ?';
         $bindSql[] = $this->visitorInfo['idvisitor'];
         $sqlVisitorId = "{$select} ,\n                1 as priority\n                {$from}\n                WHERE {$whereCommon} {$where}\n                ORDER BY visit_last_action_time DESC\n                LIMIT 1\n            ";
         // We join both queries and favor the one matching the visitor_id if it did match
         $sql = " ( {$sqlConfigId} )\n                UNION\n                ( {$sqlVisitorId} )\n                ORDER BY priority DESC\n                LIMIT 1";
     }
     $visitRow = Tracker::getDatabase()->fetch($sql, $bindSql);
     $isNewVisitForced = $this->request->getParam('new_visit');
     $isNewVisitForced = !empty($isNewVisitForced);
     $newVisitEnforcedAPI = $isNewVisitForced && ($this->request->isAuthenticated() || !Config::getInstance()->Tracker['new_visit_api_requires_admin']);
     $enforceNewVisit = $newVisitEnforcedAPI || Config::getInstance()->Debug['tracker_always_new_visitor'];
     if (!$enforceNewVisit && $visitRow && count($visitRow) > 0) {
         // These values will be used throughout the request
         foreach ($persistedVisitAttributes as $field) {
             $this->visitorInfo[$field] = $visitRow[$field];
         }
         $this->visitorInfo['visit_last_action_time'] = strtotime($visitRow['visit_last_action_time']);
         $this->visitorInfo['visit_first_action_time'] = strtotime($visitRow['visit_first_action_time']);
         // Custom Variables copied from Visit in potential later conversion
         if (!empty($selectCustomVariables)) {
             $maxCustomVariables = CustomVariables::getMaxCustomVariables();
             for ($i = 1; $i <= $maxCustomVariables; $i++) {
                 if (isset($visitRow['custom_var_k' . $i]) && strlen($visitRow['custom_var_k' . $i])) {
                     $this->visitorInfo['custom_var_k' . $i] = $visitRow['custom_var_k' . $i];
                 }
                 if (isset($visitRow['custom_var_v' . $i]) && strlen($visitRow['custom_var_v' . $i])) {
                     $this->visitorInfo['custom_var_v' . $i] = $visitRow['custom_var_v' . $i];
                 }
             }
         }
         $this->setIsVisitorKnown(true);
         Common::printDebug("The visitor is known (idvisitor = " . bin2hex($this->visitorInfo['idvisitor']) . ",\n                    config_id = " . bin2hex($configId) . ",\n                    idvisit = {$this->visitorInfo['idvisit']},\n                    last action = " . date("r", $this->visitorInfo['visit_last_action_time']) . ",\n                    first action = " . date("r", $this->visitorInfo['visit_first_action_time']) . ",\n                    visit_goal_buyer' = " . $this->visitorInfo['visit_goal_buyer'] . ")");
         //Common::printDebug($this->visitorInfo);
     } else {
         Common::printDebug("The visitor was not matched with an existing visitor...");
     }
 }
Esempio n. 15
0
 private function getIdVisit($idVisit)
 {
     $LogVisit = Factory::getDAO('log_visit', Tracker::getDatabase());
     return $LogVisit->getByIdvisit($idVisit);
 }
Esempio n. 16
0
 private function getIdVisit($idVisit)
 {
     return Tracker::getDatabase()->fetchRow("SELECT * FROM " . Common::prefixTable('log_visit') . " WHERE idvisit = ?", array($idVisit));
 }
Esempio n. 17
0
 /**
  * @param $valuesToUpdate
  * @throws VisitorNotFoundInDb
  */
 protected function updateExistingVisit($valuesToUpdate)
 {
     $sqlQuery = "UPDATE " . Common::prefixTable('log_visit') . "\n                    SET %s\n                    WHERE idsite = ?\n                        AND idvisit = ?";
     // build sql query
     $updateParts = $sqlBind = array();
     foreach ($valuesToUpdate as $name => $value) {
         // Case where bind parameters don't work
         if (strpos($value, $name) !== false) {
             //$name = 'visit_total_events'
             //$value = 'visit_total_events + 1';
             $updateParts[] = " {$name} = {$value} ";
         } else {
             $updateParts[] = $name . " = ?";
             $sqlBind[] = $value;
         }
     }
     $sqlQuery = sprintf($sqlQuery, implode($updateParts, ', '));
     array_push($sqlBind, $this->request->getIdSite(), (int) $this->visitorInfo['idvisit']);
     $result = Tracker::getDatabase()->query($sqlQuery, $sqlBind);
     $this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp();
     // Debug output
     if (isset($valuesToUpdate['idvisitor'])) {
         $valuesToUpdate['idvisitor'] = bin2hex($valuesToUpdate['idvisitor']);
     }
     Common::printDebug('Updating existing visit: ' . var_export($valuesToUpdate, true));
     if (Tracker::getDatabase()->rowCount($result) == 0) {
         Common::printDebug("Visitor with this idvisit wasn't found in the DB.");
         Common::printDebug("{$sqlQuery} --- ");
         Common::printDebug($sqlBind);
         throw new VisitorNotFoundInDb("The visitor with idvisitor=" . bin2hex($this->visitorInfo['idvisitor']) . " and idvisit=" . $this->visitorInfo['idvisit'] . " wasn't found in the DB, we fallback to a new visitor");
     }
 }
Esempio n. 18
0
 /**
  * Records in the DB the association between the visit and this action.
  *
  * @param int $idVisit is the ID of the current visit in the DB table log_visit
  * @param $visitorIdCookie
  * @param int $idReferrerActionUrl is the ID of the last action done by the current visit.
  * @param $idReferrerActionName
  * @param int $timeSpentReferrerAction is the number of seconds since the last action was done.
  *                 It is directly related to idReferrerActionUrl.
  */
 public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idReferrerActionName, $timeSpentReferrerAction)
 {
     $this->loadIdsFromLogActionTable();
     $visitAction = array('idvisit' => $idVisit, 'idsite' => $this->request->getIdSite(), 'idvisitor' => $visitorIdCookie, 'server_time' => Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()), 'idaction_url' => $this->getIdActionUrl(), 'idaction_url_ref' => $idReferrerActionUrl, 'idaction_name_ref' => $idReferrerActionName, 'time_spent_ref_action' => $timeSpentReferrerAction);
     // idaction_name is NULLable. we only set it when applicable
     if ($this->isActionHasActionName()) {
         $visitAction['idaction_name'] = (int) $this->getIdActionName();
     }
     foreach ($this->actionIdsCached as $field => $idAction) {
         $visitAction[$field] = $idAction === false ? 0 : $idAction;
     }
     $customValue = $this->getCustomFloatValue();
     if (!empty($customValue)) {
         $visitAction[self::DB_COLUMN_CUSTOM_FLOAT] = $customValue;
     }
     $customVariables = $this->getCustomVariables();
     if (!empty($customVariables)) {
         Common::printDebug("Page level Custom Variables: ");
         Common::printDebug($customVariables);
     }
     $visitAction = array_merge($visitAction, $customVariables);
     $fields = implode(", ", array_keys($visitAction));
     $bind = array_values($visitAction);
     $values = Common::getSqlStringFieldsArray($visitAction);
     $sql = "INSERT INTO " . Common::prefixTable('log_link_visit_action') . " ({$fields}) VALUES ({$values})";
     Tracker::getDatabase()->query($sql, $bind);
     $this->idLinkVisitAction = Tracker::getDatabase()->lastInsertId();
     $visitAction['idlink_va'] = $this->idLinkVisitAction;
     Common::printDebug("Inserted new action:");
     Common::printDebug($visitAction);
     /**
      * Triggered after successfully persisting a [visit action entity](/guides/persistence-and-the-mysql-backend#visit-actions).
      * 
      * @param Action $tracker Action The Action tracker instance.
      * @param array $visitAction The visit action entity that was persisted. Read
      *                           [this](/guides/persistence-and-the-mysql-backend#visit-actions) to see what it contains.
      */
     Piwik::postEvent('Tracker.recordAction', array($trackerAction = $this, $visitAction));
 }