public function run($userId, $mode = 'test') { $testMode = $mode != 'run'; $message = "Ensure DB Indexes\n"; $numberOfIndexesCreated = 0; $website = Website::get(); $onDevMachine = strpos($website->domain, 'dev.') !== false; $onLocalMachine = strrpos($website->domain, '.local') !== false; $message .= "\n------------- Main Database:\n"; $mainCollectionName = ProjectModelMongoMapper::instance()->getCollectionName(); $mainIndexes = ProjectModelMongoMapper::instance()->INDEXES_REQUIRED; $mainIndexesToCreate = MongoStore::getIndexesNotSetInCollection(SF_DATABASE, $mainCollectionName, $mainIndexes); $numberOfIndexesCreated += count($mainIndexesToCreate); $message .= count($mainIndexesToCreate) . " main indexes created.\n"; if (($onDevMachine || $onLocalMachine) && MongoStore::hasDB(SF_TEST_DATABASE)) { $message .= "\n------------- Test Database:\n"; $mainIndexesToCreate = MongoStore::getIndexesNotSetInCollection(SF_TEST_DATABASE, $mainCollectionName, $mainIndexes); $numberOfIndexesCreated += count($mainIndexesToCreate); $message .= count($mainIndexesToCreate) . " test indexes created.\n"; } if (!$testMode) { MongoStore::ensureIndexesInCollection(SF_DATABASE, $mainCollectionName, $mainIndexes); if (($onDevMachine || $onLocalMachine) && MongoStore::hasDB(SF_TEST_DATABASE)) { MongoStore::ensureIndexesInCollection(SF_TEST_DATABASE, $mainCollectionName, $mainIndexes); } } // loop over every project $projectList = new ProjectListModel(); $projectList->read(); foreach ($projectList->entries as $projectParams) { $project = ProjectModel::getById($projectParams['id']); if ($project->appName == 'lexicon') { $message .= "\n------------- {$project->projectName} project:\n"; $lexiconCollectionName = LexEntryModel::mapper($project->databaseName())->getCollectionName(); $lexiconIndexes = LexEntryModel::mapper($project->databaseName())->INDEXES_REQUIRED; $lexiconIndexesToCreate = MongoStore::getIndexesNotSetInCollection($project->databaseName(), $lexiconCollectionName, $lexiconIndexes); $numberOfIndexesCreated += count($lexiconIndexesToCreate); $optionListCollectionName = LexOptionListModel::mapper($project->databaseName())->getCollectionName(); $optionListIndexes = LexOptionListModel::mapper($project->databaseName())->INDEXES_REQUIRED; $optionListIndexesToCreate = MongoStore::getIndexesNotSetInCollection($project->databaseName(), $optionListCollectionName, $optionListIndexes); $numberOfIndexesCreated += count($optionListIndexesToCreate); if (count($lexiconIndexesToCreate) + count($optionListIndexesToCreate) > 0) { $message .= count($lexiconIndexesToCreate) . " lexicon indexes created.\n"; $message .= count($optionListIndexesToCreate) . " option list indexes created.\n"; } else { $message .= "No indexes needed creating.\n"; } if (!$testMode) { MongoStore::ensureIndexesInCollection($project->databaseName(), $lexiconCollectionName, $lexiconIndexes); MongoStore::ensureIndexesInCollection($project->databaseName(), $optionListCollectionName, $optionListIndexes); } } } if ($numberOfIndexesCreated > 0) { $message .= "\nCreated {$numberOfIndexesCreated} DB Indexes.\n\n"; } else { $message .= "\nAll indexes were present.\n\n"; } return $message; }
public function testUpdateThenRemove_NewProject_CreatesThenRemovesProjectDatabase() { $environ = new MongoTestEnvironment(); $environ->clean(); $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $databaseName = $project->databaseName(); $project->remove(); $this->assertEquals(0, MongoStore::countCollections($databaseName)); $text = new TextModel($project); $text->title = 'Some Title'; $text->write(); $this->assertTrue(MongoStore::hasDB($databaseName)); $this->assertEquals(1, MongoStore::countCollections($databaseName)); $project->remove(); $this->assertEquals(0, MongoStore::countCollections($databaseName)); }
/** * Create or update project * @param string $projectId * @param string $userId * @param array<projectModel> $object * @throws UserUnauthorizedException * @throws \Exception * @return string projectId */ public static function updateProject($projectId, $userId, $object) { $project = new LexProjectModel($projectId); ProjectCommands::checkIfArchivedAndThrow($project); if (!$project->hasRight($userId, Domain::USERS + Operation::EDIT)) { throw new UserUnauthorizedException("Insufficient privileges to update project in method 'updateProject'"); } $oldDBName = $project->databaseName(); $object['id'] = $projectId; JsonDecoder::decode($project, $object); $newDBName = $project->databaseName(); if ($oldDBName != '' && $oldDBName != $newDBName) { if (MongoStore::hasDB($newDBName)) { throw new \Exception("Cannot rename '{$oldDBName}' to ' {$newDBName}' . New project name {$newDBName} already exists. Not renaming."); } MongoStore::renameDB($oldDBName, $newDBName); } $projectId = $project->write(); return $projectId; }
public function checkProject($projectId) { $project = new ProjectModel($projectId); $this->projectsChecked++; $this->info("Checking {$project->projectName}"); if ($project->projectName == '') { $this->warn("{$projectId} has an empty projectName"); } if ($project->projectCode == '') { $this->warn("{$project->projectName} has an empty projectCode. This will certainly cause failures"); } // check that a database exists for this project try { $databaseName = $project->databaseName(); } catch (\Exception $e) { $databaseName = ""; } if (!MongoStore::hasDB($databaseName)) { $newProjectCode = str_replace(' ', '_', strtolower($project->projectName)); $newDatabaseName = 'sf_' . $newProjectCode; if (MongoStore::hasDB($newDatabaseName)) { $this->warn("projectCode does not correspond to an existing MongoDb but projectName does (db migration required)"); $this->fix("Changed projectCode to {$newProjectCode}"); $this->projectsFixed++; $project->projectCode = $newProjectCode; } else { $this->warn("{$project->projectName} has no corresponding database. (could indicate a brand new project with no data"); } } if ($project->siteName == '') { $this->warn("{$project->projectName} has no corresponding website (will not appear on any site)"); } if ($project->appName == '') { $this->warn("{$project->projectName} has no app associated with it"); } if ($this->makeChanges) { $project->write(); } }
public function createDatabaseIndexes() { $collectionName = LexEntryModel::mapper($this->databaseName())->getCollectionName(); $indexes = LexEntryModel::mapper($this->databaseName())->INDEXES_REQUIRED; MongoStore::addIndexesToCollection($this->databaseName(), $collectionName, $indexes); $collectionName = LexOptionListModel::mapper($this->databaseName())->getCollectionName(); $indexes = LexOptionListModel::mapper($this->databaseName())->INDEXES_REQUIRED; MongoStore::addIndexesToCollection($this->databaseName(), $collectionName, $indexes); }
/** * @param ProjectModel $project */ protected function cleanProjectEnvironment($project) { // clean out old db if it is present $projectDb = MongoStore::connect($project->databaseName()); foreach ($projectDb->listCollections() as $collectionInfo) { if ($collectionInfo->getName() != 'system.indexes') { $collection = $projectDb->selectCollection($collectionInfo->getName()); $collection->drop(); } } // clean up assets folder $folderPath = $project->getAssetsFolderPath(); $cleanupFiles = glob($folderPath . '/*'); foreach ($cleanupFiles as $cleanupFile) { @unlink($cleanupFile); } @rmdir($folderPath); }
/** * @param string $databaseName * @param string $collectionName * @param string $idKey defaults to id */ public function __construct($databaseName, $collectionName, $idKey = 'id') { $this->_db = MongoStore::connect($databaseName); $this->_collection = $this->_db->selectCollection($collectionName); $this->_idKey = $idKey; }
public function testCreateProject_LexProject_IndexesCreated() { self::$environ = new LexiconMongoTestEnvironment(); self::$environ->clean(); $user1Id = self::$environ->createUser("user1name", "User1 Name", "*****@*****.**"); $user1 = new UserModel($user1Id); $srProject = null; $projectId = ProjectCommands::createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE, LexProjectModel::LEXICON_APP, $user1->id->asString(), self::$environ->website, $srProject); $project = new LexProjectModel($projectId); $databaseName = $project->databaseName(); $collectionName = LexEntryModel::mapper($databaseName)->getCollectionName(); $indexCount = iterator_count(MongoStore::getCollectionIndexes($databaseName, $collectionName)); $this->assertTrue($indexCount >= 3); $index = ['key' => ['guid' => 1]]; $this->assertTrue(MongoStore::isAllIndexFieldNamesInCollection($index, $databaseName, $collectionName)); $collectionName = LexOptionListModel::mapper($databaseName)->getCollectionName(); $indexCount = iterator_count(MongoStore::getCollectionIndexes($databaseName, $collectionName)); $this->assertTrue($indexCount >= 2); $index = ['key' => ['code' => 1]]; $this->assertTrue(MongoStore::isAllIndexFieldNamesInCollection($index, $databaseName, $collectionName)); }
MongoStore::dropAllCollections($projectModel->databaseName()); } // drop the third database because it is used in a rename test $projectModel = new ProjectModel(); $projectModel->projectName = $constants['thirdProjectName']; $projectModel->projectCode = $constants['thirdProjectCode']; MongoStore::dropDB($projectModel->databaseName()); // drop the 'new' and 'empty' database because it is used in a 'create new project' test $projectModel = new ProjectModel(); $projectModel->projectName = $constants['newProjectName']; $projectModel->projectCode = $constants['newProjectCode']; MongoStore::dropDB($projectModel->databaseName()); $projectModel = new ProjectModel(); $projectModel->projectName = $constants['emptyProjectName']; $projectModel->projectCode = $constants['emptyProjectCode']; MongoStore::dropDB($projectModel->databaseName()); $adminUserId = UserCommands::createUser(array('id' => '', 'name' => $constants['adminName'], 'email' => $constants['adminEmail'], 'username' => $constants['adminUsername'], 'password' => $constants['adminPassword'], 'active' => true, 'role' => SystemRoles::SYSTEM_ADMIN), $website); $managerUserId = UserCommands::createUser(array('id' => '', 'name' => $constants['managerName'], 'email' => $constants['managerEmail'], 'username' => $constants['managerUsername'], 'password' => $constants['managerPassword'], 'active' => true, 'role' => SystemRoles::USER), $website); $memberUserId = UserCommands::createUser(array('id' => '', 'name' => $constants['memberName'], 'email' => $constants['memberEmail'], 'username' => $constants['memberUsername'], 'password' => $constants['memberPassword'], 'active' => true, 'role' => SystemRoles::USER), $website); $expiredUserId = UserCommands::createUser(array('id' => '', 'name' => $constants['expiredName'], 'email' => $constants['expiredEmail'], 'username' => $constants['expiredUsername'], 'password' => $constants['memberPassword'], 'active' => true, 'role' => SystemRoles::USER), $website); $resetUserId = UserCommands::createUser(array('id' => '', 'name' => $constants['resetName'], 'email' => $constants['resetEmail'], 'username' => $constants['resetUsername'], 'password' => $constants['memberPassword'], 'active' => true, 'role' => SystemRoles::USER), $website); $observerUserId = UserCommands::createUser(array('id' => '', 'name' => $constants['observerName'], 'email' => $constants['observerEmail'], 'username' => $constants['observerUsername'], 'password' => $constants['observerPassword'], 'active' => true, 'role' => SystemRoles::USER), $website); // set forgot password with expired date $today = new DateTime(); $expiredUser = new UserModel($expiredUserId); $expiredUser->resetPasswordKey = $constants['expiredPasswordKey']; $expiredUser->resetPasswordExpirationDate = $today; $expiredUser->write(); // set forgot password with valid date $resetUser = new UserModel($resetUserId); $resetUser->resetPasswordKey = $constants['resetPasswordKey'];
public function Run($argv) { $runForReal = false; if (count($argv) > 1 && $argv[1] == 'run') { $runForReal = true; } else { print "\nUsage: FactoryReset.php <run> <DIRECTORY>\n"; print "Run factory reset and restore mongodb and assets from DIRECTORY\n"; print "\nTest Mode - no data will be changed\n--------------------------------\n\n"; } $archivePath = count($argv) > 2 ? $argv[2] : ""; $projectList = new ProjectListModel(); $projectList->read(); // remove all existing projects print "\n{$projectList->count} projects will be deleted\n"; foreach ($projectList->entries as $p) { $project = new ProjectModel($p['id']); print "Deleting Project " . $project->projectName . "\n"; if ($runForReal) { try { $project->remove(); } catch (\Exception $e) { // don't do anything } } } // start with a fresh database print "\nDropping main database...\n"; if ($runForReal) { MongoStore::dropAllCollections(SF_DATABASE); } print "\nDropping other dbs on the server (like test dbs)\n"; $cmd = "mongo --quiet {$this->hostOption} --eval 'db.getMongo().getDBNames().forEach(function(i){ " . "if (i.indexOf(\"sf_\") == 0 || i.indexOf(\"scriptureforge\") == 0) { " . "print(\"Dropping \" + i); db.getSiblingDB(i).dropDatabase()}})'"; $this->Execute($runForReal, $cmd); if (is_dir($archivePath)) { print "\nExtracting archives...\n"; foreach (glob("{$archivePath}/*.tgz") as $filename) { print "Extracting {$filename}\n"; $cmd = "tar -xzf {$filename} -C {$archivePath}"; $this->Execute($runForReal, $cmd); } print "\nEnsure www-data has permissions...\n"; $cmd = "sudo chgrp -R www-data {$archivePath}/var/www"; $this->Execute($runForReal, $cmd); $cmd = "sudo chown -R www-data:fieldworks {$archivePath}/var/lib"; $this->Execute($runForReal, $cmd); print "\nRestoring mongodb...\n"; $mongodbBackup = $archivePath . "/mongo_backup"; $cmd = "mongorestore {$this->hostOption} {$mongodbBackup}"; $this->Execute($runForReal, $cmd); print "\nUpdating DB site names...\n"; $this->UpdateDBSiteName($runForReal); print "\nRestoring assets...\n"; $cmd = "rsync -rzlt --chmod=Dug=rwx,Fug=rw,o-rwx --group " . "--delete-during --stats --rsync-path='sudo rsync' " . "--exclude=sfchecks " . "{$archivePath}/var/www/languageforge.org/htdocs/assets/ " . "{$this->lfAssetsPath}/htdocs/assets/"; $this->Execute($runForReal, $cmd); $cmd = "rsync -rzlt --chmod=Dug=rwx,Fug=rw,o-rwx --group " . "--delete-during --stats --rsync-path='sudo rsync' " . "--exclude=lexicon --exclude=semdomtrans " . "{$archivePath}/var/www/scriptureforge.org/htdocs/assets/ " . "{$this->sfAssetsPath}/htdocs/assets/"; $this->Execute($runForReal, $cmd); $cmd = "sudo rm -R {$this->lfmergeSendReceivePath}/state/*"; $this->Execute($runForReal, $cmd); $cmd = "sudo rm -R {$this->lfmergeSendReceivePath}/webwork/*"; $this->Execute($runForReal, $cmd); $cmd = "rsync -rzlt --chmod=Dug=rwx,Fug=rw,o-rwx --group " . "--delete-during --stats --rsync-path='sudo rsync' " . "{$archivePath}{$this->lfmergeSendReceivePath} {$this->lfmergeSendReceivePath}"; $this->Execute($runForReal, $cmd); print "\nCleanup extracted files...\n"; $cmd = "sudo rm -R {$archivePath}/var"; $this->Execute($runForReal, $cmd); $cmd = "sudo rm -R {$archivePath}/mongo_backup"; $this->Execute($runForReal, $cmd); } else { print "\nCreating local user: admin password: password\n"; if ($runForReal) { $scriptureforgeWebsite = Website::get('scriptureforge.org'); $languageforgeWebsite = Website::get('languageforge.org'); $adminUser = UserCommands::createUser(array('id' => '', 'name' => 'Admin', 'email' => '*****@*****.**', 'username' => 'admin', 'password' => 'password', 'active' => true, 'role' => SystemRoles::SYSTEM_ADMIN), $languageforgeWebsite); } } }