%PDF-1.7 GIF89;
| Server IP : 104.20.45.2 / Your IP : 172.16.20.3 Web Server : Apache/2.4.25 (Debian) System : Linux f64a392e70de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 User : application ( 1000) PHP Version : 5.6.40 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /app/plugins/oaiMetadataFormats/nlm/ |
Upload File : |
<?php
/**
* @defgroup oai_format_nlm
*/
/**
* @file plugins/oaiMetadataFormats/nlm/OAIMetadataFormat_NLM.inc.php
*
* Copyright (c) 2013-2019 Simon Fraser University
* Copyright (c) 2003-2019 John Willinsky
* Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
*
* @class OAIMetadataFormat_NLM
* @ingroup oai_format
* @see OAI
*
* @brief OAI metadata format class -- NLM 2.3
*/
class OAIMetadataFormat_NLM extends OAIMetadataFormat {
/**
* @see OAIMetadataFormat#toXml
* TODO:
* <copyright-holder>
* In Isabelle's mapping document:
* Article order in the issue's Table of Contents
*/
function toXml(&$record, $format = null) {
AppLocale::requireComponents(array(LOCALE_COMPONENT_APPLICATION_COMMON));
$article =& $record->getData('article');
$journal =& $record->getData('journal');
$section =& $record->getData('section');
$issue =& $record->getData('issue');
$galleys =& $record->getData('galleys');
$articleId = $article->getId();
// Cache issue ordering information.
static $issueId;
static $sectionSeq;
if (!isset($issueId) || $issueId != $issue->getId()) {
$sectionDao =& DAORegistry::getDAO('SectionDAO');
$issueId = $issue->getId();
$sections =& $sectionDao->getSectionsForIssue($issueId);
$sectionSeq = array();
$i=0;
foreach ($sections as $thisSection) {
$sectionSeq[$thisSection->getId()] = $i++;
}
unset($sections);
}
$abbreviation = $journal->getLocalizedSetting('abbreviation');
$printIssn = $journal->getSetting('printIssn');
$onlineIssn = $journal->getSetting('onlineIssn');
$primaryLocale = ($article->getLanguage() != '') ? $article->getLanguage() : $journal->getPrimaryLocale();
$publisherInstitution = $journal->getSetting('publisherInstitution');
$datePublished = $article->getDatePublished();
if (!$datePublished) $datePublished = $issue->getDatePublished();
if ($datePublished) $datePublished = strtotime($datePublished);
$response = "<article\n" .
"\txmlns=\"http://dtd.nlm.nih.gov/publishing/2.3\"\n" .
"\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" .
"\txmlns:mml=\"http://www.w3.org/1998/Math/MathML\"\n" .
"\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" .
"\txsi:schemaLocation=\"http://dtd.nlm.nih.gov/publishing/2.3\n" .
"\thttp://dtd.nlm.nih.gov/publishing/2.3/xsd/journalpublishing.xsd\"\n" .
(($s = $section->getLocalizedIdentifyType())!=''?"\tarticle-type=\"" . htmlspecialchars(Core::cleanVar($s)) . "\"":'') .
"\txml:lang=\"" . strtoupper(substr($primaryLocale, 0, 2)) . "\">\n" .
"\t<front>\n" .
"\t\t<journal-meta>\n" .
"\t\t\t<journal-id journal-id-type=\"other\">" . htmlspecialchars(Core::cleanVar(($s = Config::getVar('oai', 'nlm_journal_id'))!=''?$s:$journal->getPath())) . "</journal-id>\n" .
"\t\t\t<journal-title>" . htmlspecialchars(Core::cleanVar($journal->getLocalizedTitle())) . "</journal-title>\n";
// Include translated journal titles
foreach ($journal->getTitle(null) as $locale => $title) {
if ($locale == $primaryLocale) continue;
$response .= "\t\t\t<trans-title xml:lang=\"" . strtoupper(substr($locale, 0, 2)) . "\">" . htmlspecialchars(Core::cleanVar($title)) . "</trans-title>\n";
}
$response .=
(!empty($onlineIssn)?"\t\t\t<issn pub-type=\"epub\">" . htmlspecialchars(Core::cleanVar($onlineIssn)) . "</issn>":'') .
(!empty($printIssn)?"\t\t\t<issn pub-type=\"ppub\">" . htmlspecialchars(Core::cleanVar($printIssn)) . "</issn>":'') .
($publisherInstitution != ''?"\t\t\t<publisher><publisher-name>" . htmlspecialchars(Core::cleanVar($publisherInstitution)) . "</publisher-name></publisher>\n":'') .
"\t\t</journal-meta>\n" .
"\t\t<article-meta>\n" .
"\t\t\t<article-id pub-id-type=\"other\">" . htmlspecialchars(Core::cleanVar($article->getBestArticleId())) . "</article-id>\n" .
(($s = $article->getPubId('doi'))?"\t\t\t<article-id pub-id-type=\"doi\">" . htmlspecialchars(Core::cleanVar($s)) . "</article-id>\n":'') .
"\t\t\t<article-categories><subj-group subj-group-type=\"heading\"><subject>" . htmlspecialchars(Core::cleanVar($section->getLocalizedTitle())) . "</subject></subj-group></article-categories>\n" .
"\t\t\t<title-group>\n" .
"\t\t\t\t<article-title>" . htmlspecialchars(Core::cleanVar(strip_tags($article->getLocalizedTitle()))) . "</article-title>\n";
// Include translated journal titles
foreach ($article->getTitle(null) as $locale => $title) {
if ($locale == $primaryLocale) continue;
$response .= "\t\t\t\t<trans-title xml:lang=\"" . strtoupper(substr($locale, 0, 2)) . "\">" . htmlspecialchars(Core::cleanVar(strip_tags($title))) . "</trans-title>\n";
}
$response .=
"\t\t\t</title-group>\n" .
"\t\t\t<contrib-group>\n";
// Include authors
foreach ($article->getAuthors() as $author) {
$response .=
"\t\t\t\t<contrib " . ($author->getPrimaryContact()?'corresp="yes" ':'') . "contrib-type=\"author\">\n" .
"\t\t\t\t\t<name name-style=\"western\">\n" .
"\t\t\t\t\t\t<surname>" . htmlspecialchars(Core::cleanVar($author->getLastName())) . "</surname>\n" .
"\t\t\t\t\t\t<given-names>" . htmlspecialchars(Core::cleanVar($author->getFirstName()) . (($s = $author->getMiddleName()) != ''?" $s":'')) . "</given-names>\n" .
"\t\t\t\t\t</name>\n" .
(($s = $author->getLocalizedAffiliation()) != ''?"\t\t\t\t\t<aff>" . htmlspecialchars(Core::cleanVar($s)) . "</aff>\n":'') .
"\t\t\t\t\t<email>" . htmlspecialchars(Core::cleanVar($author->getEmail())) . "</email>\n" .
(($s = $author->getUrl()) != ''?"\t\t\t\t\t<uri>" . htmlspecialchars(Core::cleanVar($s)) . "</uri>\n":'') .
"\t\t\t\t</contrib>\n";
}
// Include editorships (optimized)
$response .= $this->getEditorialInfo($journal->getId());
$response .= "\t\t\t</contrib-group>\n";
if ($datePublished) $response .=
"\t\t\t<pub-date pub-type=\"epub\">\n" .
"\t\t\t\t<day>" . strftime('%d', $datePublished) . "</day>\n" .
"\t\t\t\t<month>" . strftime('%m', $datePublished) . "</month>\n" .
"\t\t\t\t<year>" . strftime('%Y', $datePublished) . "</year>\n" .
"\t\t\t</pub-date>\n";
$response .=
($issue->getShowYear()?"\t\t\t<pub-date pub-type=\"collection\"><year>" . htmlspecialchars(Core::cleanVar($issue->getYear())) . "</year></pub-date>\n":'') .
($issue->getShowVolume()?"\t\t\t<volume>" . htmlspecialchars(Core::cleanVar($issue->getVolume())) . "</volume>\n":'') .
($issue->getShowNumber()?"\t\t\t<issue seq=\"" . htmlspecialchars(Core::cleanVar(($sectionSeq[$section->getId()]*100) + $article->getSeq())) . "\">" . htmlspecialchars(Core::cleanVar($issue->getNumber())) . "</issue>\n":'') .
"\t\t\t<issue-id pub-id-type=\"other\">" . htmlspecialchars(Core::cleanVar($issue->getBestIssueId())) . "</issue-id>\n" .
($issue->getShowTitle()?"\t\t\t<issue-title>" . htmlspecialchars(Core::cleanVar($issue->getLocalizedTitle())) . "</issue-title>\n":'');
// Include page info, if available and parseable.
$matches = null;
if (PKPString::regexp_match_get('/^[Pp][Pp]?[.]?[ ]?(\d+)$/', $article->getPages(), $matches)) {
$matchedPage = htmlspecialchars(Core::cleanVar($matches[1]));
$response .= "\t\t\t\t<fpage>$matchedPage</fpage><lpage>$matchedPage</lpage>\n";
$pageCount = 1;
} elseif (PKPString::regexp_match_get('/^[Pp][Pp]?[.]?[ ]?(\d+)[ ]?-[ ]?([Pp][Pp]?[.]?[ ]?)?(\d+)$/', $article->getPages(), $matches)) {
$matchedPageFrom = htmlspecialchars(Core::cleanVar($matches[1]));
$matchedPageTo = htmlspecialchars(Core::cleanVar($matches[3]));
$response .=
"\t\t\t\t<fpage>$matchedPageFrom</fpage>\n" .
"\t\t\t\t<lpage>$matchedPageTo</lpage>\n";
$pageCount = $matchedPageTo - $matchedPageFrom + 1;
}
$response .=
"\t\t\t<permissions>\n" .
"\t\t\t\t<copyright-statement>" . htmlspecialchars(__('submission.copyrightStatement', array('copyrightYear' => $article->getCopyrightYear(), 'copyrightHolder' => $article->getLocalizedCopyrightHolder()))) . "</copyright-statement>\n" .
($datePublished?"\t\t\t\t<copyright-year>" . $article->getCopyrightYear() . "</copyright-year>\n":'') .
"\t\t\t\t<license xlink:href=\"" . $article->getLicenseURL() . "\">\n" .
(($s = Application::getCCLicenseBadge($article->getLicenseURL()))?"\t\t\t\t\t<license-p>" . strip_tags($s) . "</license-p>\n":'') .
"\t\t\t\t</license>\n" .
"\t\t\t</permissions>\n" .
"\t\t\t<self-uri xlink:href=\"" . htmlspecialchars(Core::cleanVar(Request::url($journal->getPath(), 'article', 'view', $article->getBestArticleId()))) . "\" />\n";
// Include galley links
foreach ($article->getGalleys() as $galley) {
$response .= "\t\t\t<self-uri content-type=\"" . htmlspecialchars(Core::cleanVar($galley->getFileType())) . "\" xlink:href=\"" . htmlspecialchars(Core::cleanVar(Request::url($journal->getPath(), 'article', 'view', array($article->getBestArticleId(), $galley->getId())))) . "\" />\n";
}
// Include abstract(s)
$abstract = htmlspecialchars(Core::cleanVar(strip_tags($article->getLocalizedAbstract())));
if (!empty($abstract)) {
$abstract = "<p>$abstract</p>";
// $abstract = '<p>' . PKPString::regexp_replace('/\n+/', '</p><p>', $abstract) . '</p>';
$response .= "\t\t\t<abstract xml:lang=\"" . strtoupper(substr($primaryLocale, 0, 2)) . "\">$abstract</abstract>\n";
}
if (is_array($article->getAbstract(null))) foreach ($article->getAbstract(null) as $locale => $abstract) {
if ($locale == $primaryLocale || empty($abstract)) continue;
$abstract = htmlspecialchars(Core::cleanVar(strip_tags($abstract)));
if (empty($abstract)) continue;
$abstract = "<p>$abstract</p>";
//$abstract = '<p>' . PKPString::regexp_replace('/\n+/', '</p><p>', $abstract) . '</p>';
$response .= "\t\t\t<abstract-trans xml:lang=\"" . strtoupper(substr($locale, 0, 2)) . "\">$abstract</abstract-trans>\n";
}
$subjects = array();
if (is_array($article->getSubject(null))) foreach ($article->getSubject(null) as $locale => $subject) {
$s = array_map('trim', explode(';', Core::cleanVar($subject)));
if (!empty($s)) $subjects[$locale] = $s;
}
if (!empty($subjects)) foreach ($subjects as $locale => $s) {
$response .= "\t\t\t<kwd-group xml:lang=\"" . strtoupper(substr($locale, 0, 2)) . "\">\n";
foreach ($s as $subject) $response .= "\t\t\t\t<kwd>" . htmlspecialchars($subject) . "</kwd>\n";
$response .= "\t\t\t</kwd-group>\n";
}
$response .=
(isset($pageCount)?"\t\t\t<counts><page-count count=\"" . (int) $pageCount. "\" /></counts>\n":'') .
"\t\t</article-meta>\n" .
"\t</front>\n";
// Include body text (for search indexing only)
import('classes.search.ArticleSearchIndex');
$text = '';
$galleys = $article->getGalleys();
// Give precedence to HTML galleys, as they're quickest to parse
usort($galleys, create_function('$a, $b', 'return $a->isHtmlGalley()?-1:1;'));
// Determine any access limitations. If there are, do not
// provide the full-text.
import('classes.issue.IssueAction');
$subscriptionRequired = IssueAction::subscriptionRequired($issue);
$isSubscribedDomain = IssueAction::subscribedDomain($journal, $issue->getId(), $article->getId());
if (!$subscriptionRequired || $isSubscribedDomain) foreach ($galleys as $galley) {
$parser =& SearchFileParser::fromFile($galley);
if ($parser && $parser->open()) {
while(($s = $parser->read()) !== false) $text .= $s;
$parser->close();
}
if ($galley->isHtmlGalley()) $text = strip_tags($text);
unset($galley);
// Use the first parseable galley.
if (!empty($text)) break;
}
if (!empty($text)) $response .= "\t<body><p>" . htmlspecialchars(Core::cleanVar(Core::cleanVar($text))) . "</p></body>\n";
// Add NLM citation info
$filterDao =& DAORegistry::getDAO('FilterDAO'); /* @var $filterDao FilterDAO */
$nlmFilters = $filterDao->getObjectsByGroup('submission=>nlm23-article-xml');
assert(count($nlmFilters) == 1);
$nlmFilter = array_pop($nlmFilters);
$nlmXmlDom = new DOMDocument();
$nlmXmlDom->loadXML($nlmFilter->execute($article));
$documentElement =& $nlmXmlDom->documentElement;
// Work-around for hasChildNodes being stupid about whitespace.
$hasChildren = false;
if (isset($documentElement->childNodes)) foreach ($documentElement->childNodes as $c) {
if ($c->nodeType == XML_ELEMENT_NODE) $hasChildren = true;
}
// If there were any citations, include them.
if ($hasChildren) {
$innerXml = $nlmXmlDom->saveXML($documentElement);
$response .= "<back>$innerXml</back>\n";
}
$response .= "</article>";
return $response;
}
function getEditorialInfo($journalId) {
static $editorialInfo = array();
if (isset($editorialInfo[$journalId])) return $editorialInfo[$journalId];
$response = '';
$roleDao =& DAORegistry::getDAO('RoleDAO');
$roleMap = array(ROLE_ID_EDITOR => 'editor', ROLE_ID_SECTION_EDITOR => 'secteditor', ROLE_ID_JOURNAL_MANAGER => 'jmanager');
foreach ($roleMap as $roleId => $roleName) {
$users =& $roleDao->getUsersByRoleId($roleId, $journalId);
$isFirst = true;
while ($user =& $users->next()) {
$response .= "\t\t\t\t<contrib contrib-type=\"$roleName\">\n" .
"\t\t\t\t\t<name>\n" .
"\t\t\t\t\t\t<surname>" . htmlspecialchars(Core::cleanVar($user->getLastName())) . "</surname>\n" .
"\t\t\t\t\t\t<given-names>" . htmlspecialchars(Core::cleanVar($user->getFirstName() . ($user->getMiddleName() != ''?' ' . $user->getMiddleName():''))) . "</given-names>\n" .
"\t\t\t\t\t</name>\n" .
"\t\t\t\t</contrib>\n";
unset($user);
}
unset($users);
}
$editorialInfo[$journalId] =& $response;
return $response;
}
}
?>