Example #1
0
 /**
  * @return string|false false if current version is the latest available, 
  * 	 or the latest version number if a newest release is available
  */
 public static function isNewestVersionAvailable()
 {
     $latestVersion = Piwik_GetOption(self::LATEST_VERSION);
     if (!empty($latestVersion) && version_compare(Piwik_Version::VERSION, $latestVersion) == -1) {
         return $latestVersion;
     }
     return false;
 }
    function deleteLogTables()
    {
        $deleteSettings = Zend_Registry::get('config')->Deletelogs;

        //Make sure, log deletion is enabled
        if ($deleteSettings->delete_logs_enable == 0) {
            return;
        }

        //Log deletion may not run until it is once rescheduled (initial run). This is the only way to guarantee the calculated next scheduled deletion time.
        $initialDelete = Piwik_GetOption(self::OPTION_LAST_DELETE_PIWIK_LOGS_INITIAL);
        if (empty($initialDelete)) {
            Piwik_SetOption(self::OPTION_LAST_DELETE_PIWIK_LOGS_INITIAL, 1);
            return;
        }

        //Make sure, log purging is allowed to run now
        $lastDelete = Piwik_GetOption(self::OPTION_LAST_DELETE_PIWIK_LOGS);
        $deleteIntervalSeconds = $this->getDeleteIntervalInSeconds($deleteSettings->delete_logs_schedule_lowest_interval);

        if ($lastDelete === false ||
            ($lastDelete !== false && ((int)$lastDelete + $deleteIntervalSeconds) <= time())
        ) {

            $maxIdVisit = $this->getDeleteIdVisitOffset($deleteSettings->delete_logs_older_than);

            $logTables = $this->getDeleteTableLogTables();

            //set lastDelete time to today
            $date = Piwik_Date::factory("today");
            $lastDeleteDate = $date->getTimestamp();

            /*
             * Tell the DB that log deletion has run BEFORE deletion is executed;
             * If deletion / table optimization exceeds execution time, other tasks maybe prevented of being executed every time,
             * when the schedule is triggered.
             */
            Piwik_SetOption(self::OPTION_LAST_DELETE_PIWIK_LOGS, $lastDeleteDate);

            //Break if no ID was found (nothing to delete for given period)
            if (empty($maxIdVisit)) {
                return;
            }

            foreach ($logTables as $logTable) {
                $this->deleteRowsFromTable($logTable, $maxIdVisit, $deleteSettings->delete_max_rows_per_run * self::DELETE_MAX_ROWS_MULTIPLICATOR);
            }

            //optimize table overhead after deletion
            $query = "OPTIMIZE TABLE " . implode(",", $logTables);
            Piwik_Query($query);
        }
    }
Example #3
0
 public static function getScheduledTimeForTask($className, $methodName)
 {
     // Gets the array where rescheduled timetables are stored
     $option = Piwik_GetOption(self::TIMETABLE_OPTION_STRING);
     $timetable = self::getTimetableFromOption($option);
     if ($timetable === false) {
         return;
     }
     $taskName = $className . '.' . $methodName;
     if (isset($timetable[$taskName])) {
         return $timetable[$taskName];
     } else {
         return false;
     }
 }
Example #4
0
 public static function runTasks()
 {
     // Gets the array where rescheduled timetables are stored
     $option = Piwik_GetOption(self::TIMETABLE_OPTION_STRING);
     if ($option === false) {
         $timetable = array();
     } elseif (!is_string($option)) {
         return;
     } else {
         $timetable = unserialize($option);
     }
     if (isset($GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) && $GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) {
         $timetable = array();
     }
     // Collects tasks
     Piwik_PostEvent(self::GET_TASKS_EVENT, $tasks);
     $return = array();
     // Loop through each task
     foreach ($tasks as $task) {
         $scheduledTime = $task->getScheduledTime();
         $className = $task->getClassName();
         $methodName = $task->getMethodName();
         $fullyQualifiedMethodName = get_class($className) . '.' . $methodName;
         /*
          * Task has to be executed if :
          * 	- it is the first time, ie. rescheduledTime is not set
          *  - that task has already been executed and the current system time is greater than the
          *    rescheduled time.
          */
         if (!isset($timetable[$fullyQualifiedMethodName]) || isset($timetable[$fullyQualifiedMethodName]) && time() >= $timetable[$fullyQualifiedMethodName]) {
             // Updates the rescheduled time
             $timetable[$fullyQualifiedMethodName] = $scheduledTime->getRescheduledTime();
             Piwik_SetOption(self::TIMETABLE_OPTION_STRING, serialize($timetable));
             // Run the task
             try {
                 $timer = new Piwik_Timer();
                 call_user_func(array($className, $methodName));
                 $message = $timer->__toString();
             } catch (Exception $e) {
                 $message = 'ERROR: ' . $e->getMessage();
             }
             $return[] = array('task' => $fullyQualifiedMethodName, 'output' => $message);
         }
     }
     return $return;
 }
Example #5
0
 protected function getDeleteLogsInfo()
 {
     Piwik::checkUserIsSuperUser();
     $deleteLogsInfos = array();
     $taskScheduler = new Piwik_TaskScheduler();
     $deleteLogsInfos["config"] = Zend_Registry::get('config')->Deletelogs->toArray();
     $privacyManager = new Piwik_PrivacyManager();
     $deleteLogsInfos["deleteTables"] = implode(", ", $privacyManager->getDeleteTableLogTables());
     $scheduleTimetable = $taskScheduler->getScheduledTimeForTask("Piwik_PrivacyManager", "deleteLogTables");
     $optionTable = Piwik_GetOption(self::OPTION_LAST_DELETE_PIWIK_LOGS);
     //If task was already rescheduled, read time from taskTimetable. Else, calculate next possible runtime.
     if (!empty($scheduleTimetable) && $scheduleTimetable - time() > 0) {
         $nextPossibleSchedule = (int) $scheduleTimetable;
     } else {
         $date = Piwik_Date::factory("today");
         $nextPossibleSchedule = $date->addDay(1)->getTimestamp();
     }
     //deletion schedule did not run before
     if (empty($optionTable)) {
         $deleteLogsInfos["lastRun"] = false;
         //next run ASAP (with next schedule run)
         $date = Piwik_Date::factory("today");
         $deleteLogsInfos["nextScheduleTime"] = $nextPossibleSchedule;
     } else {
         $deleteLogsInfos["lastRun"] = $optionTable;
         $deleteLogsInfos["lastRunPretty"] = Piwik_Date::factory((int) $optionTable)->getLocalized('%day% %shortMonth% %longYear%');
         //Calculate next run based on last run + interval
         $nextScheduleRun = (int) ($deleteLogsInfos["lastRun"] + $deleteLogsInfos["config"]["delete_logs_schedule_lowest_interval"] * 24 * 60 * 60);
         //is the calculated next run in the past? (e.g. plugin was disabled in the meantime or something) -> run ASAP
         if ($nextScheduleRun - time() <= 0) {
             $deleteLogsInfos["nextScheduleTime"] = $nextPossibleSchedule;
         } else {
             $deleteLogsInfos["nextScheduleTime"] = $nextScheduleRun;
         }
     }
     $deleteLogsInfos["nextRunPretty"] = Piwik::getPrettyTimeFromSeconds($deleteLogsInfos["nextScheduleTime"] - time());
     return $deleteLogsInfos;
 }
 public static function setUpBeforeClass()
 {
     $dbName = false;
     if (!empty($GLOBALS['PIWIK_BENCHMARK_DATABASE'])) {
         $dbName = $GLOBALS['PIWIK_BENCHMARK_DATABASE'];
     }
     // connect to database
     self::createTestConfig();
     self::connectWithoutDatabase();
     // create specified fixture (global var not set, use default no-data fixture (see end of this file))
     if (empty($GLOBALS['PIWIK_BENCHMARK_FIXTURE'])) {
         $fixtureName = 'Piwik_Test_Fixture_EmptyOneSite';
     } else {
         $fixtureName = 'Piwik_Test_Fixture_' . $GLOBALS['PIWIK_BENCHMARK_FIXTURE'];
     }
     self::$fixture = new $fixtureName();
     // figure out if the desired fixture has already been setup, and if not empty the database
     $installedFixture = false;
     try {
         if (isset(self::$fixture->tablesPrefix)) {
             Piwik_Config::getInstance()->database['tables_prefix'] = self::$fixture->tablesPrefix;
             Piwik_Common::$cachedTablePrefix = null;
         }
         Piwik_Query("USE " . $dbName);
         $installedFixture = Piwik_GetOption('benchmark_fixture_name');
     } catch (Exception $ex) {
         // ignore
     }
     $createEmptyDatabase = $fixtureName != $installedFixture;
     parent::setUpBeforeClass($dbName, $createEmptyDatabase, $createConfig = false);
     // if we created an empty database, setup the fixture
     if ($createEmptyDatabase) {
         self::$fixture->setUp();
         Piwik_SetOption('benchmark_fixture_name', $fixtureName);
     }
 }
Example #7
0
 /**
  * Returns the cached the Piwik URL, eg. http://demo.piwik.org/ or http://example.org/piwik/ 
  * If not found, then tries to cache it and returns the value.
  *
  * If the Piwik URL changes (eg. Piwik moved to new server), the value will automatically be refreshed in the cache.
  * @return string
  */
 public static function getPiwikUrl()
 {
     $key = 'piwikUrl';
     $url = Piwik_GetOption($key);
     if (Piwik_Common::isPhpCliMode() || Piwik_Common::isArchivePhpTriggered() || defined('PIWIK_MODE_ARCHIVE')) {
         return $url;
     }
     $currentUrl = Piwik_Common::sanitizeInputValue(Piwik_Url::getCurrentUrlWithoutFileName());
     if (empty($url) || $currentUrl != $url) {
         if (strlen($currentUrl) >= strlen('http://a/')) {
             Piwik_SetOption($key, $currentUrl, $autoload = true);
         }
         $url = $currentUrl;
     }
     return $url;
 }
 protected function buildView()
 {
     // access control
     $idSite = Piwik_Common::getRequestVar('idSite', 1, 'int');
     Piwik_API_Request::reloadAuthUsingTokenAuth();
     if (!Piwik::isUserHasViewAccess($idSite)) {
         throw new Exception(Piwik_TranslateException('General_ExceptionPrivilegeAccessWebsite', array("'view'", $idSite)));
     }
     // collect data
     $this->parametersToModify['action'] = $this->currentControllerAction;
     $this->parametersToModify = array_merge($this->variablesDefault, $this->parametersToModify);
     $this->graphData = $this->getGraphData();
     // build view
     $view = new Piwik_View($this->dataTableTemplate);
     $view->width = $this->width;
     $view->height = $this->height;
     $view->chartDivId = $this->getUniqueIdViewDataTable() . "Chart";
     $view->graphType = $this->graphType;
     $view->data = $this->graphData;
     $view->isDataAvailable = strpos($this->graphData, '"series":[]') === false;
     $view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet();
     $view->properties = $this->getViewProperties();
     $view->reportDocumentation = $this->getReportDocumentation();
     // if it's likely that the report data for this data table has been purged,
     // set whether we should display a message to that effect.
     $view->showReportDataWasPurgedMessage = $this->hasReportBeenPurged();
     $view->deleteReportsOlderThan = Piwik_GetOption('delete_reports_older_than');
     return $view;
 }
Example #9
0
 private function doWelcomeUpdates($view, $componentsWithUpdateFile)
 {
     $view->new_piwik_version = Piwik_Version::VERSION;
     $view->commandUpgradePiwik = "<br /><code>php " . Piwik_Common::getPathToPiwikRoot() . "/index.php  -- \"module=CoreUpdater\" </code>";
     $pluginNamesToUpdate = array();
     $coreToUpdate = false;
     // handle case of existing database with no tables
     if (!Piwik::isInstalled()) {
         $this->errorMessages[] = Piwik_Translate('CoreUpdater_EmptyDatabaseError', Zend_Registry::get('config')->database->dbname);
         $this->coreError = true;
         $currentVersion = 'N/A';
     } else {
         $this->errorMessages = array();
         try {
             $currentVersion = Piwik_GetOption('version_core');
         } catch (Exception $e) {
             $currentVersion = '<= 0.2.9';
         }
         foreach ($componentsWithUpdateFile as $name => $filenames) {
             if ($name == 'core') {
                 $coreToUpdate = true;
             } else {
                 $pluginNamesToUpdate[] = $name;
             }
         }
     }
     // check file integrity
     $integrityInfo = Piwik::getFileIntegrityInformation();
     if (isset($integrityInfo[1])) {
         if ($integrityInfo[0] == false) {
             $this->warningMessages[] = '<b>' . Piwik_Translate('General_FileIntegrityWarningExplanation') . '</b>';
         }
         $this->warningMessages = array_merge($this->warningMessages, array_slice($integrityInfo, 1));
     }
     Piwik::deleteAllCacheOnUpdate();
     $view->coreError = $this->coreError;
     $view->warningMessages = $this->warningMessages;
     $view->errorMessages = $this->errorMessages;
     $view->current_piwik_version = $currentVersion;
     $view->pluginNamesToUpdate = $pluginNamesToUpdate;
     $view->coreToUpdate = $coreToUpdate;
     echo $view->render();
 }
Example #10
0
	public static function start($options = false)
	{
		if(Piwik_Common::isPhpCliMode() || version_compare(Piwik_GetOption('version_core'), '1.5-b5') < 0)
		{
			return;
		}

		// use cookies to store session id on the client side
		@ini_set('session.use_cookies', '1');

		// prevent attacks involving session ids passed in URLs
		@ini_set('session.use_only_cookies', '1');

		// advise browser that session cookie should only be sent over secure connection
		if(Piwik_Url::getCurrentScheme() === 'https')
		{
			@ini_set('session.cookie_secure', '1');
		}

		// advise browser that session cookie should only be accessible through the HTTP protocol (i.e., not JavaScript)
		@ini_set('session.cookie_httponly', '1');

		// don't use the default: PHPSESSID
		$sessionName = defined('PIWIK_SESSION_NAME') ? PIWIK_SESSION_NAME : 'PIWIK_SESSID';
		@ini_set('session.name', $sessionName);

		// proxies may cause the referer check to fail and
		// incorrectly invalidate the session
		@ini_set('session.referer_check', '');

		// we consider these to be misconfigurations, in that
		// - user  - we can't verify that user-defined session handler functions have been set via session_set_save_handler()
		// - mm    - this handler is not recommended, unsupported, not available for Windows, and has a potential concurrency issue
		// - files - this handler doesn't work well in load-balanced environments and may have a concurrency issue with locked session files
		$currentSaveHandler = ini_get('session.save_handler');
		if(in_array($currentSaveHandler, array('user', 'mm', 'files')))
		{
			$db = Zend_Registry::get('db');

			$config = array(
				'name' => Piwik_Common::prefixTable('session'),
				'primary' => 'id',
				'modifiedColumn' => 'modified',
				'dataColumn' => 'data',
				'lifetimeColumn' => 'lifetime',
				'db' => $db,
			);

			$saveHandler = new Piwik_Session_SaveHandler_DbTable($config);
			if($saveHandler)
			{			
				self::setSaveHandler($saveHandler);
			}
		}

		// garbage collection may disabled by default (e.g., Debian)
		if(ini_get('session.gc_probability') == 0)
		{
			@ini_set('session.gc_probability', 1);
		}

		try {
			Zend_Session::start();
			register_shutdown_function(array('Zend_Session', 'writeClose'), true);
		} catch(Exception $e) {
			Piwik::log('Unable to start session: ' . $e->getMessage());
			Piwik_ExitWithMessage(Piwik_Translate('General_ExceptionUnableToStartSession'));
		}
	}
Example #11
0
 /** Returns the date when the cacheDataByArchiveNameReports was last run. */
 public static function getDateOfLastCachingRun()
 {
     return Piwik_GetOption(self::TIME_OF_LAST_TASK_RUN_OPTION);
 }
Example #12
0
 /**
  * Returns contents of general (global) cache
  *
  * @return array
  */
 protected static function getCacheGeneral()
 {
     $cache = self::getTrackerCache();
     $cacheId = 'general';
     $expectedRows = 3;
     if (($cacheContent = $cache->get($cacheId)) !== false && count($cacheContent) == $expectedRows) {
         return $cacheContent;
     }
     self::initCorePiwikInTrackerMode();
     $cacheContent = array('isBrowserTriggerArchivingEnabled' => Piwik_ArchiveProcessing::isBrowserTriggerArchivingEnabled(), 'lastTrackerCronRun' => Piwik_GetOption('lastTrackerCronRun'), 'currentLocationProviderId' => Piwik_UserCountry_LocationProvider::getCurrentProviderId());
     return $cacheContent;
 }
Example #13
0
 private function doWelcomeUpdates($view, $componentsWithUpdateFile)
 {
     $view->new_piwik_version = Piwik_Version::VERSION;
     $pluginNamesToUpdate = array();
     $coreToUpdate = false;
     // handle case of existing database with no tables
     $tablesInstalled = Piwik::getTablesInstalled();
     if (count($tablesInstalled) == 0) {
         $this->errorMessages[] = Piwik_Translate('CoreUpdater_EmptyDatabaseError', Zend_Registry::get('config')->database->dbname);
         $this->coreError = true;
         $currentVersion = 'N/A';
     } else {
         $this->errorMessages = array();
         try {
             $currentVersion = Piwik_GetOption('version_core');
         } catch (Exception $e) {
             $currentVersion = '<= 0.2.9';
         }
         foreach ($componentsWithUpdateFile as $name => $filenames) {
             if ($name == 'core') {
                 $coreToUpdate = true;
             } else {
                 $pluginNamesToUpdate[] = $name;
             }
         }
     }
     $view->coreError = $this->coreError;
     $view->errorMessages = $this->errorMessages;
     $view->current_piwik_version = $currentVersion;
     $view->pluginNamesToUpdate = $pluginNamesToUpdate;
     $view->coreToUpdate = $coreToUpdate;
     $view->clearCompiledTemplates();
     echo $view->render();
 }
	static public function isBrowserTriggerArchivingEnabled()
	{
		$browserArchivingEnabled = Piwik_GetOption(self::OPTION_BROWSER_TRIGGER_ARCHIVING);
		if($browserArchivingEnabled !== false)
		{
			return (bool)$browserArchivingEnabled;
		}
		return (bool)Zend_Registry::get('config')->General->enable_browser_archiving_triggering;
	}
Example #15
0
 protected function initStateFromParameters()
 {
     // Detect parameters
     $reset = $this->isParameterSet("force-all-periods", $valuePossible = true);
     $forceAll = $this->isParameterSet("force-all-websites");
     $forceTimeoutPeriod = $this->isParameterSet("force-timeout-for-periods", $valuePossible = true);
     if (!empty($forceTimeoutPeriod) && $forceTimeoutPeriod !== true) {
         // Ensure the cache for periods is at least as high as cache for today
         $todayTTL = Piwik_ArchiveProcessing::getTodayArchiveTimeToLive();
         if ($forceTimeoutPeriod < $todayTTL) {
             $this->log("WARNING: Automatically increasing --force-timeout-for-periods from {$forceTimeoutPeriod} to " . $todayTTL . " to match the cache timeout for Today's report specified in Piwik UI > Settings > General Settings");
             $forceTimeoutPeriod = $todayTTL;
         }
         $this->processPeriodsMaximumEverySeconds = $forceTimeoutPeriod;
     }
     // Recommend to disable browser archiving when using this script
     if (Piwik_ArchiveProcessing::isBrowserTriggerArchivingEnabled()) {
         $this->log("NOTE: if you execute this script at least once per hour (or more often) in a crontab, you may disable 'Browser trigger archiving' in Piwik UI > Settings > General Settings. ");
         $this->log("      see doc at: http://piwik.org/docs/setup-auto-archiving/");
     }
     if ($reset) {
         $this->log("--force-all-periods was detected: the script will run as if it was its first run, and will trigger archiving for all periods.");
         $this->shouldResetState = true;
         if (!$forceAll && is_numeric($reset) && $reset > 0) {
             $this->firstRunActiveWebsitesWithTraffic = (int) $reset;
         }
     }
     if ($forceAll) {
         $this->log("--force-all-websites was detected: the script will archive all websites and all periods sequentially");
         $this->shouldArchiveAllWebsites = true;
     }
     $this->timeLastCompleted = Piwik_GetOption(self::OPTION_ARCHIVING_FINISHED_TS);
     if ($this->shouldResetState) {
         $this->timeLastCompleted = false;
     }
 }
Example #16
0
 /**
  * Determine if normal users can manage their own SMS API credential
  *
  * @return bool false if SMS API credential only manageable by super admin, true otherwise
  */
 public function getDelegatedManagement()
 {
     Piwik::checkUserIsNotAnonymous();
     return Piwik_GetOption(Piwik_MobileMessaging::DELEGATED_MANAGEMENT_OPTION) == 'true';
 }
Example #17
0
 protected function buildView()
 {
     $view = new Piwik_View($this->dataTableTemplate);
     if (!$this->isDataAvailable) {
         $view->cloudValues = array();
     } else {
         $columnToDisplay = $this->getColumnToDisplay();
         $columnTranslation = $this->getColumnTranslation($columnToDisplay);
         $values = $this->dataTable->getColumn($columnToDisplay);
         $labels = $this->dataTable->getColumn('label');
         $labelMetadata = array();
         foreach ($this->dataTable->getRows() as $row) {
             $logo = false;
             if ($this->displayLogoInsteadOfLabel) {
                 $logo = $row->getMetadata('logo');
             }
             $labelMetadata[$row->getColumn('label')] = array('logo' => $logo, 'url' => $row->getMetadata('url'));
         }
         $cloud = new Piwik_Visualization_Cloud();
         foreach ($labels as $i => $label) {
             $cloud->addWord($label, $values[$i]);
         }
         $cloudValues = $cloud->render('array');
         foreach ($cloudValues as &$value) {
             $value['logoWidth'] = round(max(16, $value['percent']));
         }
         $view->columnTranslation = $columnTranslation;
         $view->labelMetadata = $labelMetadata;
         $view->cloudValues = $cloudValues;
     }
     $view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet();
     $view->properties = $this->getViewProperties();
     $view->reportDocumentation = $this->getReportDocumentation();
     // if it's likely that the report data for this data table has been purged,
     // set whether we should display a message to that effect.
     $view->showReportDataWasPurgedMessage = $this->hasReportBeenPurged();
     $view->deleteReportsOlderThan = Piwik_GetOption('delete_reports_older_than');
     return $view;
 }
Example #18
0
 /**
  * Called at the end of the archiving process.
  * Does some cleaning job in the database.
  * 
  * @return void
  */
 protected function postCompute()
 {
     parent::postCompute();
     $blobTable = $this->tableArchiveBlob->getTableName();
     $numericTable = $this->tableArchiveNumeric->getTableName();
     // delete out of date records maximum once per day (DELETE request is costly)
     $key = 'lastPurge_' . $blobTable;
     $timestamp = Piwik_GetOption($key);
     if (!$timestamp || $timestamp < time() - 86400) {
         // we delete out of date daily archives from table, maximum once per day
         // those for day N that were processed on day N (means the archives are only partial as the day wasn't finished)
         $query = "/* SHARDING_ID_SITE = " . $this->idsite . " */ \tDELETE \n\t\t\t\t\t\tFROM %s\n\t\t\t\t\t\tWHERE period = ? \n\t\t\t\t\t\t\tAND date1 = DATE(ts_archived)\n\t\t\t\t\t\t\tAND DATE(ts_archived) <> CURRENT_DATE()\n\t\t\t\t\t\t";
         Piwik_Query(sprintf($query, $blobTable), Piwik::$idPeriods['day']);
         Piwik_Query(sprintf($query, $numericTable), Piwik::$idPeriods['day']);
         // we delete out of date Period records (week/month/etc)
         // we delete archives that were archived before the end of the period
         // and only if they are at least 1 day old (so we don't delete archives computed today that may be stil valid)
         $query = "\tDELETE \n\t\t\t\t\t\tFROM %s\n\t\t\t\t\t\tWHERE period > ? \n\t\t\t\t\t\t\tAND DATE(ts_archived) <= date2\n\t\t\t\t\t\t\tAND date(ts_archived) < date_sub(CURRENT_DATE(), INTERVAL 1 DAY)\n\t\t\t\t\t\t";
         Piwik_Query(sprintf($query, $blobTable), Piwik::$idPeriods['day']);
         Piwik_Query(sprintf($query, $numericTable), Piwik::$idPeriods['day']);
         Piwik_SetOption($key, time());
     }
     foreach ($this->archives as $archive) {
         destroy($archive);
     }
     $this->archives = array();
 }
Example #19
0
 /**
  * Gets password hash stored in password reset info.
  * 
  * @param string $login The user login to check for.
  * @return string|false The hashed password or false if no reset info exists.
  */
 public static function getPasswordToResetTo($login)
 {
     $optionName = self::getPasswordResetInfoOptionName($login);
     return Piwik_GetOption($optionName);
 }
Example #20
0
 /**
  * Called at the end of the archiving process.
  * Does some cleaning job in the database.
  */
 protected function postCompute()
 {
     parent::postCompute();
     $blobTable = $this->tableArchiveBlob->getTableName();
     $numericTable = $this->tableArchiveNumeric->getTableName();
     $key = 'lastPurge_' . $blobTable;
     $timestamp = Piwik_GetOption($key);
     if (!$timestamp || $timestamp < time() - 86400) {
         Piwik_SetOption($key, time());
         // we delete out of date daily archives from table, maximum once per day
         // we only delete archives processed that are older than 1 day, to not delete archives we just processed
         $yesterday = Piwik_Date::factory('yesterday')->getDateTime();
         $result = Piwik_FetchAll("\n\t\t\t\t\t\t\tSELECT idarchive\n\t\t\t\t\t\t\tFROM {$numericTable}\n\t\t\t\t\t\t\tWHERE name LIKE 'done%'\n\t\t\t\t\t\t\t\tAND value = " . Piwik_ArchiveProcessing::DONE_OK_TEMPORARY . "\n\t\t\t\t\t\t\t\tAND ts_archived < ?", array($yesterday));
         $idArchivesToDelete = array();
         if (!empty($result)) {
             foreach ($result as $row) {
                 $idArchivesToDelete[] = $row['idarchive'];
             }
             $query = "DELETE \n    \t\t\t\t\t\tFROM %s\n    \t\t\t\t\t\tWHERE idarchive IN (" . implode(',', $idArchivesToDelete) . ")\n    \t\t\t\t\t\t";
             Piwik_Query(sprintf($query, $blobTable));
             Piwik_Query(sprintf($query, $numericTable));
         }
         Piwik::log("Purging temporary archives: done [ purged archives older than {$yesterday} from {$blobTable} and {$numericTable} ] [Deleted IDs: " . implode(',', $idArchivesToDelete) . "]");
         // Deleting "Custom Date Range" reports after 1 day, since they can be re-processed
         // and would take up unecessary space
         $query = "DELETE \n    \t\t\t\t\tFROM %s\n    \t\t\t\t\tWHERE period = ?\n    \t\t\t\t\t\tAND ts_archived < ?";
         $bind = array(Piwik::$idPeriods['range'], $yesterday);
         Piwik_Query(sprintf($query, $blobTable), $bind);
         Piwik_Query(sprintf($query, $numericTable), $bind);
     } else {
         Piwik::log("Purging temporary archives: skipped.");
     }
     if (!isset($this->archives)) {
         return;
     }
     foreach ($this->archives as $archive) {
         destroy($archive);
     }
     $this->archives = array();
 }
Example #21
0
 public function test_deleteLike()
 {
     // empty table, expect false (i.e., not found)
     $this->assertTrue(Piwik_GetOption('anonymous_defaultReport') === false);
     $this->assertTrue(Piwik_GetOption('admin_defaultReport') === false);
     $this->assertTrue(Piwik_GetOption('visitor_defaultReport') === false);
     // insert guard - to test unescaped underscore
     Piwik_SetOption('adefaultReport', '0', true);
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // populate table, expect '1'
     Piwik_SetOption('anonymous_defaultReport', '1', true);
     Piwik_Option::getInstance()->deleteLike('\\_defaultReport');
     $this->assertTrue(Piwik_Option::getInstance()->get('anonymous_defaultReport') === '1');
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // populate table, expect '2'
     Piwik_SetOption('admin_defaultReport', '2', false);
     Piwik_Option::getInstance()->deleteLike('\\_defaultReport');
     $this->assertTrue(Piwik_Option::getInstance()->get('admin_defaultReport') === '2');
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // populate table, expect '3'
     Piwik_SetOption('visitor_defaultReport', '3', false);
     Piwik_Option::getInstance()->deleteLike('\\_defaultReport');
     $this->assertTrue(Piwik_Option::getInstance()->get('visitor_defaultReport') === '3');
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // delete with non-matching value, expect '1'
     Piwik_Option::getInstance()->deleteLike('%\\_defaultReport', '4');
     $this->assertTrue(Piwik_Option::getInstance()->get('anonymous_defaultReport') === '1');
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // delete with matching pattern, expect false
     Piwik_Option::getInstance()->deleteLike('%\\_defaultReport', '1');
     $this->assertTrue(Piwik_Option::getInstance()->get('anonymous_defaultReport') === false);
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // this shouldn't have been deleted, expect '2' and '3'
     $this->assertTrue(Piwik_Option::getInstance()->get('admin_defaultReport') === '2');
     $this->assertTrue(Piwik_Option::getInstance()->get('visitor_defaultReport') === '3');
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // deleted, expect false (except for the guard)
     Piwik_Option::getInstance()->deleteLike('%\\_defaultReport');
     $this->assertTrue(Piwik_Option::getInstance()->get('admin_defaultReport') === false);
     $this->assertTrue(Piwik_Option::getInstance()->get('visitor_defaultReport') === false);
     // unescaped backslash (single quotes)
     Piwik_Option::getInstance()->deleteLike('%\\_defaultReport');
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // escaped backslash (single quotes)
     Piwik_Option::getInstance()->deleteLike('%\\_defaultReport');
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // unescaped backslash (double quotes)
     Piwik_Option::getInstance()->deleteLike("%\\_defaultReport");
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
     // escaped backslash (double quotes)
     Piwik_Option::getInstance()->deleteLike("%\\_defaultReport");
     $this->assertTrue(Piwik_GetOption('adefaultReport') === '0');
 }
Example #22
0
 /**
  * Gets a user preference
  * @param string $userLogin
  * @param string $preferenceName
  * @return bool|string
  */
 public function getUserPreference($userLogin, $preferenceName)
 {
     Piwik::checkUserIsSuperUserOrTheUser($userLogin);
     return Piwik_GetOption($this->getPreferenceId($userLogin, $preferenceName));
 }
Example #23
0
	/**
	 * Returns the default timezone that will be set when creating a website through the API.
	 * Via the UI, if the default timezone is not UTC, it will be pre-selected in the drop down
	 * 
	 * @return string Timezone eg. UTC+7 or Europe/Paris
	 */
	public function getDefaultTimezone()
	{
		$defaultTimezone = Piwik_GetOption(self::OPTION_DEFAULT_TIMEZONE);
		if($defaultTimezone)
		{
			return $defaultTimezone;
		}
		return 'UTC';
	}
Example #24
0
 /**
  * Called at the end of the archiving process.
  * Does some cleaning job in the database.
  */
 protected function postCompute()
 {
     parent::postCompute();
     $blobTable = $this->tableArchiveBlob->getTableName();
     $numericTable = $this->tableArchiveNumeric->getTableName();
     $key = 'lastPurge_' . $blobTable;
     $timestamp = Piwik_GetOption($key);
     // we shall purge temporary archives after their timeout is finished, plus an extra 2 hours
     // in case archiving is disabled and is late to run, we give it this extra time to run and re-process more recent records
     $temporaryArchivingTimeout = self::getTodayArchiveTimeToLive();
     $purgeEveryNSeconds = $temporaryArchivingTimeout + 2 * 3600;
     // we only delete archives if we are able to process them, otherwise, the browser might process reports
     // when &segment= is specified (or custom date range) and would below, delete temporary archives that the
     // browser is not able to process until next cron run (which could be more than 1 hour away)
     if ($this->isRequestAuthorizedToArchive() && (!$timestamp || $timestamp < time() - $purgeEveryNSeconds)) {
         Piwik_SetOption($key, time());
         $purgeArchivesOlderThan = Piwik_Date::factory(time() - $purgeEveryNSeconds)->getDateTime();
         $result = Piwik_FetchAll("\n\t\t\t\t\t\t\tSELECT idarchive\n\t\t\t\t\t\t\tFROM {$numericTable}\n\t\t\t\t\t\t\tWHERE name LIKE 'done%'\n\t\t\t\t\t\t\t\tAND value = " . Piwik_ArchiveProcessing::DONE_OK_TEMPORARY . "\n\t\t\t\t\t\t\t\tAND ts_archived < ?", array($purgeArchivesOlderThan));
         $idArchivesToDelete = array();
         if (!empty($result)) {
             foreach ($result as $row) {
                 $idArchivesToDelete[] = $row['idarchive'];
             }
             $query = "DELETE \n    \t\t\t\t\t\tFROM %s\n    \t\t\t\t\t\tWHERE idarchive IN (" . implode(',', $idArchivesToDelete) . ")\n    \t\t\t\t\t\t";
             Piwik_Query(sprintf($query, $blobTable));
             Piwik_Query(sprintf($query, $numericTable));
         }
         Piwik::log("Purging temporary archives: done [ purged archives older than {$purgeArchivesOlderThan} from {$blobTable} and {$numericTable} ] [Deleted IDs: " . implode(',', $idArchivesToDelete) . "]");
         // Deleting "Custom Date Range" reports after 1 day, since they can be re-processed
         // and would take up unecessary space
         $yesterday = Piwik_Date::factory('yesterday')->getDateTime();
         $query = "DELETE \n    \t\t\t\t\tFROM %s\n    \t\t\t\t\tWHERE period = ?\n    \t\t\t\t\t\tAND ts_archived < ?";
         $bind = array(Piwik::$idPeriods['range'], $yesterday);
         Piwik::log("Purging Custom Range archives: done [ purged archives older than {$yesterday} from {$blobTable} and {$numericTable} ]");
         Piwik_Query(sprintf($query, $blobTable), $bind);
         Piwik_Query(sprintf($query, $numericTable), $bind);
         // these tables will be OPTIMIZEd daily in a scheduled task, to claim lost space
     } else {
         Piwik::log("Purging temporary archives: skipped.");
     }
     if (!isset($this->archives)) {
         return;
     }
     foreach ($this->archives as $archive) {
         destroy($archive);
     }
     $this->archives = array();
 }
Example #25
0
 function _retrieveCurrentValue()
 {
     $this->current_value = Piwik_Version::VERSION;
     $this->recommended_value = Piwik_GetOption(Piwik_UpdateCheck::LATEST_VERSION);
 }
Example #26
0
 /**
  * @return Piwik_View with all data set
  */
 protected function buildView()
 {
     $view = new Piwik_View($this->dataTableTemplate);
     if (!$this->isDataAvailable) {
         $view->arrayDataTable = array();
     } else {
         $columns = $this->getColumnsToDisplay();
         $columnTranslations = $columnDocumentation = array();
         foreach ($columns as $columnName) {
             $columnTranslations[$columnName] = $this->getColumnTranslation($columnName);
             $columnDocumentation[$columnName] = $this->getMetricDocumentation($columnName);
         }
         $nbColumns = count($columns);
         // case no data in the array we use the number of columns set to be displayed
         if ($nbColumns == 0) {
             $nbColumns = count($this->columnsToDisplay);
         }
         $view->arrayDataTable = $this->getPHPArrayFromDataTable();
         $view->dataTableColumns = $columns;
         $view->reportDocumentation = $this->getReportDocumentation();
         $view->columnTranslations = $columnTranslations;
         $view->columnDocumentation = $columnDocumentation;
         $view->nbColumns = $nbColumns;
         $view->defaultWhenColumnValueNotDefined = '-';
         // if it's likely that the report data for this data table has been purged,
         // set whether we should display a message to that effect.
         $view->showReportDataWasPurgedMessage = $this->hasReportBeenPurged();
         $view->deleteReportsOlderThan = Piwik_GetOption('delete_reports_older_than');
     }
     $view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet();
     $view->properties = $this->getViewProperties();
     return $view;
 }
Example #27
0
 /**
  * Given a monthly archive table, will delete all reports that are now outdated, 
  * or reports that ended with an error
  */
 public static function doPurgeOutdatedArchives($numericTable)
 {
     $blobTable = str_replace("numeric", "blob", $numericTable);
     $key = self::FLAG_TABLE_PURGED . $blobTable;
     $timestamp = Piwik_GetOption($key);
     // we shall purge temporary archives after their timeout is finished, plus an extra 6 hours
     // in case archiving is disabled or run once a day, we give it this extra time to run
     // and re-process more recent records...
     // TODO: Instead of hardcoding 6 we should put the actual number of hours between 2 archiving runs
     $temporaryArchivingTimeout = self::getTodayArchiveTimeToLive();
     $purgeEveryNSeconds = max($temporaryArchivingTimeout, 6 * 3600);
     // we only delete archives if we are able to process them, otherwise, the browser might process reports
     // when &segment= is specified (or custom date range) and would below, delete temporary archives that the
     // browser is not able to process until next cron run (which could be more than 1 hour away)
     if (self::isRequestAuthorizedToArchive() && (!$timestamp || $timestamp < time() - $purgeEveryNSeconds)) {
         Piwik_SetOption($key, time());
         // If Browser Archiving is enabled, it is likely there are many more temporary archives
         // We delete more often which is safe, since reports are re-processed on demand
         if (self::isBrowserTriggerArchivingEnabled()) {
             $purgeArchivesOlderThan = Piwik_Date::factory(time() - 2 * $temporaryArchivingTimeout)->getDateTime();
         } else {
             $purgeArchivesOlderThan = Piwik_Date::factory('today')->getDateTime();
         }
         $result = Piwik_FetchAll("\n\t\t\t\tSELECT idarchive\n\t\t\t\tFROM {$numericTable}\n\t\t\t\tWHERE name LIKE 'done%'\n\t\t\t\t\tAND ((  value = " . Piwik_ArchiveProcessing::DONE_OK_TEMPORARY . "\n\t\t\t\t\t\t    AND ts_archived < ?)\n\t\t\t\t\t\t OR value = " . Piwik_ArchiveProcessing::DONE_ERROR . ")", array($purgeArchivesOlderThan));
         $idArchivesToDelete = array();
         if (!empty($result)) {
             foreach ($result as $row) {
                 $idArchivesToDelete[] = $row['idarchive'];
             }
             $query = "DELETE \n    \t\t\t\t\t\tFROM %s\n    \t\t\t\t\t\tWHERE idarchive IN (" . implode(',', $idArchivesToDelete) . ")\n    \t\t\t\t\t\t";
             Piwik_Query(sprintf($query, $numericTable));
             // Individual blob tables could be missing
             try {
                 Piwik_Query(sprintf($query, $blobTable));
             } catch (Exception $e) {
             }
         }
         Piwik::log("Purging temporary archives: done [ purged archives older than {$purgeArchivesOlderThan} from {$blobTable} and {$numericTable} ] [Deleted IDs: " . implode(',', $idArchivesToDelete) . "]");
         // Deleting "Custom Date Range" reports after 1 day, since they can be re-processed
         // and would take up unecessary space
         $yesterday = Piwik_Date::factory('yesterday')->getDateTime();
         $query = "DELETE \n    \t\t\t\t\tFROM %s\n    \t\t\t\t\tWHERE period = ?\n    \t\t\t\t\t\tAND ts_archived < ?";
         $bind = array(Piwik::$idPeriods['range'], $yesterday);
         Piwik::log("Purging Custom Range archives: done [ purged archives older than {$yesterday} from {$blobTable} and {$numericTable} ]");
         Piwik_Query(sprintf($query, $numericTable), $bind);
         // Individual blob tables could be missing
         try {
             Piwik_Query(sprintf($query, $blobTable), $bind);
         } catch (Exception $e) {
         }
         // these tables will be OPTIMIZEd daily in a scheduled task, to claim lost space
     } else {
         Piwik::log("Purging temporary archives: skipped.");
     }
 }
 public static function isBrowserTriggerArchivingEnabled()
 {
     $browserArchivingEnabled = Piwik_GetOption(self::OPTION_BROWSER_TRIGGER_ARCHIVING);
     if ($browserArchivingEnabled !== false) {
         return (bool) $browserArchivingEnabled;
     }
     return (bool) Piwik_Config::getInstance()->General['enable_browser_archiving_triggering'];
 }
Example #29
0
 /** Make sure the first time deleteReportData is run, nothing happens. */
 public function test_deleteReportData_initialRun()
 {
     $this->addLogData();
     $this->addReportData();
     $this->instance->deleteReportData();
     // check that initial option is set
     $this->assertEqual(1, Piwik_GetOption(Piwik_PrivacyManager::OPTION_LAST_DELETE_PIWIK_LOGS_INITIAL));
     // perform other checks
     $this->checkNoDataChanges();
 }
Example #30
0
 /**
  * Construct list of outdated components
  *
  * @return array array( componentName => array( oldVersion, newVersion), [...])
  */
 private function loadComponentsWithNewVersion()
 {
     $componentsToUpdate = array();
     // we make sure core updates are processed before any plugin updates
     if (isset($this->componentsToCheck['core'])) {
         $coreVersions = $this->componentsToCheck['core'];
         unset($this->componentsToCheck['core']);
         $this->componentsToCheck = array_merge(array('core' => $coreVersions), $this->componentsToCheck);
     }
     foreach ($this->componentsToCheck as $name => $version) {
         try {
             $currentVersion = Piwik_GetOption('version_' . $name);
         } catch (Exception $e) {
             // mysql error 1146: table doesn't exist
             if (Zend_Registry::get('db')->isErrNo($e, '1146')) {
                 // case when the option table is not yet created (before 0.2.10)
                 $currentVersion = false;
             } else {
                 // failed for some other reason
                 throw $e;
             }
         }
         if ($currentVersion === false) {
             if ($name === 'core') {
                 $currentVersion = '0.2.9';
             } else {
                 $currentVersion = '0.0.1';
             }
             $this->recordComponentSuccessfullyUpdated($name, $currentVersion);
         }
         $versionCompare = version_compare($currentVersion, $version);
         if ($versionCompare == -1) {
             $componentsToUpdate[$name] = array(self::INDEX_CURRENT_VERSION => $currentVersion, self::INDEX_NEW_VERSION => $version);
         } else {
             if ($versionCompare == 1) {
                 // the version in the DB is newest.. we choose to ignore (for the time being)
             }
         }
     }
     return $componentsToUpdate;
 }