Open Journal Systems  3.3.0
NativeXmlIssueFilter.inc.php
1 <?php
2 
16 import('lib.pkp.plugins.importexport.native.filter.NativeImportFilter');
17 
23  function __construct($filterGroup) {
24  $this->setDisplayName('Native XML issue import');
25  parent::__construct($filterGroup);
26  }
27 
28 
29  //
30  // Implement template methods from PersistableFilter
31  //
35  function getClassName() {
36  return 'plugins.importexport.native.filter.NativeXmlIssueFilter';
37  }
38 
39 
40  //
41  // Implement template methods from NativeImportFilter
42  //
47  function getPluralElementName() {
48  return 'issues';
49  }
50 
56  return 'issue';
57  }
58 
64  function handleElement($node) {
65  $deployment = $this->getDeployment();
66  $context = $deployment->getContext();
67 
68  $issueDao = DAORegistry::getDAO('IssueDAO'); /* @var $issueDao IssueDAO */
69  // if the issue identification matches an existing issue, flag to process only child objects
70  $issueExists = false;
71  $issue = $this->_issueExists($node);
72  if ($issue) {
73  $issueExists = true;
74  } else {
75  // Create and insert the issue (ID needed for other entities)
76  $issue = $issueDao->newDataObject();
77  $issue->setJournalId($context->getId());
78  $issue->setPublished($node->getAttribute('published'));
79  $issue->setCurrent($node->getAttribute('current'));
80  $issue->setAccessStatus($node->getAttribute('access_status'));
81  $issue->setData('urlPath', $node->getAttribute('url_path'));
82  if ($issue) $issueDao->updateCurrent($context->getId());
83  $issueDao->insertObject($issue);
84  $deployment->addProcessedObjectId(ASSOC_TYPE_ISSUE, $issue->getId());
85  }
86  $deployment->setIssue($issue);
87 
88  for ($n = $node->firstChild; $n !== null; $n=$n->nextSibling) {
89  if (is_a($n, 'DOMElement')) {
90  $this->handleChildElement($n, $issue, $issueExists);
91  }
92  }
93  if (!$issueExists) {
94  $issueDao->updateObject($issue); // Persist setters
95  }
96  return $issue;
97  }
98 
105  function handleChildElement($n, $issue, $processOnlyChildren) {
106  $deployment = $this->getDeployment();
107  $context = $deployment->getContext();
108 
109  $localizedSetterMappings = $this->_getLocalizedIssueSetterMappings();
110  $dateSetterMappings = $this->_getDateIssueSetterMappings();
111 
112  if (isset($localizedSetterMappings[$n->tagName])) {
113  if (!$processOnlyChildren) {
114  // If applicable, call a setter for localized content.
115  $setterFunction = $localizedSetterMappings[$n->tagName];
116  list($locale, $value) = $this->parseLocalizedContent($n);
117  if (empty($locale)) $locale = $context->getPrimaryLocale();
118  $issue->$setterFunction($value, $locale);
119  }
120  } else if (isset($dateSetterMappings[$n->tagName])) {
121  if (!$processOnlyChildren) {
122  // Not a localized element? Check for a date.
123  $setterFunction = $dateSetterMappings[$n->tagName];
124  $issue->$setterFunction(strtotime($n->textContent));
125  }
126  } else switch ($n->tagName) {
127  // Otherwise, delegate to specific parsing code
128  case 'id':
129  if (!$processOnlyChildren) {
130  $this->parseIdentifier($n, $issue);
131  }
132  break;
133  case 'articles':
134  $this->parseArticles($n, $issue);
135  break;
136  case 'issue_galleys':
137  if (!$processOnlyChildren) {
138  $this->parseIssueGalleys($n, $issue);
139  }
140  break;
141  case 'sections':
142  $this->parseSections($n, $issue);
143  break;
144  case 'covers':
145  if (!$processOnlyChildren) {
146  import('plugins.importexport.native.filter.NativeFilterHelper');
147  $nativeFilterHelper = new NativeFilterHelper();
148  $nativeFilterHelper->parseIssueCovers($this, $n, $issue, ASSOC_TYPE_ISSUE);
149  }
150  break;
151  case 'issue_identification':
152  if (!$processOnlyChildren) {
153  $this->parseIssueIdentification($n, $issue);
154  }
155  break;
156  default:
157  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.common.error.unknownElement', array('param' => $n->tagName)));
158  }
159  }
160 
161  //
162  // Element parsing
163  //
169  function parseIdentifier($element, $issue) {
170  $deployment = $this->getDeployment();
171  $advice = $element->getAttribute('advice');
172  switch ($element->getAttribute('type')) {
173  case 'internal':
174  // "update" advice not supported yet.
175  assert(!$advice || $advice == 'ignore');
176  break;
177  case 'public':
178  if ($advice == 'update') {
179  $issue->setStoredPubId('publisher-id', $element->textContent);
180  }
181  break;
182  default:
183  if ($advice == 'update') {
184  // Load pub id plugins
185  $pubIdPlugins = PluginRegistry::loadCategory('pubIds', true, $deployment->getContext()->getId());
186  $issue->setStoredPubId($element->getAttribute('type'), $element->textContent);
187  }
188  }
189  }
190 
196  function parseIssueGalleys($node, $issue) {
197  $deployment = $this->getDeployment();
198  for ($n = $node->firstChild; $n !== null; $n=$n->nextSibling) {
199  if (is_a($n, 'DOMElement')) {
200  switch ($n->tagName) {
201  case 'issue_galley':
202  $this->parseIssueGalley($n, $issue);
203  break;
204  default:
205  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.common.error.unknownElement', array('param' => $n->tagName)));
206  }
207  }
208  }
209  }
210 
216  function parseIssueGalley($n, $issue) {
217  $filterDao = DAORegistry::getDAO('FilterDAO'); /* @var $filterDao FilterDAO */
218  $importFilters = $filterDao->getObjectsByGroup('native-xml=>IssueGalley');
219  assert(count($importFilters)==1); // Assert only a single unserialization filter
220  $importFilter = array_shift($importFilters);
221  $importFilter->setDeployment($this->getDeployment());
222  $issueGalleyDoc = new DOMDocument();
223  $issueGalleyDoc->appendChild($issueGalleyDoc->importNode($n, true));
224  return $importFilter->execute($issueGalleyDoc);
225  }
226 
232  function parseArticles($node, $issue) {
233  $deployment = $this->getDeployment();
234  for ($n = $node->firstChild; $n !== null; $n=$n->nextSibling) {
235  if (is_a($n, 'DOMElement')) {
236  switch ($n->tagName) {
237  case 'article':
238  $this->parseArticle($n, $issue);
239  break;
240  default:
241  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.common.error.unknownElement', array('param' => $n->tagName)));
242  }
243  }
244  }
245  }
246 
252  function parseArticle($n, $issue) {
253  $filterDao = DAORegistry::getDAO('FilterDAO'); /* @var $filterDao FilterDAO */
254  $importFilters = $filterDao->getObjectsByGroup('native-xml=>article');
255  assert(count($importFilters)==1); // Assert only a single unserialization filter
256  $importFilter = array_shift($importFilters);
257  $importFilter->setDeployment($this->getDeployment());
258  $articleDoc = new DOMDocument();
259  $articleDoc->appendChild($articleDoc->importNode($n, true));
260  return $importFilter->execute($articleDoc);
261  }
262 
268  function parseSections($node, $issue) {
269  $deployment = $this->getDeployment();
270  for ($n = $node->firstChild; $n !== null; $n=$n->nextSibling) {
271  if (is_a($n, 'DOMElement')) {
272  switch ($n->tagName) {
273  case 'section':
274  $this->parseSection($n);
275  break;
276  default:
277  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.common.error.unknownElement', array('param' => $n->tagName)));
278  }
279  }
280  }
281  }
282 
287  function parseSection($node) {
288  $deployment = $this->getDeployment();
289  $context = $deployment->getContext();
290 
291  // Create the data object
292  $sectionDao = DAORegistry::getDAO('SectionDAO'); /* @var $sectionDao SectionDAO */
293  $section = $sectionDao->newDataObject();
294  $section->setContextId($context->getId());
295  $section->setReviewFormId($node->getAttribute('review_form_id'));
296  $section->setSequence($node->getAttribute('seq'));
297  $section->setEditorRestricted($node->getAttribute('editor_restricted'));
298  $section->setMetaIndexed($node->getAttribute('meta_indexed'));
299  $section->setMetaReviewed($node->getAttribute('meta_reviewed'));
300  $section->setAbstractsNotRequired($node->getAttribute('abstracts_not_required'));
301  $section->setHideAuthor($node->getAttribute('hide_author'));
302  $section->setHideTitle($node->getAttribute('hide_title'));
303  $section->setAbstractWordCount($node->getAttribute('abstract_word_count'));
304 
305  $unknownNodes = array();
306  for ($n = $node->firstChild; $n !== null; $n=$n->nextSibling) {
307  if (is_a($n, 'DOMElement')) {
308  switch ($n->tagName) {
309  case 'id':
310  // Only support "ignore" advice for now
311  $advice = $n->getAttribute('advice');
312  assert(!$advice || $advice == 'ignore');
313  break;
314  case 'abbrev':
315  list($locale, $value) = $this->parseLocalizedContent($n);
316  if (empty($locale)) $locale = $context->getPrimaryLocale();
317  $section->setAbbrev($value, $locale);
318  break;
319  case 'policy':
320  list($locale, $value) = $this->parseLocalizedContent($n);
321  if (empty($locale)) $locale = $context->getPrimaryLocale();
322  $section->setPolicy($value, $locale);
323  break;
324  case 'title':
325  list($locale, $value) = $this->parseLocalizedContent($n);
326  if (empty($locale)) $locale = $context->getPrimaryLocale();
327  $section->setTitle($value, $locale);
328  break;
329  default:
330  $unknownNodes[] = $n->tagName;
331  }
332  }
333  }
334 
335  if (!$this->_sectionExist($section)) {
336  $sectionId = $sectionDao->insertObject($section);
337  if (count($unknownNodes)) {
338  foreach ($unknownNodes as $tagName) {
339  $deployment->addWarning(ASSOC_TYPE_SECTION, $sectionId, __('plugins.importexport.common.error.unknownElement', array('param' => $tagName)));
340  }
341  }
342  $deployment->addProcessedObjectId(ASSOC_TYPE_SECTION, $sectionId);
343  }
344  }
345 
352  function parseIssueIdentification($node, $issue, $allowWarnings = true) {
353  $deployment = $this->getDeployment();
354  $context = $deployment->getContext();
355  for ($n = $node->firstChild; $n !== null; $n=$n->nextSibling) {
356  if (is_a($n, 'DOMElement')) {
357  switch ($n->tagName) {
358  case 'volume':
359  $issue->setVolume($n->textContent);
360  $issue->setShowVolume(1);
361  break;
362  case 'number':
363  $issue->setNumber($n->textContent);
364  $issue->setShowNumber(1);
365  break;
366  case 'year':
367  $issue->setYear($n->textContent);
368  $issue->setShowYear(1);
369  break;
370  case 'title':
371  list($locale, $value) = $this->parseLocalizedContent($n);
372  if (empty($locale)) $locale = $context->getPrimaryLocale();
373  $issue->setTitle($value, $locale);
374  $issue->setShowTitle(1);
375  break;
376  default:
377  if ($allowWarnings) {
378  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.common.error.unknownElement', array('param' => $n->tagName)));
379  }
380  }
381  }
382  }
383  }
384 
385  //
386  // Helper functions
387  //
393  return array(
394  'description' => 'setDescription',
395  );
396  }
397 
403  return array(
404  'date_published' => 'setDatePublished',
405  'date_notified' => 'setDateNotified',
406  'last_modified' => 'setLastModified',
407  'open_access_date' => 'setOpenAccessDate',
408  );
409  }
410 
416  function _issueExists($node) {
417  $deployment = $this->getDeployment();
418  $context = $deployment->getContext();
419  $issue = null;
420  $issueDao = DAORegistry::getDAO('IssueDAO'); /* @var $issueDao IssueDAO */
421  foreach ($node->getElementsByTagName('issue_identification') as $n) {
422  $searchIssue = $issueDao->newDataObject();
423  $this->parseIssueIdentification($n, $searchIssue, false);
424  $foundIssues = $issueDao->getIssuesByIdentification($context->getId(), $searchIssue->getVolume(), $searchIssue->getNumber(), $searchIssue->getYear(), (array) $searchIssue->getTitle(null));
425  foreach ($foundIssues->toArray() as $issue) {
426  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.native.import.error.issueIdentificationDuplicate', array('issueId' => $issue->getId(), 'issueIdentification' => $n->ownerDocument->saveXML($n))));
427  }
428  }
429  return $issue;
430  }
431 
437  function _sectionExist($importSection) {
438  $deployment = $this->getDeployment();
439  $issue = $deployment->getIssue();
440  // title and, optionally, abbrev contain information that can
441  // be used to locate an existing section. If title and abbrev each match an
442  // existing section, but not the same section, throw an error.
443  $sectionDao = DAORegistry::getDAO('SectionDAO');
444  $contextId = $importSection->getContextId();
445  $section = null;
446  $foundSectionId = $foundSectionTitle = null;
447  $index = 0;
448  $titles = $importSection->getTitle(null);
449  foreach($titles as $locale => $title) {
450  $section = $sectionDao->getByTitle($title, $contextId);
451  if ($section) {
452  $sectionId = $section->getId();
453  if ($foundSectionId) {
454  if ($foundSectionId != $sectionId) {
455  // Mismatching sections found.
456  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.native.import.error.sectionTitleMismatch', array('section1Title' => $title, 'section2Title' => $foundSectionTitle, 'issueTitle' => $issue->getIssueIdentification())));
457  }
458  } else if ($index > 0) {
459  // the current title matches, but the prev titles didn't
460  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.native.import.error.sectionTitleMatch', array('sectionTitle' => $title, 'issueTitle' => $issue->getIssueIdentification())));
461  }
462  $foundSectionId = $sectionId;
463  $foundSectionTitle = $title;
464  } else {
465  if ($foundSectionId) {
466  // a prev title matched, but the current doesn't
467  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.native.import.error.sectionTitleMatch', array('sectionTitle' => $foundSectionTitle, 'issueTitle' => $issue->getIssueIdentification())));
468  }
469  }
470  $index++;
471  }
472  // check abbrevs:
473  $abbrevSection = null;
474  $foundSectionId = $foundSectionAbbrev = null;
475  $index = 0;
476  $abbrevs = $importSection->getAbbrev(null);
477  foreach($abbrevs as $locale => $abbrev) {
478  $abbrevSection = $sectionDao->getByAbbrev($abbrev, $contextId);
479  if ($abbrevSection) {
480  $sectionId = $abbrevSection->getId();
481  if ($foundSectionId) {
482  if ($foundSectionId != $sectionId) {
483  // Mismatching sections found.
484  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.native.import.error.sectionAbbrevMismatch', array('section1Abbrev' => $abbrev, 'section2Abbrev' => $foundSectionAbbrev, 'issueTitle' => $issue->getIssueIdentification())));
485  }
486  } else if ($index > 0) {
487  // the current abbrev matches, but the prev abbrevs didn't
488  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.native.import.error.sectionAbbrevMatch', array('sectionAbbrev' => $abbrev, 'issueTitle' => $issue->getIssueIdentification())));
489  }
490  $foundSectionId = $sectionId;
491  $foundSectionAbbrev = $abbrev;
492  } else {
493  if ($foundSectionId) {
494  // a prev abbrev matched, but the current doesn't
495  $deployment->addWarning(ASSOC_TYPE_ISSUE, $issue->getId(), __('plugins.importexport.native.import.error.sectionAbbrevMatch', array('sectionAbbrev' => $foundSectionAbbrev, 'issueTitle' => $issue->getIssueIdentification())));
496  }
497  }
498  $index++;
499  }
500  if (isset($section) && isset($abbrevSection)) {
501  return $section->getId() == $abbrevSection->getId();
502  } else {
503  return isset($section) || isset($abbrevSection);
504  }
505  }
506 
507 }
NativeXmlIssueFilter\parseIssueGalleys
parseIssueGalleys($node, $issue)
Definition: NativeXmlIssueFilter.inc.php:196
NativeXmlIssueFilter\getClassName
getClassName()
Definition: NativeXmlIssueFilter.inc.php:35
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
NativeXmlIssueFilter\_getLocalizedIssueSetterMappings
_getLocalizedIssueSetterMappings()
Definition: NativeXmlIssueFilter.inc.php:392
NativeXmlIssueFilter\parseArticles
parseArticles($node, $issue)
Definition: NativeXmlIssueFilter.inc.php:232
NativeXmlIssueFilter\__construct
__construct($filterGroup)
Definition: NativeXmlIssueFilter.inc.php:23
NativeXmlIssueFilter\parseIdentifier
parseIdentifier($element, $issue)
Definition: NativeXmlIssueFilter.inc.php:169
NativeXmlIssueFilter\getPluralElementName
getPluralElementName()
Definition: NativeXmlIssueFilter.inc.php:47
NativeImportExportFilter\getDeployment
getDeployment()
Definition: NativeImportExportFilter.inc.php:49
NativeXmlIssueFilter\_sectionExist
_sectionExist($importSection)
Definition: NativeXmlIssueFilter.inc.php:437
NativeXmlIssueFilter\parseIssueIdentification
parseIssueIdentification($node, $issue, $allowWarnings=true)
Definition: NativeXmlIssueFilter.inc.php:352
NativeImportFilter\parseLocalizedContent
parseLocalizedContent($element)
Definition: NativeImportFilter.inc.php:98
PluginRegistry\loadCategory
static loadCategory($category, $enabledOnly=false, $mainContextId=null)
Definition: PluginRegistry.inc.php:103
NativeXmlIssueFilter\handleElement
handleElement($node)
Definition: NativeXmlIssueFilter.inc.php:64
NativeImportFilter
Base class that converts a Native XML document to a DataObject.
Definition: NativeImportFilter.inc.php:18
NativeXmlIssueFilter\_getDateIssueSetterMappings
_getDateIssueSetterMappings()
Definition: NativeXmlIssueFilter.inc.php:402
NativeXmlIssueFilter\parseArticle
parseArticle($n, $issue)
Definition: NativeXmlIssueFilter.inc.php:252
NativeXmlIssueFilter\handleChildElement
handleChildElement($n, $issue, $processOnlyChildren)
Definition: NativeXmlIssueFilter.inc.php:105
NativeXmlIssueFilter\parseSections
parseSections($node, $issue)
Definition: NativeXmlIssueFilter.inc.php:268
NativeXmlIssueFilter
Base class that converts a Native XML document to a set of issues.
Definition: NativeXmlIssueFilter.inc.php:18
NativeXmlIssueFilter\parseIssueGalley
parseIssueGalley($n, $issue)
Definition: NativeXmlIssueFilter.inc.php:216
NativeXmlIssueFilter\parseSection
parseSection($node)
Definition: NativeXmlIssueFilter.inc.php:287
Filter\setDisplayName
setDisplayName($displayName)
Definition: Filter.inc.php:140
NativeXmlIssueFilter\_issueExists
_issueExists($node)
Definition: NativeXmlIssueFilter.inc.php:416
NativeFilterHelper
Class that provides native import/export filter-related helper methods.
Definition: NativeFilterHelper.inc.php:15
NativeXmlIssueFilter\getSingularElementName
getSingularElementName()
Definition: NativeXmlIssueFilter.inc.php:55