/**
  * PRIVATE routine to upload the file, add it to the database, convert into proof formats and ingest in repository.
  * @param $fileName string index into the $_FILES array
  * @param $type string identifying type
  * @param $fileId int ID of an existing file to update
  * @param $overwrite boolean overwrite all previous revisions of the file (revision number is still incremented)
  * @return int the file ID (false if upload failed)
  */
 function handleUpload($fileName, $type, $fileId = null, $overwrite = false)
 {
     if (HookRegistry::call('ArticleFileManager::handleUpload', array(&$fileName, &$type, &$fileId, &$overwrite, &$result))) {
         return $result;
     }
     $articleDao =& DAORegistry::getDAO('ArticleDAO');
     $articleFileDao =& DAORegistry::getDAO('ArticleFileDAO');
     $typePath = $this->typeToPath($type);
     $dir = $this->filesDir . $typePath . '/';
     //%CBP% get the most recent supplementary files - this is used later for upating supplmentary file datastreams
     $CBPPlatformDao =& DAORegistry::getDAO('CBPPlatformDAO');
     $mostRecentSupplementaryFiles = $CBPPlatformDao->getMostRecentSupplementaryFiles($this->articleId, $fileId);
     if (!$fileId) {
         // Insert dummy file to generate file id FIXME?
         $dummyFile = true;
         $articleFile =& $this->generateDummyFile($this->article);
     } else {
         $dummyFile = false;
         $articleFile = new ArticleFile();
         $articleFile->setRevision($articleFileDao->getRevisionNumber($fileId) + 1);
         $articleFile->setArticleId($this->articleId);
         $articleFile->setFileId($fileId);
         $articleFile->setDateUploaded(Core::getCurrentDate());
         $articleFile->setDateModified(Core::getCurrentDate());
     }
     $article = $articleDao->getArticle($articleFile->getArticleId());
     $articleFile->setFileType($_FILES[$fileName]['type']);
     $articleFile->setFileSize($_FILES[$fileName]['size']);
     $articleFile->setOriginalFileName(ArticleFileManager::truncateFileName($_FILES[$fileName]['name'], 127));
     $articleFile->setType($typePath);
     $articleFile->setRound($this->article->getCurrentRound());
     $newFileName = $this->generateFilename($articleFile, $type, $this->getUploadedFileName($fileName));
     if (!$this->uploadFile($fileName, $dir . $newFileName)) {
         // Delete the dummy file we inserted
         $articleFileDao->deleteArticleFileById($articleFile->getFileId());
         return false;
     }
     if ($dummyFile) {
         $articleFileDao->updateArticleFile($articleFile);
     } else {
         $articleFileDao->insertArticleFile($articleFile);
     }
     if ($overwrite) {
         $this->removePriorRevisions($articleFile->getFileId(), $articleFile->getRevision());
     }
     //%CBP% Upload file to Repository and update database with PID/DsId
     $epubconvert = new CBPPlatformEpubConvert();
     $mobiconvert = new CBPPlatformMobiConvert();
     $pdfconvert = new CBPPlatformPdfConvert();
     if ($type == "SP") {
         //if we're uploading a supplementary file
         if ($fileId) {
             $dsSuffix = str_replace("content", "", $mostRecentSupplementaryFiles[0]['fedora_dsid']);
         } else {
             $mostRecentSupplementaryFiles = $CBPPlatformDao->getMostRecentSupplementaryFiles($this->articleId);
         }
         if (count($mostRecentSupplementaryFiles) == 1 && !$fileId) {
             $dsSuffix = "05";
         } elseif (count($mostRecentSupplementaryFiles) > 1 && !$fileId) {
             $mostRecentSupplementaryFiles = $CBPPlatformDao->getMostRecentSupplementaryFiles($this->articleId);
             $dsId = str_replace("content", "", $mostRecentSupplementaryFiles[1]['fedora_dsid']);
             $dsId = (int) $dsId;
             $dsId++;
             $dsSuffix = sprintf("%02d", $dsId);
         }
     }
     if (mime_content_type($dir . $newFileName) == "application/zip" && $type != "SP") {
         $ebookFileName = str_replace($this->parseFileExtension($newFileName), "", $newFileName);
         $epubArgs = array("author" => $this->article->getAuthorString(), "title" => $this->article->getArticleTitle(), "description" => $this->article->getArticleAbstract());
         $epubconvert->createEpub($dir, $newFileName, $dir . $ebookFileName . "epub", null, $this->article->getJournalId(), $epubArgs);
         $mobiconvert->createMobi($dir, $newFileName, $dir . $ebookFileName . "mobi", null, $this->article->getJournalId(), $epubArgs);
         $pdfconvert->createPdf($dir, $newFileName, $dir . $ebookFileName . "pdf", null, $this->article->getJournalId(), $epubArgs);
         $digitalObject = new CBPPlatformDigitalObject();
         $digitalObject->setPID($this->articleId);
         //we use articleId as the unique identifier -- this should correspond with articleId in OJS database
         $digitalObject->setLabel($article->getArticleTitle());
         //label could be anything
         $digitalObject->setNamespace(Config::getVar('general', 'component_namespace'));
         $digitalObject->setPrimaryFormat("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
         $ext = $this->parseFileExtension($newFileName);
         $label = str_replace(".{$ext}", "", $newFileName);
         $ext = "docx";
         $digitalObject->setDatastream(array($dsId = $dsPrefix . "content" => array("id" => $dsPrefix . "content", "file" => "{$dir}{$newFileName}", "label" => $label . ".{$ext}", "mimetype" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "filetype" => $ext)));
         //
         $ext = "pdf";
         $digitalObject->setDatastream(array($dsPrefix . "content02" => array("id" => $dsPrefix . "content02", "file" => "{$dir}{$ebookFileName}" . "{$ext}", "label" => $label . ".{$ext}", "mimetype" => "application/pdf", "filetype" => $ext)));
         //
         $ext = "epub";
         $digitalObject->setDatastream(array($dsPrefix . "content03" => array("id" => $dsPrefix . "content03", "file" => "{$dir}{$ebookFileName}" . "{$ext}", "label" => $label . ".{$ext}", "mimetype" => "application/epub+zip", "filetype" => $ext)));
         ///
         $ext = "mobi";
         $digitalObject->setDatastream(array($dsPrefix . "content04" => array("id" => $dsPrefix . "content04", "file" => "{$dir}{$ebookFileName}" . "{$ext}", "label" => $label . ".{$ext}", "mimetype" => "application/x-mobipocket-ebook", "filetype" => $ext)));
     } else {
         $digitalObject = new CBPPlatformDigitalObject();
         $digitalObject->setPID($this->articleId);
         //we use articleId as the unique identifier -- this should correspond with articleId in OJS database
         $digitalObject->setLabel($article->getArticleTitle());
         //label could be anything
         $digitalObject->setNamespace(Config::getVar('general', 'component_namespace'));
         if ($type != "SP") {
             $digitalObject->setPrimaryFormat(mime_content_type($dir . $newFileName));
         }
         $label = $newFileName;
         $path_parts = pathinfo("{$dir}{$newFileName}");
         $digitalObject->setDatastream(array($dsId = $dsPrefix . "content" . $dsSuffix => array("id" => $dsPrefix . "content" . $dsSuffix, "file" => "{$dir}{$newFileName}", "label" => $label, "mimetype" => $this->returnMIMEType($dir . $newFileName), "filetype" => $path_parts['extension'])));
     }
     $obj = new SimpleXMLElement($digitalObject->readObjectProperties());
     foreach ($obj as $result) {
         $noObjects = $result->count();
     }
     if ($noObjects == 0) {
         $digitalObject->createObject();
     }
     $digitalObject->createObjectDatastreams();
     if ($type != "SP") {
         $digitalObject->makeHydraCompliant(null, $article->getArticleTitle(), $article->getAuthorString());
     }
     if ($digitalObject->obj->PID != "" && $dsId != "") {
         $CBPPlatformDao->setFedoraObjectInformation($digitalObject->obj->PID, $digitalObject->obj->ns, $dsId, $articleFile->getFileId(), $articleFile->getRevision());
     }
     return $articleFile->getFileId();
 }
 /**
  * Record the reviewer recommendation.
  */
 function recordRecommendation()
 {
     $reviewId = Request::getUserVar('reviewId');
     $recommendation = Request::getUserVar('recommendation');
     $this->validate($reviewId);
     $reviewerSubmission =& $this->submission;
     $CBPPlatformDao =& DAORegistry::getDAO('CBPPlatformDAO');
     $userDao =& DAORegistry::getDAO('UserDAO');
     $user = $userDao->getUser($reviewerSubmission->getReviewerId());
     $reviewComments = $CBPPlatformDao->getReviewComments($reviewId);
     $tempFileName = tempnam(sys_get_temp_dir(), ".txt");
     $tempFile = fopen($tempFileName, 'w');
     fwrite($tempFile, "On " . date("F j, Y, g:i a") . " " . $user->getFullName() . " (user id: " . $reviewerSubmission->getReviewerId() . ") wrote: \n\n");
     foreach ($reviewComments as $reviewComment) {
         if ($reviewComment['viewable'] == 1) {
             fwrite($tempFile, "Comments to author and editor: \n");
         }
         if ($reviewComment['viewable'] == 0) {
             fwrite($tempFile, "Comments editor only: \n");
         }
         fwrite($tempFile, $reviewComment['comments'] . "\n\n");
     }
     fseek($tempFile, 0);
     //%CBP% upload to repository - using articleId / constituent namespace
     $digitalObject = new CBPPlatformDigitalObject();
     $digitalObject->setNamespace("CBPPlatform");
     $digitalObject->setPID($reviewerSubmission->getArticleId());
     $digitalObject->setDatastream(array("contentComments" => array("id" => "contentComments", "file" => $tempFileName, "label" => "comments")));
     $obj = new SimpleXMLElement($digitalObject->readObjectProperties());
     foreach ($obj as $result) {
         $noObjects = $result->count();
     }
     if ($noObjects == 0) {
         $digitalObject->createObject();
     }
     $digitalObject->createObjectDatastreams();
     fclose($tempFile);
     unlink($tempFileName);
     $this->setupTemplate(true);
     if (!$reviewerSubmission->getCancelled()) {
         if (ReviewerAction::recordRecommendation($reviewerSubmission, $recommendation, Request::getUserVar('send'))) {
             Request::redirect(null, null, 'submission', array("reviewId" => $reviewId, "complete" => 1));
         }
     } else {
         Request::redirect(null, null, 'submission', array("reviewId" => $reviewId, "complete" => 1));
     }
 }
 /**
  * Publish issue, and ingest converted distribution formats (EPUB, PDF, MOBI and front cover artwork) in repository
  */
 function publishIssue($args)
 {
     $issueId = isset($args[0]) ? (int) $args[0] : 0;
     $this->validate($issueId);
     $issue =& $this->issue;
     $journal =& Request::getJournal();
     $journalId = $journal->getId();
     $CBPPlatformDao =& DAORegistry::getDAO('CBPPlatformDAO');
     $requiredSections = $CBPPlatformDao->getRequiredSections($journalId);
     foreach ($requiredSections as $requiredSection) {
         $requiredSectionsArr[$requiredSection['title']] = 1;
     }
     $requiredSections = $requiredSectionsArr;
     $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
     $articleDao =& DAORegistry::getDAO('ArticleDAO');
     $publishedArticles =& $publishedArticleDao->getPublishedArticles($issueId);
     $numberPublishedArticles = count($publishedArticles);
     foreach ($publishedArticles as $publishedArticle) {
         $article =& $articleDao->getArticle($publishedArticle->getId());
         if ($article && $article->getStatus() == STATUS_QUEUED) {
             $article->setStatus(STATUS_PUBLISHED);
             $article->stampStatusModified();
             $articleDao->updateArticle($article);
         }
         //TODO: %CBP% get most recent galley, not just a submission, review version etc
         $articleGalleys = $publishedArticle->getGalleys();
         $articleGalley = end($articleGalleys);
         //get the most recent galley
         if (strpos($articleGalley->_data['fileName'], "RV") !== false) {
             $path = "/submission/review/";
         }
         if (strpos($articleGalley->_data['fileName'], "ED") !== false) {
             $path = "/submission/editor/";
         }
         if (strpos($articleGalley->_data['fileName'], "PB") !== false) {
             $path = "/public/";
         }
         $issueChapters[] = array("id" => $article->getArticleId(), "name" => $article->getArticleTitle(), "description" => $article->getArticleAbstract(), "author" => $article->getAuthorString(false, ', ', false), "src" => $articleGalley->_data['fileName'], "dir" => Config::getVar('files', 'files_dir') . "/journals/{$journalId}/articles/" . $articleGalley->_data['submissionId'] . $path);
         $relatedItems[] = Config::getVar('general', 'component_namespace') . ":" . $article->getArticleId();
         //%CBP% retreive docx supplementary files for publication in the book
         $suppFiles = $publishedArticle->getSuppFiles();
         foreach ($suppFiles as $suppFile) {
             if ($suppFile->_data['fileType'] == "application/vnd.openxmlformats-officedocument.wordprocessingml.document") {
                 $suppFilesArr[] = $suppFile;
             }
         }
         $issueAuthors[] = $article->getAuthorString(false, ', ', false);
         unset($article);
     }
     //%CBP% adding author biographies section to the end of the book
     if (array_key_exists("Author Biographies", $requiredSections)) {
         foreach ($suppFilesArr as $suppFile) {
             $path = "/supp/";
             $title = $suppFile->getTitle();
             if (stristr($title['en_US'], "author biography") != false) {
                 //if the title of the supplementary file doesn't include the words 'author biography', don't include
                 $issueChapters[] = array("id" => $suppFile->getArticleId(), "name" => $title['en_US'], "src" => $suppFile->_data['fileName'], "dir" => Config::getVar('files', 'files_dir') . "/journals/{$journalId}/articles/" . $suppFile->getArticleId() . $path, "type" => "supp", "desc" => "Author Biography");
             }
         }
     }
     asort($issueAuthors);
     $numberOfIssueAuthors = count($issueAuthors);
     $i = 0;
     $issueAuthorsString = "";
     $issueAuthors = array_unique($issueAuthors);
     foreach ($issueAuthors as $issueAuthor) {
         $issueAuthorsString .= $issueAuthor;
         $i + 1 == $numberOfIssueAuthors ? $issueAuthorsString .= "" : ($issueAuthorsString .= "; ");
         $i++;
     }
     //%CBP% Upload file to Repository and update database with PID/DsId
     $digitalObject = new CBPPlatformDigitalObject();
     $epubconvert = new CBPPlatformEpubConvert();
     $mobiconvert = new CBPPlatformMobiConvert();
     $pdfconvert = new CBPPlatformPdfConvert();
     $coverImage = Config::getVar('general', 'base_url') . "/" . Config::getVar('files', 'public_files_dir') . "/journals/" . $issue->getJournalId() . "/" . $issue->getIssueFileName();
     $epubArgs = array("author" => $issueAuthorsString, "imprint" => $journal->getJournalTitle(), "title" => $issue->getIssueTitle(), "description" => $issue->getIssueDescription(), "isbn" => $CBPPlatformDao->getIssueISBN($issueId), "cover" => $coverImage);
     $epubconvert->createEpub(null, null, "cache/{$journalId}-{$issueId}.epub", $issueChapters, $journalId, $epubArgs);
     $mobiconvert->createMobi(null, null, "cache/{$journalId}-{$issueId}.mobi", $issueChapters, $journalId, $epubArgs);
     $pdfconvert->createPdf(null, null, "cache/{$journalId}-{$issueId}.pdf", $issueChapters, $journalId, $epubArgs, "cache/{$journalId}-{$issueId}-FC.pdf");
     $digitalObject->setPID($journalId . "-" . $issueId);
     $digitalObject->setLabel($issue->getIssueTitle());
     $digitalObject->setNamespace(Config::getVar('general', 'compiled_namespace'));
     ///
     $ext = "pdf";
     $digitalObject->setDatastream(array($ds = "content" => array("file" => Config::getVar('general', 'docroot') . "/cache/{$journalId}-{$issueId}.{$ext}", "label" => $issue->getIssueTitle() . ".{$ext}", "mimetype" => "application/pdf", "filetype" => $ext)));
     ///
     $ext = "epub";
     $digitalObject->setDatastream(array("content02" => array("file" => Config::getVar('general', 'docroot') . "/cache/{$journalId}-{$issueId}.{$ext}", "label" => $issue->getIssueTitle() . ".{$ext}", "mimetype" => "application/epub+zip", "filetype" => $ext)));
     ///
     $ext = "mobi";
     $digitalObject->setDatastream(array("content03" => array("file" => Config::getVar('general', 'docroot') . "/cache/{$journalId}-{$issueId}.{$ext}", "label" => $issue->getIssueTitle() . ".{$ext}", "mimetype" => "application/x-mobipocket-ebook", "filetype" => $ext)));
     ///
     $ext = "pdf";
     if (file_exists(Config::getVar('general', 'docroot') . "/cache/{$journalId}-{$issueId}-FC.{$ext}")) {
         $digitalObject->setDatastream(array("content04" => array("file" => Config::getVar('general', 'docroot') . "/cache/{$journalId}-{$issueId}-FC.{$ext}", "label" => $issue->getIssueTitle() . " Front Cover Artwork.pdf", "mimetype" => "application/pdf", "filetype" => $ext)));
     }
     $obj = new SimpleXMLElement($digitalObject->readObjectProperties());
     foreach ($obj as $result) {
         $noObjects = $result->count();
     }
     if ($noObjects == 0) {
         $digitalObject->createObject();
     }
     $digitalObject->createObjectDatastreams();
     $digitalObject->makeHydraCompliant("book", $issue->getIssueTitle(), $issueAuthorsString, $relatedItems);
     $CBPPlatformDao->setFedoraIssueObjectInformation($digitalObject->obj->PID, $digitalObject->obj->ns, $ds, $issueId);
     //%CBP% don't publish just yet, we don't have EIC approval for the publication, but still create the issue...
     $issue->setCurrent(1);
     $CBPPlatformDao->setIssuePending($issueId, 1);
     // If subscriptions with delayed open access are enabled then
     // update open access date according to open access delay policy
     if ($journal->getSetting('publishingMode') == PUBLISHING_MODE_SUBSCRIPTION && $journal->getSetting('enableDelayedOpenAccess')) {
         $delayDuration = $journal->getSetting('delayedOpenAccessDuration');
         $delayYears = (int) floor($delayDuration / 12);
         $delayMonths = (int) fmod($delayDuration, 12);
         $curYear = date('Y');
         $curMonth = date('n');
         $curDay = date('j');
         $delayOpenAccessYear = $curYear + $delayYears + (int) floor(($curMonth + $delayMonths) / 12);
         $delayOpenAccessMonth = (int) fmod($curMonth + $delayMonths, 12);
         $issue->setAccessStatus(ISSUE_ACCESS_SUBSCRIPTION);
         $issue->setOpenAccessDate(date('Y-m-d H:i:s', mktime(0, 0, 0, $delayOpenAccessMonth, $curDay, $delayOpenAccessYear)));
     }
     $issueDao =& DAORegistry::getDAO('IssueDAO');
     $issueDao->updateCurrentIssue($journalId, $issue);
     // Send a notification to associated users
     // %CBP% TODO: move this to EIC publishing approval stage
     /*import('lib.pkp.classes.notification.NotificationManager');
     		$notificationManager = new NotificationManager();
     		$roleDao =& DAORegistry::getDAO('RoleDAO');
     		$notificationUsers = array();
     		$allUsers = $roleDao->getUsersByJournalId($journalId);
     		while (!$allUsers->eof()) {
     			$user =& $allUsers->next();
     			$notificationUsers[] = array('id' => $user->getId());
     			unset($user);
     		}
     		$url = Request::url(null, 'issue', 'current');
     		foreach ($notificationUsers as $userRole) {
     			$notificationManager->createNotification(
     				$userRole['id'], 'notification.type.issuePublished',
     				null, $url, 1, NOTIFICATION_TYPE_PUBLISHED_ISSUE
     			);
     		}
     		$notificationManager->sendToMailingList(
     			$notificationManager->createNotification(
     				0, 'notification.type.issuePublished',
     				null, $url, 1, NOTIFICATION_TYPE_PUBLISHED_ISSUE
     			)
     		);*/
     Request::redirect(null, null, 'issueToc', $issue->getId());
 }