/** * Gets called when crawler runs. * * About crawler exclusivity (mutex usage): * When launched by an admin, no other user, admin or not, will be able to launch a crawl until this one is done. * When launched by a non-admin, we first check that no admin run is under way, and if that's the case, * we launch a crawl for the current user only. * No user will be able to launch two crawls in parallel, but different non-admin users crawls can run in parallel. */ public function crawl() { if (!Session::isLoggedIn() ) { throw new UnauthorizedUserException('You need a valid session to launch the crawler.'); } $mutex_dao = DAOFactory::getDAO('MutexDAO'); $owner_dao = DAOFactory::getDAO('OwnerDAO'); $owner = $owner_dao->getByEmail(Session::getLoggedInUser()); if (empty($owner)) { throw new UnauthorizedUserException('You need a valid session to launch the crawler.'); } // are we in an upgrading state if(UpgradeController::isUpgrading(true, 'Crawler')) { throw new InstallerException("ThinkUp needs a database migration, so we are unable to run the crawler."); } $global_mutex_name = 'crawler'; // Everyone needs to check the global mutex $lock_successful = $mutex_dao->getMutex($global_mutex_name); if ($lock_successful) { // Global mutex was free, which means no admin crawls are under way if ($owner->is_admin) { // Nothing more needs to be done, since admins use the global mutex $mutex_name = $global_mutex_name; } else { // User is a non-admin; let's use a user mutex. $mutex_name = 'crawler-'.$owner->id; $lock_successful = $mutex_dao->getMutex($mutex_name); $mutex_dao->releaseMutex($global_mutex_name); } } if ($lock_successful) { $this->emitObjectMethod('crawl'); $mutex_dao->releaseMutex($mutex_name); } else { throw new CrawlerLockedException("Error starting crawler; another crawl is already in progress."); } }
public function testLoadBackupViewCLIWarn() { $this->simulateLogin('*****@*****.**', true); $controller = new BackupController(true); $results = $controller->control(); $this->assertPattern('/Back Up Your ThinkUp Data/', $results); $v_mgr = $controller->getViewManager(); $this->assertNull($v_mgr->getTemplateDataItem('high_table_row_count')); // table row counts are bad $old_count = UpgradeController::$WARN_TABLE_ROW_COUNT; UpgradeController::$WARN_TABLE_ROW_COUNT = 2; $results = $controller->control(); $this->assertPattern('/we recommend that you use the/', $results); $table_counts = $v_mgr->getTemplateDataItem('high_table_row_count'); $this->assertNotNull($table_counts); $this->assertNotNull(3, $table_counts['count']); // tu_plugins, defaults to three UpgradeController::$WARN_TABLE_ROW_COUNT = $old_count; }
/** * Determin if ThinkUp needs to show the upgrading page. * @param bool Is the current user an admin * @param str The calling classname * @return bool Whether or not we need to show the upgrade page */ public static function isUpgrading($is_admin, $class_name) { $config = Config::getInstance(); $status = false; $db_version = UpgradeController::getCurrentDBVersion($config->getValue('cache_pages')); if (version_compare($db_version, $config->getValue('THINKUP_VERSION'), '<')) { if ($class_name != 'UpgradeController') { $status = true; } else { if (!$is_admin && !isset($_GET['upgrade_token'])) { $status = true; } } if ($status == true) { self::generateUpgradeToken(); } } return $status; }
public function testProcessMigrationsDifferentPrefix() { $config = Config::getInstance(); $config->setValue('table_prefix', 'new_prefix_'); $stmt = $this->pdo->query("show tables"); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt->closeCursor(); //var_dump($data); foreach($data as $table) { foreach($table as $key=> $value) { $new_value = preg_replace("/tu_/", " new_prefix_", $value); $sql = "RENAME TABLE $value TO $new_value"; $this->pdo->query($sql); } } $this->simulateLogin('*****@*****.**', true); $controller = new UpgradeController(true); $this->migrationFiles(1); $_GET['migration_index'] = 1; $results = $controller->go(); $obj = json_decode($results); $this->assertTrue($obj->processed); $updated_file = file_get_contents($this->test_migrations[0]); $updated_file = preg_replace("/\s`tu_/", " `new_prefix_", $updated_file); $updated_file = preg_replace("/\stu_/", " new_prefix_", $updated_file); $this->assertEqual($obj->sql, $updated_file); $sql = "show tables like 'new_prefix_test1'"; $stmt = $this->pdo->query($sql); $data = $stmt->fetch(); $this->assertEqual($data[0], 'new_prefix_test1'); $sql = 'select * from new_prefix_test1'; $stmt = $this->pdo->query($sql); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $this->assertEqual(count($data), 3); }
* * ThinkUp/webapp/install/upgrade.php * * Copyright (c) 2009-2010 Mark Wilkie * * LICENSE: * * This file is part of ThinkUp (http://thinkupapp.com). * * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any * later version. * * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see * <http://www.gnu.org/licenses/>. * * * @license http://www.gnu.org/licenses/gpl.html * @copyright 2009-2010 Mark Wilkie * @author Mark Wilkie <mwilkie[at]gmail[dot]com> * */ chdir(".."); require_once 'init.php'; $controller = new UpgradeController(); echo $controller->go();
usage(); } else { putenv('BACKUP_VERBOSE=true'); $backup_dao = DAOFactory::getDAO('BackupDAO'); print "\nExporting data to: {$filename}\n\n"; $backup_dao->export($filename); print "\nBackup completed.\n\n"; } } } // run updates... // get migrations we need to run... print "\nUpgrading Thinkup to version {$thinkup_db_version}...\n\n"; $upgrade_start_time = microtime(true); putenv('CLI_BACKUP=true'); $upgrade_ctl = new UpgradeController(); $migrations = $upgrade_ctl->getMigrationList($db_version); $install_dao = DAOFactory::getDAO('InstallerDAO'); foreach ($migrations as $migration) { print " Running migration " . $migration['version'] . "\n"; $install_dao->runMigrationSQL($migration['sql']); } $option_dao = DAOFactory::getDAO('OptionDAO'); $option = $option_dao->getOptionByName(OptionDAO::APP_OPTIONS, 'database_version'); if ($option) { $option_dao->updateOptionByName(OptionDAO::APP_OPTIONS, 'database_version', $thinkup_db_version); } else { $option_dao->insertOption(OptionDAO::APP_OPTIONS, 'database_version', $thinkup_db_version); } // release global mutex BackupController::mutexLock();
/** * Invoke the controller * * Always use this method, not control(), to invoke the controller. * @TODO show get 500 error template on Exception * (if debugging is true, pass the exception details to the 500 template) */ public function go() { try { $this->initalizeApp(); // are we in need of a database migration? $classname = get_class($this); if ($classname != 'InstallerController' && $classname != 'BackupController' && UpgradeController::isUpgrading($this->isAdmin(), $classname)) { $this->setViewTemplate('install.upgradeneeded.tpl'); $this->disableCaching(); $option_dao = DAOFactory::getDAO('OptionDAO'); $option_dao->clearSessionData(OptionDAO::APP_OPTIONS); return $this->generateView(); } else { $results = $this->control(); if ($this->profiler_enabled && !isset($this->json_data) && strpos($this->content_type, 'text/javascript') === false && strpos($this->content_type, 'text/csv') === false) { $end_time = microtime(true); $total_time = $end_time - $this->start_time; $profiler = Profiler::getInstance(); $this->disableCaching(); $profiler->add($total_time, "total page execution time, running " . $profiler->total_queries . " queries."); $this->setViewTemplate('_profiler.tpl'); $this->addToView('profile_items', $profiler->getProfile()); return $results . $this->generateView(); } else { return $results; } } } catch (ControllerAuthException $e) { Utils::setDefaultTimezonePHPini(); $this->setErrorTemplateState(); $this->addToView('error_type', get_class($e)); $config = Config::getInstance(); $message = 'You must <a href="' . $config->getValue('site_root_path') . 'session/login.php">log in</a> to do this.'; $this->addErrorMessage($message, null, true); return $this->generateView(); } catch (ConfigurationException $e) { $this->setErrorTemplateState(); $this->addToView('error_type', get_class($e)); $message = 'ThinkUp\'s configuration file does not exist! Try <a href="' . THINKUP_BASE_URL . 'install/">installing ThinkUp.</a>'; $this->addErrorMessage($message, null, true); return $this->generateView(); } catch (Exception $e) { Utils::setDefaultTimezonePHPini(); $this->setErrorTemplateState(); $this->addToView('error_type', get_class($e)); $disable_xss = false; // if we are an installer exception, don't filter XSS, we have markup, and we trust this content if (get_class($e) == 'InstallerException') { $disable_xss = true; } $this->addErrorMessage($e->getMessage(), null, $disable_xss); return $this->generateView(); } }
/** * Invoke the controller * * Always use this method, not control(), to invoke the controller. * @TODO show get 500 error template on Exception * (if debugging is true, pass the exception details to the 500 template) */ public function go() { try { $this->initalizeApp(); // are we in need of a database migration? $classname = get_class($this); if ($classname != 'InstallerController' && $classname != 'BackupController' && UpgradeController::isUpgrading($this->isAdmin(), $classname)) { $this->setViewTemplate('install.upgradeneeded.tpl'); $this->disableCaching(); $option_dao = DAOFactory::getDAO('OptionDAO'); $option_dao->clearSessionData(OptionDAO::APP_OPTIONS); return $this->generateView(); } else { $results = $this->control(); if ($this->profiler_enabled && !isset($this->json_data) && strpos($this->content_type, 'text/javascript') === false && strpos($this->content_type, 'text/csv') === false) { $end_time = microtime(true); $total_time = $end_time - $this->start_time; $profiler = Profiler::getInstance(); $this->disableCaching(); $profiler->add($total_time, "total page execution time, running " . $profiler->total_queries . " queries."); $this->setViewTemplate('_profiler.tpl'); $this->addToView('profile_items', $profiler->getProfile()); return $results . $this->generateView(); } else { return $results; } } } catch (Exception $e) { //Explicitly set TZ (before we have user's choice) to avoid date() warning about using system settings date_default_timezone_set('America/Los_Angeles'); $content_type = $this->content_type; if (strpos($content_type, ';') !== false) { $exploded = explode(';', $content_type); $content_type = array_shift($exploded); } switch ($content_type) { case 'application/json': $this->setViewTemplate('500.json.tpl'); break; case 'text/plain': $this->setViewTemplate('500.txt.tpl'); break; default: $this->setViewTemplate('500.tpl'); } $this->addToView('error_type', get_class($e)); $this->addErrorMessage($e->getMessage()); return $this->generateView(); } }