Open Preprint Systems  3.3.0
PreprintCrossrefXmlFilter.inc.php
1 <?php
2 
16 import('lib.pkp.plugins.importexport.native.filter.NativeExportFilter');
17 
23  function __construct($filterGroup) {
24  $this->setDisplayName('Crossref XML preprint export');
25  parent::__construct($filterGroup);
26  }
27 
28  //
29  // Implement template methods from PersistableFilter
30  //
34  function getClassName() {
35  return 'plugins.importexport.crossref.filter.PreprintCrossrefXmlFilter';
36  }
37 
38  //
39  // Implement template methods from Filter
40  //
46  function &process(&$pubObjects) {
47  // Create the XML document
48  $doc = new DOMDocument('1.0', 'utf-8');
49  $doc->preserveWhiteSpace = false;
50  $doc->formatOutput = true;
51  $deployment = $this->getDeployment();
52  $context = $deployment->getContext();
53 
54  // Create the root node
55  $rootNode = $this->createRootNode($doc);
56  $doc->appendChild($rootNode);
57 
58  // Create and appet the 'head' node and all parts inside it
59  $rootNode->appendChild($this->createHeadNode($doc));
60 
61  // Create and append the 'body' node, that contains everything
62  $bodyNode = $doc->createElementNS($deployment->getNamespace(), 'body');
63  $rootNode->appendChild($bodyNode);
64 
65  foreach($pubObjects as $pubObject) {
66  $publications = $pubObject->getData('publications');
67  // Use array reverse so that the latest version of the submission is first in the xml output and the DOI relations do not cause an error with Crossref
68  $publications = array_reverse($publications, true);
69  foreach ($publications as $publication) {
70  if ($publication->getStoredPubId('doi')) {
71  $postedContentNode = $this->createPostedContentNode($doc, $publication, $pubObject);
72  $bodyNode->appendChild($postedContentNode);
73  }
74  }
75  }
76  return $doc;
77  }
78 
79  //
80  // Submission conversion functions
81  //
82 
88  function createRootNode($doc) {
89  $deployment = $this->getDeployment();
90  $rootNode = $doc->createElementNS($deployment->getNamespace(), $deployment->getRootElementName());
91  $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', $deployment->getXmlSchemaInstance());
92  $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:jats', $deployment->getJATSNamespace());
93  $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ai', $deployment->getAINamespace());
94  $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:rel', $deployment->getRELNamespace());
95  $rootNode->setAttribute('version', $deployment->getXmlSchemaVersion());
96  $rootNode->setAttribute('xsi:schemaLocation', $deployment->getNamespace() . ' ' . $deployment->getSchemaFilename());
97  return $rootNode;
98  }
99 
105  function createHeadNode($doc) {
106  $deployment = $this->getDeployment();
107  $context = $deployment->getContext();
108  $plugin = $deployment->getPlugin();
109  $headNode = $doc->createElementNS($deployment->getNamespace(), 'head');
110  $headNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'doi_batch_id', htmlspecialchars($context->getData('initials', $context->getPrimaryLocale()) . '_' . time(), ENT_COMPAT, 'UTF-8')));
111  $headNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'timestamp', time()));
112  $depositorNode = $doc->createElementNS($deployment->getNamespace(), 'depositor');
113  $depositorName = $plugin->getSetting($context->getId(), 'depositorName');
114  if (empty($depositorName)) {
115  $depositorName = $context->getData('supportName');
116  }
117  $depositorEmail = $plugin->getSetting($context->getId(), 'depositorEmail');
118  if (empty($depositorEmail)) {
119  $depositorEmail = $context->getData('supportEmail');
120  }
121  $depositorNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'depositor_name', htmlspecialchars($depositorName, ENT_COMPAT, 'UTF-8')));
122  $depositorNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'email_address', htmlspecialchars($depositorEmail, ENT_COMPAT, 'UTF-8')));
123  $headNode->appendChild($depositorNode);
124  $publisherServer = $context->getLocalizedName();
125  $headNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'registrant', htmlspecialchars($publisherServer, ENT_COMPAT, 'UTF-8')));
126  return $headNode;
127  }
128 
134  function createPostedContentNode($doc, $publication, $submission) {
135  assert(is_a($publication, 'Publication'));
136  $deployment = $this->getDeployment();
137  $context = $deployment->getContext();
138  $request = Application::get()->getRequest();
139 
140  $locale = $publication->getData('locale');
141 
142  $postedContentNode = $doc->createElementNS($deployment->getNamespace(), 'posted_content');
143  $postedContentNode->setAttribute('type', 'preprint');
144 
145  // contributors
146  $contributorsNode = $doc->createElementNS($deployment->getNamespace(), 'contributors');
147  $authors = $publication->getData('authors');
148  $isFirst = true;
149  foreach ($authors as $author) {
150  $personNameNode = $doc->createElementNS($deployment->getNamespace(), 'person_name');
151  $personNameNode->setAttribute('contributor_role', 'author');
152  if ($isFirst) {
153  $personNameNode->setAttribute('sequence', 'first');
154  } else {
155  $personNameNode->setAttribute('sequence', 'additional');
156  }
157 
158  $familyNames = $author->getFamilyName(null);
159  $givenNames = $author->getGivenName(null);
160 
161  // Check if both givenName and familyName is set for the submission language.
162  if (isset($familyNames[$locale]) && isset($givenNames[$locale])) {
163  $personNameNode->setAttribute('language', PKPLocale::getIso1FromLocale($locale));
164  $personNameNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'given_name', htmlspecialchars(ucfirst($givenNames[$locale]), ENT_COMPAT, 'UTF-8')));
165  $personNameNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'surname', htmlspecialchars(ucfirst($familyNames[$locale]), ENT_COMPAT, 'UTF-8')));
166 
167  $hasAltName = false;
168  foreach($familyNames as $otherLocal => $familyName) {
169  if ($otherLocal != $locale && isset($familyName) && !empty($familyName)) {
170  if (!$hasAltName) {
171  $altNameNode = $doc->createElementNS($deployment->getNamespace(), 'alt-name');
172  $personNameNode->appendChild($altNameNode);
173 
174  $hasAltName = true;
175  }
176 
177  $nameNode = $doc->createElementNS($deployment->getNamespace(), 'name');
178  $nameNode->setAttribute('language', PKPLocale::getIso1FromLocale($otherLocal));
179 
180  $nameNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'surname', htmlspecialchars(ucfirst($familyName), ENT_COMPAT, 'UTF-8')));
181  if (isset($givenNames[$otherLocal]) && !empty($givenNames[$otherLocal])) {
182  $nameNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'given_name', htmlspecialchars(ucfirst($givenNames[$otherLocal]), ENT_COMPAT, 'UTF-8')));
183  }
184 
185  $altNameNode->appendChild($nameNode);
186  }
187  }
188 
189  } else {
190  $personNameNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'surname', htmlspecialchars(ucfirst($author->getFullName(false)), ENT_COMPAT, 'UTF-8')));
191  }
192 
193  if ($author->getData('orcid')) {
194  $personNameNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'ORCID', $author->getData('orcid')));
195  }
196  $contributorsNode->appendChild($personNameNode);
197  $isFirst = false;
198  }
199  $postedContentNode->appendChild($contributorsNode);
200 
201  // Titles
202  $titlesNode = $doc->createElementNS($deployment->getNamespace(), 'titles');
203  $titlesNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'title', htmlspecialchars($publication->getData('title', $submission->getLocale()), ENT_COMPAT, 'UTF-8')));
204  if ($subtitle = $publication->getData('subtitle', $submission->getLocale())) $titlesNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'subtitle', htmlspecialchars($subtitle, ENT_COMPAT, 'UTF-8')));
205  $postedContentNode->appendChild($titlesNode);
206 
207  // Posted date
208  $postedContentNode->appendChild($this->createPostedDateNode($doc, $publication->getData('datePublished')));
209 
210  // license
211  if ($publication->getData('licenseUrl')) {
212  $licenseNode = $doc->createElementNS($deployment->getAINamespace(), 'ai:program');
213  $licenseNode->setAttribute('name', 'AccessIndicators');
214  $licenseNode->appendChild($node = $doc->createElementNS($deployment->getAINamespace(), 'ai:license_ref', htmlspecialchars($publication->getData('licenseUrl'), ENT_COMPAT, 'UTF-8')));
215  $postedContentNode->appendChild($licenseNode);
216  }
217 
218  // DOI relations
219  if ($submission->getLatestPublication()->getStoredPubId('doi') && $submission->getLatestPublication()->getStoredPubId('doi') != $publication->getStoredPubId('doi')){
220  $postedContentNode->appendChild($this->createRelationsDataNode($doc, $submission->getLatestPublication()->getStoredPubId('doi')));
221  }
222 
223  // DOI data
224  $postedContentNode->appendChild($this->createDOIDataNode($doc, $publication->getStoredPubId('doi'), $request->getDispatcher()->url($request, ROUTE_PAGE, null, 'preprint', 'view', [$submission->getBestId(), 'version', $publication->getId()], null, null, true)));
225 
226  return $postedContentNode;
227  }
228 
235  function createPostedDateNode($doc, $objectPostedDate) {
236  $deployment = $this->getDeployment();
237  $postedDate = strtotime($objectPostedDate);
238  $postedDateNode = $doc->createElementNS($deployment->getNamespace(), 'posted_date');
239  if (date('m', $postedDate)) {
240  $postedDateNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'month', date('m', $postedDate)));
241  }
242  if (date('d', $postedDate)) {
243  $postedDateNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'day', date('d', $postedDate)));
244  }
245  $postedDateNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'year', date('Y', $postedDate)));
246  return $postedDateNode;
247  }
248 
256  function createDOIDataNode($doc, $doi, $url) {
257  $deployment = $this->getDeployment();
258  $doiDataNode = $doc->createElementNS($deployment->getNamespace(), 'doi_data');
259  $doiDataNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'doi', htmlspecialchars($doi, ENT_COMPAT, 'UTF-8')));
260  $doiDataNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'resource', htmlspecialchars($url, ENT_COMPAT, 'UTF-8')));
261  return $doiDataNode;
262  }
263 
270  function createRelationsDataNode($doc, $parentDoi) {
271  $deployment = $this->getDeployment();
272  $relationsDataNode = $doc->createElementNS($deployment->getRELNamespace(), 'rel:program');
273  $relationsDataNode->setAttribute('name', 'relations');
274 
275  $relatedItemNode = $doc->createElementNS($deployment->getRELNamespace(), 'rel:related_item');
276  $intraWorkRelationNode = $doc->createElementNS($deployment->getRELNamespace(), 'rel:intra_work_relation', htmlspecialchars($parentDoi, ENT_COMPAT, 'UTF-8'));
277  $intraWorkRelationNode->setAttribute('relationship-type', 'isVersionOf');
278  $intraWorkRelationNode->setAttribute('identifier-type', 'doi');
279  $relatedItemNode->appendChild($intraWorkRelationNode);
280  $relationsDataNode->appendChild($relatedItemNode);
281 
282  return $relationsDataNode;
283  }
284 }
285 
286 
PreprintCrossrefXmlFilter
Class that converts a Preprint to a Crossref XML document.
Definition: PreprintCrossrefXmlFilter.inc.php:18
PreprintCrossrefXmlFilter\createRelationsDataNode
createRelationsDataNode($doc, $parentDoi)
Definition: PreprintCrossrefXmlFilter.inc.php:270
NativeImportExportFilter\getDeployment
getDeployment()
Definition: NativeImportExportFilter.inc.php:49
PreprintCrossrefXmlFilter\createPostedContentNode
createPostedContentNode($doc, $publication, $submission)
Definition: PreprintCrossrefXmlFilter.inc.php:134
NativeExportFilter
Base class that converts a DataObject to a Native XML document.
Definition: NativeExportFilter.inc.php:18
PKPLocale\getIso1FromLocale
static getIso1FromLocale($locale)
Definition: PKPLocale.inc.php:762
PreprintCrossrefXmlFilter\getClassName
getClassName()
Definition: PreprintCrossrefXmlFilter.inc.php:34
PreprintCrossrefXmlFilter\__construct
__construct($filterGroup)
Definition: PreprintCrossrefXmlFilter.inc.php:23
PreprintCrossrefXmlFilter\process
& process(&$pubObjects)
Definition: PreprintCrossrefXmlFilter.inc.php:46
PreprintCrossrefXmlFilter\createDOIDataNode
createDOIDataNode($doc, $doi, $url)
Definition: PreprintCrossrefXmlFilter.inc.php:256
PreprintCrossrefXmlFilter\createRootNode
createRootNode($doc)
Definition: PreprintCrossrefXmlFilter.inc.php:88
PreprintCrossrefXmlFilter\createHeadNode
createHeadNode($doc)
Definition: PreprintCrossrefXmlFilter.inc.php:105
PKPApplication\get
static get()
Definition: PKPApplication.inc.php:235
Filter\setDisplayName
setDisplayName($displayName)
Definition: Filter.inc.php:140
PreprintCrossrefXmlFilter\createPostedDateNode
createPostedDateNode($doc, $objectPostedDate)
Definition: PreprintCrossrefXmlFilter.inc.php:235