/** * 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; }
/** * @expectedException Api\Library\Shared\Palaso\Exception\ResourceNotAvailableException */ public function testCheckIfArchivedAndThrow_ArchivedProject_Throw() { self::$environ->clean(); $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE); $project->isArchived = true; $project->write(); $this->assertTrue($project->isArchived); ProjectCommands::checkIfArchivedAndThrow($project); }
/** * 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(); }
/** * 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; }
/** * @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; }
/** * 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; }
/** * * @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 \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 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); }
/** * 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 $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); }