/**
  * Updates the given LexEntry in $projectId
  * @param string $projectId
  * @param array $params
  * @param string $userId
  * @param string $mergeQueuePath
  * @param string $pidFilePath
  * @param string $command
  * @return bool|array<encoded LexEntryModel> if the project is syncing (or on hold) return false (no save)FixSe
  */
 public static function updateEntry($projectId, $params, $userId, $mergeQueuePath = null, $pidFilePath = null, $command = null)
 {
     CodeGuard::checkTypeAndThrow($params, 'array');
     $project = new LexProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($project);
     $now = UniversalTimestamp::now();
     if (array_key_exists('id', $params) && $params['id'] != '') {
         $entry = new LexEntryModel($project, $params['id']);
         $action = 'update';
     } else {
         $entry = new LexEntryModel($project);
         $entry->authorInfo->createdByUserRef->id = $userId;
         $entry->authorInfo->createdDate = $now;
         $entry->guid = Guid::create();
         $action = 'create';
         // TODO: Consider adding more specific activity entry: which fields were modified? 2014-09-03 RM
         // E.g., "User _____ updated entry _____ by adding a new sense with definition ______"
     }
     $entry->authorInfo->modifiedDate = $now;
     $entry->authorInfo->modifiedByUserRef->id = $userId;
     if ($project->hasSendReceive()) {
         //            $entry->dirtySR++;
         $entry->dirtySR = 0;
         $status = SendReceiveCommands::getProjectStatus($projectId);
         if ($status && $status['SRState'] != 'IDLE') {
             return false;
         }
     }
     LexEntryDecoder::decode($entry, $params);
     $entry->write();
     ActivityCommands::writeEntry($project, $userId, $entry, $action);
     //        SendReceiveCommands::queueProjectForUpdate($project, $mergeQueuePath);
     //        SendReceiveCommands::startLFMergeIfRequired($projectId, 'merge', $pidFilePath, $command);
     return JsonEncoder::encode($entry);
 }
 public static function updateTemplate($projectId, $params)
 {
     $projectModel = new ProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($projectModel);
     $questionTemplate = new QuestionTemplateModel($projectModel);
     JsonDecoder::decode($questionTemplate, $params);
     $result = $questionTemplate->write();
     return $result;
 }
 public function testSessionData_userIsPartOfProject()
 {
     $environ = new SessionTestEnvironment();
     $environ->create();
     ProjectCommands::updateUserRole($environ->projectId, $environ->userId);
     $data = SessionCommands::getSessionData($environ->projectId, $environ->userId, $environ->website);
     // Session data should contain user project rights, an array of integers
     $this->assertArrayHasKey('userProjectRights', $data);
     $this->assertTrue(is_array($data['userProjectRights']));
     // ... which should not be empty once the user has been assigned to the project
     $this->assertFalse(empty($data['userProjectRights']));
     $this->assertTrue(is_integer($data['userProjectRights'][0]));
 }
 /**
  * Update the optionlist with params
  * @param $projectId
  * @param array $params (encoded LexOptionListModel)
  * @return string $optionlistId
  */
 public static function updateList($projectId, $params)
 {
     CodeGuard::checkTypeAndThrow($params, 'array');
     $project = new LexProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($project);
     if (array_key_exists('id', $params) && $params['id'] != '') {
         $optionlist = new LexOptionListModel($project, $params['id']);
     } else {
         $optionlist = new LexOptionListModel($project);
     }
     JsonDecoder::decode($optionlist, $params);
     return $optionlist->write();
 }
 public function testLexEntryCrud_CreateUpdateDeleteListOk()
 {
     $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $projectId = $project->id->asString();
     // create an user and add to the project
     $userId = self::$environ->getProjectMember($projectId, 'user1');
     $entry = new LexEntryModel($project);
     $entry->lexeme->form('th', 'SomeEntry');
     $sense = new LexSense();
     $sense->definition->form('en', 'red fruit');
     $sense->partOfSpeech->value = 'noun';
     $example = new LexExample();
     $example->sentence->form('th', 'example1');
     $example->translation->form('en', 'trans1');
     $sense->examples[] = $example;
     $entry->senses[] = $sense;
     // List
     $dto = LexEntryCommands::listEntries($projectId);
     $this->assertEquals(0, $dto->count);
     // Create
     $params = JsonEncoder::encode($entry);
     $result1 = LexEntryCommands::updateEntry($projectId, $params, $userId);
     $entryId = $result1['id'];
     $this->assertNotNull($entryId);
     $this->assertEquals(24, strlen($entryId));
     // Read
     $result2 = LexEntryCommands::readEntry($projectId, $entryId);
     $this->assertNotNull($result2['id']);
     $this->assertEquals('SomeEntry', $result2['lexeme']['th']['value']);
     // Update
     $result2['lexeme']['th']['value'] = 'OtherEntry';
     $result3 = LexEntryCommands::updateEntry($projectId, $result2, $userId);
     $this->assertNotNull($result3);
     $this->assertEquals($entryId, $result3['id']);
     // Read back
     $result4 = LexEntryCommands::readEntry($projectId, $entryId);
     $this->assertNotNull($result4['id']);
     $this->assertEquals('OtherEntry', $result4['lexeme']['th']['value']);
     // List
     $dto = LexEntryCommands::listEntries($projectId);
     $this->assertEquals(1, $dto->count);
     // Delete
     $result5 = LexEntryCommands::removeEntry($projectId, $entryId, $userId);
     $this->assertTrue($result5);
     // List to confirm delete
     $dto = LexEntryCommands::listEntries($projectId);
     $this->assertEquals(0, $dto->count);
     // Clean up after ourselves
     ProjectCommands::deleteProjects(array($projectId), $project->ownerRef->asString());
 }
 private static function _createEmptyProject($languageCode, $languageName, $userId)
 {
     $website = Website::get();
     $projectCode = SemDomTransProjectModel::projectCode($languageCode);
     $projectName = SemDomTransProjectModel::projectName($languageCode, $languageName);
     $projectID = ProjectCommands::createProject($projectName, $projectCode, LfProjectModel::SEMDOMTRANS_APP, $userId, $website);
     $project = new SemDomTransProjectModel($projectID);
     $project->languageIsoCode = $languageCode;
     $project->isSourceLanguage = false;
     $project->semdomVersion = SemDomTransProjectModel::SEMDOM_VERSION;
     // by default all created projects have English as their source.  A future feature would allow creating projects off of other source languages
     $englishProject = SemDomTransProjectModel::getEnglishProject();
     $project->sourceLanguageProjectId->id = $englishProject->id->asString();
     return $project->write();
 }
 /**
  * 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 testUserEngagementReport_simpleProjectWithQuestionsAndAnswers_AsExpected()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $text = new TextModel($project);
     $text->title = "Text 1";
     $usx = MongoTestEnvironment::usxSample();
     $text->content = $usx;
     $textId = $text->write();
     $user1Id = $environ->createUser("user1", "user1", "*****@*****.**");
     $user2Id = $environ->createUser("user2", "user2", "*****@*****.**");
     $user3Id = $environ->createUser("user3", "user3", "*****@*****.**");
     ProjectCommands::updateUserRole($project->id->asString(), $user1Id);
     ProjectCommands::updateUserRole($project->id->asString(), $user2Id);
     ProjectCommands::updateUserRole($project->id->asString(), $user3Id);
     // Workflow is first to create a question
     $question = new QuestionModel($project);
     $question->title = "the question";
     $question->description = "question description";
     $question->textRef->id = $textId;
     $questionId = $question->write();
     // Then to add an answer to a question
     $answer = new AnswerModel();
     $answer->content = "first answer";
     $answer->score = 10;
     $answer->userRef->id = $user3Id;
     $answer->textHightlight = "text highlight";
     $answerId = $question->writeAnswer($answer);
     // Followed by comments
     $comment1 = new CommentModel();
     $comment1->content = "first comment";
     $comment1->userRef->id = $user1Id;
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment1);
     $comment2 = new CommentModel();
     $comment2->content = "second comment";
     $comment2->userRef->id = $user2Id;
     QuestionModel::writeComment($project->databaseName(), $questionId, $answerId, $comment2);
     $data = SfchecksReports::UserEngagementReport($project->id->asString());
     $this->assertNotEmpty($data['output']);
 }
 /**
  * @param string $projectId
  * @param array $object (json encoded)
  * @return string Id of text updated/added
  */
 public static function updateText($projectId, $object)
 {
     $projectModel = new ProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($projectModel);
     $textModel = new TextModel($projectModel);
     $isNewText = $object['id'] == '';
     if (!$isNewText) {
         $textModel->read($object['id']);
     }
     JsonDecoder::decode($textModel, $object);
     TextCommands::makeValidRange($object);
     if (TextCommands::hasRange($object)) {
         $usxTrimHelper = new UsxTrimHelper($textModel->content, $object['startCh'] || 0, $object['startVs'] || 0, $object['endCh'] || 0, $object['endVs'] || 0);
         $textModel->content = $usxTrimHelper->trimUsx();
     }
     $textId = $textModel->write();
     if ($isNewText) {
         ActivityCommands::addText($projectModel, $textId, $textModel);
     }
     return $textId;
 }
 public function testUpdateProject_ReadOnlyProperties_PropertiesNotChanged()
 {
     $environ = new MongoTestEnvironment();
     $environ->clean();
     $userId = $environ->createUser('User', 'Name', '*****@*****.**');
     $user = new UserModel($userId);
     $user->role = SystemRoles::USER;
     $hackerId = $environ->createUser('Hacker', 'Hacker', '*****@*****.**');
     $hacker = new UserModel($hackerId);
     $hacker->role = SystemRoles::USER;
     $hacker->write();
     $project = $environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $projectId = $project->id->asString();
     $project->addUser($userId, ProjectRoles::MANAGER);
     $project->ownerRef = $user->id->asString();
     $user->addProject($projectId);
     $user->write();
     $project->write();
     $hackedData = 'hacked';
     $params = ProjectCommands::readProject($projectId);
     $params['projectName'] = 'new project name';
     $params['id'] = $hackedData;
     $params['ownerRef'] = $hacker->id->asString();
     $params['users'][$hacker->id->asString()]['role'] = ProjectRoles::MANAGER;
     $params['projectCode'] = $hackedData;
     $params['siteName'] = $hackedData;
     $params['appName'] = $hackedData;
     $params['userProperties']['userProfilePickLists']['city']['name'] = $hackedData;
     SfchecksProjectCommands::updateProject($projectId, $userId, $params);
     $updatedProject = ProjectCommands::readProject($projectId);
     $this->assertEquals('new project name', $updatedProject['projectName']);
     $this->assertNotEquals($hackedData, $updatedProject['id']);
     $this->assertNotEquals($hacker->id->asString(), $updatedProject['ownerRef']);
     $this->assertFalse(isset($updatedProject['users'][$hacker->id->asString()]));
     $this->assertNotEquals($hackedData, $updatedProject['projectCode']);
     $this->assertNotEquals($hackedData, $updatedProject['siteName']);
     $this->assertNotEquals($hackedData, $updatedProject['appName']);
     $this->assertNotEquals($hackedData, $updatedProject['userProperties']['userProfilePickLists']['city']['name']);
 }
 /**
  *
  * @param string $projectId
  * @param string $mediaType, options are 'image'.
  * @param string $fileName
  * @throws \Exception
  * @return UploadResponse
  */
 public static function deleteMediaFile($projectId, $mediaType, $fileName)
 {
     $response = new UploadResponse();
     $response->result = false;
     $project = new LexProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($project);
     switch ($mediaType) {
         case 'audio':
             $folderPath = $project->getAudioFolderPath();
             break;
         case 'sense-image':
             $folderPath = $project->getImageFolderPath();
             break;
         default:
             $errorMsg = "Error in function deleteImageFile, unsupported mediaType: {$mediaType}";
             throw new \Exception($errorMsg);
             $data = new ErrorResult();
             $data->errorType = 'Exception';
             $data->errorMessage = $errorMsg;
             return $response;
     }
     $filePath = $folderPath . '/' . $fileName;
     if (file_exists($filePath) and !is_dir($filePath)) {
         if (unlink($filePath)) {
             $data = new MediaResult();
             $data->path = $folderPath;
             $data->fileName = $fileName;
             $response->result = true;
         } else {
             $data = new ErrorResult();
             $data->errorType = 'UserMessage';
             $data->errorMessage = "{$fileName} could not be deleted. Contact your Site Administrator.";
         }
         return $response;
     }
     $data = new ErrorResult();
     $data->errorType = 'UserMessage';
     $data->errorMessage = "{$fileName} does not exist in this project. Contact your Site Administrator.";
     return $response;
 }
 /**
  * @param string $projectId
  * @param string $userId
  * @param Website $website
  * @param ProjectRoles $role
  * @param DeliveryInterface $delivery
  * @return IdReference|UserModel
  */
 public static function acceptJoinRequest($projectId, $userId, $website, $role, DeliveryInterface $delivery = null)
 {
     $newUser = new UserModel($userId);
     $project = new ProjectModel();
     $project->read($projectId);
     ProjectCommands::updateUserRole($projectId, $userId, $role);
     // Make sure the user exists on the site
     if (!$newUser->hasRoleOnSite($website)) {
         $newUser->siteRole[$website->domain] = $website->userDefaultSiteRole;
     }
     // Determine if user is already a member of the project
     if ($project->userIsMember($newUser->id->asString())) {
         return $newUser->id;
     }
     $admin = new UserModel($project->ownerRef->asString());
     if ($admin->email != '') {
         Communicate::sendJoinRequestAccepted($newUser, $project, $website, $delivery);
     }
     return $admin;
 }
 /**
  * Upload a file
  *
  * @param string $projectId
  * @param string $mediaType
  * @param string $tmpFilePath
  * @throws \Exception
  * @return UploadResponse
  */
 public static function uploadFile($projectId, $mediaType, $tmpFilePath)
 {
     if ($mediaType != 'audio') {
         throw new \Exception("Unsupported upload type: {$mediaType}");
     }
     if (!$tmpFilePath) {
         throw new \Exception("Upload controller did not move the uploaded file.");
     }
     $textId = $_POST['textId'];
     $file = $_FILES['file'];
     $fileName = $file['name'];
     $finfo = finfo_open(FILEINFO_MIME_TYPE);
     $fileType = finfo_file($finfo, $tmpFilePath);
     finfo_close($finfo);
     $fileName = FileUtilities::replaceSpecialCharacters($fileName);
     $fileExt = false === ($pos = strrpos($fileName, '.')) ? '' : substr($fileName, $pos);
     // allowed types: documented, observed
     $allowedTypes = array("audio/mpeg", "audio/mp3");
     $allowedExtensions = array(".mp3");
     $response = new UploadResponse();
     if (in_array(strtolower($fileType), $allowedTypes) && in_array(strtolower($fileExt), $allowedExtensions)) {
         // make the folders if they don't exist
         $project = new SfchecksProjectModel($projectId);
         ProjectCommands::checkIfArchivedAndThrow($project);
         $folderPath = $project->getAssetsFolderPath();
         FileUtilities::createAllFolders($folderPath);
         // cleanup previous files of any allowed extension
         self::cleanupFiles($folderPath, $textId, $allowedExtensions);
         // move uploaded file from tmp location to assets
         $filePath = self::mediaFilePath($folderPath, $textId, $fileName);
         $moveOk = copy($tmpFilePath, $filePath);
         @unlink($tmpFilePath);
         // update database with file location
         $text = new TextModel($project, $textId);
         $text->audioFileName = '';
         if ($moveOk) {
             $text->audioFileName = $fileName;
         }
         $text->write();
         // construct server response
         if ($moveOk && $tmpFilePath) {
             $data = new MediaResult();
             $data->path = $project->getAssetsRelativePath();
             $data->fileName = $fileName;
             $response->result = true;
         } else {
             $data = new ErrorResult();
             $data->errorType = 'UserMessage';
             $data->errorMessage = "{$fileName} could not be saved to the right location. Contact your Site Administrator.";
             $response->result = false;
         }
     } else {
         $allowedExtensionsStr = implode(", ", $allowedExtensions);
         $data = new ErrorResult();
         $data->errorType = 'UserMessage';
         if (count($allowedExtensions) < 1) {
             $data->errorMessage = "{$fileName} is not an allowed audio file. No audio file formats are currently enabled, contact your Site Administrator.";
         } elseif (count($allowedExtensions) == 1) {
             $data->errorMessage = "{$fileName} is not an allowed audio file. Ensure the file is a {$allowedExtensionsStr}.";
         } else {
             $data->errorMessage = "{$fileName} is not an allowed audio file. Ensure the file is one of the following types: {$allowedExtensionsStr}.";
         }
         $response->result = false;
     }
     $response->data = $data;
     return $response;
 }
 /**
  * @param  string $projectId
  * @param  string $userId
  * @param  \Api\Library\Shared\Website $website
  * @param  string $commentId
  * @param  string $replyId
  * @throws \Exception
  * @return string $commentId
  */
 public static function deleteReply($projectId, $userId, $website, $commentId, $replyId)
 {
     // if the userId is different from the author, throw if user does not have DELETE privilege
     $project = new LexProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($project);
     $comment = new LexCommentModel($project, $commentId);
     $reply = $comment->getReply($replyId);
     if ($reply->authorInfo->createdByUserRef->asString() != $userId) {
         // if the userId is different from the author, throw if user does not have DELETE privilege
         $rh = new RightsHelper($userId, $project, $website);
         if (!$rh->userHasProjectRight(Domain::COMMENTS + Operation::DELETE)) {
             throw new \Exception("No permission to delete other people's comment replies!");
         }
     }
     $comment->deleteReply($replyId);
     return $comment->write();
 }
 public function testCreateProject_NewSRProject_SRProjectWithLinks()
 {
     self::$environ = new LexiconMongoTestEnvironment();
     self::$environ->clean();
     $user1Id = self::$environ->createUser("user1name", "User1 Name", "*****@*****.**");
     $user1 = new UserModel($user1Id);
     $srProject = array('identifier' => 'srIdentifier', 'name' => 'srName', 'repository' => 'http://public.languagedepot.org', 'role' => 'manager');
     $projectId = ProjectCommands::createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE, LexProjectModel::LEXICON_APP, $user1->id->asString(), self::$environ->website, $srProject);
     $project = new LexProjectModel($projectId);
     $assetImagePath = $project->getImageFolderPath();
     $assetAudioPath = $project->getAudioFolderPath();
     $this->assertTrue($project->hasSendReceive());
     $this->assertTrue(is_link($assetImagePath));
     $this->assertTrue(is_link($assetAudioPath));
     $projectWorkPath = $project->getSendReceiveWorkFolder();
     FileUtilities::removeFolderAndAllContents($project->getAssetsFolderPath());
     FileUtilities::removeFolderAndAllContents($projectWorkPath);
 }
$changeDatabase = false;
// process xml into a php data structure, organized by language
$xml = simplexml_load_file($xmlFilePath);
$lang = $argv[2];
$version = $argv[3];
$projectCode = "semdom-{$lang}-{$semdomVersion}";
$projectName = "Semdom {$lang} Project";
$appName = LfProjectModel::SEMDOMTRANS_APP;
$website = new Website($domain, Website::LANGUAGEFORGE);
// if a previous project for that language and semantic domain version exists, DO NOT IMPORT
$previousProject = new SemDomTransProjectModel();
$previousProject->readByProperties(array("languageIsoCode" => $lang, "semdomVersion" => $semdomVersion));
if ($previousProject->id->asString() == "") {
    $sourceProject = new SemDomTransProjectModel();
    $sourceProject->readByCode("en");
    $projectID = ProjectCommands::createProject($projectName, $projectCode, $appName, $userId, $website);
    $projectModel = new SemDomTransProjectModel($projectID);
    $newXmlFilePath = $projectModel->getAssetsFolderPath() . '/' . basename($xmlFilePath);
    FileUtilities::createAllFolders($projectModel->getAssetsFolderPath());
    print "copying {$xmlFilePath} to  {$newXmlFilePath}\n";
    copy($xmlFilePath, $newXmlFilePath);
    $projectModel->xmlFilePath = $newXmlFilePath;
    $projectModel->languageIsoCode = $lang;
    $projectModel->semdomVersion = $semdomVersion;
    $projectModel->sourceLanguageProjectId = $sourceProject->id->asString();
    $projectModel->write();
    $importer = new SemDomXMLImporter($xmlFilePath, $projectModel, false, $isEnglish);
    $importer->run();
} else {
    echo "Project exists already" . "\n";
}
 /**
  * Creates a semdomtrans project and prefills it (using Google Translate data if appropriate flag is set)
  * @param string $languageCode
  * @param string $languageName
  * @param bool $useGoogleTranslateData
  * @param string $userId
  * @param Website $website
  * @param int $semdomVersion
  * @return string
  */
 public static function createProject($languageCode, $languageName, $useGoogleTranslateData, $userId, $website, $semdomVersion = SemDomTransProjectModel::SEMDOM_VERSION)
 {
     $projectCode = SemDomTransProjectModel::projectCode($languageCode, $semdomVersion);
     $projectName = SemDomTransProjectModel::projectName($languageCode, $languageName, $semdomVersion);
     $projectID = ProjectCommands::createProject($projectName, $projectCode, LfProjectModel::SEMDOMTRANS_APP, $userId, $website);
     $project = new SemDomTransProjectModel($projectID);
     $project->languageIsoCode = $languageCode;
     $project->isSourceLanguage = false;
     $project->semdomVersion = $semdomVersion;
     $project->languageName = $languageName;
     // by default all created projects have English as their source.  A future feature would allow creating projects off of other source languages
     $englishProject = SemDomTransProjectModel::getEnglishProject($semdomVersion);
     $project->sourceLanguageProjectId->id = $englishProject->id->asString();
     // prefill project with semdom items
     $project->preFillFromSourceLanguage($useGoogleTranslateData);
     return $project->write();
 }
 public function testUserCRUD_CRUDOK()
 {
     // initial list
     $result = self::$environ->fixJson(UserCommands::listUsers());
     $count = $result['count'];
     // Create
     $userId = self::$environ->createUser('someuser', 'SomeUser', '*****@*****.**');
     $someUser = new UserModel($userId);
     $this->assertNotNull($someUser);
     $this->assertEquals(24, strlen($someUser->id->asString()));
     // create project
     ProjectCommands::createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE, 'sfchecks', $someUser->id->asString(), self::$environ->website);
     // list
     $result = self::$environ->fixJson(UserCommands::listUsers());
     $this->assertEquals($count + 1, $result['count']);
     // Read
     $result = self::$environ->fixJson(UserCommands::readUser($someUser->id->asString()));
     $this->assertNotNull($result['id']);
     $this->assertEquals('someuser', $result['username']);
     $this->assertEquals('*****@*****.**', $result['email']);
     // Update
     $result['username'] = '******';
     $result['email'] = '*****@*****.**';
     $id = UserCommands::updateUser($result, self::$environ->website);
     $this->assertNotNull($id);
     $this->assertEquals($result['id'], $id);
     // typeahead
     $result = self::$environ->fixJson(UserCommands::userTypeaheadList('ome', '', self::$environ->website));
     $this->assertTrue($result['count'] > 0);
     // change password
     UserCommands::changePassword($id, 'newpassword', $id);
     // Delete
     $result = UserCommands::deleteUsers(array($id));
     $this->assertTrue($result > 0);
 }
 /**
  * Updates the ProjectSettingsModel which are settings accessible only to site administrators
  * @param string $projectId
  * @param array<SmsSettings> $smsSettingsArray
  * @param array<EmailSettings> $emailSettingsArray
  * @return string $result id to the projectSettingsModel
  */
 public static function updateProjectSettings($projectId, $smsSettingsArray, $emailSettingsArray)
 {
     $projectSettings = new ProjectSettingsModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($projectSettings);
     $smsSettings = new SmsSettings();
     $emailSettings = new EmailSettings();
     JsonDecoder::decode($smsSettings, $smsSettingsArray);
     JsonDecoder::decode($emailSettings, $emailSettingsArray);
     $projectSettings->smsSettings = $smsSettings;
     $projectSettings->emailSettings = $emailSettings;
     $result = $projectSettings->write();
     return $result;
 }
 public function project_readSettings()
 {
     return ProjectCommands::readProjectSettings($this->projectId);
 }
 public static function voteDown($userId, $projectId, $questionId, $answerId)
 {
     $projectModel = new ProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($projectModel);
     $questionModel = new QuestionModel($projectModel, $questionId);
     // Check the vote lock.
     $vote = new UserVoteModel($userId, $projectId, $questionId);
     if (!$vote->hasVote($answerId)) {
         // Don't throw.  There's no harm in this, just don't decrement the vote.
         return self::encodeAnswer($questionModel->readAnswer($answerId));
     }
     // If ok down vote the question and remove the lock.
     $answerModel = $questionModel->readAnswer($answerId);
     $answerModel->score--;
     $questionModel->writeAnswer($answerModel);
     $vote->removeVote($answerId);
     $vote->write();
     // Return the answer dto.
     return self::encodeAnswer($answerModel);
 }
if ($site == 'scriptureforge') {
    $text1 = TextCommands::updateText($testProjectId, array('id' => '', 'title' => $constants['testText1Title'], 'content' => $constants['testText1Content']));
    $text2 = TextCommands::updateText($testProjectId, array('id' => '', 'title' => $constants['testText2Title'], 'content' => $constants['testText2Content']));
    $question1 = QuestionCommands::updateQuestion($testProjectId, array('id' => '', 'textRef' => $text1, 'title' => $constants['testText1Question1Title'], 'description' => $constants['testText1Question1Content']));
    $question2 = QuestionCommands::updateQuestion($testProjectId, array('id' => '', 'textRef' => $text1, 'title' => $constants['testText1Question2Title'], 'description' => $constants['testText1Question2Content']));
    $template1 = QuestionTemplateCommands::updateTemplate($testProjectId, array('id' => '', 'title' => 'first template', 'description' => 'not particularly interesting'));
    $template2 = QuestionTemplateCommands::updateTemplate($testProjectId, array('id' => '', 'title' => 'second template', 'description' => 'not entirely interesting'));
    $answer1 = QuestionCommands::updateAnswer($testProjectId, $question1, array('id' => '', 'content' => $constants['testText1Question1Answer']), $managerUserId);
    $answer1Id = array_keys($answer1)[0];
    $answer2 = QuestionCommands::updateAnswer($testProjectId, $question2, array('id' => '', 'content' => $constants['testText1Question2Answer']), $managerUserId);
    $answer2Id = array_keys($answer2)[0];
    $comment1 = QuestionCommands::updateComment($testProjectId, $question1, $answer1Id, array('id' => '', 'content' => $constants['testText1Question1Answer1Comment']), $managerUserId);
    $comment2 = QuestionCommands::updateComment($testProjectId, $question2, $answer2Id, array('id' => '', 'content' => $constants['testText1Question2Answer2Comment']), $managerUserId);
} elseif ($site == 'languageforge') {
    // Set up LanguageForge E2E test envrionment here
    ProjectCommands::updateUserRole($testProjectId, $observerUserId, LexRoles::OBSERVER);
    $testProjectModel = new LexProjectModel($testProjectId);
    $testProjectModel->addInputSystem('th-fonipa', 'tipa', 'Thai');
    $testProjectModel->config->entry->fields[LexConfig::LEXEME]->inputSystems[] = 'th-fonipa';
    $testProjectModel->addInputSystem('th-Zxxx-x-audio', 'taud', 'Thai Voice');
    $testProjectModel->config->entry->fields[LexConfig::LEXEME]->inputSystems[] = 'th-Zxxx-x-audio';
    $testProjectId = $testProjectModel->write();
    // setup to mimic file upload
    $fileName = $constants['testEntry1']['lexeme']['th-Zxxx-x-audio']['value'];
    $file = array();
    $file['name'] = $fileName;
    $_FILES['file'] = $file;
    // put a copy of the test file in tmp
    $tmpFilePath = sys_get_temp_dir() . "/CopyOf{$fileName}";
    copy(TestPath . "php/common/{$fileName}", $tmpFilePath);
    $response = LexUploadCommands::uploadAudioFile($testProjectId, 'audio', $tmpFilePath);
 /**
  * @param string $projectId
  * @param string $pidFilePath
  * @param string $command
  * @return bool true if process started or already running, otherwise false
  * @throws ResourceNotAvailableException
  * @throws \Exception
  */
 public static function startLFMergeIfRequired($projectId, $pidFilePath = null, $command = null)
 {
     $project = new LexProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($project);
     if (!$project->hasSendReceive()) {
         return false;
     }
     if (is_null($pidFilePath)) {
         $pidFilePath = self::$lfmergePidFilePaths[0];
         foreach (self::$lfmergePidFilePaths as $path) {
             if (file_exists($path)) {
                 $pidFilePath = $path;
                 break;
             }
         }
     }
     if (self::isProcessRunningByPidFile($pidFilePath)) {
         return true;
     }
     if (is_null($command)) {
         $command = self::LFMERGE_EXE . ' -p ' . $project->projectCode;
     }
     if (!self::commandExists($command)) {
         throw new \Exception('LFMerge is not installed. Contact the website administrator.');
     }
     $pid = self::runInBackground($command);
     return self::isProcessRunningByPid($pid);
 }