Пример #1
0
    /**
     * Authenticates user
     *
     * @return AuthResult
     */
    public function authenticate()
    {
        $rootLogin = Config::getInstance()->superuser['login'];
        $rootPassword = Config::getInstance()->superuser['password'];
        $rootToken = API::getInstance()->getTokenAuth($rootLogin, $rootPassword);
        if (is_null($this->login)) {
            if ($this->token_auth === $rootToken) {
                return new AuthResult(AuthResult::SUCCESS_SUPERUSER_AUTH_CODE, $rootLogin, $this->token_auth);
            }
            $login = Db::fetchOne('SELECT login
                FROM ' . Common::prefixTable('user') . '
					WHERE token_auth = ?', array($this->token_auth));
            if (!empty($login)) {
                return new AuthResult(AuthResult::SUCCESS, $login, $this->token_auth);
            }
        } else {
            if (!empty($this->login)) {
                if ($this->login === $rootLogin && $this->getHashTokenAuth($rootLogin, $rootToken) === $this->token_auth || $rootToken === $this->token_auth) {
                    $this->setTokenAuth($rootToken);
                    return new AuthResult(AuthResult::SUCCESS_SUPERUSER_AUTH_CODE, $rootLogin, $this->token_auth);
                }
                $login = $this->login;
                $userToken = Db::fetchOne('SELECT token_auth
                FROM ' . Common::prefixTable('user') . '
					WHERE login = ?', array($login));
                if (!empty($userToken) && ($this->getHashTokenAuth($login, $userToken) === $this->token_auth || $userToken === $this->token_auth)) {
                    $this->setTokenAuth($userToken);
                    return new AuthResult(AuthResult::SUCCESS, $login, $userToken);
                }
            }
        }
        return new AuthResult(AuthResult::FAILURE, $this->login, $this->token_auth);
    }
Пример #2
0
 /**
  * @param $name
  * @param $type
  * @return string
  */
 private static function getIdActionMatchingNameAndType($name, $type)
 {
     $sql = TableLogAction::getSqlSelectActionId();
     $bind = array($name, $name, $type);
     $idAction = \Piwik\Db::fetchOne($sql, $bind);
     return $idAction;
 }
Пример #3
0
 public static function getDbVersion()
 {
     $version = Db::fetchOne("SELECT option_value FROM " . Common::prefixTable('option') . " WHERE option_name = ?", array('version_Chat_DB'));
     if (!$version) {
         $version = Db::tableExists(Common::prefixTable('chat')) === false ? 0 : 1;
     }
     return $version;
 }
Пример #4
0
 public function insertVisit($visit = array())
 {
     $defaultProperties = array('idsite' => 1, 'idvisitor' => $this->getDummyVisitorId(), 'visit_last_action_time' => '2012-01-01 00:00:00', 'config_id' => $this->getDummyVisitorId(), 'location_ip' => IPUtils::stringToBinaryIP('1.2.3.4'), 'visitor_localtime' => '2012-01-01 00:00:00', 'location_country' => 'xx', 'config_os' => 'xxx', 'visit_total_events' => 0, 'visitor_days_since_last' => 0, 'config_quicktime' => 0, 'config_pdf' => 0, 'config_realplayer' => 0, 'config_silverlight' => 0, 'config_windowsmedia' => 0, 'config_java' => 0, 'config_gears' => 0, 'config_resolution' => 0, 'config_resolution' => '', 'config_cookie' => 0, 'config_director' => 0, 'config_flash' => 0, 'config_browser_version' => '', 'visitor_count_visits' => 1, 'visitor_returning' => 0, 'visit_total_time' => 123, 'visit_entry_idaction_name' => 0, 'visit_entry_idaction_url' => 0, 'visitor_days_since_order' => 0, 'visitor_days_since_first' => 0, 'visit_first_action_time' => '2012-01-01 00:00:00', 'visit_goal_buyer' => 0, 'visit_goal_converted' => 0, 'visit_exit_idaction_name' => 0, 'referer_url' => '', 'location_browser_lang' => 'xx', 'config_browser_engine' => '', 'config_browser_name' => '', 'referer_type' => 0, 'referer_name' => '', 'visit_total_actions' => 0, 'visit_total_searches' => 0);
     $visit = array_merge($defaultProperties, $visit);
     $this->insertInto('log_visit', $visit);
     $idVisit = Db::fetchOne("SELECT LAST_INSERT_ID()");
     return $this->getVisit($idVisit, $allColumns = true);
 }
Пример #5
0
 public function getAverageVisitTimeData($idSite, $lastMinutes = 30, $lastDays = 30)
 {
     \Piwik\Piwik::checkUserHasViewAccess($idSite);
     $lastMinutes = (int) $lastMinutes;
     $lastDays = (int) $lastDays;
     /* Time is UTC in database. */
     $refNow = Date::factory('now');
     $timeLimit = $refNow->subDay($lastDays)->toString('Y-m-d H:i:s');
     $sql = "SELECT MAX(g.average_time) AS maxtime\n                FROM (\n                  SELECT    AVG(visit_total_time) as average_time\n                  FROM      " . \Piwik\Common::prefixTable("log_visit") . "\n                  WHERE     visit_last_action_time >= ?\n                  AND       idsite = ?\n                  GROUP BY  round(UNIX_TIMESTAMP(visit_last_action_time) / ?)\n        ) g";
     $maxtime = \Piwik\Db::fetchOne($sql, array($timeLimit, $idSite, $lastMinutes * 60));
     $timeLimit = $refNow->subHour($lastMinutes / 60)->toString('Y-m-d H:i:s');
     $sql = "SELECT AVG(visit_total_time)\n                FROM " . \Piwik\Common::prefixTable("log_visit") . "\n                WHERE idsite = ?\n                AND visit_last_action_time >= ?";
     $average_time = \Piwik\Db::fetchOne($sql, array($idSite, $timeLimit));
     return array('maxtime' => (int) $maxtime, 'average_time' => (int) $average_time);
 }
Пример #6
0
 public function performSetUp($setupEnvironmentOnly = false)
 {
     parent::performSetUp($setupEnvironmentOnly);
     $this->createSegments();
     $this->setupDashboards();
     $visitorIdDeterministic = bin2hex(Db::fetchOne("SELECT idvisitor FROM " . Common::prefixTable('log_visit') . " WHERE idsite = 2 AND location_latitude IS NOT NULL LIMIT 1"));
     $this->testEnvironment->forcedIdVisitor = $visitorIdDeterministic;
     $this->testEnvironment->overlayUrl = $this->getLocalTestSiteUrl();
     $this->createOverlayTestSite();
     $forcedNowTimestamp = Option::get("Tests.forcedNowTimestamp");
     if ($forcedNowTimestamp == false) {
         throw new Exception("Incorrect fixture setup, Tests.forcedNowTimestamp option does not exist! Run the setup again.");
     }
     $this->testEnvironment->forcedNowTimestamp = $forcedNowTimestamp;
     $this->testEnvironment->save();
 }
Пример #7
0
 public static function getSql()
 {
     $result = array('ALTER TABLE ' . Common::prefixTable('logger_message') . ' MODIFY level VARCHAR(16) NULL' => false);
     $unneededLogTables = array('logger_exception', 'logger_error', 'logger_api_call');
     foreach ($unneededLogTables as $table) {
         $tableName = Common::prefixTable($table);
         try {
             $rows = Db::fetchOne("SELECT COUNT(*) FROM {$tableName}");
             if ($rows == 0) {
                 $result["DROP TABLE {$tableName}"] = false;
             }
         } catch (\Exception $ex) {
             // ignore
         }
     }
     return $result;
 }
Пример #8
0
 public function getMigrations(Updater $updater)
 {
     $result = array($this->migration->db->sql('ALTER TABLE ' . Common::prefixTable('logger_message') . ' MODIFY level VARCHAR(16) NULL'));
     $unneededLogTables = array('logger_exception', 'logger_error', 'logger_api_call');
     foreach ($unneededLogTables as $table) {
         $tableName = Common::prefixTable($table);
         try {
             $rows = Db::fetchOne("SELECT COUNT(*) FROM {$tableName}");
             if ($rows == 0) {
                 $result[] = $this->migration->db->dropTable($table);
             }
         } catch (\Exception $ex) {
             // ignore
         }
     }
     return $result;
 }
Пример #9
0
 private function addArchivingIdMigrationQueries($sql)
 {
     $tables = ArchiveTableCreator::getTablesArchivesInstalled();
     foreach ($tables as $table) {
         $type = ArchiveTableCreator::getTypeFromTableName($table);
         if ($type === ArchiveTableCreator::NUMERIC_TABLE) {
             $maxId = Db::fetchOne('SELECT MAX(idarchive) FROM ' . $table);
             if (!empty($maxId)) {
                 $maxId = (int) $maxId + 500;
             } else {
                 $maxId = 1;
             }
             $sql[] = $this->migration->db->insert($this->sequenceTable, array('name' => $table, 'value' => $maxId));
         }
     }
     return $sql;
 }
Пример #10
0
 private static function addArchivingIdMigrationQueries($sql)
 {
     $tables = ArchiveTableCreator::getTablesArchivesInstalled();
     foreach ($tables as $table) {
         $type = ArchiveTableCreator::getTypeFromTableName($table);
         if ($type === ArchiveTableCreator::NUMERIC_TABLE) {
             $maxId = Db::fetchOne('SELECT MAX(idarchive) FROM ' . $table);
             if (!empty($maxId)) {
                 $maxId = (int) $maxId + 500;
             } else {
                 $maxId = 1;
             }
             $query = self::getQueryToCreateSequence($table, $maxId);
             // refs  #6696, ignores  Integrity constraint violation: 1062 Duplicate entry 'piwik_archive_numeric_2010_01' for key 'PRIMARY'
             $sql[$query] = '1062';
         }
     }
     return $sql;
 }
Пример #11
0
 public function performSetUp($setupEnvironmentOnly = false)
 {
     $this->extraTestEnvVars = array('loadRealTranslations' => 1);
     parent::performSetUp($setupEnvironmentOnly);
     $this->createSegments();
     $this->setupDashboards();
     $visitorIdDeterministic = bin2hex(Db::fetchOne("SELECT idvisitor FROM " . Common::prefixTable('log_visit') . " WHERE idsite = 2 AND location_latitude IS NOT NULL LIMIT 1"));
     $this->testEnvironment->forcedIdVisitor = $visitorIdDeterministic;
     $this->testEnvironment->overlayUrl = $this->getLocalTestSiteUrl();
     $this->createOverlayTestSite();
     $forcedNowTimestamp = Option::get("Tests.forcedNowTimestamp");
     if ($forcedNowTimestamp == false) {
         throw new Exception("Incorrect fixture setup, Tests.forcedNowTimestamp option does not exist! Run the setup again.");
     }
     $this->testEnvironment->forcedNowTimestamp = $forcedNowTimestamp;
     $this->testEnvironment->save();
     // launch archiving so tests don't run out of time
     print "Archiving in fixture set up...";
     VisitsSummaryAPI::getInstance()->get('all', 'year', '2012-08-09');
     VisitsSummaryAPI::getInstance()->get('all', 'year', '2012-08-09', urlencode(OmniFixture::DEFAULT_SEGMENT));
     print "Done.";
 }
Пример #12
0
 private function bannerStats($bannerName, $params)
 {
     $contentPiece = false;
     if (strpos($bannerName, '_') !== false) {
         list($bannerName, $contentPiece) = explode('_', $bannerName);
     }
     $segment = 'contentName==' . $bannerName;
     $recordName = Dimensions::getRecordNameForAction('getContentPieces');
     $subTable = Archive::getDataTableFromArchive($recordName, $params['idSite'], $params['period'], $params['date'], $segment, true);
     //echo '<pre>';
     $bannerTable = new DataTable();
     if (!$contentPiece) {
         foreach ($subTable->getRows() as $row) {
             $ContentPieceId = Db::fetchOne("SELECT idaction FROM piwik_log_action WHERE TYPE = 14 and name = ?", array($row->getColumn('label')));
             $bannerRow = new Row(array(Row::COLUMNS => array('Label' => $row->getColumn('label'), 'Impressions' => $row->getColumn(41), 'Interactions' => $row->getColumn(42), 'Conversion rate' => $this->interactionRate($row->getColumn(41), $row->getColumn(42))), Row::DATATABLE_ASSOCIATED => implode('_', array($bannerName, $ContentPieceId))));
             $bannerTable->addRow($bannerRow);
         }
     } else {
         $orderColumn = str_replace(' ', '_', strtolower($params['filter_sort_column']));
         $orderOrder = in_array($params['filter_sort_order'], array('asc', 'desc')) ? $params['filter_sort_order'] : 'asc';
         $orderLimit = intval($params['filter_limit']);
         $where = '';
         /*
         TODO: filter_pattern is processed by piwik in some way. The results are good with this query, but piwik does some post-processing?
         if (isset($params['filter_pattern'])) {
              $where = 'and piwik_log_action.name like "%' .  $params['filter_pattern'] . '%"';
         }
         */
         $result = Db::fetchAll("\n                    SELECT \n                        trim(substring_index(piwik_log_action.name, '|', 1)) as referrer,\n                        trim(substring_index(piwik_log_action.name, '|', -1)) as target,\n                        sum(IF(idaction_content_interaction is null, 1, 0)) as impressions, \n                        sum(IF(idaction_content_interaction is null, 0, 1)) as interactions,\n                        ((100 / sum(IF(idaction_content_interaction is null, 1, 0))) * sum(IF(idaction_content_interaction is null, 0, 1))) as conversion_rate\n                    FROM piwik_log_link_visit_action \n                    left join piwik_log_action on piwik_log_action.idaction = idaction_content_target\n                    WHERE \n                        idaction_content_name in (SELECT idaction FROM piwik_log_action WHERE name = ?)\n                    and\n                        idaction_content_piece = ?\n                    \n                    {$where}\n\n                    group by piwik_log_action.name\n                    order by {$orderColumn} {$orderOrder}\n                    limit {$orderLimit}\n            ", array($bannerName, $contentPiece));
         foreach ($result as $row) {
             $bannerRow = new Row(array(Row::COLUMNS => array('Referrer' => $row['referrer'], 'Target' => $row['target'], 'Impressions' => $row['impressions'], 'Interactions' => $row['interactions'], 'Conversion rate' => round($row['conversion_rate']) . '%')));
             $bannerTable->addRow($bannerRow);
         }
     }
     return $bannerTable;
 }
 private function getArchiveRowCountWithId($table, $archiveIds)
 {
     return Db::fetchOne("SELECT COUNT(*) FROM {$table} WHERE idarchive IN (" . implode(',', $archiveIds) . ")");
 }
Пример #14
0
 private static function getMaxGoalId()
 {
     return Db::fetchOne("SELECT MAX(idgoal) FROM " . Common::prefixTable('goal'));
 }
Пример #15
0
 protected function insertActionsToKeep($maxIds, $olderThan = true, $insertIntoTempIterationStep = 100000)
 {
     $tempTableName = Common::prefixTable(self::DELETE_UNUSED_ACTIONS_TEMP_TABLE_NAME);
     $idColumns = $this->getTableIdColumns();
     foreach ($this->dimensionMetadataProvider->getActionReferenceColumnsByTable() as $table => $columns) {
         $idCol = $idColumns[$table];
         foreach ($columns as $col) {
             $select = "SELECT {$col} FROM " . Common::prefixTable($table) . " WHERE {$idCol} >= ? AND {$idCol} < ?";
             $sql = "INSERT IGNORE INTO {$tempTableName} {$select}";
             if ($olderThan) {
                 $start = 0;
                 $finish = $maxIds[$table];
             } else {
                 $start = $maxIds[$table];
                 $finish = Db::fetchOne("SELECT MAX({$idCol}) FROM " . Common::prefixTable($table));
             }
             Db::segmentedQuery($sql, $start, $finish, $insertIntoTempIterationStep);
         }
     }
 }
Пример #16
0
 private function getNextIdDashboard($login)
 {
     $nextIdQuery = sprintf('SELECT MAX(iddashboard)+1 FROM %s WHERE login = ?', Common::prefixTable('user_dashboard'));
     $nextId = Db::fetchOne($nextIdQuery, array($login));
     if (empty($nextId)) {
         $nextId = 1;
         return $nextId;
     }
     return $nextId;
 }
Пример #17
0
 private function checkNoMessagesLogged($backend)
 {
     if ($backend == 'file') {
         $this->assertFalse(file_exists(self::getLogFileLocation()));
     } else {
         if ($backend == 'database') {
             $this->assertEquals(0, Db::fetchOne("SELECT COUNT(*) FROM " . Common::prefixTable('logger_message')));
         }
     }
 }
Пример #18
0
 /**
  * Truncates all tables then inserts the data in $tables into each
  * mapped table.
  *
  * @param array $tables Array mapping table names with arrays of row data.
  */
 protected static function restoreDbTables($tables)
 {
     $db = Db::fetchOne("SELECT DATABASE()");
     if (empty($db)) {
         Db::exec("USE " . Config::getInstance()->database_tests['dbname']);
     }
     DbHelper::truncateAllTables();
     // insert data
     $existingTables = DbHelper::getTablesInstalled();
     foreach ($tables as $table => $rows) {
         // create table if it's an archive table
         if (strpos($table, 'archive_') !== false && !in_array($table, $existingTables)) {
             $tableType = strpos($table, 'archive_numeric') !== false ? 'archive_numeric' : 'archive_blob';
             $createSql = DbHelper::getTableCreateSql($tableType);
             $createSql = str_replace(Common::prefixTable($tableType), $table, $createSql);
             Db::query($createSql);
         }
         if (empty($rows)) {
             continue;
         }
         $rowsSql = array();
         $bind = array();
         foreach ($rows as $row) {
             $values = array();
             foreach ($row as $value) {
                 if (is_null($value)) {
                     $values[] = 'NULL';
                 } else {
                     if (is_numeric($value)) {
                         $values[] = $value;
                     } else {
                         if (!ctype_print($value)) {
                             $values[] = "x'" . bin2hex($value) . "'";
                         } else {
                             $values[] = "?";
                             $bind[] = $value;
                         }
                     }
                 }
             }
             $rowsSql[] = "(" . implode(',', $values) . ")";
         }
         $sql = "INSERT INTO `{$table}` VALUES " . implode(',', $rowsSql);
         Db::query($sql, $bind);
     }
 }
Пример #19
0
 private function getRowCountWithIdVisit($table, $idVisit)
 {
     return Db::fetchOne("SELECT COUNT(*) FROM " . Common::prefixTable($table) . " WHERE idvisit = {$idVisit}");
 }
Пример #20
0
 public static function goalExists($idSite, $idGoal)
 {
     return Db::fetchOne("SELECT COUNT(*) FROM " . Common::prefixTable('goal') . " WHERE idgoal = ? AND idsite = ?", array($idGoal, $idSite)) != 0;
 }
Пример #21
0
 private static function getBestPathForLoadData()
 {
     try {
         $path = Db::fetchOne('SELECT @@secure_file_priv');
         // was introduced in 5.0.38
     } catch (Exception $e) {
         // we do not rethrow exception as an error is expected if MySQL is < 5.0.38
         // in this case tableInsertBatch might still work
     }
     if (empty($path) || !@is_dir($path) || !@is_writable($path)) {
         $path = StaticContainer::get('path.tmp') . '/assets/';
     } elseif (!Common::stringEndsWith($path, '/')) {
         $path .= '/';
     }
     return $path;
 }
Пример #22
0
 /**
  * Returns true if the site doesn't have log data.
  *
  * @param int $siteId
  * @return bool
  */
 public function isSiteEmpty($siteId)
 {
     $sql = sprintf('SELECT idsite FROM %s WHERE idsite = ? limit 1', Common::prefixTable('log_visit'));
     $result = \Piwik\Db::fetchOne($sql, array($siteId));
     return $result == null;
 }
Пример #23
0
 protected function _tableExists($tableName)
 {
     $dbName = Config::getInstance()->database['dbname'];
     $sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ?";
     return Db::fetchOne($sql, array($dbName, Common::prefixTable($tableName))) == 1;
 }
Пример #24
0
 public static function isOptimizeInnoDBSupported($version = null)
 {
     if ($version === null) {
         $version = Db::fetchOne("SELECT VERSION()");
     }
     $version = strtolower($version);
     if (strpos($version, "mariadb") === false) {
         return false;
     }
     $semanticVersion = strstr($version, '-', $beforeNeedle = true);
     return version_compare($semanticVersion, '10.1.1', '>=');
 }
Пример #25
0
 private function insertArchiveRow($idSite, $date, $periodLabel)
 {
     $periodObject = \Piwik\Period\Factory::build($periodLabel, $date);
     $dateStart = $periodObject->getDateStart();
     $dateEnd = $periodObject->getDateEnd();
     $table = ArchiveTableCreator::getNumericTable($dateStart);
     $idArchive = (int) Db::fetchOne("SELECT MAX(idarchive) FROM {$table} WHERE name LIKE 'done%'");
     $idArchive = $idArchive + 1;
     $periodId = Piwik::$idPeriods[$periodLabel];
     $doneFlag = 'done';
     if ($idArchive % 5 == 1) {
         $doneFlag = Rules::getDoneFlagArchiveContainsAllPlugins(self::$segment1);
     } else {
         if ($idArchive % 5 == 2) {
             $doneFlag .= '.VisitsSummary';
         } else {
             if ($idArchive % 5 == 3) {
                 $doneFlag = Rules::getDoneFlagArchiveContainsOnePlugin(self::$segment1, 'UserCountry');
             } else {
                 if ($idArchive % 5 == 4) {
                     $doneFlag = Rules::getDoneFlagArchiveContainsAllPlugins(self::$segment2);
                 }
             }
         }
     }
     $sql = "INSERT INTO {$table} (idarchive, name, idsite, date1, date2, period, ts_archived)\n                     VALUES ({$idArchive}, 'nb_visits', {$idSite}, '{$dateStart}', '{$dateEnd}', {$periodId}, NOW()),\n                            ({$idArchive}, '{$doneFlag}', {$idSite}, '{$dateStart}', '{$dateEnd}', {$periodId}, NOW())";
     Db::query($sql);
 }
Пример #26
0
 private function getNextAlertId()
 {
     $idAlert = Db::fetchOne("SELECT max(idalert) + 1 FROM " . Common::prefixTable('alert'));
     if (empty($idAlert)) {
         $idAlert = 1;
     }
     return $idAlert;
 }
Пример #27
0
 private function insertActionsToKeep($maxIds, $olderThan = true)
 {
     $tempTableName = Common::prefixTable(self::TEMP_TABLE_NAME);
     $idColumns = $this->getTableIdColumns();
     foreach ($this->getIdActionColumns() as $table => $columns) {
         $idCol = $idColumns[$table];
         foreach ($columns as $col) {
             $select = "SELECT {$col} FROM " . Common::prefixTable($table) . " WHERE {$idCol} >= ? AND {$idCol} < ?";
             $sql = "INSERT IGNORE INTO {$tempTableName} {$select}";
             if ($olderThan) {
                 $start = 0;
                 $finish = $maxIds[$table];
             } else {
                 $start = $maxIds[$table];
                 $finish = Db::fetchOne("SELECT MAX({$idCol}) FROM " . Common::prefixTable($table));
             }
             Db::segmentedQuery($sql, $start, $finish, self::$selectSegmentSize);
         }
     }
     // allow code to be executed after data is inserted. for concurrency testing purposes.
     if ($olderThan) {
         /**
          * @ignore
          */
         Piwik::postEvent("LogDataPurger.ActionsToKeepInserted.olderThan");
     } else {
         /**
          * @ignore
          */
         Piwik::postEvent("LogDataPurger.ActionsToKeepInserted.newerThan");
     }
 }
 /**
  * @param $pageUrlFoundInDb
  * @return string
  * @throws Exception
  */
 private function insertPageUrlAsAction($pageUrlFoundInDb)
 {
     TableLogAction::loadIdsAction(array('idaction_url' => array($pageUrlFoundInDb, Action::TYPE_PAGE_URL)));
     $actionIdFoundInDb = Db::fetchOne("SELECT idaction from " . Common::prefixTable('log_action') . " WHERE name = ?", $pageUrlFoundInDb);
     $this->assertNotEmpty($actionIdFoundInDb, "Action {$pageUrlFoundInDb} was not found in the " . Common::prefixTable('log_action') . " table.");
     return $actionIdFoundInDb;
 }
Пример #29
0
 static function update()
 {
     $returningMetrics = array('nb_visits_returning', 'nb_actions_returning', 'max_actions_returning', 'sum_visit_length_returning', 'bounce_count_returning', 'nb_visits_converted_returning', 'nb_uniq_visitors_returning');
     $now = Date::factory('now')->getDatetime();
     $archiveNumericTables = Db::get()->fetchCol("SHOW TABLES LIKE '%archive_numeric%'");
     // for each numeric archive table, copy *_returning metrics to VisitsSummary metrics w/ the appropriate
     // returning visit segment
     foreach ($archiveNumericTables as $table) {
         // get archives w/ *._returning
         $sql = "SELECT idarchive, idsite, period, date1, date2\n                      FROM {$table}\n                     WHERE name IN ('" . implode("','", $returningMetrics) . "')\n                  GROUP BY idarchive";
         $idArchivesWithReturning = Db::fetchAll($sql);
         // get archives for visitssummary returning visitor segment
         $sql = "SELECT idarchive, idsite, period, date1, date2\n                      FROM {$table}\n                     WHERE name = ?\n                  GROUP BY idarchive";
         $visitSummaryReturningSegmentDone = Rules::getDoneFlagArchiveContainsOnePlugin(new Segment(VisitFrequencyApi::RETURNING_VISITOR_SEGMENT, $idSites = array()), 'VisitsSummary');
         $idArchivesWithVisitReturningSegment = Db::fetchAll($sql, array($visitSummaryReturningSegmentDone));
         // collect info for new visitssummary archives have to be created to match archives w/ *._returning
         // metrics
         $missingIdArchives = array();
         $idArchiveMappings = array();
         foreach ($idArchivesWithReturning as $row) {
             $withMetricsIdArchive = $row['idarchive'];
             foreach ($idArchivesWithVisitReturningSegment as $segmentRow) {
                 if ($row['idsite'] == $segmentRow['idsite'] && $row['period'] == $segmentRow['period'] && $row['date1'] == $segmentRow['date1'] && $row['date2'] == $segmentRow['date2']) {
                     $idArchiveMappings[$withMetricsIdArchive] = $segmentRow['idarchive'];
                 }
             }
             if (!isset($idArchiveMappings[$withMetricsIdArchive])) {
                 $missingIdArchives[$withMetricsIdArchive] = $row;
             }
         }
         // if there are missing idarchives, fill out new archive row values
         if (!empty($missingIdArchives)) {
             $newIdArchiveStart = Db::fetchOne("SELECT MAX(idarchive) FROM {$table}") + 1;
             foreach ($missingIdArchives as $withMetricsIdArchive => &$rowToInsert) {
                 $idArchiveMappings[$withMetricsIdArchive] = $newIdArchiveStart;
                 $rowToInsert['idarchive'] = $newIdArchiveStart;
                 $rowToInsert['ts_archived'] = $now;
                 $rowToInsert['name'] = $visitSummaryReturningSegmentDone;
                 $rowToInsert['value'] = ArchiveWriter::DONE_OK;
                 ++$newIdArchiveStart;
             }
             // add missing archives
             try {
                 $params = array();
                 foreach ($missingIdArchives as $missingIdArchive) {
                     $params[] = array_values($missingIdArchive);
                 }
                 BatchInsert::tableInsertBatch($table, array_keys(reset($missingIdArchives)), $params, $throwException = false);
             } catch (\Exception $ex) {
                 Updater::handleQueryError($ex, "<batch insert>", false, __FILE__);
             }
         }
         // update idarchive & name columns in rows with *._returning metrics
         $updateSqlPrefix = "UPDATE {$table}\n                                   SET idarchive = CASE idarchive ";
         $updateSqlSuffix = " END, name = CASE name ";
         foreach ($returningMetrics as $metric) {
             $newMetricName = substr($metric, 0, strlen($metric) - strlen(VisitFrequencyApi::COLUMN_SUFFIX));
             $updateSqlSuffix .= "WHEN '{$metric}' THEN '" . $newMetricName . "' ";
         }
         $updateSqlSuffix .= " END WHERE idarchive IN (%s)\n                                        AND name IN ('" . implode("','", $returningMetrics) . "')";
         // update only 1000 rows at a time so we don't send too large an SQL query to MySQL
         foreach (array_chunk($missingIdArchives, 1000, $preserveKeys = true) as $chunk) {
             $idArchives = array();
             $updateSql = $updateSqlPrefix;
             foreach ($chunk as $withMetricsIdArchive => $row) {
                 $updateSql .= "WHEN {$withMetricsIdArchive} THEN {$row['idarchive']} ";
                 $idArchives[] = $withMetricsIdArchive;
             }
             $updateSql .= sprintf($updateSqlSuffix, implode(',', $idArchives));
             Updater::executeMigrationQuery($updateSql, false, __FILE__);
         }
     }
 }
Пример #30
0
 /**
  * Returns the language for the user
  *
  * @param string $login
  * @return string
  */
 public function getLanguageForUser($login)
 {
     if ($login == 'anonymous') {
         return false;
     }
     Piwik::checkUserHasSuperUserAccessOrIsTheUser($login);
     return Db::fetchOne('SELECT language FROM ' . Common::prefixTable('user_language') . ' WHERE login = ? ', array($login));
 }