public function testNativeDoiImport() { $testfile = 'tests/functional/plugins/importexport/native/testissue.xml'; $args = array('import', $testfile, 'test', 'admin'); $result = $this->executeCli('NativeImportExportPlugin', $args); self::assertRegExp('/##plugins.importexport.native.import.success.description##/', $result); $daos = array('Issue' => 'IssueDAO', 'PublishedArticle' => 'PublishedArticleDAO', 'Galley' => 'ArticleGalleyDAO'); $articleId = null; foreach ($daos as $objectType => $daoName) { $dao = DAORegistry::getDAO($daoName); $pubObject = call_user_func(array($dao, "get{$objectType}ByPubId"), 'doi', $this->expectedDois[$objectType]); self::assertNotNull($pubObject, "Error while testing {$objectType}: object or DOI has not been imported."); $pubObjectByURN = call_user_func(array($dao, "get{$objectType}ByPubId"), 'other::urn', $this->expectedURNs[$objectType]); self::assertNotNull($pubObjectByURN, "Error while testing {$objectType}: object or URN has not been imported."); if ($objectType == 'PublishedArticle') { $articleId = $pubObject->getId(); } } // Trying to import the same file again should lead to an error. $args = array('import', $testfile, 'test', 'admin'); $result = $this->executeCli('NativeImportExportPlugin', $args); self::assertRegExp('/##plugins.importexport.native.import.error.duplicatePubId##/', $result); // Delete inserted article files from the filesystem. $request = $application->getRequest(); $context = $request->getContext(); import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($context->getId(), $articleId); $submissionFileManager->rmtree($submissionFileManager->getBasePath()); }
/** * Upload the file in an app-specific manner. * @param PKPRequest $request * @param PKPUser $user * @param $uploaderUserGroupId int * @param $revisedFileId int * @param $fileGenre int * @param $assocType int * @param $assocType int * @return SubmissionFile */ function _uploadFile($request, $user, $uploaderUserGroupId, $revisedFileId, $fileGenre, $assocType, $assocId) { $context = $request->getContext(); import('lib.pkp.classes.file.SubmissionFileManager'); $articleFileManager = new SubmissionFileManager($context->getId(), $this->getData('submissionId')); $fileStage = $this->getData('fileStage'); $submissionFile = $articleFileManager->uploadSubmissionFile('uploadedFile', $fileStage, $user->getId(), $uploaderUserGroupId, $revisedFileId, $fileGenre, $assocType, $assocId); return $submissionFile; }
/** * Fix broken submission filenames (bug #8461) * @param $upgrade Upgrade * @param $params array * @param $dryrun boolean True iff only a dry run (displaying rather than executing changes) should be done. * @return boolean */ function fixFilenames($upgrade, $params, $dryrun = false) { $pressDao = DAORegistry::getDAO('PressDAO'); $submissionDao = DAORegistry::getDAO('MonographDAO'); $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); DAORegistry::getDAO('GenreDAO'); // Load constants $siteDao = DAORegistry::getDAO('SiteDAO'); /* @var $siteDao SiteDAO */ $site = $siteDao->getSite(); $adminEmail = $site->getLocalizedContactEmail(); import('lib.pkp.classes.file.SubmissionFileManager'); $contexts = $pressDao->getAll(); while ($context = $contexts->next()) { $submissions = $submissionDao->getByPressId($context->getId()); while ($submission = $submissions->next()) { $submissionFileManager = new SubmissionFileManager($context->getId(), $submission->getId()); $submissionFiles = $submissionFileDao->getBySubmissionId($submission->getId()); foreach ($submissionFiles as $submissionFile) { $generatedFilename = $submissionFile->getServerFileName(); $basePath = $submissionFileManager->getBasePath() . $submissionFile->_fileStageToPath($submissionFile->getFileStage()) . '/'; $globPattern = $submissionFile->getSubmissionId() . '-' . '*' . '-' . $submissionFile->getFileId() . '-' . $submissionFile->getRevision() . '-' . $submissionFile->getFileStage() . '-' . date('Ymd', strtotime($submissionFile->getDateUploaded())) . '.' . strtolower_codesafe($submissionFile->getExtension()); $matchedResults = glob($basePath . $globPattern); if (count($matchedResults) > 1) { error_log("Duplicate potential files for \"{$globPattern}\"!", 1, $adminEmail); continue; } if (count($matchedResults) == 1) { // 1 result matched. $discoveredFilename = array_shift($matchedResults); if ($dryrun) { echo "Need to rename \"{$discoveredFilename}\" to \"{$generatedFilename}\".\n"; } else { rename($discoveredFilename, $basePath . $generatedFilename); } } else { // 0 results matched. error_log("Unable to find a match for \"{$globPattern}\".\n", 1, $adminEmail); continue; } } } } return true; }
/** * record a file view. * Must be overridden in subclases. * @param $submissionFile SubmissionFile the file to record. */ function recordView($submissionFile) { SubmissionFileManager::recordView($submissionFile); }
/** * Download an article file * @param array $args * @param PKPRequest $request */ function download($args, $request) { $articleId = isset($args[0]) ? $args[0] : 0; $galleyId = isset($args[1]) ? $args[1] : 0; $fileId = isset($args[2]) ? (int) $args[2] : 0; if ($this->userCanViewGalley($request, $articleId, $galleyId)) { if (!$fileId) { $submissionFile = $this->galley->getFile(); if ($submissionFile) { $fileId = $submissionFile->getFileId(); // The file manager expects the real article id. Extract it from the submission file. $articleId = $submissionFile->getSubmissionId(); } else { // no proof files assigned to this galley! assert(false); return null; } } if (!HookRegistry::call('ArticleHandler::download', array($this->article, &$this->galley, &$fileId))) { import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($this->article->getContextId(), $articleId); $submissionFileManager->downloadFile($fileId, null, $request->getUserVar('inline') ? true : false); } } }
/** * Initiate a new review round and add selected files * to it. Also saves the new round to the submission. * @param $submission Submission * @param $stageId integer One of the WORKFLOW_STAGE_ID_* constants. * @param $request Request * @param $status integer One of the REVIEW_ROUND_STATUS_* constants. * @return $newRound integer The round number of the new review round. */ function _initiateReviewRound($submission, $stageId, $request, $status = null) { // If we already have review round for this stage, // we create a new round after the last one. $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /* @var $reviewRoundDao ReviewRoundDAO */ $lastReviewRound = $reviewRoundDao->getLastReviewRoundBySubmissionId($submission->getId(), $stageId); if ($lastReviewRound) { $newRound = $lastReviewRound->getRound() + 1; } else { // If we don't have any review round, we create the first one. $newRound = 1; } // Create a new review round. $reviewRound = $reviewRoundDao->build($submission->getId(), $stageId, $newRound, $status); // Check for a notification already in place for the current review round. $notificationDao = DAORegistry::getDAO('NotificationDAO'); $notificationFactory = $notificationDao->getByAssoc(ASSOC_TYPE_REVIEW_ROUND, $reviewRound->getId(), null, NOTIFICATION_TYPE_REVIEW_ROUND_STATUS, $submission->getContextId()); // Create round status notification if there is no notification already. if ($notificationFactory->wasEmpty()) { $notificationMgr = new NotificationManager(); $notificationMgr->createNotification($request, null, NOTIFICATION_TYPE_REVIEW_ROUND_STATUS, $submission->getContextId(), ASSOC_TYPE_REVIEW_ROUND, $reviewRound->getId(), NOTIFICATION_LEVEL_NORMAL); } // Add the selected files to the new round. $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */ // Bring in the SUBMISSION_FILE_* constants. import('lib.pkp.classes.submission.SubmissionFile'); // Bring in the Manager (we need it). import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($submission->getContextId(), $submission->getId()); foreach (array('selectedFiles', 'selectedAttachments') as $userVar) { $selectedFiles = $this->getData($userVar); if (is_array($selectedFiles)) { foreach ($selectedFiles as $fileId) { // Retrieve the file last revision number. $revisionNumber = $submissionFileDao->getLatestRevisionNumber($fileId); list($newFileId, $newRevision) = $submissionFileManager->copyFileToFileStage($fileId, $revisionNumber, SUBMISSION_FILE_REVIEW_FILE, null, true); $submissionFileDao->assignRevisionToReviewRound($newFileId, $newRevision, $reviewRound); } } } return $newRound; }
/** * Return string containing the contents of the HTML file. * This function performs any necessary filtering, like image URL replacement. * @param $fileId int optional file id, otherwise the 'best' file will be chosen. * @return string */ function _getHTMLContents($request, $galley, $fileId = null) { import('lib.pkp.classes.file.SubmissionFileManager'); $fileManager = new SubmissionFileManager($request->getContext()->getId(), $galley->getSubmissionId()); if (!$fileId) { // Note: Some HTML file uploads may be stored with incorrect file_type settings // due to incorrect finfo or mime.magic entries. As such, we examine the file extension // of the original file name for 'htm'. This will match .html, .htm, .xhtml, etc. // The file_type isn't important since the plugin includes the HTML content inline rather // than including a URL loaded in an iframe. $file = $galley->getFirstGalleyFile('htm'); if ($file) { $fileId = $file->getFileId(); } else { assert(false); // No HTML file in this HTML Article galley? return false; } } $contents = $fileManager->readFile($fileId); $journal = $request->getJournal(); // Replace media file references $images = $this->_getImageFiles($galley, $fileId, $journal); foreach ($images as $image) { $imageUrl = $request->url(null, 'article', 'viewFile', array($galley->getSubmissionId(), $galley->getBestGalleyId($journal), $image->getFileId())); $pattern = preg_quote($image->getOriginalFileName()); $contents = preg_replace('/([Ss][Rr][Cc]|[Hh][Rr][Ee][Ff]|[Dd][Aa][Tt][Aa])\\s*=\\s*"([^"]*' . $pattern . ')"/', '\\1="' . $imageUrl . '"', $contents); // Replacement for Flowplayer $contents = preg_replace('/[Uu][Rr][Ll]\\s*\\:\\s*\'(' . $pattern . ')\'/', 'url:\'' . $imageUrl . '\'', $contents); // Replacement for other players (ested with odeo; yahoo and google player won't work w/ OJS URLs, might work for others) $contents = preg_replace('/[Uu][Rr][Ll]=([^"]*' . $pattern . ')/', 'url=' . $imageUrl, $contents); } // Perform replacement for ojs://... URLs $contents = preg_replace_callback('/(<[^<>]*")[Oo][Jj][Ss]:\\/\\/([^"]+)("[^<>]*>)/', array(&$this, '_handleOjsUrl'), $contents); // Perform variable replacement for journal, issue, site info $issueDao = DAORegistry::getDAO('IssueDAO'); $issue = $issueDao->getIssueByArticleId($galley->getSubmissionId()); $journal = $request->getJournal(); $site = $request->getSite(); $paramArray = array('issueTitle' => $issue ? $issue->getIssueIdentification() : __('editor.article.scheduleForPublication.toBeAssigned'), 'journalTitle' => $journal->getLocalizedName(), 'siteTitle' => $site->getLocalizedTitle(), 'currentUrl' => $request->getRequestUrl()); foreach ($paramArray as $key => $value) { $contents = str_replace('{$' . $key . '}', $value, $contents); } return $contents; }
/** * Save the email in the submission email log. */ function log($request = null) { import('classes.log.SubmissionEmailLogEntry'); $entry = new SubmissionEmailLogEntry(); $submission = $this->submission; // Event data $entry->setEventType($this->logEventType); $entry->setAssocType(ASSOC_TYPE_SUBMISSION); $entry->setAssocId($submission->getId()); $entry->setDateSent(Core::getCurrentDate()); // User data if ($request) { $user = $request->getUser(); $entry->setSenderId($user == null ? 0 : $user->getId()); $entry->setIPAddress($request->getRemoteAddr()); } else { // No user supplied -- this is e.g. a cron-automated email $entry->setSenderId(0); } // Email data $entry->setSubject($this->getSubject()); $entry->setBody($this->getBody()); $entry->setFrom($this->getFromString(false)); $entry->setRecipients($this->getRecipientString()); $entry->setCcs($this->getCcString()); $entry->setBccs($this->getBccString()); // Add log entry $logDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); $logEntryId = $logDao->insertObject($entry); // Add attachments import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($submission->getContextId(), $submission->getId()); foreach ($this->getAttachmentFiles() as $attachment) { $submissionFileManager->temporaryFileToSubmissionFile($attachment, SUBMISSION_FILE_ATTACHMENT, ASSOC_TYPE_SUBMISSION_EMAIL_LOG_ENTRY, $logEntryId); } }
/** * Save the submission file upload form. * @see Form::execute() * @param $request Request * @return SubmissionFile if successful, otherwise null */ function execute($request) { // Identify the file genre and category. $revisedFileId = $this->getRevisedFileId(); if ($revisedFileId) { // The file genre and category will be copied over from the revised file. $fileGenre = null; } else { // This is a new file so we need the file genre and category from the form. $fileGenre = $this->getData('genreId') ? (int) $this->getData('genreId') : null; } // Retrieve the uploader's user group. $uploaderUserGroupId = $this->getData('uploaderUserGroupId'); if (!$uploaderUserGroupId) { fatalError('Invalid uploader user group!'); } // Identify the uploading user. $user = $request->getUser(); assert(is_a($user, 'User')); $assocType = $this->getData('assocType') ? (int) $this->getData('assocType') : null; $assocId = $this->getData('assocId') ? (int) $this->getData('assocId') : null; $fileStage = $this->getData('fileStage'); // Upload the file. import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($request->getContext()->getId(), $this->getData('submissionId')); $submissionFile = $submissionFileManager->uploadSubmissionFile('uploadedFile', $fileStage, $user->getId(), $uploaderUserGroupId, $revisedFileId, $fileGenre, $assocType, $assocId); if (!$submissionFile) { return null; } // Log the event. import('lib.pkp.classes.log.SubmissionFileLog'); import('lib.pkp.classes.log.SubmissionFileEventLogEntry'); // constants SubmissionFileLog::logEvent($request, $submissionFile, $revisedFileId ? SUBMISSION_LOG_FILE_REVISION_UPLOAD : SUBMISSION_LOG_FILE_UPLOAD, $revisedFileId ? 'submission.event.revisionUploaded' : 'submission.event.fileUploaded', array('fileStage' => $fileStage, 'revisedFileId' => $revisedFileId, 'fileId' => $submissionFile->getFileId(), 'fileRevision' => $submissionFile->getRevision(), 'originalFileName' => $submissionFile->getOriginalFileName(), 'submissionId' => $this->getData('submissionId'), 'username' => $user->getUsername())); return $submissionFile; }
/** * @copydoc Form::execute() */ function execute($args, $request) { // Retrieve the submission. $submission = $this->getSubmission(); // Get this form decision actions labels. $actionLabels = EditorDecisionActionsManager::getActionLabels($this->_getDecisions()); // Record the decision. $reviewRound = $this->getReviewRound(); $decision = $this->getDecision(); import('lib.pkp.classes.submission.action.EditorAction'); $editorAction = new EditorAction(); $editorAction->recordDecision($request, $submission, $decision, $actionLabels, $reviewRound); // Identify email key and status of round. import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($submission->getContextId(), $submission->getId()); switch ($decision) { case SUBMISSION_EDITOR_DECISION_ACCEPT: $emailKey = 'EDITOR_DECISION_ACCEPT'; $status = REVIEW_ROUND_STATUS_ACCEPTED; $this->_updateReviewRoundStatus($submission, $status, $reviewRound); // Move to the editing stage. $editorAction->incrementWorkflowStage($submission, WORKFLOW_STAGE_ID_EDITING, $request); // Bring in the SUBMISSION_FILE_* constants. import('lib.pkp.classes.submission.SubmissionFile'); // Bring in the Manager (we need it). import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */ $selectedFiles = $this->getData('selectedFiles'); if (is_array($selectedFiles)) { foreach ($selectedFiles as $fileId) { $revisionNumber = $submissionFileDao->getLatestRevisionNumber($fileId); $submissionFileManager->copyFileToFileStage($fileId, $revisionNumber, SUBMISSION_FILE_FINAL, null, true); } } // Send email to the author. $this->_sendReviewMailToAuthor($submission, $emailKey, $request); break; case SUBMISSION_EDITOR_DECISION_EXTERNAL_REVIEW: $emailKey = 'EDITOR_DECISION_SEND_TO_EXTERNAL'; $status = REVIEW_ROUND_STATUS_SENT_TO_EXTERNAL; $this->_updateReviewRoundStatus($submission, $status, $reviewRound); // Move to the external review stage. $editorAction->incrementWorkflowStage($submission, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW, $request); // Create an initial external review round. $this->_initiateReviewRound($submission, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW, $request, REVIEW_ROUND_STATUS_PENDING_REVIEWERS); // Send email to the author. $this->_sendReviewMailToAuthor($submission, $emailKey, $request); break; case SUBMISSION_EDITOR_DECISION_SEND_TO_PRODUCTION: $emailKey = 'EDITOR_DECISION_SEND_TO_PRODUCTION'; // FIXME: this is copy-pasted from above, save the FILE_GALLEY. // Move to the editing stage. $editorAction->incrementWorkflowStage($submission, WORKFLOW_STAGE_ID_PRODUCTION, $request); // Bring in the SUBMISSION_FILE_* constants. import('lib.pkp.classes.submission.SubmissionFile'); // Bring in the Manager (we need it). import('lib.pkp.classes.file.SubmissionFileManager'); // Move the revisions to the next stage $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */ $selectedFiles = $this->getData('selectedFiles'); if (is_array($selectedFiles)) { foreach ($selectedFiles as $fileId) { $revisionNumber = $submissionFileDao->getLatestRevisionNumber($fileId); $submissionFileManager->copyFileToFileStage($fileId, $revisionNumber, SUBMISSION_FILE_PRODUCTION_READY); } } // Send email to the author. $this->_sendReviewMailToAuthor($submission, $emailKey, $request); break; default: fatalError('Unsupported decision!'); } }
/** * @see Form::execute() * @param $request Request * @return MonographFile if successful, otherwise null */ function execute($request) { // Retrieve the signoff we're working with. $signoffDao = DAORegistry::getDAO('SubmissionFileSignoffDAO'); $signoff = $signoffDao->getById($this->getData('signoffId')); assert(is_a($signoff, 'Signoff')); // Insert the note, if existing content and/or file. $temporaryFileId = $this->getData('temporaryFileId'); if ($temporaryFileId || $this->getData('newNote')) { $user = $request->getUser(); $noteDao = DAORegistry::getDAO('NoteDAO'); $note = $noteDao->newDataObject(); $note->setUserId($user->getId()); $note->setContents($this->getData('newNote')); $note->setAssocType(ASSOC_TYPE_SIGNOFF); $note->setAssocId($signoff->getId()); $noteId = $noteDao->insertObject($note); $note->setId($noteId); // Upload the file, if any, and associate it with the note. if ($temporaryFileId) { // Fetch the temporary file storing the uploaded library file $temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); $temporaryFile = $temporaryFileDao->getTemporaryFile($temporaryFileId, $user->getId()); // Upload the file. // Bring in the SUBMISSION_FILE_* constants import('classes.monograph.MonographFile'); $press = $request->getPress(); import('lib.pkp.classes.file.SubmissionFileManager'); $monographFileManager = new SubmissionFileManager($press->getId(), $this->getMonographId()); $signoffFileId = $monographFileManager->temporaryFileToSubmissionFile($temporaryFile, SUBMISSION_FILE_NOTE, $signoff->getUserId(), $signoff->getUserGroupId(), $signoff->getAssocId(), null, ASSOC_TYPE_NOTE, $noteId); // FIXME: Currently the code allows for a signoff to be // added many times (if the option is presented in the // form). Need to delete previous files uploaded to this // signoff. Partially due to #6799. // Mark ALL the signoffs for this user as completed with this file upload. if ($signoffFileId) { $signoff->setFileId($signoffFileId); $signoff->setFileRevision(1); } } // Now mark the signoff as completed (we have a note with content // or a file or both). $signoff->setDateCompleted(Core::getCurrentDate()); $signoffDao->updateObject($signoff); $notificationMgr = new NotificationManager(); $notificationMgr->updateNotification($request, array(NOTIFICATION_TYPE_AUDITOR_REQUEST), array($signoff->getUserId()), ASSOC_TYPE_SIGNOFF, $signoff->getId()); $notificationMgr->updateNotification($request, array(NOTIFICATION_TYPE_SIGNOFF_COPYEDIT, NOTIFICATION_TYPE_SIGNOFF_PROOF), array($signoff->getUserId()), ASSOC_TYPE_SUBMISSION, $this->getMonographId()); // log the event. import('lib.pkp.classes.log.SubmissionFileLog'); import('lib.pkp.classes.log.SubmissionFileEventLogEntry'); // constants $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); $monographFile = $submissionFileDao->getLatestRevision($signoff->getFileId()); if (isset($monographFile)) { SubmissionFileLog::logEvent($request, $monographFile, SUBMISSION_LOG_FILE_AUDIT_UPLOAD, 'submission.event.fileAuditUploaded', array('file' => $monographFile->getOriginalFileName(), 'name' => $user->getFullName(), 'username' => $user->getUsername())); } return $signoff->getId(); } }
/** * Delete a submission by ID. * @param $submissionId int */ function deleteById($submissionId) { // Delete submission files. $submission = $this->getById($submissionId); assert(is_a($submission, 'Submission')); // 'deleteAllRevisionsBySubmissionId' has to be called before 'rmtree' // because SubmissionFileDaoDelegate::deleteObjects checks the file // and returns false if the file is not there, which makes the foreach loop in // PKPSubmissionFileDAO::_deleteInternally not run till the end. $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */ $submissionFileDao->deleteAllRevisionsBySubmissionId($submissionId); import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($submission->getContextId(), $submission->getId()); $submissionFileManager->rmtree($submissionFileManager->getBasePath()); $this->authorDao->deleteBySubmissionId($submissionId); $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); $reviewRoundDao->deleteBySubmissionId($submissionId); $editDecisionDao = DAORegistry::getDAO('EditDecisionDAO'); $editDecisionDao->deleteDecisionsBySubmissionId($submissionId); $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); $reviewAssignmentDao->deleteBySubmissionId($submissionId); // Delete the queries associated with a submission $queryDao = DAORegistry::getDAO('QueryDAO'); $queryDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); // Delete the stage assignments. $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); $stageAssignments = $stageAssignmentDao->getBySubmissionAndStageId($submissionId); while ($stageAssignment = $stageAssignments->next()) { $stageAssignmentDao->deleteObject($stageAssignment); } $noteDao = DAORegistry::getDAO('NoteDAO'); $noteDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); $submissionCommentDao = DAORegistry::getDAO('SubmissionCommentDAO'); $submissionCommentDao->deleteBySubmissionId($submissionId); // Delete any outstanding notifications for this submission $notificationDao = DAORegistry::getDAO('NotificationDAO'); $notificationDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); $submissionEventLogDao = DAORegistry::getDAO('SubmissionEventLogDAO'); $submissionEventLogDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); $submissionEmailLogDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); $submissionEmailLogDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); // Delete controlled vocab lists assigned to this submission $submissionKeywordDao = DAORegistry::getDAO('SubmissionKeywordDAO'); $submissionKeywordVocab = $submissionKeywordDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_KEYWORD, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionKeywordVocab)) { $submissionKeywordDao->deleteObject($submissionKeywordVocab); } $submissionDisciplineDao = DAORegistry::getDAO('SubmissionDisciplineDAO'); $submissionDisciplineVocab = $submissionDisciplineDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_DISCIPLINE, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionDisciplineVocab)) { $submissionDisciplineDao->deleteObject($submissionDisciplineVocab); } $submissionAgencyDao = DAORegistry::getDAO('SubmissionAgencyDAO'); $submissionAgencyVocab = $submissionAgencyDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_AGENCY, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionAgencyVocab)) { $submissionAgencyDao->deleteObject($submissionAgencyVocab); } $submissionLanguageDao = DAORegistry::getDAO('SubmissionLanguageDAO'); $submissionLanguageVocab = $submissionLanguageDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_LANGUAGE, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionLanguageVocab)) { $submissionLanguageDao->deleteObject($submissionLanguageVocab); } $submissionSubjectDao = DAORegistry::getDAO('SubmissionSubjectDAO'); $submissionSubjectVocab = $submissionSubjectDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_SUBJECT, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionSubjectVocab)) { $submissionSubjectDao->deleteObject($submissionSubjectVocab); } $this->update('DELETE FROM submission_settings WHERE submission_id = ?', (int) $submissionId); $this->update('DELETE FROM submissions WHERE submission_id = ?', (int) $submissionId); }
/** * Download a file. * @param $fileId int the file id of the file to download * @param $revision int the revision of the file to download * @param $inline boolean print file as inline instead of attachment, optional * @param $filename string The client-side download filename (optional) * @return boolean */ function downloadFile($fileId, $revision = null, $inline = false, $filename = null) { $returner = false; $submissionFile = $this->_getFile($fileId, $revision); if (isset($submissionFile)) { // Make sure that the file belongs to the submission. if ($submissionFile->getSubmissionId() != $this->getSubmissionId()) { fatalError('Invalid file id!'); } SubmissionFileManager::recordView($submissionFile); // Send the file to the user. $filePath = $submissionFile->getFilePath(); $mediaType = $submissionFile->getFileType(); $returner = parent::downloadFile($filePath, $mediaType, $inline, $filename); } return $returner; }
/** * Download a published monograph publication format file. * @param $args array * @param $request PKPRequest * @param $view boolean True iff inline viewer should be used, if available */ function download($args, $request, $view = false) { $dispatcher = $request->getDispatcher(); $publishedMonograph = $this->getAuthorizedContextObject(ASSOC_TYPE_PUBLISHED_MONOGRAPH); $this->setupTemplate($request, $publishedMonograph); $press = $request->getPress(); $monographId = array_shift($args); // Validated thru auth $representationId = array_shift($args); $bestFileId = array_shift($args); $publicationFormatDao = DAORegistry::getDAO('PublicationFormatDAO'); $publicationFormat = $publicationFormatDao->getByBestId($representationId, $publishedMonograph->getId()); if (!$publicationFormat || !$publicationFormat->getIsApproved() || !$publicationFormat->getIsAvailable() || ($remoteURL = $publicationFormat->getRemoteURL())) { fatalError('Invalid publication format specified.'); } $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); import('lib.pkp.classes.submission.SubmissionFile'); // File constants $submissionFile = $submissionFileDao->getByBestId($bestFileId, $publishedMonograph->getId()); if (!$submissionFile) { $dispatcher->handle404(); } $fileIdAndRevision = $submissionFile->getFileIdAndRevision(); list($fileId, $revision) = array_map(create_function('$a', 'return (int) $a;'), preg_split('/-/', $fileIdAndRevision)); import('lib.pkp.classes.file.SubmissionFileManager'); $monographFileManager = new SubmissionFileManager($publishedMonograph->getContextId(), $publishedMonograph->getId()); switch ($submissionFile->getAssocType()) { case ASSOC_TYPE_PUBLICATION_FORMAT: // Publication format file if ($submissionFile->getAssocId() != $publicationFormat->getId() || $submissionFile->getDirectSalesPrice() === null) { fatalError('Invalid monograph file specified!'); } break; case ASSOC_TYPE_SUBMISSION_FILE: // Dependent file $genreDao = DAORegistry::getDAO('GenreDAO'); $genre = $genreDao->getById($submissionFile->getGenreId()); if (!$genre->getDependent()) { fatalError('Invalid monograph file specified!'); } return $monographFileManager->downloadFile($fileId, $revision); break; default: fatalError('Invalid monograph file specified!'); } $ompCompletedPaymentDao = DAORegistry::getDAO('OMPCompletedPaymentDAO'); $user = $request->getUser(); if ($submissionFile->getDirectSalesPrice() === '0' || $user && $ompCompletedPaymentDao->hasPaidPurchaseFile($user->getId(), $fileIdAndRevision)) { // Paid purchase or open access. if (!$user && $press->getSetting('restrictMonographAccess')) { // User needs to register first. Validation::redirectLogin(); } // If inline viewing is requested, permit plugins to // handle the document. PluginRegistry::loadCategory('viewableFiles', true); if ($view) { if (HookRegistry::call('CatalogBookHandler::view', array(&$this, &$publishedMonograph, &$publicationFormat, &$submissionFile))) { // If the plugin handled the hook, prevent further default activity. exit; } } // Inline viewer not available, or viewing not wanted. // Download or show the file. $inline = $request->getUserVar('inline') ? true : false; if (!HookRegistry::call('CatalogBookHandler::download', array(&$this, &$publishedMonograph, &$publicationFormat, &$submissionFile, &$inline))) { return $monographFileManager->downloadFile($fileId, $revision, $inline); } } // Fall-through: user needs to pay for purchase. // Users that are not logged in need to register/login first. if (!$user) { return $request->redirect(null, 'login', null, null, array('source' => $request->url(null, null, null, array($monographId, $representationId, $bestFileId)))); } // They're logged in but need to pay to view. import('classes.payment.omp.OMPPaymentManager'); $ompPaymentManager = new OMPPaymentManager($request); if (!$ompPaymentManager->isConfigured()) { $request->redirect(null, 'catalog'); } $queuedPayment = $ompPaymentManager->createQueuedPayment($press->getId(), PAYMENT_TYPE_PURCHASE_FILE, $user->getId(), $fileIdAndRevision, $submissionFile->getDirectSalesPrice(), $press->getSetting('currency')); $ompPaymentManager->displayPaymentForm($ompPaymentManager->queuePayment($queuedPayment), $queuedPayment); }
/** * Migrate submission filenames from OJS 2.x * @param $upgrade Upgrade * @param $params array * @return boolean */ function migrateFiles($upgrade, $params) { $journalDao = DAORegistry::getDAO('JournalDAO'); $submissionDao = DAORegistry::getDAO('ArticleDAO'); $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); DAORegistry::getDAO('GenreDAO'); // Load constants $siteDao = DAORegistry::getDAO('SiteDAO'); /* @var $siteDao SiteDAO */ $site = $siteDao->getSite(); $adminEmail = $site->getLocalizedContactEmail(); import('lib.pkp.classes.file.SubmissionFileManager'); $contexts = $journalDao->getAll(); while ($context = $contexts->next()) { $submissions = $submissionDao->getByContextId($context->getId()); while ($submission = $submissions->next()) { $submissionFileManager = new SubmissionFileManager($context->getId(), $submission->getId()); $submissionFiles = $submissionFileDao->getBySubmissionId($submission->getId()); foreach ($submissionFiles as $submissionFile) { $generatedFilename = $submissionFile->getServerFileName(); $basePath = $submissionFileManager->getBasePath() . '/'; $globPattern = $submissionFile->getSubmissionId() . '-' . $submissionFile->getFileId() . '-' . $submissionFile->getRevision() . '-' . '??' . '.' . strtolower_codesafe($submissionFile->getExtension()); $matchedResults = array_merge(glob($basePath . '*/*/' . $globPattern), glob($basePath . '*/' . $globPattern)); if (count($matchedResults) > 1) { // Too many filenames matched. Continue with the first; this is just a warning. error_log("WARNING: Duplicate potential files for \"{$globPattern}\" in \"" . $submissionFileManager->getBasePath() . "\". Taking the first."); } elseif (count($matchedResults) == 0) { // No filenames matched. Skip migrating. error_log("WARNING: Unable to find a match for \"{$globPattern}\" in \"" . $submissionFileManager->getBasePath() . "\". Skipping this file."); continue; } $discoveredFilename = array_shift($matchedResults); $targetFilename = $basePath . $submissionFile->_fileStageToPath($submissionFile->getFileStage()) . '/' . $generatedFilename; if (file_exists($targetFilename)) { continue; } // Skip existing files/links if (!file_exists($path = dirname($targetFilename)) && !$submissionFileManager->mkdirtree($path)) { error_log("Unable to make directory \"{$path}\""); } if (!rename($discoveredFilename, $targetFilename)) { error_log("Unable to move \"{$discoveredFilename}\" to \"{$targetFilename}\"."); } } } } return true; }
/** * Delete a submission by ID. * @param $submissionId int */ function deleteById($submissionId) { // Delete submission files. $submission = $this->getById($submissionId); assert(is_a($submission, 'Submission')); import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($submission->getContextId(), $submission->getId()); $submissionFileManager->rmtree($submissionFileManager->getBasePath()); $this->authorDao->deleteBySubmissionId($submissionId); $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); $reviewRoundDao->deleteBySubmissionId($submissionId); $editDecisionDao = DAORegistry::getDAO('EditDecisionDAO'); $editDecisionDao->deleteDecisionsBySubmissionId($submissionId); $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); $reviewAssignmentDao->deleteBySubmissionId($submissionId); // Signoff DAOs $signoffDao = DAORegistry::getDAO('SignoffDAO'); $submissionFileSignoffDao = DAORegistry::getDAO('SubmissionFileSignoffDAO'); // Delete Signoffs associated with a submission file of this submission. $submissionFileSignoffs = $submissionFileSignoffDao->getAllBySubmission($submissionId); while ($signoff = $submissionFileSignoffs->next()) { $signoffDao->deleteObject($signoff); } // Delete the Signoffs associated with the submission itself. $submissionSignoffs = $signoffDao->getAllByAssocType(ASSOC_TYPE_SUBMISSION, $submissionId); while ($signoff = $submissionSignoffs->next()) { $signoffDao->deleteObject($signoff); } // Delete the stage assignments. $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); $stageAssignments = $stageAssignmentDao->getBySubmissionAndStageId($submissionId); while ($stageAssignment = $stageAssignments->next()) { $stageAssignmentDao->deleteObject($stageAssignment); } // N.B. Files must be deleted after signoffs to identify submission file signoffs. // Delete submission files. $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */ $submissionFileDao->deleteAllRevisionsBySubmissionId($submissionId); $noteDao = DAORegistry::getDAO('NoteDAO'); $noteDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); $submissionCommentDao = DAORegistry::getDAO('SubmissionCommentDAO'); $submissionCommentDao->deleteBySubmissionId($submissionId); // Delete any outstanding notifications for this submission $notificationDao = DAORegistry::getDAO('NotificationDAO'); $notificationDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); $submissionEventLogDao = DAORegistry::getDAO('SubmissionEventLogDAO'); $submissionEventLogDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); $submissionEmailLogDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); $submissionEmailLogDao->deleteByAssoc(ASSOC_TYPE_SUBMISSION, $submissionId); // Delete controlled vocab lists assigned to this submission $submissionKeywordDao = DAORegistry::getDAO('SubmissionKeywordDAO'); $submissionKeywordVocab = $submissionKeywordDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_KEYWORD, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionKeywordVocab)) { $submissionKeywordDao->deleteObject($submissionKeywordVocab); } $submissionDisciplineDao = DAORegistry::getDAO('SubmissionDisciplineDAO'); $submissionDisciplineVocab = $submissionDisciplineDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_DISCIPLINE, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionDisciplineVocab)) { $submissionDisciplineDao->deleteObject($submissionDisciplineVocab); } $submissionAgencyDao = DAORegistry::getDAO('SubmissionAgencyDAO'); $submissionAgencyVocab = $submissionAgencyDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_AGENCY, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionAgencyVocab)) { $submissionAgencyDao->deleteObject($submissionAgencyVocab); } $submissionLanguageDao = DAORegistry::getDAO('SubmissionLanguageDAO'); $submissionLanguageVocab = $submissionLanguageDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_LANGUAGE, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionLanguageVocab)) { $submissionLanguageDao->deleteObject($submissionLanguageVocab); } $submissionSubjectDao = DAORegistry::getDAO('SubmissionSubjectDAO'); $submissionSubjectVocab = $submissionSubjectDao->getBySymbolic(CONTROLLED_VOCAB_SUBMISSION_SUBJECT, ASSOC_TYPE_SUBMISSION, $submissionId); if (isset($submissionSubjectVocab)) { $submissionSubjectDao->deleteObject($submissionSubjectVocab); } $this->update('DELETE FROM submission_settings WHERE submission_id = ?', (int) $submissionId); $this->update('DELETE FROM submissions WHERE submission_id = ?', (int) $submissionId); }
/** * Make a copy of the file to the specified file stage. * @param $context Context * @param $submissionFile SubmissionFile * @param $fileStage int SUBMISSION_FILE_... * @return SubmissionFile Resultant new submission file */ protected function importFile($context, $submissionFile, $fileStage) { $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($context->getId(), $submissionFile->getSubmissionId()); // Split the file into file id and file revision. $fileId = $submissionFile->getFileId(); $revision = $submissionFile->getRevision(); list($newFileId, $newRevision) = $submissionFileManager->copyFileToFileStage($fileId, $revision, $fileStage, null, true); return $submissionFileDao->getRevision($newFileId, $newRevision); }
/** * Return a context-aware file path. */ function getFilePath() { // Get the context ID $submissionDao = Application::getSubmissionDAO(); $submission = $submissionDao->getById($this->getSubmissionId()); if (!$submission) { return null; } $contextId = $submission->getContextId(); unset($submission); // Construct the file path import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($contextId, $this->getSubmissionId()); return $submissionFileManager->getBasePath() . $this->_fileStageToPath($this->getFileStage()) . '/' . $this->getServerFileName(); }
function execute($request, $userRoles) { $user = $request->getUser(); // Retrieve the signoff we're working with. $signoffDao = DAORegistry::getDAO('SubmissionFileSignoffDAO'); $signoff = $signoffDao->getById($this->getData('signoffId')); assert(is_a($signoff, 'Signoff')); // Insert the note, if existing content and/or file. $temporaryFileId = $this->getData('temporaryFileId'); if ($temporaryFileId || $this->getData('newNote')) { $noteDao = DAORegistry::getDAO('NoteDAO'); $note = $noteDao->newDataObject(); $note->setUserId($user->getId()); $note->setContents($this->getData('newNote')); $note->setAssocType(ASSOC_TYPE_SIGNOFF); $note->setAssocId($signoff->getId()); $noteId = $noteDao->insertObject($note); $note->setId($noteId); // Upload the file, if any, and associate it with the note. if ($temporaryFileId) { // Fetch the temporary file storing the uploaded library file $temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); $temporaryFile =& $temporaryFileDao->getTemporaryFile($temporaryFileId, $user->getId()); // Upload the file. // Bring in the SUBMISSION_FILE_* constants import('lib.pkp.classes.submission.SubmissionFile'); $context = $request->getContext(); import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($context->getId(), $this->_submissionId); // Get the submission file that is associated with the signoff. $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /** @var $submissionFileDao SubmissionFileDAO */ $signoffFile =& $submissionFileDao->getLatestRevision($signoff->getAssocId()); assert(is_a($signoffFile, 'SubmissionFile')); $noteFileId = $submissionFileManager->temporaryFileToSubmissionFile($temporaryFile, SUBMISSION_FILE_NOTE, $signoff->getUserId(), $signoff->getUserGroupId(), null, $signoffFile->getGenreId(), ASSOC_TYPE_NOTE, $noteId); } if ($user->getId() == $signoff->getUserId() && !$signoff->getDateCompleted()) { // Considered as a signoff response. // Mark the signoff as completed (we have a note with content // or a file or both). $signoff->setDateCompleted(Core::getCurrentDate()); $signoffDao->updateObject($signoff); $notificationMgr = new NotificationManager(); $notificationMgr->updateNotification($request, array(NOTIFICATION_TYPE_AUDITOR_REQUEST), array($signoff->getUserId()), ASSOC_TYPE_SIGNOFF, $signoff->getId()); $notificationMgr->updateNotification($request, array(NOTIFICATION_TYPE_SIGNOFF_COPYEDIT, NOTIFICATION_TYPE_SIGNOFF_PROOF), array($signoff->getUserId()), ASSOC_TYPE_SUBMISSION, $this->_submissionId); // Define the success trivial notification locale key. $successLocaleKey = 'notification.uploadedResponse'; // log the event. import('lib.pkp.classes.log.SubmissionFileLog'); import('lib.pkp.classes.log.SubmissionFileEventLogEntry'); // constants $submissionDao = Application::getSubmissionDAO(); $submission = $submissionDao->getById($this->_submissionId); $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); $submissionFile = $submissionFileDao->getLatestRevision($signoff->getFileId()); if (isset($submissionFile)) { SubmissionFileLog::logEvent($request, $submissionFile, SUBMISSION_LOG_FILE_AUDIT_UPLOAD, 'submission.event.fileAuditUploaded', array('file' => $submissionFile->getOriginalFileName(), 'name' => $user->getFullName(), 'username' => $user->getUsername())); } } else { // Common note addition. if ($user->getId() !== $signoff->getUserId() && array_intersect($userRoles, array(ROLE_ID_MANAGER, ROLE_ID_ASSISTANT, ROLE_ID_SUB_EDITOR))) { // If the current user is a context/series/sub editor or assistant, open the signoff again. if ($signoff->getDateCompleted()) { $signoff->setDateCompleted(null); $signoffDao->updateObject($signoff); $notificationMgr = new NotificationManager(); $notificationMgr->updateNotification($request, array(NOTIFICATION_TYPE_AUDITOR_REQUEST), array($signoff->getUserId()), ASSOC_TYPE_SIGNOFF, $signoff->getId()); $notificationMgr->updateNotification($request, array(NOTIFICATION_TYPE_SIGNOFF_COPYEDIT, NOTIFICATION_TYPE_SIGNOFF_PROOF), array($signoff->getUserId()), ASSOC_TYPE_SUBMISSION, $this->_submissionId); } } $successLocaleKey = 'notification.addedNote'; } NotificationManager::createTrivialNotification($user->getId(), NOTIFICATION_TYPE_SUCCESS, array('contents' => __($successLocaleKey))); return $signoff->getId(); } }
/** * Save review round files * @param $args array * @param $request PKPRequest * @stageSubmissionFiles array The files that belongs to a file stage * that is currently being used by a grid inside this form. */ function execute($args, $request, $stageSubmissionFiles, $fileStage) { $selectedFiles = (array) $this->getData('selectedFiles'); $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); $submissionFiles = $submissionFileDao->getLatestRevisions($this->getSubmissionId()); foreach ($submissionFiles as $submissionFile) { // Get the viewable flag value. $isViewable = in_array($submissionFile->getFileId(), $selectedFiles); // If this is a submission file that belongs to the current stage id... if (array_key_exists($submissionFile->getFileId(), $stageSubmissionFiles)) { // ...update the "viewable" flag accordingly. $submissionFile->setViewable($isViewable); } else { // If the viewable flag is set to true... if ($isViewable) { // Make a copy of the file to the current file stage. import('lib.pkp.classes.file.SubmissionFileManager'); $context = $request->getContext(); $submissionFileManager = new SubmissionFileManager($context->getId(), $submissionFile->getSubmissionId()); // Split the file into file id and file revision. $fileId = $submissionFile->getFileId(); $revision = $submissionFile->getRevision(); list($newFileId, $newRevision) = $submissionFileManager->copyFileToFileStage($fileId, $revision, $fileStage, null, true); if ($fileStage == SUBMISSION_FILE_REVIEW_FILE) { $submissionFileDao->assignRevisionToReviewRound($newFileId, $newRevision, $this->getReviewRound()); } $submissionFile = $submissionFileDao->getRevision($newFileId, $newRevision); } } $submissionFileDao->updateObject($submissionFile); } }