From 5ecc0a72ecd0983b86acc877331a5c84001a9e10 Mon Sep 17 00:00:00 2001 From: marsilius Date: Tue, 5 Jan 2021 11:30:42 +0100 Subject: [PATCH 1/5] =?UTF-8?q?Angeglichen=20an=20das=20OJS=20Datacite-Plu?= =?UTF-8?q?gin,=20Marked=20registerd=20erg=C3=A4nzt,=20das=20Feld=20dataci?= =?UTF-8?q?te-export::status=20erg=C3=A4nzt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataciteExportPlugin.inc.php | 1389 +++++++++++++---- .../grid/DataciteQueuedListHandler.inc.php | 35 - css/datacite-content.css | 83 + js/datacite-script.js | 218 +++ locale/en_US/locale.xml | 21 +- templates/index.tpl | 527 +++++-- 6 files changed, 1785 insertions(+), 488 deletions(-) delete mode 100644 controllers/grid/DataciteQueuedListHandler.inc.php create mode 100644 css/datacite-content.css create mode 100644 js/datacite-script.js diff --git a/DataciteExportPlugin.inc.php b/DataciteExportPlugin.inc.php index bbd2a84..2e438e8 100644 --- a/DataciteExportPlugin.inc.php +++ b/DataciteExportPlugin.inc.php @@ -1,459 +1,1264 @@ assign( 'plugin', $this->getName() ); - function __construct() + //Ajax + $params = $request->getUserVars(); + if( array_key_exists( 'isAjax', $params ) && $params['isAjax'] === 'true' ) + { + $filteredData = $this->filterData( + $params['sel-search-type'], + $params['search-text'], + $params['sel-search-status'], + $request + ); + if( count( $filteredData ) > 0 ) + { + $this->buildSearchTable( $filteredData ); + } + } + else + { + //reguläre Seitenaufrufe + switch( array_shift( $args ) ) + { + case 'settings': + $this->getSettings( $templateMgr ); + $this->updateSettings( $request ); + $request->redirect( NULL, 'management', 'importexport', array( 'plugin', 'DataciteExportPlugin' ) ); + case '': + $this->getSettings( $templateMgr ); + $this->depositHandler( $request, $templateMgr ); + $templateMgr->display( $this->getTemplateResource( 'index.tpl' ) ); + break; + case 'export': + $selectedSubmissions = $request->getUserVar( 'selectedSubmissions' ); + $selectedChapters = $request->getUserVar( 'selectedChapters' ); + + if( NULL !== $selectedSubmissions && count( $selectedSubmissions ) !== 0 ) + { + if( $request->getUserVar( self::EXPORT_ACTION_DEPOSIT ) ) + { + $responses = $this->exportSubmissions( $selectedSubmissions ); + $this->createNotifications( $request, $responses ); + } + else if( $request->getUserVar( self::EXPORT_ACTION_MARKREGISTERED ) ) + { + $responses = $this->markSubmissionsRegistered( $selectedSubmissions ); + $this->createNotifications( $request, $responses ); + } + } + + if( NULL !== $selectedChapters && count( $selectedChapters ) !== 0 ) + { + if( $request->getUserVar( self::EXPORT_ACTION_DEPOSIT ) ) + { + $responses = $this->exportChapters( $selectedChapters ); + $this->createNotifications( $request, $responses ); + } + else if( $request->getUserVar( self::EXPORT_ACTION_MARKREGISTERED ) ) + { + $responses = $this->markChaptersRegistered( $selectedChapters ); + $this->createNotifications( $request, $responses ); + } + } + $request->redirect( NULL, 'management', 'importexport', array( 'plugin', 'DataciteExportPlugin' ) ); + break; + default: + $dispatcher = $request->getDispatcher(); + if( NULL !== $dispatcher ) + { + $dispatcher->handle404(); + } + } + } + } + + public function getSettings( TemplateManager $templateMgr ) : array { + $request = Application::getRequest(); + $press = $request->getPress(); + - parent::__construct(); + $api = $this->getSetting( $press->getId(), 'api' ); + $templateMgr->assign( 'api', $api ); + $username = $this->getSetting( $press->getId(), 'username' ); + $templateMgr->assign( 'username', $username ); + $password = $this->getSetting( $press->getId(), 'password' ); + $templateMgr->assign( 'password', $password ); + $testMode = $this->getSetting( $press->getId(), 'testMode' ); + $templateMgr->assign( 'testMode', $testMode ); + $testPrefix = $this->getSetting( $press->getId(), 'testPrefix' ); + $templateMgr->assign( 'testPrefix', $testPrefix ); + $testRegistry = $this->getSetting( $press->getId(), 'testRegistry' ); + $templateMgr->assign( 'testRegistry', $testRegistry ); + $testUrl = $this->getSetting( $press->getId(), 'testUrl' ); + $templateMgr->assign( 'testUrl', $testUrl ); + $daraMode = $this->getSetting( $press->getId(), 'daraMode' ); + $templateMgr->assign( 'daraMode', $daraMode ); + + return array( $press, $api, $username, $password, $testMode, $testPrefix, $testRegistry, $testUrl, $daraMode ); } - function display($args, $request) + private function updateSettings( $request ) : void { + $contextId = $request->getContext() + ->getId(); + $userVars = $request->getUserVars(); + if( count( $userVars ) > 0 ) + { + $this->updateSetting( $contextId, 'api', $userVars['api'] ); + $this->updateSetting( $contextId, 'daraMode', $userVars['daraMode'] ); + $this->updateSetting( $contextId, 'username', $userVars['username'] ); + $this->updateSetting( $contextId, 'password', $userVars['password'] ); + $this->updateSetting( $contextId, 'testMode', $userVars['testMode'] ); + $this->updateSetting( $contextId, 'testPrefix', $userVars['testPrefix'] ); + $this->updateSetting( $contextId, 'testRegistry', $userVars['testRegistry'] ); + $this->updateSetting( $contextId, 'testUrl', $userVars['testUrl'] ); + } + } - $templateMgr = TemplateManager::getManager($request); - parent::display($args, $request); - - $templateMgr->assign('plugin', $this->getName()); - - switch (array_shift($args)) { - case 'settings': - $this->getSettings($templateMgr); - $this->updateSettings($request); - $request->redirect(null, 'management', 'importexport', array('plugin', 'DataciteExportPlugin')); - case '': - $this->getSettings($templateMgr); - $this->depositHandler($request, $templateMgr); - $templateMgr->display($this->getTemplateResource('index.tpl')); - - break; - case 'export': - import('classes.notification.NotificationManager'); - - $responses = $this->exportSubmissions((array)$request->getUserVar('submission')); - $this->createNotifications($request, $responses); - $request->redirect(null, 'management', 'importexport', array('plugin', 'DataciteExportPlugin')); - break; - default: - $dispatcher = $request->getDispatcher(); - $dispatcher->handle404(); + /** + * @param $request + * + * @return array + */ + private function load( $request ) : array + { + $context = $request->getContext(); + $submissionService = ServicesContainer::instance(); + if( NULL !== $submissionService ) + { + $submissionService = $submissionService->get( 'submission' ); } + $submissions = $submissionService->getSubmissions( $context->getId() ); + $itemsQueue = []; + + /** @noinspection PhpUndefinedClassInspection */ + $locale = AppLocale::getLocale(); + $contextPaths = $request->_router->_contextPaths; + $workflowPath = $request->_protocol . '://' + . $request->_serverHost + . $request->_basePath + . '/index.php/' + . $contextPaths[0] + . '/workflow/access/'; + /** @var Submission $submission */ + foreach( $submissions as $submission ) + { + $submissionId = $submission->getId(); + $doi = $submission->getData( 'pub-id::doi' ); + + //Berücksichtige nur Submissions mit doi + if( NULL !== $doi && !empty( $doi ) ) + { + $publisherID = $submission->getData( 'pub-id::publisher-id' ); + $published = '-'; + $currentStatus = $submission->getData( 'datacite-export::status' ); + //Wenn noch kein Status gesetzt ist, wird der Status anhand der publisherID ermittelt und gesetzt + if( NULL === $currentStatus || empty( $currentStatus ) ) + { + $submission = $this->setInitialExportStatus( $submission, $publisherID, TRUE ); + } + $isChapterPublicationDatesEnabled = FALSE; + if( NULL !== $publisherID && !empty( $publisherID ) ) + { + $publishedMonographDAO = new PublishedMonographDAO(); + $publishedMonograph = $publishedMonographDAO->getBySubmissionId( $submissionId, $context ); + if( NULL !== $publishedMonograph ) + { + $published = (string) $publishedMonograph->getData( 'datePublished' ); + //Entfernen der Uhrzeit + $published = explode( ' ', $published ); + $published = $published[0]; + $isChapterPublicationDatesEnabled = + (bool) $publishedMonograph->getEnableChapterPublicationDates(); + } + } + + /** @var ChapterDAO $chapterDao */ + $chapterDao = DAORegistry::getDAO( 'ChapterDAO' ); + $chaptersList = $chapterDao->getChapters( $submissionId ); + $chapters = $chaptersList->toAssociativeArray(); + $chaptersData = array(); + foreach( $chapters as $chapter ) + { + $chapterPubId = $chapter->getData( 'pub-id::publisher-id' ); + $currentChapterStatus = $chapter->getData( 'datacite-export::status' ); + if( NULL === $currentChapterStatus || empty( $currentChapterStatus ) ) + { + $chapter = $this->setInitialExportStatus( $chapter, $chapterPubId, FALSE ); + } + + if( $isChapterPublicationDatesEnabled ) + { + $chapterPubDate = ( $chapter->getDatePublished() ) ?: '-'; + } + else + { + $chapterPubDate = $published; + } + + $chaptersData[] = array( + 'chapterId' => $chapter->getId(), + 'chapterAuthors' => $chapter->getAuthorNamesAsString(), + 'chapterTitle' => $chapter->getLocalizedTitle( $locale ), + 'chapterPubId' => ( $chapterPubId ) ?: '', + 'chapterDoi' => $chapter->getData( 'pub-id::doi' ), + 'chapterPubDate' => $chapterPubDate, + 'chapterStatus' => $chapter->getData( 'datacite-export::status' ), + 'chapterObject' => $chapter, + ); + } + + $itemsQueue[] = array( + 'id' => $submissionId, + 'title' => $submission->getLocalizedTitle( $locale ), + 'authors' => $submission->getAuthorString( $locale ), + 'pubId' => ( $publisherID ) ?: '', + 'chapters' => $chaptersData, + 'doi' => $doi, + 'date' => $published, + 'workflow' => $workflowPath . $submissionId, + 'status' => $submission->getData( 'datacite-export::status' ), + 'submissionObject' => $submission, + ); + } + } + + return $itemsQueue; } - function getName() + /** + * @param string $searchType + * @param string $searchText + * @param string $searchStatus + * @param $request + * + * @return array + */ + private function filterData( string $searchType, string $searchText, string $searchStatus, $request ) : array { + $useStatusFilter = ( $searchStatus !== 'all' ); + $useTextSearch = ( !empty( $searchText ) ); + $itemsQueue = $this->load( $request ); - return 'DataciteExportPlugin'; + if( $useStatusFilter || $useTextSearch ) + { + $filteredByStatus = array(); + $filteredByText = array(); + if( $useStatusFilter ) + { + foreach( $itemsQueue as $item ) + { + if( $item['status'] === $searchStatus ) + { + $filteredByStatus[] = $item; + } + else if( is_array( $item['chapters'] ) ) + { + foreach( $item['chapters'] as $chapter ) + { + if( !empty( $chapter['chapterDoi'] ) && $chapter['chapterStatus'] === $searchStatus ) + { + $filteredByStatus[] = $item; + break; + } + } + } + } + } + else + { + $filteredByStatus = $itemsQueue; + } + + if( $useTextSearch ) + { + $searchTextArray = explode( ' ', mb_strtolower( $searchText ) ); + + if( $searchType === 'authors' ) + { + foreach( $filteredByStatus as $item ) + { + $authors = mb_strtolower( $item['authors'] ); + $found = true; + foreach( $searchTextArray as $text ) + { + if( strpos( $authors, $text ) === FALSE ) + { + $found = FALSE; + break; + } + } + if( $found ) + { + $filteredByText[] = $item; + } + + } + } + else if( $searchType === 'title' ) + { + foreach( $filteredByStatus as $item ) + { + $titles = array(); + /** @var Submission $submission */ + $submission = $item['submissionObject']; + /** @noinspection PhpUndefinedClassInspection */ + $supportedLocales = AppLocale::getAllLocales(); + $found = false; + //Zu erst wird nur des Submissiontitel durchsucht + foreach( $supportedLocales as $locale => $name ) + { + $title = $submission->getFullTitle( $locale ); + if( NULL !== $title && !empty( $title ) ) + { + $titles[] = mb_strtolower( $title ); + } + } + foreach( $titles as $title ) + { + $found = true; + foreach( $searchTextArray as $text ) + { + if( strpos( $title, $text ) === FALSE ) + { + $found = FALSE; + break; + } + } + if( $found ) + { + break; + } + } + + //Lieferte der Submissiontitel keinen Treffer, werden auch die Kapitel durchsucht + if( !$found ) + { + $chapters = $item['chapters']; + $chapterTitles = array(); + foreach( $chapters as $chapter ) + { + /** @var Chapter $chapter */ + $chapter = $chapter['chapterObject']; + foreach( $supportedLocales as $locale => $name ) + { + $chapterTitle = $chapter->getTitle( $locale ); + if( NULL !== $chapterTitle && !empty( $chapterTitle ) ) + { + $chapterTitles[] = mb_strtolower( $chapterTitle ); + } + } + } + + foreach( $chapterTitles as $title ) + { + $found = true; + foreach( $searchTextArray as $text ) + { + if( strpos( $title, $text ) === FALSE ) + { + $found = FALSE; + break; + } + } + if( $found ) + { + break; + } + } + } + + if( $found ) + { + $filteredByText[] = $item; + } + } + } + } + else + { + $filteredByText = $filteredByStatus; + } + + return $filteredByText; + } + return $itemsQueue; } - function getSettings(TemplateManager $templateMgr) + /** + * @param array $itemsQueue + */ + private function buildSearchTable( array $itemsQueue ) : void { - $request = Application::getRequest(); - $press = $request->getPress(); + $html = ''; + foreach( $itemsQueue as $key => $item ) + { + //Submission Zeile + $html .= ''; + } + else + { + $html .= ' datacite-hide-row">'; + } + $html .= '' + . '' + . '' + . '' + . '' + . '' . $item['id'] . '' + . '' + . '' + . '
' + . $item['authors'] . '
' + . '
' + . $item['title'] . '
' + . '' + . '' . $item['date'] . '' + . '' + . '' + . ''; + $html .= ( empty( $item['pubId'] ) ) ? $item['doi'] : $item['pubId']; + $html .= '' + . '' + . '' + . ''; + + if( $item['status'] === 'notDeposited' ) + { + $html .= __('plugins.importexport.datacite.status.todeposit'); + } + else if( $item['status'] === 'registered' ) + { + $html .= __( 'plugins.importexport.datacite.status.registered' ); + } + else if( $item['status'] === 'markedRegistered' ) + { + $html .= __( 'plugins.importexport.datacite.status.markedregistered' ); + } + $html .= ''; + + //Kapitelzeilen + $html .= '' + . '' + . '' + . '' + . '' + . ''; + + foreach( $item['chapters'] as $chapterKey => $chapter ) + { + $html .= '' + . ''; + } + $html .= '' + . '' + . '' + . '' + . ''; + } + $html .= '
' + . '' + . '' + . 'c' . $chapter['chapterId'] . '' + . '
' . $chapter['chapterAuthors'] . '
' + . '
' . $chapter['chapterTitle'] . '
' + . '' + . $chapter['chapterPubDate'] . '' + . '' + . ''; + $html .= (empty($chapter['chapterPubId'])) ? $chapter['chapterDoi'] : $chapter['chapterPubId']; + $html .= '' + . '' + . ''; + if( $chapter['chapterStatus'] === 'notDeposited') + { + $html .= __('plugins.importexport.datacite.status.todeposit'); + } + elseif( $chapter['chapterStatus'] === 'registered' ) + { + $html .= __('plugins.importexport.datacite.status.registered'); + } + elseif( $chapter['chapterStatus'] === 'markedRegistered') + { + $html .= __('plugins.importexport.datacite.status.markedregistered'); + } + $html .= '
'; + } + echo $html; + die(); + } - $api = $this->getSetting($press->getId(), 'api'); - $templateMgr->assign('api', $api); - $username = $this->getSetting($press->getId(), 'username'); - $templateMgr->assign('username', $username); - $password = $this->getSetting($press->getId(), 'password'); - $templateMgr->assign('password', $password); - $testMode = $this->getSetting($press->getId(), 'testMode'); - $templateMgr->assign('testMode', $testMode); - $testPrefix = $this->getSetting($press->getId(), 'testPrefix'); - $templateMgr->assign('testPrefix', $testPrefix); - $testRegistry = $this->getSetting($press->getId(), 'testRegistry'); - $templateMgr->assign('testRegistry', $testRegistry); - $testUrl = $this->getSetting($press->getId(), 'testUrl'); - $templateMgr->assign('testUrl', $testUrl); - $daraMode = $this->getSetting($press->getId(), 'daraMode'); - $templateMgr->assign('daraMode', $daraMode); - - return array($press, $api, $username, $password, $testMode, $testPrefix, $testRegistry, $testUrl, $daraMode); + /** + * Übergibt die Daten dem Template + * + * @param $request + * @param TemplateManager $templateMgr + */ + private function depositHandler( $request, TemplateManager $templateMgr ) : void + { + $itemsQueue = $this->load( $request ); + + //Übergabe ans Template + $templateMgr->assign( 'itemsQueue', $itemsQueue ) + ->assign( 'itemsSizeQueue', count( $itemsQueue ) ) + ->assign( 'currentPage', 1 ) + ->assign( 'startItem', 1 ) + ->assign( 'endItem', self::PAGINATION_DEFAULT_ITEMS_PER_PAGE - 1 ); } - function updateSettings($request) + /** + * @param $object + * @param $publisherId + * @param bool $isSubmission + * + * @return mixed + */ + private function setInitialExportStatus( $object, $publisherId, bool $isSubmission ) { + $status = ( NULL === $publisherId || empty( $publisherId ) ) + ? self::EXPORT_STATUS_NOT_DEPOSITED + : self::EXPORT_STATUS_REGISTERED; - $contextId = $request->getContext()->getId(); - $userVars = $request->getUserVars(); - if (count($userVars) > 0) { - $this->updateSetting($contextId, "api", $userVars["api"]); - $this->updateSetting($contextId, "daraMode", $userVars["daraMode"]); - $this->updateSetting($contextId, "username", $userVars["username"]); - $this->updateSetting($contextId, "password", $userVars["password"]); - $this->updateSetting($contextId, "testMode", $userVars["testMode"]); - $this->updateSetting($contextId, "testPrefix", $userVars["testPrefix"]); - $this->updateSetting($contextId, "testRegistry", $userVars["testRegistry"]); - $this->updateSetting($contextId, "testUrl", $userVars["testUrl"]); + $object->setData( 'datacite-export::status', $status ); + if( $isSubmission ) + { + /** @var MonographDAO $submissionDao */ + $submissionDao = Application::getSubmissionDAO(); + $submissionDao->updateObject( $object ); + } + else + { + /** @var ChapterDAO $chapterDao */ + $chapterDao = DAORegistry::getDAO( 'ChapterDAO' ); + $chapterDao->updateObject( $object ); } + + return $object; } - private function depositHandler($request, TemplateManager $templateMgr) + private function markSubmissionsRegistered( $submissionIds ) : array { - - $context = $request->getContext(); - $press = $request->getPress(); - $submissionService = ServicesContainer::instance()->get('submission'); - $submissions = $submissionService->getSubmissions($context->getId()); - $itemsQueue = []; - $itemsDeposited = []; + /** @var MonographDAO $submissionDao */ + $submissionDao = Application::getSubmissionDAO(); + /** @noinspection PhpUndefinedClassInspection */ $locale = AppLocale::getLocale(); - $registry = $this->getRegistry($press); - foreach ($submissions as $submission) { - $submissionId = $submission->getId(); - $doi = $submission->getData('pub-id::doi'); - $publisherID = $submission->getData('pub-id::publisher-id'); - if ($doi and $publisherID) { - $itemsDeposited[] = array( - 'id' => $submissionId, - 'title' => $submission->getLocalizedTitle($locale), - 'authors' => $submission->getAuthorString($locale), - 'pubId' => $publisherID, - 'registry' => $registry, - ); - } - if ($doi and !$publisherID) { - $itemsQueue[] = array( - 'id' => $submissionId, - 'title' => $submission->getLocalizedTitle($locale), - 'authors' => $submission->getAuthorString($locale), - 'pubId' => $doi, - 'registry' => $registry, + $request = Application::getRequest(); + $context = $request->getContext(); + $response = array(); + + if( NULL !== $context ) + { + foreach( $submissionIds as $submissionId ) + { + $submission = $submissionDao->getById( + $submissionId, + $context->getId() ); + if( NULL !== $submission ) + { + $currentStatus = $submission->getData( 'datacite-export::status' ); + $message = self::RESPONSE_MESSAGE_NOT_POSSIBLE; + if( $currentStatus !== self::EXPORT_STATUS_REGISTERED ) + { + $submission->setData( 'datacite-export::status', self::EXPORT_STATUS_MARKEDREGISTERED ); + $submissionDao->updateObject( $submission ); + $message = self::RESPONSE_MESSAGE_MARKED_REGISTERED; + } + $response[$submissionId] = array( + self::RESPONSE_KEY_STATUS => '', + self::RESPONSE_KEY_MESSAGE => $message, + self::RESPONSE_KEY_TITLE => $submission->getTitle( $locale ), + self::RESPONSE_KEY_ACTION => self::RESPONSE_ACTION_MARKREGISTERED, + self::RESPONSE_KEY_TYPE => self::RESPONSE_OBJECT_TYPE_SUBMISSION, + ); + } } } - $templateMgr->assign('itemsQueue', $itemsQueue); - $templateMgr->assign('itemsSizeQueue', sizeof($itemsQueue)); - $templateMgr->assign('itemsDeposited', $itemsDeposited); - $templateMgr->assign('itemsSizeDeposited', sizeof($itemsDeposited)); + return $response; } - function getRegistry($press) + private function markChaptersRegistered( $chapterIds ) : array { + /** @var ChapterDAO $chapterDao */ + $chapterDao = DAORegistry::getDAO( 'ChapterDAO' ); + /** @noinspection PhpUndefinedClassInspection */ + $locale = AppLocale::getLocale(); + $response = array(); - $registry = DATACITE_API_REGISTRY; - if ($this->isTestMode($press)) { - $registry = $this->getSetting($press->getId(), 'testRegistry'); + foreach( $chapterIds as $submissionChapterId ) + { + $submissionChapterId = explode( '-', $submissionChapterId ); + $submissionId = (int) $submissionChapterId[0]; + $chapterId = (int) $submissionChapterId[1]; + /** @var Chapter $chapter */ + $chapter = $chapterDao->getChapter( $chapterId, $submissionId ); + if( NULL !== $chapter ) + { + $currentStatus = $chapter->getData( 'datacite-export::status' ); + $message = self::RESPONSE_MESSAGE_NOT_POSSIBLE; + if( $currentStatus !== self::EXPORT_STATUS_REGISTERED ) + { + $chapter->setData( 'datacite-export::status', self::EXPORT_STATUS_MARKEDREGISTERED ); + $chapterDao->updateObject( $chapter ); + $message = self::RESPONSE_MESSAGE_MARKED_REGISTERED; + + } + $response[$submissionId . ' .c' . $chapterId] = array( + self::RESPONSE_KEY_STATUS => '', + self::RESPONSE_KEY_MESSAGE => $message, + self::RESPONSE_KEY_TITLE => $chapter->getTitle( $locale ), + self::RESPONSE_KEY_ACTION => self::RESPONSE_ACTION_MARKREGISTERED, + self::RESPONSE_KEY_TYPE => self::RESPONSE_OBJECT_TYPE_CHAPTER, + ); + } } + return $response; + } + /** @noinspection PhpMissingReturnTypeInspection */ + public function getRegistry( $press ) + { + $registry = $this->getSetting( $press->getId(), 'api' ); + if( $this->isTestMode( $press ) ) + { + $registry = $this->getSetting( $press->getId(), 'testRegistry' ); + } return $registry; } - function isTestMode($press) + public function isTestMode( $press ) : bool { - $testMode = $this->getSetting($press->getId(), 'testMode'); + $testMode = $this->getSetting( $press->getId(), 'testMode' ); - return ($testMode == "on"); + return ( $testMode === 'on' ); } - function exportSubmissions($submissionIds) + private function exportSubmissions( $submissionIds ) : array { - - import('lib.pkp.classes.file.FileManager'); + /** @var MonographDAO $submissionDao */ $submissionDao = Application::getSubmissionDAO(); + /** @noinspection PhpUndefinedClassInspection */ + $locale = AppLocale::getLocale(); $request = Application::getRequest(); $press = $request->getPress(); $fileManager = new FileManager(); $result = array(); - foreach ($submissionIds as $submissionId) { - $deployment = new DataciteExportDeployment($request, $this); - $submission = $submissionDao->getById($submissionId, $request->getContext()->getId()); - if ($submission->getData('pub-id::doi')) { - $DOMDocument = new DOMDocument('1.0', 'utf-8'); - $DOMDocument->formatOutput = true; - $DOMDocument = $deployment->createNodes($DOMDocument, $submission, null, true); - $exportFileName = $this->getExportFileName($this->getExportPath(), 'datacite-' . $submissionId, $press, '.xml'); - $exportXml = $DOMDocument->saveXML(); - $fileManager->writeFile($exportFileName, $exportXml); - $response = $this->depositXML($submission, $exportFileName, true); - $result[$submissionId] = ($response != "") ? $response : ""; - $fileManager->deleteByPath($exportFileName); - } - $chapterDao = DAORegistry::getDAO('ChapterDAO'); - $chaptersList = $chapterDao->getChapters($submissionId); - $chapters = $chaptersList->toAssociativeArray(); - foreach ($chapters as $chapter) { - if ($chapter->getData('pub-id::doi')) { - $DOMDocumentChapter = new DOMDocument('1.0', 'utf-8'); - $DOMDocumentChapter->formatOutput = true; - $DOMDocumentChapter = $deployment->createNodes($DOMDocumentChapter, $chapter, $submission, false); - $exportFileName = $this->getExportFileName($this->getExportPath(), 'datacite-' . $submissionId . 'c' . $chapter->getId(), $press, '.xml'); - $exportXml = $DOMDocumentChapter->saveXML(); - $fileManager->writeFile($exportFileName, $exportXml); - $response = $this->depositXML($chapter, $exportFileName, false); - $result[$submissionId . ".c" . $chapter->getId()] = ($response != "") ? implode($chapter->getTitle()) . " : " . $response : ''; - $fileManager->deleteByPath($exportFileName); + $context = $request->getContext(); + + if( NULL !== $context ) + { + foreach( $submissionIds as $submissionId ) + { + $submission = $submissionDao->getById( + $submissionId, + $context->getId() + ); + + if( NULL !== $submission ) + { + $status = $submission->getData( 'datacite-export::status' ); + if( NULL !== $status + && $status !== self::EXPORT_STATUS_MARKEDREGISTERED + && $submission->getData( 'pub-id::doi' ) ) + { + $isRedeposit = ( $status === self::EXPORT_STATUS_REGISTERED ); + $deployment = new DataciteExportDeployment( $request, $this ); + $DOMDocument = new DOMDocument( '1.0', 'utf-8' ); + $DOMDocument->formatOutput = TRUE; + $DOMDocument = $deployment->createNodes( $DOMDocument, $submission, NULL, TRUE ); + $exportFileName = + $this->getExportFileName( + $this->getExportPath(), + 'datacite-' . $submissionId, + $press + ); + $exportXml = $DOMDocument->saveXML(); + $fileManager->writeFile( $exportFileName, $exportXml ); + $response = $this->depositXML( + $submission, + $exportFileName, + TRUE, + $isRedeposit + ); + $response[self::RESPONSE_KEY_TITLE] = $submission->getTitle( $locale ); + $response[self::RESPONSE_KEY_ACTION] = $isRedeposit + ? self::RESPONSE_ACTION_REDEPOSIT + : self::RESPONSE_ACTION_DEPOSIT; + $response[self::RESPONSE_KEY_TYPE] = self::RESPONSE_OBJECT_TYPE_SUBMISSION; + $result[$submissionId] = $response; + + $fileManager->deleteByPath( $exportFileName ); + } } } } + return $result; } - function depositXML($object, $filename, $isSubmission) + private function exportChapters( $chapterIds ) : array { + /** @var MonographDAO $submissionDao */ + $submissionDao = Application::getSubmissionDAO(); + /** @noinspection PhpUndefinedClassInspection */ + $locale = AppLocale::getLocale(); + $request = Application::getRequest(); + $press = $request->getPress(); + $fileManager = new FileManager(); + $result = array(); + /** @var ChapterDAO $chapterDao */ + $chapterDao = DAORegistry::getDAO( 'ChapterDAO' ); + $context = $request->getContext(); + + if( NULL !== $context ) + { + foreach( $chapterIds as $submissionChapterId ) + { + + $submissionChapterId = explode( '-', $submissionChapterId ); + $submissionId = (int) $submissionChapterId[0]; + $chapterId = (int) $submissionChapterId[1]; + /** @var Chapter $chapter */ + $chapter = $chapterDao->getChapter( $chapterId, $submissionId ); + $status = $chapter->getData( 'datacite-export::status' ); + $submission = $submissionDao->getById( + $submissionId, + $context->getId() + ); + + if( NULL !== $status + && NULL !== $submission + && $status !== self::EXPORT_STATUS_MARKEDREGISTERED + && $chapter->getData( 'pub-id::doi' ) ) + { + $isRedeposit = ( $status === self::EXPORT_STATUS_REGISTERED ); + $deployment = new DataciteExportDeployment( $request, $this ); + $DOMDocumentChapter = new DOMDocument( '1.0', 'utf-8' ); + $DOMDocumentChapter->formatOutput = TRUE; + $DOMDocumentChapter = $deployment->createNodes( $DOMDocumentChapter, $chapter, $submission, FALSE ); + $exportFileName = $this->getExportFileName( + $this->getExportPath(), + 'datacite-' . $submissionId . 'c' . $chapter->getId(), + $press + ); + $exportXml = $DOMDocumentChapter->saveXML(); + $fileManager->writeFile( $exportFileName, $exportXml ); + $response = $this->depositXML( + $chapter, + $exportFileName, + FALSE, + $isRedeposit, + $submissionId + ); + $response[self::RESPONSE_KEY_TITLE] = $chapter->getTitle( $locale ); + $response[self::RESPONSE_KEY_ACTION] = $isRedeposit + ? self::RESPONSE_ACTION_REDEPOSIT + : self::RESPONSE_ACTION_DEPOSIT; + $response[self::RESPONSE_KEY_TYPE] = self::RESPONSE_OBJECT_TYPE_CHAPTER; + + $result[$submissionId . ' .c' . $chapter->getId()] = $response; + $fileManager->deleteByPath( $exportFileName ); + } + } + } + return $result; + } - $doi = $object->getData('pub-id::doi'); + /** + * @param $object + * @param $filename + * @param bool $isSubmission + * @param $isRedeposit + * @param int $submissionId + * + * @return mixed + */ + public function depositXML( $object, $filename, bool $isSubmission, $isRedeposit, $submissionId = 0 ) : array + { + $doi = $object->getData( 'pub-id::doi' ); $request = Application::getRequest(); $press = $request->getPress(); - assert(!empty($doi)); - if ($this->isTestMode($press)) { - $doi = $this->createTestDOI($request, $doi); + assert( !empty( $doi ) ); + if( $this->isTestMode( $press ) ) + { + $doi = $this->createTestDOI( $doi ); + } + + if( $isSubmission ) + { + /** @noinspection PhpUndefinedClassInspection */ + $url = Request::url( + $press->getPath(), + 'catalog', + 'book', + array( $object->getId() ) + ); + } + else + { + /** @noinspection PhpUndefinedClassInspection */ + $url = Request::url( + $press->getPath(), + 'catalog', + 'book', + array( $submissionId, 'c' . $object->getId() ) + ); } - $url = Request::url($press->getPath(), 'catalog', 'book', array($object->getId())); - assert(!empty($url)); + assert( !empty( $url ) ); $curlCh = curl_init(); - $username = $this->getSetting($press->getId(), 'username'); - $api = $this->getSetting($press->getId(), 'api'); - $password = $this->getSetting($press->getId(), 'password'); + $username = $this->getSetting( $press->getId(), 'username' ); + $api = $this->getSetting( $press->getId(), 'api' ); + $password = $this->getSetting( $press->getId(), 'password' ); + + if( $httpProxyHost = Config::getVar( 'proxy', 'http_host' ) ) + { + curl_setopt( $curlCh, CURLOPT_PROXY, $httpProxyHost ); + curl_setopt( $curlCh, CURLOPT_PROXYPORT, Config::getVar( 'proxy', 'http_port', '80' ) ); - if ($httpProxyHost = Config::getVar('proxy', 'http_host')) { - curl_setopt($curlCh, CURLOPT_PROXY, $httpProxyHost); - curl_setopt($curlCh, CURLOPT_PROXYPORT, Config::getVar('proxy', 'http_port', '80')); - if ($username = Config::getVar('proxy', 'username')) { - curl_setopt($curlCh, CURLOPT_PROXYUSERPWD, $username . ':' . Config::getVar('proxy', 'password')); + if( $username = Config::getVar( 'proxy', 'username' ) ) + { + curl_setopt( $curlCh, CURLOPT_PROXYUSERPWD, $username . ':' . Config::getVar( 'proxy', 'password' ) ); } } - if ($this->isDara()) { - curl_setopt($curlCh, CURLOPT_HTTPHEADER, array('Accept: application/json')); - curl_setopt($curlCh, CURLOPT_HTTPHEADER, array('Content-Type: application/xml;charset=UTF-8')); - } else { - if (array_key_exists('redeposit', $request->getUserVars())) { - if ($request->getUserVar('redeposit') == 1) { - $api = ($this->isTestMode($press)) ? DATACITE_MDS_TEST__REGISTRY . $doi : DATACITE_MDS_REGISTRY . $doi; - curl_setopt($curlCh, CURLOPT_HTTPHEADER, array('Content-Type: text/plain;charset=UTF-8')); - } - } else { - curl_setopt($curlCh, CURLOPT_HTTPHEADER, array('Content-Type: application/vnd.api+json')); - } + if( $this->isDara() ) + { + curl_setopt( $curlCh, CURLOPT_HTTPHEADER, array( 'Accept: application/json' ) ); + curl_setopt( $curlCh, CURLOPT_HTTPHEADER, array( 'Content-Type: application/xml;charset=UTF-8' ) ); + } + else if( $isRedeposit ) + { + $api = str_replace( array( 'api', '/dois' ), array( 'mds', '/metadata/' ), $api ); + $api .= $doi; + curl_setopt( $curlCh, CURLOPT_HTTPHEADER, array( 'Content-Type: text/plain;charset=UTF-8' ) ); + } + else + { + curl_setopt( $curlCh, CURLOPT_HTTPHEADER, array( 'Content-Type: application/vnd.api+json' ) ); } - curl_setopt($curlCh, CURLOPT_VERBOSE, true); - curl_setopt($curlCh, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curlCh, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - curl_setopt($curlCh, CURLOPT_USERPWD, "$username:$password"); - curl_setopt($curlCh, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($curlCh, CURLOPT_URL, $api); - - assert(is_readable($filename)); - $payload = file_get_contents($filename); - - assert($payload !== false && !empty($payload)); - $fp = fopen ($filename, "r"); - - curl_setopt($curlCh, CURLOPT_VERBOSE, false); - if ($this->isDara()) { - curl_setopt($curlCh, CURLOPT_POSTFIELDS, $payload); - $response = curl_exec($curlCh); - } else { - if (array_key_exists('redeposit', $request->getUserVars())) { - if ($request->getUserVar('redeposit') == 1) { - curl_setopt($curlCh, CURLOPT_PUT, true); - curl_setopt($curlCh, CURLOPT_INFILE, $fp); + curl_setopt( $curlCh, CURLOPT_VERBOSE, TRUE ); + curl_setopt( $curlCh, CURLOPT_RETURNTRANSFER, TRUE ); + curl_setopt( $curlCh, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ); + curl_setopt( $curlCh, CURLOPT_USERPWD, "$username:$password" ); + curl_setopt( $curlCh, CURLOPT_SSL_VERIFYPEER, TRUE ); + curl_setopt( $curlCh, CURLOPT_URL, $api ); - } - } else { - $datacitePayloadObject = $this->createDatacitePayload($object, $url, $payload, true); - curl_setopt($curlCh, CURLOPT_POSTFIELDS, $datacitePayloadObject); - } - $response = curl_exec($curlCh); + assert( is_readable( $filename ) ); + $payload = file_get_contents( $filename ); + + assert( $payload !== FALSE && !empty( $payload ) ); + $fp = fopen( $filename, 'rb' ); + + curl_setopt( $curlCh, CURLOPT_VERBOSE, FALSE ); + if( $isRedeposit ) + { + curl_setopt( $curlCh, CURLOPT_PUT, TRUE ); + curl_setopt( $curlCh, CURLOPT_INFILE, $fp ); + } + else + { + if( !$this->isDara() ) + { + $payload = $this->createDatacitePayload( $object, $url, $payload, TRUE ); + } + curl_setopt( $curlCh, CURLOPT_POSTFIELDS, $payload ); } - $status = curl_getinfo($curlCh, CURLINFO_HTTP_CODE); - curl_close($curlCh); - fclose($fp); + $responseMessage = curl_exec( $curlCh ); + //Um sich die Antwort anzuzeigen + //var_dump( $responseMessage ); + //exit(); + $status = curl_getinfo( $curlCh, CURLINFO_HTTP_CODE ); + curl_close( $curlCh ); + fclose( $fp ); - $this->setDOI($object, $isSubmission, $status, $response, $press, $request, $doi); + if( in_array( $status, self::DATACITE_API_RESPONSE_OK, FALSE ) ) + { + $this->setDOI( $object, $isSubmission, $press, $doi ); + } - return $response; + return array( + self::RESPONSE_KEY_STATUS => $status, + self::RESPONSE_KEY_MESSAGE => $responseMessage + ); } - public function createTestDOI($request, $doi) + public function createTestDOI( $doi ) { - return PKPString::regexp_replace('#^[^/]+/#', $this->getDataciteAPITestPrefix() . '/', $doi); + return PKPString::regexp_replace( '#^[^/]+/#', $this->getDataciteAPITestPrefix() . '/', $doi ); } - function getDataciteAPITestPrefix() + /** @noinspection PhpMissingReturnTypeInspection */ + public function getDataciteAPITestPrefix() { $request = Application::getRequest(); $press = $request->getPress(); - return $this->getSetting($press->getId(), 'testPrefix'); + return $this->getSetting( $press->getId(), 'testPrefix' ); } - function isDara() + public function isDara() : bool { $request = Application::getRequest(); $press = $request->getPress(); - $daraMode = $this->getSetting($press->getId(), 'daraMode'); + $daraMode = $this->getSetting( $press->getId(), 'daraMode' ); - return ($daraMode == "on"); + return ( $daraMode === 'on' ); } - function createDatacitePayload($obj, $url, $payload, $payLoadAvailable = false) + public function createDatacitePayload( + $obj, $url, $payload, $payLoadAvailable = FALSE ) { { - $doi = $obj->getStoredPubId("doi"); + $doi = $obj->getStoredPubId( 'doi' ); $request = Application::getRequest(); $press = $request->getPress(); - if ($this->isTestMode($press)) { - $doi = $this->createTestDOI($request, $doi); + if( $this->isTestMode( $press ) ) + { + $doi = $this->createTestDOI( $doi ); } - if ($payLoadAvailable) { - $jsonPayload = array("data" => (array('id' => $doi, 'type' => "dois", 'attributes' => array("event" => "publish", "doi" => $doi, "url" => $url, "xml" => base64_encode($payload))))); - } else { - $jsonPayload = array("data" => (array('type' => "dois", 'attributes' => array("doi" => $doi)))); + if( $payLoadAvailable ) + { + $jsonPayload = array( + 'data' => array( + 'id' => $doi, + 'type' => 'dois', + 'attributes' => array( + 'event' => 'publish', + 'doi' => $doi, + 'url' => $url, + 'xml' => base64_encode( $payload ) + ) + ) + ); + } + else + { + $jsonPayload = array( + 'data' => array( + 'type' => 'dois', + 'attributes' => array( + 'doi' => $doi + ) + ) + ); } - return json_encode($jsonPayload, JSON_UNESCAPED_SLASHES); - + try + { + return json_encode( $jsonPayload, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES ); + } + catch( JsonException $e ) + { + $notificationManager = new NotificationManager(); + $user = $request->getUser(); + if( NULL !== $user ) + { + $notificationManager->createTrivialNotification( + $user->getId(), + NOTIFICATION_TYPE_ERROR, + array( 'contents' => $e ) + ); + } + return ''; + } } - } - private function setDOI($object, $isSubmission, $status, $response, $press, $request, $doi): void - + /** + * @param $object + * @param bool $isSubmission + * @param $press + * @param $doi + */ + public function setDOI( + $object, bool $isSubmission, $press, $doi ) : void { - $result = true; - if (!in_array($status, DATACITE_API_RESPONSE_OK)) { - $result = array(array('plugins.importexport.common.register.error.mdsError', $response)); + if( $this->isTestMode( $press ) ) + { + $doi = $this->createTestDOI( $doi ); } - - if ($result === true) { - if ($this->isTestMode($press)) { - $doi = $this->createTestDOI($request, $doi); - } - $object->setData('pub-id::publisher-id', $doi); - if ($isSubmission) { - $submissionDao = Application::getSubmissionDAO(); - $submissionDao->updateObject($object); - } else { - $chapterDao = DAORegistry::getDAO('ChapterDAO'); - $chapterDao->updateObject($object); - } + $object->setData( 'pub-id::publisher-id', $doi ); + $object->setData( 'datacite-export::status', self::EXPORT_STATUS_REGISTERED ); + if( $isSubmission ) + { + /** @var MonographDAO $submissionDao */ + $submissionDao = Application::getSubmissionDAO(); + $submissionDao->updateObject( $object ); + } + else + { + /** @var ChapterDAO $chapterDao */ + $chapterDao = DAORegistry::getDAO( 'ChapterDAO' ); + $chapterDao->updateObject( $object ); } } - private function createNotifications($request, array $responses) + public function createNotifications( + $request, array $responses ) : void { - - $success = 1; - $notification = ""; $notificationManager = new NotificationManager(); - foreach ($responses as $submission => $error) { - $result = json_decode(str_replace("\n", "", $error), true); - - if (isset($result["errors"])) { - if ($this->isDara()) { - $detail = $result["errors"]["detail"]; - $notification .= str_replace('"', '', $detail); - } else { - $detail = $result["errors"][0]["title"]; + foreach( $responses as $id => $returnValues ) + { + $status = $returnValues[self::RESPONSE_KEY_STATUS]; + $title = $returnValues[self::RESPONSE_KEY_TITLE]; + $message = $returnValues[self::RESPONSE_KEY_MESSAGE]; + $type = $returnValues[self::RESPONSE_KEY_TYPE]; + $action = $returnValues[self::RESPONSE_KEY_ACTION]; + $success = in_array( $status, self::DATACITE_API_RESPONSE_OK, FALSE ) + || ( empty( $status ) && $message === self::RESPONSE_MESSAGE_MARKED_REGISTERED ); + + try + { + $decoded_message = json_decode( $message, TRUE, 512, JSON_THROW_ON_ERROR ); + $log_message = $decoded_message['errors'][0]['title']; + } + catch( JsonException $e ) + { + $log_message = $message; + } + $message = str_replace( '{http://datacite.org/schema/kernel-4}', ' ', $log_message ); + + if( $success ) + { + switch( $action ) + { + case self::RESPONSE_ACTION_DEPOSIT: + case self::RESPONSE_ACTION_REDEPOSIT: + $actionType = $action . 'ed'; + break; + case self::RESPONSE_ACTION_MARKREGISTERED: + $actionType = 'marked registered'; + break; + default: + $actionType = ''; } - $success = 0; - self::writeLog($submission . " :: " . $detail, 'ERROR'); - $notificationManager->createTrivialNotification($request->getUser()->getId(), NOTIFICATION_TYPE_ERROR, array('contents' => $detail)); + $notificationManager->createTrivialNotification( + $request->getUser() + ->getId(), + NOTIFICATION_TYPE_SUCCESS, + array( + 'contents' => 'Successfully ' . $actionType . '
' . $type . '-id: ' . $id . '
Title: ' . $title + . '
Status: ' . $status . '
Message:
' . $message + ) + ); + } + else + { + self::writeLog( + 'STATUS ' . $status . ' | ' . strtoupper( $type ) . '-ID ' . $id . ' | ' . $message, + strtoupper( $action ) . ' ERROR' + ); + $notificationManager->createTrivialNotification( + $request->getUser() + ->getId(), + NOTIFICATION_TYPE_ERROR, + array( + 'contents' => 'Error
Action: ' . $action . '
' . $type . '-id: ' . $id . '
Title: ' . $title . '
Status: ' + . $status . '
Message:
' . $message + ) + ); } - } - - if ($success == 1) { - $detail = (strpos(implode($responses), 'OK') !== false) ? implode($responses) : "Successfully deposited"; - $notificationManager->createTrivialNotification($request->getUser()->getId(), NOTIFICATION_TYPE_SUCCESS, array('contents' => $detail)); } } - private static function writeLog($message, $level) + public static function writeLog( $message, $level ) : void { - - $fineStamp = date('Y-m-d H:i:s') . substr(microtime(), 1, 4); - error_log("$fineStamp $level $message\n", 3, self::logFilePath()); + $time = new DateTime(); + $time = $time->format( 'd-M-Y H:i:s e' ); + /** @noinspection ForgottenDebugOutputInspection */ + error_log( "[$time] | $level | $message\n", 3, self::logFilePath() ); } - public static function logFilePath() + public static function logFilePath() : string { - return Config::getVar('files', 'files_dir') . '/DATACITE_ERROR.log'; + return Config::getVar( 'files', 'files_dir' ) . '/DATACITE_ERROR.log'; } - function setupGridHandler($hookName, $args) + public function executeCLI( + $scriptName, &$args ) : void { - - import('plugins.generic.customLocale.controllers.grid.DataciteSubmittedListHandler'); - DataciteSubmittedListHandler::setPlugin($this); - - return true; + fatalError( 'Not implemented.' ); } - function executeCLI($scriptName, &$args) + public function getName() : string { - fatalError('Not implemented.'); + return 'DataciteExportPlugin'; } - function getDescription() + public function getDescription() : string { - return __('plugins.importexport.datacite.description'); + return __( 'plugins.importexport.datacite.description' ); } - function getDisplayName() + public function getDisplayName() : string { - return __('plugins.importexport.datacite.displayName'); + return __( 'plugins.importexport.datacite.displayName' ); } - function getPluginSettingsPrefix() + public function getPluginSettingsPrefix() : string { - return 'datacite'; } - function register($category, $path, $mainContextId = null) + public function register( $category, $path, $mainContextId = NULL ) : bool { - HookRegistry::register('PKPLocale::registerLocaleFile', array(&$this, 'addCustomLocale')); - HookRegistry::register('LoadComponentHandler', array($this, 'setupGridHandler')); - HookRegistry::register('Templates::Management::Settings::website', array($this, 'callbackShowWebsiteSettingsTabs')); - HookRegistry::register('LoadHandler', array($this, 'handleLoadRequest')); - $success = parent::register($category, $path, $mainContextId); - if (!Config::getVar('general', 'installed') || defined('RUNNING_UPGRADE')) return $success; - if ($success && $this->getEnabled()) { + HookRegistry::register( 'PKPLocale::registerLocaleFile', array( &$this, 'addCustomLocale' ) ); + HookRegistry::register( 'LoadComponentHandler', array( $this, 'setupGridHandler' ) ); + HookRegistry::register( + 'Templates::Management::Settings::website', array( $this, 'callbackShowWebsiteSettingsTabs' ) + ); + HookRegistry::register( 'LoadHandler', array( $this, 'handleLoadRequest' ) ); + $success = parent::register( $category, $path, $mainContextId ); + + HookRegistry::register( 'chapterdao::getAdditionalFieldNames', array( $this, 'addStatusField' ) ); + HookRegistry::register( 'monographdao::getAdditionalFieldNames', array( $this, 'addStatusField' ) ); + + if( defined( 'RUNNING_UPGRADE' ) || !Config::getVar( 'general', 'installed' ) ) + { + return $success; + } + + if( $success && $this->getEnabled() ) + { $this->addLocaleData(); - $this->import('DataciteExportDeployment'); + $this->import( 'DataciteExportDeployment' ); } + $request = Application::getRequest(); + $templateMgr = TemplateManager::getManager( $request ); + $templateMgr->addStyleSheet( + 'dataciteExportPluginStyles', + $request->getBaseUrl() . '/' . $this->getPluginPath() . '/css/datacite-content.css', + array( + 'priority' => STYLE_SEQUENCE_LAST, + 'contexts' => array( 'backend' ), + 'inline' => FALSE, + ) + ); + $templateMgr->addJavaScript( + 'dataciteExportPluginScript', + $request->getBaseUrl() . '/' . $this->getPluginPath() . '/js/datacite-script.js', + array( + 'priority' => STYLE_SEQUENCE_LAST, + 'contexts' => array('backend'), + 'inline' => FALSE, + ) + ); + return $success; } - function usage($scriptName) + /** Wird in $this->register() indirekt aufgrufen um das Status-Feld in Chapter und Submission zu + * ergänzen, bitte nicht löschen! + * + * @param $hookName + * @param $args + * + * @noinspection PhpUnused + * @noinspection PhpUnusedParameterInspection + * @noinspection UnknownInspectionInspection + */ + public function addStatusField( $hookName, $args ) : void { + $additionalFields =& $args[1]; + $additionalFields[] = 'datacite-export::status'; + } - fatalError('Not implemented.'); + public function usage( $scriptName ) : void + { + fatalError( 'Not implemented.' ); } } diff --git a/controllers/grid/DataciteQueuedListHandler.inc.php b/controllers/grid/DataciteQueuedListHandler.inc.php deleted file mode 100644 index dd20391..0000000 --- a/controllers/grid/DataciteQueuedListHandler.inc.php +++ /dev/null @@ -1,35 +0,0 @@ -getContext(); - $submissionService = ServicesContainer::instance()->get('submission'); - $submissions = $submissionService->getSubmissions($context->getId(), $this->_getItemsParams()); - $items = array(); - if (!empty($submissions)) { - $propertyArgs = array( - 'request' => $request, - ); - foreach ($submissions as $submission) { - $items[] = $submissionService->getBackendListProperties($submission, $propertyArgs); - } - } - - return $items; - } - - public function init($args = array()) - { - - $this->_inputName = isset($args['inputName']) ? $args['inputName'] : $this->_inputName; - } - - -} diff --git a/css/datacite-content.css b/css/datacite-content.css new file mode 100644 index 0000000..8b67b02 --- /dev/null +++ b/css/datacite-content.css @@ -0,0 +1,83 @@ +.datacite-table +{ + table-layout : fixed; +} + +.datacite-ellipsis +{ + display : block; + overflow-x : hidden; + text-overflow : ellipsis; + white-space : nowrap; +} + +.datacite-authors +{ + font-weight : bolder; +} + +.datacite-break-word +{ + word-wrap : break-word; +} + +input[type="checkbox"]:disabled +{ + cursor: not-allowed; +} + +.gridItemsPerPage label +{ + font-size: 14px; + font-weight: 400; +} + +.datacite-show-row +{ + display: table-row; +} + +.datacite-hide +{ + display: none; +} + +.datacite-nav-button +{ + padding: 7px 16px; + vertical-align: middle; + background-color: #eee; + background-image: linear-gradient(#eee, #ddd); + border: 1px solid #ccc; + border-radius: 2px; + box-shadow: 0 1px 2px rgba(0,0,0,0.1),inset 0 1px 1px rgba(255,255,255,0.6); + font-size: 12px; + font-weight: 700; + line-height: 16px; + color: rgba(0,0,0,0.84); + text-shadow: 0 2px 0 rgba(255,255,255,0.6); + cursor: pointer; + text-decoration: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-appearance: none; +} + +#pageId +{ + background-color: #009de5; + background-image: linear-gradient(#19b7ff, #006999); + color: #fff; + box-shadow: 0 1px 2px rgba(0,0,0,0.1),inset 0 1px 1px rgba(255,255,255,0.4); + text-shadow: 0 2px 0 rgba(0,0,0,0.2); + border-color: #007ab2; +} + +body.waiting, +body.waiting a:hover, +body.waiting * +{ + cursor: wait !important; +} diff --git a/js/datacite-script.js b/js/datacite-script.js new file mode 100644 index 0000000..c66f49a --- /dev/null +++ b/js/datacite-script.js @@ -0,0 +1,218 @@ +let paginationButtons, selectItemsPerPage, mainForm, grid, itemsCount; + +function changeDatacitePagination(page = 1, itemsPerPage = 10) { + let firstItem = (page * itemsPerPage) - itemsPerPage; + let lastItem = firstItem + itemsPerPage - 1; + let startPageText = 0; + let endPageText; + let endPage = $('#datacite-page-end'); + + if( itemsCount > 0 ) + { + startPageText = firstItem + 1; + } + + for (let i = 0; i < itemsCount; i++) { + let row = $('#datacitelistgrid-row-' + i) + if (i < firstItem || i > lastItem) { + row.removeClass('datacite-show-row'); + row.addClass('datacite-hide'); + } else { + row.removeClass('datacite-hide'); + row.addClass('datacite-show-row'); + } + } + + startPageText = startPageText.toString(); + $('#datacite-page-start').text(startPageText); + if (lastItem > itemsCount) { + endPage.text( String(itemsCount) ); + } else { + endPageText = (lastItem + 1).toString(); + endPage.text(endPageText); + } +} + +function changeDatacitePaginationButton(currentPage = 1) { + let itemsPerPage = parseInt(selectItemsPerPage.val()); + let totalPages = 1; + let pageMinus2 = $('#pageId-2'); + let pageMinus1 = $('#pageId-1'); + let pagePlus1 = $('#pageIdPlus1'); + let pagePlus2 = $('#pageIdPlus2'); + + if( itemsCount > 0 ) + { + totalPages = Math.ceil(itemsCount / itemsPerPage); + } + + $('#pageId').val(currentPage.toString()); + pageMinus2.val((currentPage - 2).toString()); + pageMinus1.val((currentPage - 1).toString()); + pagePlus1.val((currentPage + 1).toString()); + pagePlus2.val((currentPage + 2).toString()); + paginationButtons.removeClass('datacite-hide'); + + if (currentPage === 1) { + $('#firstPageId').addClass('datacite-hide'); + $('#prevPageId').addClass('datacite-hide'); + pageMinus2.addClass('datacite-hide'); + pageMinus1.addClass('datacite-hide'); + } + + if (currentPage === totalPages) { + $('#lastPageId').addClass('datacite-hide'); + $('#nextPageId').addClass('datacite-hide'); + pagePlus2.addClass('datacite-hide'); + pagePlus1.addClass('datacite-hide'); + } + + if (currentPage === totalPages - 1) { + pagePlus2.addClass('datacite-hide'); + } + + if (currentPage === 2) { + pageMinus2.addClass('datacite-hide'); + } +} + +function bindCollapseButtonClick() { + $('td.first_column > a').click( function () { + let classList = $(this).attr('class').split(/\s+/); + let itemId = ''; + $.each( classList, function (index, item) { + if( item.toLowerCase().indexOf( 'dropdown-' ) >= 0 ) { + itemId = item.replace( 'dropdown-', '' ); + return false; + } + }); + + if( itemId !== '' ) { + let collapseTable = $('#datacitelistgrid-row-' + itemId + '-control-row'); + if ($(this).hasClass( 'show_extras' )) { + $(this).addClass( 'hide_extras' ); + $(this).removeClass( 'show_extras' ) + collapseTable.css('display', 'table-row'); + } + else { + $(this).addClass( 'show_extras' ); + $(this).removeClass( 'hide_extras' ) + collapseTable.css('display', 'none'); + } + } + }); +} + +$(document).ready(function () { + paginationButtons = $('.datacite-nav-button'); + selectItemsPerPage = $('#selItemsPerPage'); + mainForm = $('#queueXmlForm'); + grid = $('#datacitelistgrid'); + itemsCount = $('#datacitelistgrid-table > tbody > tr').length / 2; + + bindCollapseButtonClick(); + grid.pkpHandler( + '$.pkp.controllers.grid.GridHandler', + { + bodySelector: '#datacitelistgrid-table', + }); + + $('body').on('change','.submissionCheckbox',function(){ + let itemId = $(this).val(); + let collapseTable = $('#datacitelistgrid-row-' + itemId + '-control-row') + if (this.checked) { + $('input.select-chapter-' + itemId).each(function () { + $(this).prop('checked', true); + }); + } else { + $('input.select-chapter-' + itemId).each(function () { + $(this).prop('checked', false); + }); + } + if (collapseTable.is(':hidden')) { + $('.dropdown-' + itemId).trigger('click'); + } + }); + + $('#datacite-search-button').click(function () { + $('body').addClass('waiting'); + $.ajax({ + type: 'POST', + dataType: "html", + data: { + 'isAjax':true, + 'sel-search-type':$('#sel-search-type').val(), + 'search-text':$('#search-text').val(), + 'sel-search-status':$('#sel-search-status').val() + }, + success: function (data) { + $('#datacitelistgrid-table > tbody').html(data); + if( data !== '' ) { + itemsCount = $('#datacitelistgrid-table > tbody > tr').length / 2; + } + else + { + itemsCount = 0; + } + $('#datacite-page-count-items').html( itemsCount ); + changeDatacitePaginationButton(); + changeDatacitePagination(); + bindCollapseButtonClick(); + $('body').removeClass('waiting'); + }, + error: function(jqXHR, textStatus, errorThrown) { + $('body').removeClass('waiting'); + alert( 'Error: Status: ' + jqXHR.status + ': ' + errorThrown); + } + }); + }); + paginationButtons.click(function () { + let buttonValue = $(this).val(); + let itemsPerPage = parseInt(selectItemsPerPage.val()); + let currentPage = parseInt($('#pageId').val()); + let totalPages = Math.ceil(itemsCount / itemsPerPage); + + if (buttonValue === '<<') { + buttonValue = 1; + } else if (buttonValue === '<') { + if (currentPage !== 1) { + buttonValue = currentPage - 1; + } else { + buttonValue = 1; + } + + } else if (buttonValue === '>') { + if (currentPage !== totalPages) { + buttonValue = currentPage + 1; + } else { + buttonValue = totalPages; + } + } else if (buttonValue === '>>') { + buttonValue = totalPages + } + + changeDatacitePagination(parseInt(buttonValue), itemsPerPage); + changeDatacitePaginationButton(parseInt(buttonValue)); + }); + selectItemsPerPage.change(function () { + + let itemsPerPage = $('#selItemsPerPage').val(); + changeDatacitePaginationButton(); + + let currentPage = $('#pageId').val(); + changeDatacitePagination(parseInt(currentPage), parseInt(itemsPerPage)); + + }); + + + $('#search-text').keydown(function(event) { + // noinspection JSUnresolvedVariable + if (event.keyCode === 13) { + event.preventDefault(); + $('#datacite-search-button').click(); + } + }); + + changeDatacitePaginationButton(); + changeDatacitePagination(); +}); diff --git a/locale/en_US/locale.xml b/locale/en_US/locale.xml index b30dd57..499134e 100644 --- a/locale/en_US/locale.xml +++ b/locale/en_US/locale.xml @@ -16,7 +16,7 @@ da|ra as DOI provider]]> Test Url Password - + Datacite URL Username (symbol) Please enter the username (symbol) you got from DataCite. The username may not contain colons. @@ -29,4 +29,23 @@ Test URL DataCite automatic registration task + Monographs / Chapters + Deposited + Marked registered + Not Deposited + Any Status + Status + DOI + Published + Author; Title + ID + Select + items + of + Register + Mark registered + Registration was not successful! The DOI registration server returned an error: '{$param}'. + Search + Authors + Title diff --git a/templates/index.tpl b/templates/index.tpl index 6634fcd..6d3d024 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -1,173 +1,380 @@ -{strip} - {assign var="pageTitle" value="plugins.importexport.datacite.displayName"} - {include file="common/header.tpl"} -{/strip} +{assign var="pageTitle" value="plugins.importexport.datacite.displayName"} +{include file="common/header.tpl"} + +{block name="page"} -
- -
- -
- {if $doiPluginSettingsLinkAction} - {fbvFormArea id="doiPluginSettingsLink"} - {fbvFormSection} - {include file="linkAction/linkAction.tpl" action=$doiPluginSettingsLinkAction} - {/fbvFormSection} - {/fbvFormArea} - {/if} - {fbvFormArea id="dataciteSettingsFormArea"} -

{translate key="plugins.importexport.datacite.settings.description"}

-

{translate key="plugins.importexport.datacite.intro"}

+ {rdelim}); + + + {if $doiPluginSettingsLinkAction} + {fbvFormArea id="doiPluginSettingsLink"} + {fbvFormSection} + {include file="linkAction/linkAction.tpl" action=$doiPluginSettingsLinkAction} + {/fbvFormSection} + {/fbvFormArea} + {/if} + {fbvFormArea id="dataciteSettingsFormArea"} +

{translate key="plugins.importexport.datacite.settings.description"}

+

{translate key="plugins.importexport.datacite.intro"}

{fbvFormSection list="true"} {fbvElement type="checkbox" id="daraMode" label="plugins.importexport.datacite.settings.form.dara" checked=$daraMode|compare:true} {/fbvFormSection} {fbvFormSection} - {fbvElement type="text" id="api" value=$api label="plugins.importexport.datacite.settings.form.url" maxlength="100" size=$fbvStyles.size.MEDIUM} - {fbvElement type="text" id="username" value=$username label="plugins.importexport.datacite.settings.form.username" maxlength="50" size=$fbvStyles.size.MEDIUM} - {fbvElement type="text" password="true" id="password" value=$password label="plugins.importexport.datacite.settings.form.password" maxLength="50" size=$fbvStyles.size.MEDIUM} - {translate key="plugins.importexport.datacite.settings.form.password.description"} -
- {/fbvFormSection} -
- {fbvFormSection list="true"} - {fbvElement type="checkbox" id="testMode" label="plugins.importexport.datacite.settings.form.testMode.description" checked=$testMode|compare:true} - {/fbvFormSection} - {fbvElement type="text" id="testRegistry" value=$testRegistry label="plugins.importexport.datacite.settings.form.testRegistry" maxlength="200" size=$fbvStyles.size.MEDIUM} - {fbvElement type="text" id="testPrefix" value=$testPrefix label="plugins.importexport.datacite.settings.form.testPrefix" maxlength="10" size=$fbvStyles.size.MEDIUM} - {fbvElement type="text" id="testUrl" value=$testUrl label="plugins.importexport.datacite.settings.form.testUrl" maxlength="200" size=$fbvStyles.size.MEDIUM} - {/fbvFormArea} - {fbvFormButtons submitText="common.save"} -
-
-
- -
-
- {csrf} -
-
-
-
-
    - {foreach $itemsQueue as $key=>$item} -
  • -
    -
    -
    {$item["id"]}
    - -
    -
  • - {/foreach} -
-
-
- -
-
-
-
-
- -
- - {csrf} -
-
-
-
-
    - {foreach $itemsDeposited as $key=>$item} -
  • -
    -
    -
    - -
    - {$item["authors"]} -
    -
    - {$item["title"]} -
    -
    -
    - -
    -
    -
  • - {/foreach} -
-
-
- -
-
-
-
-
-{include file="common/footer.tpl"} + + + + + {/block} + {include file="common/footer.tpl"} From 47e7b7fd6de3907c493670d5f6a43bed0826ca66 Mon Sep 17 00:00:00 2001 From: marsilius Date: Tue, 5 Jan 2021 16:21:22 +0100 Subject: [PATCH 2/5] =?UTF-8?q?CSRF-Token-Kontrolle=20erg=C3=A4nzt,=20Pagi?= =?UTF-8?q?nation=20Fehler=20behoben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataciteExportPlugin.inc.php | 30 ++++++++++++++++++++++++++++-- js/datacite-script.js | 16 +++++++++++++--- templates/index.tpl | 6 ++---- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/DataciteExportPlugin.inc.php b/DataciteExportPlugin.inc.php index 2e438e8..25f14df 100644 --- a/DataciteExportPlugin.inc.php +++ b/DataciteExportPlugin.inc.php @@ -48,9 +48,34 @@ public function display( $args, $request ) : void parent::display( $args, $request ); $templateMgr = TemplateManager::getManager( $request ); $templateMgr->assign( 'plugin', $this->getName() ); + $params = $request->getUserVars(); + + //CSRF Token Kontrolle + if( ( array_key_exists( 'isAjax', $params ) || !empty( $args[0]) ) + && !$request->checkCSRF() ) + { + $args[0] = ''; + $params['sel-search-type'] = 'title'; + $params['search-text'] = ''; + $params['sel-search-status'] = 'all'; + $user = $request->getUser(); + $userId = 'unknown'; + if( NULL !== $user ) + { + $userId = $user->getId(); + } + $responses = array(); + $responses[$userId] = array( + self::RESPONSE_KEY_STATUS => '403', + self::RESPONSE_KEY_MESSAGE => 'CSRF Token is not valid.', + self::RESPONSE_KEY_TITLE => '', + self::RESPONSE_KEY_ACTION => 'CSRF', + self::RESPONSE_KEY_TYPE => 'user', + ); + $this->createNotifications( $request, $responses ); + } //Ajax - $params = $request->getUserVars(); if( array_key_exists( 'isAjax', $params ) && $params['isAjax'] === 'true' ) { $filteredData = $this->filterData( @@ -575,7 +600,8 @@ private function depositHandler( $request, TemplateManager $templateMgr ) : void ->assign( 'itemsSizeQueue', count( $itemsQueue ) ) ->assign( 'currentPage', 1 ) ->assign( 'startItem', 1 ) - ->assign( 'endItem', self::PAGINATION_DEFAULT_ITEMS_PER_PAGE - 1 ); + ->assign( 'endItem', self::PAGINATION_DEFAULT_ITEMS_PER_PAGE - 1 ) + ->assign( 'csrfToken', $request->getSession()->getCSRFToken() ); } /** diff --git a/js/datacite-script.js b/js/datacite-script.js index c66f49a..7da4526 100644 --- a/js/datacite-script.js +++ b/js/datacite-script.js @@ -1,4 +1,4 @@ -let paginationButtons, selectItemsPerPage, mainForm, grid, itemsCount; +let paginationButtons, selectItemsPerPage, mainForm, grid, itemsCount, csrfToken; function changeDatacitePagination(page = 1, itemsPerPage = 10) { let firstItem = (page * itemsPerPage) - itemsPerPage; @@ -103,6 +103,12 @@ function bindCollapseButtonClick() { }); } +function closeAllChapterTables() { + $('a.hide_extras').each(function () { + $(this).click(); + }); +} + $(document).ready(function () { paginationButtons = $('.datacite-nav-button'); selectItemsPerPage = $('#selItemsPerPage'); @@ -140,6 +146,7 @@ $(document).ready(function () { type: 'POST', dataType: "html", data: { + 'csrfToken':$('input[name ="csrfToken"]').val(), 'isAjax':true, 'sel-search-type':$('#sel-search-type').val(), 'search-text':$('#search-text').val(), @@ -155,6 +162,7 @@ $(document).ready(function () { itemsCount = 0; } $('#datacite-page-count-items').html( itemsCount ); + closeAllChapterTables(); changeDatacitePaginationButton(); changeDatacitePagination(); bindCollapseButtonClick(); @@ -166,6 +174,7 @@ $(document).ready(function () { } }); }); + paginationButtons.click(function () { let buttonValue = $(this).val(); let itemsPerPage = parseInt(selectItemsPerPage.val()); @@ -191,20 +200,21 @@ $(document).ready(function () { buttonValue = totalPages } + closeAllChapterTables(); changeDatacitePagination(parseInt(buttonValue), itemsPerPage); changeDatacitePaginationButton(parseInt(buttonValue)); }); + selectItemsPerPage.change(function () { + closeAllChapterTables(); let itemsPerPage = $('#selItemsPerPage').val(); changeDatacitePaginationButton(); - let currentPage = $('#pageId').val(); changeDatacitePagination(parseInt(currentPage), parseInt(itemsPerPage)); }); - $('#search-text').keydown(function(event) { // noinspection JSUnresolvedVariable if (event.keyCode === 13) { diff --git a/templates/index.tpl b/templates/index.tpl index 6d3d024..003af4e 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -31,6 +31,7 @@
+ {csrf} {if $doiPluginSettingsLinkAction} {fbvFormArea id="doiPluginSettingsLink"} {fbvFormSection} @@ -66,9 +67,7 @@ {rdelim}); - + {csrf}

{translate key='plugins.importexport.datacite.tab.monographs'}

@@ -370,7 +369,6 @@ {/fbvFormSection} -
From 6d088460e1c178418e7de45ee8b5c57a3b119625 Mon Sep 17 00:00:00 2001 From: marsilius Date: Mon, 25 Jan 2021 10:12:24 +0100 Subject: [PATCH 3/5] =?UTF-8?q?Blauer=20Pfeil=20bei=20B=C3=BCchern=20ohne?= =?UTF-8?q?=20Kapitel=20ausgeblendet,=20Aufruf=20der=20getBySubmissionId?= =?UTF-8?q?=20Methode=20der=20PublishedMonographDAO=20ersetzt=20durch=20ge?= =?UTF-8?q?tById,=20f=C3=BCr=20h=C3=B6here=20Kompatibilit=C3=A4t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataciteExportPlugin.inc.php | 9 ++++++--- css/datacite-content.css | 5 +++++ templates/index.tpl | 22 +++++++++++----------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/DataciteExportPlugin.inc.php b/DataciteExportPlugin.inc.php index 25f14df..eba6fbb 100644 --- a/DataciteExportPlugin.inc.php +++ b/DataciteExportPlugin.inc.php @@ -236,7 +236,7 @@ private function load( $request ) : array if( NULL !== $publisherID && !empty( $publisherID ) ) { $publishedMonographDAO = new PublishedMonographDAO(); - $publishedMonograph = $publishedMonographDAO->getBySubmissionId( $submissionId, $context ); + $publishedMonograph = $publishedMonographDAO->getById( $submissionId, $context ); if( NULL !== $publishedMonograph ) { $published = (string) $publishedMonograph->getData( 'datePublished' ); @@ -253,6 +253,7 @@ private function load( $request ) : array $chaptersList = $chapterDao->getChapters( $submissionId ); $chapters = $chaptersList->toAssociativeArray(); $chaptersData = array(); + /** @var Chapter $chapter */ foreach( $chapters as $chapter ) { $chapterPubId = $chapter->getData( 'pub-id::publisher-id' ); @@ -274,7 +275,7 @@ private function load( $request ) : array $chaptersData[] = array( 'chapterId' => $chapter->getId(), 'chapterAuthors' => $chapter->getAuthorNamesAsString(), - 'chapterTitle' => $chapter->getLocalizedTitle( $locale ), + 'chapterTitle' => $chapter->getLocalizedTitle(), 'chapterPubId' => ( $chapterPubId ) ?: '', 'chapterDoi' => $chapter->getData( 'pub-id::doi' ), 'chapterPubDate' => $chapterPubDate, @@ -478,8 +479,10 @@ private function buildSearchTable( array $itemsQueue ) : void { $html .= ' datacite-hide-row">'; } + + $arrowClass = ( count( $item['chapters'] ) < 1 ) ? ' datacite-hidden' : ''; $html .= '' - . '' + . '' . '' . ' - + {/fbvFormSection} - {fbvFormSection} -
    -
  • - {fbvElement type="submit" label="plugins.importexport.datacite.button.register" id="deposit" name="deposit" value="1" class="deposit" translate=true inline=true} -
  • -
  • - {fbvElement type="submit" label="plugins.importexport.datacite.button.markRegistered" id="markRegistered" name="markRegistered" value="1" class="markRegistered" translate=true inline=true} -
  • -
- {/fbvFormSection} + {fbvFormSection} +
    +
  • + {fbvElement type="submit" label="plugins.importexport.datacite.button.register" id="deposit" name="deposit" value="1" class="deposit" translate=true inline=true} +
  • +
  • + {fbvElement type="submit" label="plugins.importexport.datacite.button.markRegistered" id="markRegistered" name="markRegistered" value="1" class="markRegistered" translate=true inline=true} +
  • +
+ {/fbvFormSection}