Skip to content

Commit 7b57119

Browse files
Merge branch 'externalDatasetsRelation330-906' into 'stable-3_3_0'
Adiciona datasets externos à exportação Crossref - 3.3.0 See merge request softwares-pkp/plugins_ojs/dataverse!223
2 parents b186577 + b8ba7e4 commit 7b57119

14 files changed

Lines changed: 188 additions & 99 deletions

classes/CrossrefXmlEditor.inc.php

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<?php
22

33
import('plugins.generic.dataverse.classes.dataverseStudy.DataverseStudyDAO');
4+
import('plugins.generic.dataverse.classes.DataverseDAO');
45
import('plugins.generic.dataverse.dataverseAPI.actions.DatasetActions');
6+
import('plugins.generic.dataverse.classes.services.DataStatementService');
57
import('plugins.generic.dataverse.classes.exception.DataverseException');
68

7-
use Illuminate\Database\Capsule\Manager as Capsule;
8-
99
class CrossrefXmlEditor
1010
{
1111
private const RELATIONS_NAMESPACE = 'http://www.crossref.org/relations.xsd';
12+
private const ID_TYPE_DOI = 'doi';
13+
private const ID_TYPE_URL = 'uri';
1214

1315
private $datasetActions;
1416

@@ -24,17 +26,13 @@ public function addDatasetRelationToDepositXml(DOMDocument $depositXml): DOMDocu
2426
$submissionNodes = $depositXml->getElementsByTagName('posted_content');
2527
}
2628

29+
$dataverseDao = new DataverseDAO();
2730
foreach ($submissionNodes as $submissionNode) {
2831
$doiDataNode = $submissionNode->getElementsByTagName('doi_data')->item(0);
2932
$doiNode = $doiDataNode->getElementsByTagName('doi')->item(0);
3033
$doi = $doiNode->nodeValue;
3134

32-
$submissionId = Capsule::table('publications as p')
33-
->leftJoin('publication_settings as ps', 'p.publication_id', '=', 'ps.publication_id')
34-
->where('ps.setting_name', '=', 'pub-id::doi')
35-
->where('ps.setting_value', '=', $doi)
36-
->value('p.submission_id');
37-
35+
$submissionId = $dataverseDao->getSubmissionIdByDoi($doi);
3836
if (!$submissionId) {
3937
continue;
4038
}
@@ -55,28 +53,39 @@ public function addDatasetRelationToDepositXml(DOMDocument $depositXml): DOMDocu
5553
}
5654

5755
if ($dataset->isPublished()) {
58-
$this->addDatasetRelationToWorkNode($submissionNode, $study->getPersistentId());
56+
$doi = preg_replace('/^doi:/i', '', $study->getPersistentId());
57+
$this->addDatasetRelationToWorkNode($submissionNode, $doi);
58+
}
59+
60+
$dataStatementTypes = $dataverseDao->getSubmissionStatementTypes($submissionId);
61+
if (in_array(DATA_STATEMENT_TYPE_REPO_AVAILABLE, $dataStatementTypes)) {
62+
$externalDatasets = $dataverseDao->getSubmissionExternalDatasets($submissionId);
63+
64+
foreach ($externalDatasets as $externalDatasetUrl) {
65+
$this->addDatasetRelationToWorkNode($submissionNode, $externalDatasetUrl, true);
66+
}
5967
}
6068
}
6169

6270
return $depositXml;
6371
}
6472

65-
public function addDatasetRelationToWorkNode(DOMElement $workNode, string $persistentId): DOMElement
73+
public function addDatasetRelationToWorkNode(DOMElement $workNode, string $identifier, bool $isExternalDataset = false): DOMElement
6674
{
6775
$doc = $workNode->ownerDocument;
6876

6977
$relatedItemNode = $doc->createElementNS(self::RELATIONS_NAMESPACE, 'related_item');
7078

79+
$descriptionText = $isExternalDataset
80+
? 'Dataset deposited in repository'
81+
: 'Dataset deposited in Dataverse repository.';
7182
$descriptionNode = $doc->createElementNS(self::RELATIONS_NAMESPACE, 'description');
72-
$descriptionNode->appendChild($doc->createTextNode('Dataset deposited in Dataverse repository.'));
73-
74-
$doi = preg_replace('/^doi:/i', '', $persistentId);
83+
$descriptionNode->appendChild($doc->createTextNode($descriptionText));
7584

7685
$interWorkRelationNode = $doc->createElementNS(self::RELATIONS_NAMESPACE, 'inter_work_relation');
7786
$interWorkRelationNode->setAttribute('relationship-type', 'isSupplementedBy');
78-
$interWorkRelationNode->setAttribute('identifier-type', 'doi');
79-
$interWorkRelationNode->appendChild($doc->createTextNode($doi));
87+
$interWorkRelationNode->setAttribute('identifier-type', ($isExternalDataset ? self::ID_TYPE_URL : self::ID_TYPE_DOI));
88+
$interWorkRelationNode->appendChild($doc->createTextNode($identifier));
8089

8190
$relatedItemNode->appendChild($descriptionNode);
8291
$relatedItemNode->appendChild($interWorkRelationNode);
@@ -86,6 +95,7 @@ public function addDatasetRelationToWorkNode(DOMElement $workNode, string $persi
8695
$existingProgramNodes->item(0)->appendChild($relatedItemNode);
8796
} else {
8897
$programNode = $doc->createElementNS(self::RELATIONS_NAMESPACE, 'program');
98+
$programNode->setAttribute('name', 'relations');
8999
$programNode->appendChild($relatedItemNode);
90100
$doiDataNode = $workNode->getElementsByTagName('doi_data')->item(0);
91101
$workNode->insertBefore($programNode, $doiDataNode);

classes/DataverseDAO.inc.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
use Illuminate\Database\Capsule\Manager as Capsule;
4+
5+
class DataverseDAO
6+
{
7+
public function getSubmissionIdByDoi(string $doi): ?int
8+
{
9+
return Capsule::table('publications as p')
10+
->leftJoin('publication_settings as ps', 'p.publication_id', '=', 'ps.publication_id')
11+
->where('ps.setting_name', '=', 'pub-id::doi')
12+
->where('ps.setting_value', '=', $doi)
13+
->value('p.submission_id');
14+
}
15+
16+
public function getSubmissionStatementTypes(int $submissionId): ?array
17+
{
18+
$dataStatementTypes = $this->getCurrentPublicationSettingValue($submissionId, 'dataStatementTypes') ?? '[]';
19+
return json_decode($dataStatementTypes, true);
20+
}
21+
22+
public function getSubmissionExternalDatasets(int $submissionId): ?array
23+
{
24+
$dataStatementUrls = $this->getCurrentPublicationSettingValue($submissionId, 'dataStatementUrls') ?? '[]';
25+
return json_decode($dataStatementUrls, true);
26+
}
27+
28+
private function getCurrentPublicationSettingValue(int $submissionId, string $settingName)
29+
{
30+
return Capsule::table('submissions as s')
31+
->leftJoin('publications as p', 's.current_publication_id', '=', 'p.publication_id')
32+
->leftJoin('publication_settings as ps', 'p.publication_id', '=', 'ps.publication_id')
33+
->where('s.submission_id', '=', $submissionId)
34+
->where('ps.setting_name', '=', $settingName)
35+
->value('ps.setting_value');
36+
}
37+
}

cypress/tests/Test03_ResearchDataDeposit.spec.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ describe('Research data deposit', function () {
2020
keywords: ['Modern History'],
2121
}
2222
});
23+
afterEach(function () {
24+
cy.logout();
25+
});
2326

2427
it('Check research data deposit in submission wizard', function () {
2528
cy.login('ckwantes', null, 'publicknowledge');
@@ -154,7 +157,6 @@ describe('Research data deposit', function () {
154157
});
155158

156159
cy.get('input[name="datasetTitle"]').should('have.value', 'Replication data for: ' + submission.title);
157-
cy.logout();
158160
});
159161
it('Check if options are disabled for authors without edit permission', function () {
160162
cy.login('ckwantes', null, 'publicknowledge');
@@ -489,7 +491,6 @@ describe('Research data deposit', function () {
489491
cy.get('.data_citation .value').contains('Kwantes, Catherine, ' + currentYear + ', "Replication data for: ' + submission.title + '"');
490492
cy.get('.data_citation .value a').contains(/https:\/\/doi\.org\/10\.[^\/]*\/FK2\//);
491493
cy.get('.data_citation .value').contains(dataverseServerName + ', V1');
492-
cy.logout();
493494
});
494495

495496
it('Check editor actions were registered in activity log', function () {

tests/CrossrefXmlEditorTest.php

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import('plugins.generic.dataverse.classes.dataverseStudy.DataverseStudyDAO');
77
import('plugins.generic.dataverse.classes.entities.Dataset');
88
import('plugins.generic.dataverse.dataverseAPI.actions.DatasetActions');
9+
import('plugins.generic.dataverse.classes.services.DataStatementService');
910
import('plugins.generic.dataverse.classes.dispatchers.DataStatementDispatcher');
1011
import('plugins.generic.dataverse.DataversePlugin');
1112

@@ -14,23 +15,22 @@
1415
class CrossrefXmlEditorTest extends DatabaseTestCase
1516
{
1617
private $xmlEditor;
17-
private $doc;
1818
private $contextId = 1;
19-
private $submissionId = null;
20-
private $doiId = null;
19+
private $submission;
20+
private $publication;
2121
private $doi = '10.1234/PublicKnowledge.17';
2222
private $study = null;
2323
private $dataset = null;
2424
private $persistentId = 'doi:10.5072/FK2/ABCDEF';
25+
private $externalDatasetUrl = 'https://doi.org/10.1234/zenodo.98765';
2526

2627
public function setUp(): void
2728
{
2829
parent::setUp();
2930
$plugin = new DataversePlugin();
3031
$dispatcher = new DataStatementDispatcher($plugin);
3132

32-
$this->doc = $this->createTestXml();
33-
$this->submissionId = $this->createTestSubmission();
33+
$this->createTestSubmission();
3434
$this->study = $this->createDataverseStudy();
3535
$this->dataset = $this->createTestDataset();
3636
$this->xmlEditor = $this->createXmlEditor();
@@ -41,7 +41,7 @@ protected function getAffectedTables(): array
4141
return ['submissions', 'submission_settings', 'publications', 'publication_settings', 'dataverse_studies'];
4242
}
4343

44-
private function createTestSubmission(): int
44+
private function createTestSubmission()
4545
{
4646
$submissionDao = DAORegistry::getDAO('SubmissionDAO');
4747
$submission = $submissionDao->newDataObject();
@@ -50,24 +50,36 @@ private function createTestSubmission(): int
5050

5151
$publicationDao = DAORegistry::getDAO('PublicationDAO');
5252
$publication = $publicationDao->newDataObject();
53-
$publication->setData('pub-id::doi', $this->doi);
5453
$publication->setData('submissionId', $submissionId);
55-
$pubId = $publicationDao->insertObject($publication);
54+
$publicationId = $publicationDao->insertObject($publication);
55+
56+
$submission->setData('currentPublicationId', $publicationId);
57+
$submissionDao->updateObject($submission);
5658

5759
Capsule::table('publication_settings')->insert([
58-
'publication_id' => $pubId,
60+
'publication_id' => $publicationId,
5961
'locale' => '',
6062
'setting_name' => 'pub-id::doi',
6163
'setting_value' => $this->doi,
6264
]);
6365

64-
return $submissionId;
66+
$this->submission = $submissionDao->getById($submissionId);
67+
$this->publication = $this->submission->getCurrentPublication();
68+
}
69+
70+
private function addExternalDatasetsToPublication()
71+
{
72+
$this->publication->setData('dataStatementTypes', [DATA_STATEMENT_TYPE_REPO_AVAILABLE]);
73+
$this->publication->setData('dataStatementUrls', [$this->externalDatasetUrl]);
74+
75+
$publicationDao = DAORegistry::getDAO('PublicationDAO');
76+
$publicationDao->updateObject($this->publication);
6577
}
6678

6779
private function createDataverseStudy(): DataverseStudy
6880
{
6981
$study = new DataverseStudy();
70-
$study->setSubmissionId($this->submissionId);
82+
$study->setSubmissionId($this->submission->getId());
7183
$study->setEditUri('https://demo.dataverse.org/dvn/api/data-deposit/v1.1/swordv2/edit/study/' . $this->persistentId);
7284
$study->setEditMediaUri('https://demo.dataverse.org/dvn/api/data-deposit/v1.1/swordv2/edit-media/study/' . $this->persistentId);
7385
$study->setStatementUri('https://demo.dataverse.org/dvn/api/data-deposit/v1.1/swordv2/statement/study/' . $this->persistentId);
@@ -81,10 +93,10 @@ private function createDataverseStudy(): DataverseStudy
8193
return $study;
8294
}
8395

84-
private function createTestXml()
96+
private function openTestXml(string $fixture): DomDocument
8597
{
8698
$xml = new DOMDocument('1.0', 'UTF-8');
87-
$xml->appendChild($xml->createElement('work'));
99+
$xml->load(__DIR__ . '/fixtures/crossref/' . $fixture);
88100

89101
return $xml;
90102
}
@@ -108,37 +120,58 @@ private function createXmlEditor(): CrossrefXmlEditor
108120

109121
public function testAddsDatasetRelationToWorkNode(): void
110122
{
111-
$workNode = $this->doc->documentElement;
123+
$worksXml = $this->openTestXml('work_node.xml');
124+
$doi = preg_replace('/^doi:/i', '', $this->persistentId);
112125

113-
$result = $this->xmlEditor->addDatasetRelationToWorkNode($workNode, $this->persistentId);
126+
$noPreviousRelWorkNode = $worksXml->getElementsByTagName('work')->item(0);
127+
$this->xmlEditor->addDatasetRelationToWorkNode($noPreviousRelWorkNode, $doi);
114128

115-
$programNode = $result->getElementsByTagNameNS('http://www.crossref.org/relations.xsd', 'program')->item(0);
116-
$resultXml = $result->ownerDocument->saveXML($programNode);
129+
$withPreviousRelWorkNode = $worksXml->getElementsByTagName('work')->item(1);
130+
$this->xmlEditor->addDatasetRelationToWorkNode($withPreviousRelWorkNode, $doi);
117131

118-
$expectedXml = file_get_contents(__DIR__ . '/fixtures/crossref/expected/dataset_relation.xml');
132+
$resultXml = $worksXml->saveXML();
133+
$expectedXml = file_get_contents(__DIR__ . '/fixtures/crossref/expected/work_node.xml');
134+
135+
$this->assertXmlStringEqualsXmlString($expectedXml, $resultXml);
136+
}
137+
138+
public function testAddsExternalDatasetRelationToWorkNode(): void
139+
{
140+
$worksXml = $this->openTestXml('work_node.xml');
141+
142+
$noPreviousRelWorkNode = $worksXml->getElementsByTagName('work')->item(0);
143+
$this->xmlEditor->addDatasetRelationToWorkNode($noPreviousRelWorkNode, $this->externalDatasetUrl, true);
144+
145+
$withPreviousRelWorkNode = $worksXml->getElementsByTagName('work')->item(1);
146+
$this->xmlEditor->addDatasetRelationToWorkNode($withPreviousRelWorkNode, $this->externalDatasetUrl, true);
147+
148+
$resultXml = $worksXml->saveXML();
149+
$expectedXml = file_get_contents(__DIR__ . '/fixtures/crossref/expected/work_node_external.xml');
119150

120151
$this->assertXmlStringEqualsXmlString($expectedXml, $resultXml);
121152
}
122153

123154
public function testAddsDatasetRelationToDepositXml(): void
124155
{
125-
$this->assertAddingOfRelationToXmlMatchesExpected('preprint_deposit.xml');
126-
$this->assertAddingOfRelationToXmlMatchesExpected('article_deposit.xml');
156+
$this->assertAddingOfRelationToXmlMatchesExpected('preprint_deposit.xml', 'preprint_deposit.xml');
157+
$this->assertAddingOfRelationToXmlMatchesExpected('article_deposit.xml', 'article_deposit.xml');
127158
}
128159

129-
public function testAddsRelationToXmlAlreadyWithRelation(): void
160+
public function testAddsExternalDatasetRelationToDepositXml(): void
130161
{
131-
$this->assertAddingOfRelationToXmlMatchesExpected('preprint_deposit_with_relation.xml');
162+
$this->addExternalDatasetsToPublication();
163+
164+
$this->assertAddingOfRelationToXmlMatchesExpected('preprint_deposit.xml', 'preprint_deposit_external.xml');
132165
}
133166

134-
private function assertAddingOfRelationToXmlMatchesExpected(string $fixture): void
167+
private function assertAddingOfRelationToXmlMatchesExpected(string $fixture, string $expectedFixture): void
135168
{
136169
$depositXml = new DOMDocument();
137170
$depositXml->load(__DIR__ . '/fixtures/crossref/' . $fixture);
138171

139172
$result = $this->xmlEditor->addDatasetRelationToDepositXml($depositXml);
140173

141-
$expectedXml = file_get_contents(__DIR__ . '/fixtures/crossref/expected/' . $fixture);
174+
$expectedXml = file_get_contents(__DIR__ . '/fixtures/crossref/expected/' . $expectedFixture);
142175

143176
$this->assertXmlStringEqualsXmlString($expectedXml, $result->saveXML());
144177
}

tests/fixtures/crossref/expected/article_deposit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<day>18</day>
4747
<year>2023</year>
4848
</publication_date>
49-
<program xmlns="http://www.crossref.org/relations.xsd">
49+
<program xmlns="http://www.crossref.org/relations.xsd" name="relations">
5050
<related_item>
5151
<description>Dataset deposited in Dataverse repository.</description>
5252
<inter_work_relation relationship-type="isSupplementedBy" identifier-type="doi">10.5072/FK2/ABCDEF</inter_work_relation>

tests/fixtures/crossref/expected/dataset_relation.xml

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/fixtures/crossref/expected/preprint_deposit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<jats:abstract xmlns:jats="http://www.ncbi.nlm.nih.gov/JATS1" xml:lang="en">
2929
<jats:p>Lorem ipsum dolor sit amet...</jats:p>
3030
</jats:abstract>
31-
<rel:program>
31+
<rel:program name="relations">
3232
<rel:related_item>
3333
<rel:description>Dataset deposited in Dataverse repository.</rel:description>
3434
<rel:inter_work_relation relationship-type="isSupplementedBy" identifier-type="doi">10.5072/FK2/ABCDEF</rel:inter_work_relation>

tests/fixtures/crossref/expected/preprint_deposit_with_relation.xml renamed to tests/fixtures/crossref/expected/preprint_deposit_external.xml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@
2828
<jats:abstract xmlns:jats="http://www.ncbi.nlm.nih.gov/JATS1" xml:lang="en">
2929
<jats:p>Lorem ipsum dolor sit amet...</jats:p>
3030
</jats:abstract>
31-
<rel:program xmlns:rel="http://www.crossref.org/relations.xsd" name="relations">
32-
<rel:related_item>
33-
<rel:intra_work_relation relationship-type="isPreprintOf" identifier-type="doi">https://doi.org/10.1234/LepidusPeriodico.1756</rel:intra_work_relation>
34-
</rel:related_item>
31+
<rel:program name="relations">
3532
<rel:related_item>
3633
<rel:description>Dataset deposited in Dataverse repository.</rel:description>
3734
<rel:inter_work_relation relationship-type="isSupplementedBy" identifier-type="doi">10.5072/FK2/ABCDEF</rel:inter_work_relation>
3835
</rel:related_item>
36+
<rel:related_item>
37+
<rel:description>Dataset deposited in repository</rel:description>
38+
<rel:inter_work_relation relationship-type="isSupplementedBy" identifier-type="uri">https://doi.org/10.1234/zenodo.98765</rel:inter_work_relation>
39+
</rel:related_item>
3940
</rel:program>
4041
<doi_data>
4142
<doi>10.1234/PublicKnowledge.17</doi>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<works>
3+
<work> <!-- No previous relation -->
4+
<program xmlns="http://www.crossref.org/relations.xsd" name="relations">
5+
<related_item>
6+
<description>Dataset deposited in Dataverse repository.</description>
7+
<inter_work_relation relationship-type="isSupplementedBy" identifier-type="doi">10.5072/FK2/ABCDEF</inter_work_relation>
8+
</related_item>
9+
</program>
10+
</work>
11+
<work> <!-- With previous relation -->
12+
<program xmlns="http://www.crossref.org/relations.xsd" name="relations">
13+
<related_item>
14+
<intra_work_relation relationship-type="isPreprintOf" identifier-type="doi">https://doi.org/10.1234/LepidusPeriodico.1756</intra_work_relation>
15+
</related_item>
16+
<related_item>
17+
<description>Dataset deposited in Dataverse repository.</description>
18+
<inter_work_relation relationship-type="isSupplementedBy" identifier-type="doi">10.5072/FK2/ABCDEF</inter_work_relation>
19+
</related_item>
20+
</program>
21+
</work>
22+
</works>

0 commit comments

Comments
 (0)