33 import(
'lib.pkp.classes.db.DAO');
34 import(
'lib.pkp.classes.submission.Genre');
35 import(
'lib.pkp.classes.plugins.PKPPubIdPluginDAO');
36 import(
'lib.pkp.classes.submission.SubmissionFile');
58 function getRevision($fileId, $revision, $fileStage =
null, $submissionId =
null) {
59 if (!($fileId && $revision))
return null;
60 $revisions = $this->_getInternally($submissionId, $fileStage, $fileId, $revision,
null,
null,
null,
null,
null,
false,
null);
61 return $this->_checkAndReturnRevision($revisions);
72 function getFileIdsBySetting($settingName, $settingValue, $submissionId =
null, $contextId =
null) {
73 $params = array($settingName);
75 $sql =
'SELECT DISTINCT f.file_id
76 FROM submission_files f
77 INNER JOIN submissions s ON s.submission_id = f.submission_id';
78 if (is_null($settingValue)) {
79 $sql .=
' LEFT JOIN submission_file_settings fs ON f.file_id = fs.file_id AND fs.setting_name = ?
80 WHERE (fs.setting_value IS NULL OR fs.setting_value = \'\')';
82 $params[] = (string) $settingValue;
83 $sql .=
' INNER JOIN submission_file_settings fs ON f.file_id = fs.file_id
84 WHERE fs.setting_name = ? AND fs.setting_value = ?';
88 $params[] = (int) $submissionId;
89 $sql .=
' AND f.submission_id = ?';
93 $params[] = (int) $contextId;
94 $sql .=
' AND s.context_id = ?';
97 $sql .=
' ORDER BY f.file_id';
98 $result = $this->
retrieve($sql, $params);
101 while (!$result->EOF) {
102 $row = $result->getRowAssoc(
false);
103 $fileIds[] = $row[
'file_id'];
121 function getByPubId($pubIdType, $pubId, $submissionId =
null, $contextId =
null) {
123 if (!empty($pubId)) {
125 if (!empty($fileIds)) {
126 assert(count($fileIds) == 1);
127 $fileId = $fileIds[0];
143 if ($fileId !=
'') $file = $this->
getByPubId(
'publisher-id', $fileId, $submissionId,
null);
145 list($fileId, $revision) = array_map(
function($a) {
147 }, preg_split(
'/-/', $fileId));
148 $file = $this->
getRevision($fileId, $revision,
null, $submissionId);
150 if ($file && $file->getFileStage() == SUBMISSION_FILE_PROOF)
return $file;
151 if ($file && $file->getFileStage() == SUBMISSION_FILE_DEPENDENT)
return $file;
164 if (!$fileId)
return null;
166 $revisions = $this->_getInternally($submissionId, $fileStage, $fileId,
null,
null,
null,
null,
null,
null,
true,
null,
null);
167 return $this->_checkAndReturnRevision($revisions);
179 if (!$submissionId)
return null;
180 return $this->_getInternally($submissionId, $fileStage,
null,
null,
null,
null,
null,
null,
null,
true, $rangeInfo);
193 function getAllRevisions($fileId, $fileStage =
null, $submissionId =
null, $rangeInfo =
null) {
194 if (!$fileId)
return null;
195 return $this->_getInternally($submissionId, $fileStage, $fileId,
null,
null,
null,
null,
null,
null,
false, $rangeInfo);
205 if (!$submissionId)
return null;
206 return $this->_getInternally($submissionId,
null,
null,
null,
null,
null,
null,
null,
null,
false, $rangeInfo);
220 if (!($assocType && $assocId))
return null;
221 return $this->_getInternally($submissionId, $fileStage,
null,
null, $assocType, $assocId,
null,
null,
null,
true, $rangeInfo);
234 if (!($assocType && $assocId))
return null;
235 return $this->_getInternally(
null, $fileStage,
null,
null, $assocType, $assocId,
null,
null,
null,
false, $rangeInfo);
246 $uploaderUserId =
null) {
247 if (!is_a($reviewRound,
'ReviewRound'))
return null;
248 return $this->_getInternally($reviewRound->getSubmissionId(),
249 $fileStage,
null,
null,
null,
null,
null,
250 $uploaderUserId, $reviewRound->getId()
262 if (!$reviewRound)
return array();
263 return $this->_getInternally($reviewRound->getSubmissionId(),
264 $fileStage,
null,
null,
null,
null, $reviewRound->getStageId(),
265 null, $reviewRound->getId(),
true
275 assert(!is_null($fileId));
279 'SELECT MAX(revision) AS max_revision FROM submission_files WHERE file_id = ?',
282 if($result->RecordCount() != 1)
return null;
284 $row = $result->FetchRow();
287 $latestRevision = (int)$row[
'max_revision'];
288 assert($latestRevision > 0);
289 return $latestRevision;
302 function insertObject($submissionFile, $sourceFile, $isUpload =
false) {
305 $submissionFile = $this->_castToGenre($submissionFile);
309 $this->_getFileImplementationForGenreId(
310 $submissionFile->getGenreId())
312 $targetDaoDelegate = $this->_getDaoDelegate($targetImplementation);
313 $insertedFile = $targetDaoDelegate->insertObject($submissionFile, $sourceFile, $isUpload);
317 if ($insertedFile &&
strtolower_codesafe(get_class($insertedFile)) != $targetImplementation) {
318 $insertedFile = $this->_castToDatabase($insertedFile);
320 return $insertedFile;
341 function updateObject($updatedFile, $previousFileId =
null, $previousRevision =
null) {
344 $updatedFile = $this->_castToGenre($updatedFile);
347 $previousFileId = (int)($previousFileId ? $previousFileId : $updatedFile->getFileId());
348 $previousRevision = (int)($previousRevision ? $previousRevision : $updatedFile->getRevision());
351 $previousFile = $this->
getRevision($previousFileId, $previousRevision);
352 assert(is_a($previousFile,
'SubmissionFile'));
359 $this->_getFileImplementationForGenreId(
360 $updatedFile->getGenreId())
362 $targetDaoDelegate = $this->_getDaoDelegate($targetImplementation);
367 if ($previousImplementation != $targetImplementation) {
374 $previousFilePath = $previousFile->getFilePath();
375 $targetFilePath = $updatedFile->getFilePath();
377 assert($previousFilePath != $targetFilePath && !file_exists($targetFilePath));
378 import(
'lib.pkp.classes.file.FileManager');
380 $fileManager->copyFile($previousFilePath, $targetFilePath);
385 $sourceDaoDelegate = $this->_getDaoDelegate($previousImplementation);
386 $sourceDaoDelegate->deleteObject($previousFile);
387 $targetDaoDelegate->insertObject($updatedFile, $targetFilePath);
391 if (!$targetDaoDelegate->updateObject($updatedFile, $previousFile)) {
399 $updatedFile = $this->_castToDatabase($updatedFile);
418 $revisedFileId = (int)$revisedFileId;
419 $newFileId = (int)$newFileId;
420 $submissionId = (int)$submissionId;
421 $fileStage = (int)$fileStage;
424 if ($revisedFileId == $newFileId)
return null;
427 $revisedFile = $this->
getLatestRevision($revisedFileId, $fileStage, $submissionId);
429 if (!($revisedFile && $newFile))
return null;
432 $previousFileId = $newFile->getFileId();
433 $previousRevision = $newFile->getRevision();
436 $newFile->setFileId($revisedFileId);
437 $newFile->setRevision($revisedFile->getRevision()+1);
438 $newFile->setGenreId($revisedFile->getGenreId());
439 $newFile->setAssocType($revisedFile->getAssocType());
440 $newFile->setAssocId($revisedFile->getAssocId());
443 return $this->
updateObject($newFile, $previousFileId, $previousRevision);
453 if (!is_numeric($fileId) || !is_numeric($revision))
fatalError(
'Invalid file!');
459 'INSERT INTO review_round_files
460 (submission_id, review_round_id, stage_id, file_id, revision)
461 VALUES (?, ?, ?, ?, ?)',
463 (
int)$reviewRound->getSubmissionId(),
464 (
int)$reviewRound->getId(),
465 (
int)$reviewRound->getStageId(),
478 return $this->
deleteRevisionById($submissionFile->getFileId(), $submissionFile->getRevision(), $submissionFile->getFileStage(), $submissionFile->getSubmissionId());
491 function deleteRevisionById($fileId, $revision, $fileStage =
null, $submissionId =
null) {
492 return $this->_deleteInternally($submissionId, $fileStage, $fileId, $revision);
505 return $this->_deleteInternally($submissionId, $fileStage, $fileId,
null,
null,
null,
null,
null,
true);
519 return $this->_deleteInternally($submissionId, $fileStage, $fileId);
531 return $this->_deleteInternally($submissionId, $fileStage);
543 return $this->_deleteInternally(
null, $fileStage,
null,
null, $assocType, $assocId);
552 return $this->
update(
'DELETE FROM review_round_files WHERE review_round_id = ?', (
int)$reviewRoundId);
565 'DELETE FROM review_round_files
566 WHERE submission_id = ? AND stage_id = ? AND file_id = ? AND revision = ?',
582 $submissionFiles = $this->_getInternally(
null,
null,
null,
null,
null,
null,
null, $oldUserId);
583 foreach ($submissionFiles as $file) {
584 $daoDelegate = $this->_getDaoDelegateForObject($file);
585 $file->setUploaderUserId($newUserId);
586 $daoDelegate->updateObject($file, $file);
598 $daoDelegate = $this->_getDaoDelegateForGenreId($genreId);
601 return $daoDelegate->newDataObject();
621 'submissionfile' =>
'lib.pkp.classes.submission.SubmissionFileDAODelegate',
622 'submissionartworkfile' =>
'lib.pkp.classes.submission.SubmissionArtworkFileDAODelegate',
623 'supplementaryfile' =>
'lib.pkp.classes.submission.SupplementaryFileDAODelegate',
635 GENRE_CATEGORY_DOCUMENT =>
'submissionfile',
636 GENRE_CATEGORY_ARTWORK =>
'submissionartworkfile',
637 GENRE_CATEGORY_SUPPLEMENTARY =>
'supplementaryfile',
649 return 'SELECT DISTINCT
650 sf.file_id AS submission_file_id, sf.revision AS submission_revision,
651 af.file_id AS artwork_file_id, af.revision AS artwork_revision,
652 suf.file_id AS supplementary_file_id, suf.revision AS supplementary_revision,
653 p.locale AS submission_locale,
655 FROM submission_files sf
656 LEFT JOIN submission_artwork_files af ON sf.file_id = af.file_id AND sf.revision = af.revision
657 LEFT JOIN submission_supplementary_files suf ON sf.file_id = suf.file_id AND sf.revision = suf.revision
658 LEFT JOIN submissions as s ON s.submission_id = sf.submission_id
659 LEFT JOIN publications p ON s.current_publication_id = p.publication_id ';
672 function fromRow($row, $fileImplementation =
null) {
674 case isset($row[
'artwork_file_id']) && is_numeric($row[
'artwork_file_id']):
675 $daoDelegate = $this->_getDaoDelegate(
'SubmissionArtworkFile');
677 case isset($row[
'supplementary_file_id']) && is_numeric($row[
'supplementary_file_id']):
678 $daoDelegate = $this->_getDaoDelegate(
'SupplementaryFile');
681 $daoDelegate = $this->_getDaoDelegate(
'SubmissionFile');
685 return $daoDelegate->fromRow($row);
695 import(
'lib.pkp.classes.submission.SubmissionFile');
697 SUBMISSION_FILE_SUBMISSION,
698 SUBMISSION_FILE_NOTE,
699 SUBMISSION_FILE_REVIEW_FILE,
700 SUBMISSION_FILE_REVIEW_ATTACHMENT,
701 SUBMISSION_FILE_FINAL,
702 SUBMISSION_FILE_FAIR_COPY,
703 SUBMISSION_FILE_EDITOR,
704 SUBMISSION_FILE_COPYEDIT,
705 SUBMISSION_FILE_PROOF,
706 SUBMISSION_FILE_PRODUCTION_READY,
707 SUBMISSION_FILE_ATTACHMENT,
708 SUBMISSION_FILE_REVIEW_REVISION,
709 SUBMISSION_FILE_DEPENDENT,
710 SUBMISSION_FILE_QUERY,
717 function pubIdExists($pubIdType, $pubId, $excludePubObjectId, $contextId) {
718 $submissionFileDAODelegate = $this->_getDaoDelegate(
'submissionfile');
719 return $submissionFileDAODelegate->pubIdExists($pubIdType, $pubId, $excludePubObjectId, $contextId);
725 function changePubId($pubObjectId, $pubIdType, $pubId) {
726 $submissionFileDAODelegate = $this->_getDaoDelegate(
'submissionfile');
727 $submissionFileDAODelegate->changePubId($pubObjectId, $pubIdType, $pubId);
734 $submissionFileDAODelegate = $this->_getDaoDelegate(
'submissionfile');
735 $submissionFileDAODelegate->deletePubId($pubObjectId, $pubIdType);
742 $submissionFileDAODelegate = $this->_getDaoDelegate(
'submissionfile');
743 $submissionFileDAODelegate->deleteAllPubIds($contextId, $pubIdType);
757 switch ($submissionFile->getFileStage()) {
758 case SUBMISSION_FILE_SUBMISSION:
759 return WORKFLOW_STAGE_ID_SUBMISSION;
760 case SUBMISSION_FILE_REVIEW_FILE:
761 case SUBMISSION_FILE_REVIEW_ATTACHMENT:
762 case SUBMISSION_FILE_REVIEW_REVISION:
764 $reviewRound = $reviewRoundDao->getBySubmissionFileId($submissionFile->getFileId());
765 return $reviewRound->getStageId();
766 case SUBMISSION_FILE_FINAL:
767 case SUBMISSION_FILE_COPYEDIT:
768 return WORKFLOW_STAGE_ID_EDITING;
769 case SUBMISSION_FILE_PROOF:
770 case SUBMISSION_FILE_PRODUCTION_READY:
771 case SUBMISSION_FILE_DEPENDENT:
772 return WORKFLOW_STAGE_ID_PRODUCTION;
773 case SUBMISSION_FILE_QUERY:
775 $note = $noteDao->getById($submissionFile->getAssocId());
777 $query = $queryDao->getById($note->getAssocId());
778 return $query?$query->getStageId():
null;
790 private function _getFileImplementationForGenreId($genreId) {
791 static $genreCache = array();
793 if (!isset($genreCache[$genreId])) {
794 if (is_null($genreId)) {
796 $genreCategory = GENRE_CATEGORY_DOCUMENT;
802 $genre = $genreDao->getById($genreId);
803 $genreCategory = $genre->getCategory();
808 assert(isset($genreMapping[$genreCategory]));
809 $genreCache[$genreId] = $genreMapping[$genreCategory];
812 return $genreCache[$genreId];
821 private function _getDaoDelegateForGenreId($genreId) {
823 $fileImplementation = $this->_getFileImplementationForGenreId($genreId);
826 return $this->_getDaoDelegate($fileImplementation);
835 private function _getDaoDelegateForObject($object) {
836 return $this->_getDaoDelegate(get_class($object));
846 private function _getDaoDelegate($fileImplementation) {
851 if (!isset($this->_delegates[$fileImplementation])) {
854 assert(isset($delegateClasses[$fileImplementation]));
855 $delegateClass = $delegateClasses[$fileImplementation];
856 $this->_delegates[$fileImplementation] =
instantiate($delegateClass,
'SubmissionFileDAODelegate');
860 return $this->_delegates[$fileImplementation];
879 private function _getInternally($submissionId =
null, $fileStage =
null, $fileId =
null, $revision =
null,
880 $assocType =
null, $assocId =
null, $stageId =
null, $uploaderUserId =
null,
881 $reviewRoundId =
null, $latestOnly =
false, $rangeInfo =
null) {
887 if ($reviewRoundId) {
888 $sql .=
'INNER JOIN review_round_files rrf
889 ON sf.submission_id = rrf.submission_id
890 AND sf.file_id = rrf.file_id
891 AND sf.revision '.($latestOnly ?
'>=' :
'=').
' rrf.revision ';
895 list($filterClause, $params) = $this->_buildFileSelectionFilter(
896 $submissionId, $fileStage, $fileId, $revision,
897 $assocType, $assocId, $stageId, $uploaderUserId, $reviewRoundId);
907 $sql .=
'LEFT JOIN submission_files sf2 ON sf.file_id = sf2.file_id AND sf.revision < sf2.revision
908 WHERE sf2.revision IS NULL AND '.$filterClause;
910 $sql .=
'WHERE '.$filterClause;
914 $sql .=
' ORDER BY sf.submission_id ASC, sf.file_stage ASC, sf.file_id ASC, sf.revision DESC';
920 $result = $this->
retrieve($sql, $params);
924 $submissionFiles = array();
925 while (!$result->EOF) {
927 $row = $result->GetRowAssoc(
false);
931 $idAndRevision = $row[
'submission_file_id'].
'-'.$row[
'submission_revision'];
934 assert(!isset($submissionFiles[$idAndRevision]));
940 $submissionFiles[$idAndRevision] = $this->
fromRow($row);
947 return $submissionFiles;
965 private function _deleteInternally($submissionId =
null, $fileStage =
null, $fileId =
null, $revision =
null,
966 $assocType =
null, $assocId =
null, $stageId =
null, $uploaderUserId =
null,
967 $latestOnly =
false) {
970 $deletedFiles = $this->_getInternally($submissionId, $fileStage, $fileId, $revision,
971 $assocType, $assocId, $stageId, $uploaderUserId,
null, $latestOnly,
null);
972 if (empty($deletedFiles))
return 0;
974 foreach($deletedFiles as $deletedFile) {
981 $daoDelegate = $this->_getDaoDelegateForObject($deletedFile);
982 if (!$daoDelegate->deleteObject($deletedFile))
return false;
986 return count($deletedFiles);
1004 private function _buildFileSelectionFilter($submissionId, $fileStage,
1005 $fileId, $revision, $assocType, $assocId, $stageId, $uploaderUserId, $reviewRoundId) {
1008 assert($submissionId>0 || (
int)$uploaderUserId || (
int)$fileId || (
int)$assocId);
1011 assert(((
int)$assocType && (
int)$assocId) || !((
int)$assocType || (
int)$assocId));
1016 'sf.submission_id' => $submissionId,
1017 'sf.file_stage' => $fileStage,
1018 'sf.file_id' => $fileId,
1019 'sf.revision' => $revision,
1020 'sf.assoc_type' => $assocType,
1021 'sf.assoc_id' => $assocId,
1022 'sf.uploader_user_id' => $uploaderUserId,
1023 'rrf.stage_id' => $stageId,
1024 'rrf.review_round_id' => $reviewRoundId,
1032 foreach($filters as $filteredColumn => $filteredId) {
1034 $filterClause .= $conjunction.
' '.$filteredColumn.
' = ?';
1035 $conjunction =
' AND';
1036 $params[] = (int)$filteredId;
1039 return array($filterClause, $params);
1054 private function _castToGenre($submissionFile) {
1057 $this->_getFileImplementationForGenreId(
1058 $submissionFile->getGenreId())
1063 if (is_a($submissionFile, $targetImplementation))
return $submissionFile;
1068 $targetDaoDelegate = $this->_getDaoDelegate($targetImplementation);
1069 $targetFile = $targetDaoDelegate->newDataObject();
1070 $targetFile = $submissionFile->upcastTo($targetFile);
1080 private function _castToDatabase($submissionFile) {
1082 $submissionFile->getFileId(),
1083 $submissionFile->getRevision()
1093 private function _checkAndReturnRevision($revisions) {
1094 assert(count($revisions) <= 1);
1095 if (empty($revisions))
return null;
1097 $revision = array_pop($revisions);
1098 assert(is_a($revision,
'SubmissionFile'));
1109 function copyFile($context, $submissionFile, $fileStage){
1110 import(
'lib.pkp.classes.file.SubmissionFileManager');
1111 $submissionFileManager =
new SubmissionFileManager($context->getId(), $submissionFile->getSubmissionId());
1112 $fileId = $submissionFile->getFileId();
1113 $revision = $submissionFile->getRevision();
1114 list($newFileId, $newRevision) = $submissionFileManager->copyFileToFileStage($fileId, $revision, $fileStage,
null, $submissionFile->getViewable());