static public regexp_match_get ( $pattern, $subject, &$matches ) : integer | boolean | ||
$pattern | string Regular expression | |
$subject | string String to apply regular expression to | |
$matches | array Reference to receive matches | |
return | integer | boolean | Returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred. |
/** * Retrieve the export as an XML string. * @param $pluginUrl string the url to be requested for export. * @param $postParams array additional post parameters * @return string */ protected function getXmlOnExport($pluginUrl, $postParams = array()) { // Prepare HTTP session. $curlCh = curl_init(); curl_setopt($curlCh, CURLOPT_POST, true); // Create a cookie file (required for log-in). $cookies = tempnam(sys_get_temp_dir(), 'curlcookies'); // Log in. $loginUrl = $this->baseUrl . '/index.php/test/login/signIn'; // Bug #8518 safety work-around if ($this->password[0] == '@') { die('CURL parameters may not begin with @.'); } $loginParams = array('username' => 'admin', 'password' => $this->password); curl_setopt($curlCh, CURLOPT_URL, $loginUrl); curl_setopt($curlCh, CURLOPT_POSTFIELDS, $loginParams); curl_setopt($curlCh, CURLOPT_COOKIEJAR, $cookies); self::assertTrue(curl_exec($curlCh)); // Request export document. $exportUrl = $this->baseUrl . '/index.php/test/manager/importexport/plugin/' . $pluginUrl; curl_setopt($curlCh, CURLOPT_URL, $exportUrl); // Bug #8518 safety work-around foreach ($postParams as $paramValue) { if ($paramValue[0] == '@') { die('CURL parameters may not begin with @.'); } } curl_setopt($curlCh, CURLOPT_POSTFIELDS, $postParams); curl_setopt($curlCh, CURLOPT_HTTPHEADER, array('Accept: application/xml, application/x-gtar, */*')); curl_setopt($curlCh, CURLOPT_RETURNTRANSFER, true); curl_setopt($curlCh, CURLOPT_HEADER, true); $response = curl_exec($curlCh); do { list($header, $response) = explode("\r\n\r\n", $response, 2); } while (PKPString::regexp_match('#HTTP/.*100#', $header)); // Check whether we got a tar file. if (PKPString::regexp_match('#Content-Type: application/x-gtar#', $header)) { // Save the data to a temporary file. $tempfile = tempnam(sys_get_temp_dir(), 'tst'); file_put_contents($tempfile, $response); // Recursively extract tar file. $result = $this->extractTarFile($tempfile); unlink($tempfile); } else { $matches = null; PKPString::regexp_match_get('#filename="([^"]+)"#', $header, $matches); self::assertTrue(isset($matches[1])); $result = array($matches[1] => $response); } // Destroy HTTP session. curl_close($curlCh); unlink($cookies); return $result; }
/** * Extract and validate a plugin (prior to installation) * @param $filePath string Full path to plugin archive * @param $originalFileName string Original filename of plugin archive * @return string|null Extracted plugin path on success; null on error */ function extractPlugin($filePath, $originalFileName, &$errorMsg) { $fileManager = new FileManager(); // tar archive basename (less potential version number) must // equal plugin directory name and plugin files must be in a // directory named after the plug-in (potentially with version) $matches = array(); PKPString::regexp_match_get('/^[a-zA-Z0-9]+/', basename($originalFileName, '.tar.gz'), $matches); $pluginShortName = array_pop($matches); if (!$pluginShortName) { $errorMsg = __('manager.plugins.invalidPluginArchive'); $fileManager->deleteFile($filePath); return null; } // Create random dirname to avoid symlink attacks. $pluginExtractDir = dirname($filePath) . DIRECTORY_SEPARATOR . $pluginShortName . substr(md5(mt_rand()), 0, 10); mkdir($pluginExtractDir); // Test whether the tar binary is available for the export to work $tarBinary = Config::getVar('cli', 'tar'); if (!empty($tarBinary) && file_exists($tarBinary)) { exec($tarBinary . ' -xzf ' . escapeshellarg($filePath) . ' -C ' . escapeshellarg($pluginExtractDir)); } else { $errorMsg = __('manager.plugins.tarCommandNotFound'); } $fileManager->deleteFile($filePath); if (empty($errorMsg)) { // Look for a directory named after the plug-in's short // (alphanumeric) name within the extracted archive. if (is_dir($tryDir = $pluginExtractDir . '/' . $pluginShortName)) { return $tryDir; // Success } // Failing that, look for a directory named after the // archive. (Typically also contains the version number // e.g. with github generated release archives.) PKPString::regexp_match_get('/^[a-zA-Z0-9.-]+/', basename($originalFileName, '.tar.gz'), $matches); if (is_dir($tryDir = $pluginExtractDir . '/' . array_pop($matches))) { // We found a directory named after the archive // within the extracted archive. (Typically also // contains the version number, e.g. github // generated release archives.) return $tryDir; } $errorMsg = __('manager.plugins.invalidPluginArchive'); } $fileManager->rmtree($pluginExtractDir); return null; }
/** * Normalize incoming date string. * @see Filter::process() * @param $input string * @return string */ function &process(&$input) { // FIXME: We have to i18nize this when expanding citation parsing to other languages static $monthNames = array('Jan' => '01', 'Feb' => '02', 'Mar' => '03', 'Apr' => '04', 'May' => '05', 'Jun' => '06', 'Jul' => '07', 'Aug' => '08', 'Sep' => '09', 'Oct' => '10', 'Nov' => '11', 'Dec' => '12'); $dateExpressions = array('/(?P<year>\\d{4})-(?P<month>\\d{2})-(?P<day>\\d{2})/', '/(?P<year>\\d{4})(\\s|-)*(?P<monthName>[a-z]\\w+)?(\\s|-)*(?P<day>\\d+)?/i'); $normalizedDate = null; foreach ($dateExpressions as $dateExpression) { if (PKPString::regexp_match_get($dateExpression, $input, $parsedDate)) { if (isset($parsedDate['year'])) { $normalizedDate = $parsedDate['year']; $month = ''; if (isset($parsedDate['monthName'])) { $monthName = substr($parsedDate['monthName'], 0, 3); if (isset($monthNames[$monthName])) { // Convert the month name to a two digit numeric month representation. $month = $monthNames[$monthName]; } } if (isset($parsedDate['month'])) { // Convert month to a two digit representation. $month = str_pad($parsedDate['month'], 2, '0', STR_PAD_LEFT); } if (!empty($month)) { $normalizedDate .= '-' . $month; if (isset($parsedDate['day'])) { $normalizedDate .= '-' . str_pad($parsedDate['day'], 2, '0', STR_PAD_LEFT); } } } if (!empty($normalizedDate)) { break; } } } return $normalizedDate; }
/** * @see Validator::isValid() * @param $value mixed * @return boolean */ function isValid($value) { return (bool) PKPString::regexp_match_get($this->_regExp, $value, $this->_matches); }
/** * @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) { $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->getByIssueId($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->getLocalizedName())) . "</journal-title>\n"; // Include translated journal titles foreach ($journal->getName(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->getSequence())) . "\">" . 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[4])); $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->getFileType()==\'text/html\')?-1:1;')); // Determine any access limitations. If there are, do not // provide the full-text. import('classes.issue.IssueAction'); $issueAction = new 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->getFileType() == 'text/html') { $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; }
/** * Submit a new test article. * @param $title string * @return integer the id of the new article */ protected function submitArticle($title = 'Editing test article') { // We need to be logged in to submit an article. $this->logIn(); $submissionPage = $this->baseUrl . '/index.php/lucene-test/author/submit/'; // // First submission page. // $this->verifyAndOpen($submissionPage . '1'); $this->waitForElementPresent('css=input.defaultButton'); // Set Section. $this->select('sectionId', 'value=3'); // Accept submission conditions. $checkboxId = 1; while ($this->isElementPresent("checklist-{$checkboxId}")) { $this->check("checklist-{$checkboxId}"); $checkboxId++; } // Submit first submission page. $this->clickAndWait('css=input.defaultButton'); // // Second submission page. // $this->waitForLocation($submissionPage . '2*'); $this->waitForElementPresent('css=input.defaultButton'); // We should now have the article ID in the URL. $url = $this->getLocation(); $matches = null; PKPString::regexp_match_get('/articleId=([0-9]+)/', $url, $matches); self::assertTrue(count($matches) == 2); $articleId = $matches[1]; self::assertTrue(is_numeric($articleId)); $articleId = (int) $articleId; // Submit the second submission page. $this->clickAndWait('css=input.defaultButton'); $this->waitForConfirmation('*Are you sure you wish to continue*'); // // Third submission page. // $this->waitForLocation($submissionPage . '3*'); $this->waitForElementPresent('css=input.defaultButton'); // Fill in article metadata. $this->type('authors-0-firstName', 'Arthur'); $this->type('authors-0-lastName', 'McAutomatic'); $this->type('title', $title); $this->verifyElementPresent('id=abstract_ifr'); if ($this->verified()) { // TinyMCE hack. $jsScript = "selenium.browserbot.getCurrentWindow().document" . ".getElementById('abstract_ifr').contentDocument.body.innerHTML = " . "'{$title} abstract'"; $this->getEval($jsScript); } else { $this->type('abstract', $title . ' abstract'); } // Submit metadata. $this->clickAndWait('css=input.defaultButton'); // // Fourth and fifth submission page. // $this->waitForLocation($submissionPage . '4*'); $this->waitForElementPresent('css=input.defaultButton'); // Do not upload any supplementary file and continue. $this->clickAndWait('css=input.defaultButton'); $this->waitForLocation($submissionPage . '5*'); $this->waitForElementPresent('css=input.defaultButton'); // Confirm the submission. $this->clickAndWait('css=input.defaultButton'); return $articleId; }
/** * Do the actual web service request. * @param $action string * @param $arg string * @param $attachment array * @return boolean|string True for success, an error message otherwise. */ function _doRequest($action, $arg, $attachment = null) { // Build the multipart SOAP message from scratch. $soapMessage = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" ' . 'xmlns:med="http://www.medra.org">' . '<SOAP-ENV:Header/>' . '<SOAP-ENV:Body>' . "<med:{$action}>{$arg}</med:{$action}>" . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>'; $soapMessageId = $this->_getContentId($action); if ($attachment) { assert(count($attachment) == 1); $request = "--MIME_boundary\r\n" . $this->_getMimePart($soapMessageId, $soapMessage) . "--MIME_boundary\r\n" . $this->_getMimePart(key($attachment), current($attachment)) . "--MIME_boundary--\r\n"; $contentType = 'multipart/related; type="text/xml"; boundary="MIME_boundary"'; } else { $request = $soapMessage; $contentType = 'text/xml'; } // Prepare HTTP session. $curlCh = curl_init(); curl_setopt($curlCh, CURLOPT_RETURNTRANSFER, true); curl_setopt($curlCh, CURLOPT_POST, true); // Set up basic authentication. curl_setopt($curlCh, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($curlCh, CURLOPT_USERPWD, $this->_auth); // Set up SSL. curl_setopt($curlCh, CURLOPT_SSL_VERIFYPEER, false); // Make SOAP request. curl_setopt($curlCh, CURLOPT_URL, $this->_endpoint); $extraHeaders = array('SOAPAction: "' . $action . '"', 'Content-Type: ' . $contentType, 'UserAgent: OJS-mEDRA'); curl_setopt($curlCh, CURLOPT_HTTPHEADER, $extraHeaders); curl_setopt($curlCh, CURLOPT_POSTFIELDS, $request); $result = true; $response = curl_exec($curlCh); // We do not localize our error messages as they are all // fatal errors anyway and must be analyzed by technical staff. if ($response === false) { $result = 'OJS-mEDRA: Expected string response.'; } if ($result === true && ($status = curl_getinfo($curlCh, CURLINFO_HTTP_CODE)) != MEDRA_WS_RESPONSE_OK) { $result = 'OJS-mEDRA: Expected ' . MEDRA_WS_RESPONSE_OK . ' response code, got ' . $status . ' instead.'; } curl_close($curlCh); // Check SOAP response by simple string manipulation rather // than instantiating a DOM. if (is_string($response)) { $matches = array(); PKPString::regexp_match_get('#<faultstring>([^<]*)</faultstring>#', $response, $matches); if (empty($matches)) { if ($attachment) { assert(PKPString::regexp_match('#<returnCode>success</returnCode>#', $response)); } else { $parts = explode("\r\n\r\n", $response); $result = array_pop($parts); $result = PKPString::regexp_replace('/>[^>]*$/', '>', $result); } } else { $result = 'mEDRA: ' . $status . ' - ' . $matches[1]; } } else { $result = 'OJS-mEDRA: Expected string response.'; } return $result; }
/** * Converts a string with a single person * to an NLM name description. * * TODO: add initials from all given names to initials * element * * @param $personString string * @param $title boolean true to parse for title * @param $degrees boolean true to parse for degrees * @return MetadataDescription an NLM name description or null * if the string could not be converted */ function &_parsePersonString($personString, $title, $degrees) { // Expressions to parse person strings, ported from CiteULike person // plugin, see http://svn.citeulike.org/svn/plugins/person.tcl static $personRegex = array('title' => '(?:His (?:Excellency|Honou?r)\\s+|Her (?:Excellency|Honou?r)\\s+|The Right Honou?rable\\s+|The Honou?rable\\s+|Right Honou?rable\\s+|The Rt\\.? Hon\\.?\\s+|The Hon\\.?\\s+|Rt\\.? Hon\\.?\\s+|Mr\\.?\\s+|Ms\\.?\\s+|M\\/s\\.?\\s+|Mrs\\.?\\s+|Miss\\.?\\s+|Dr\\.?\\s+|Sir\\s+|Dame\\s+|Prof\\.?\\s+|Professor\\s+|Doctor\\s+|Mister\\s+|Mme\\.?\\s+|Mast(?:\\.|er)?\\s+|Lord\\s+|Lady\\s+|Madam(?:e)?\\s+|Priv\\.-Doz\\.\\s+)+', 'degrees' => '(,\\s+(?:[A-Z\\.]+))+', 'initials' => '(?:(?:[A-Z]\\.){1,3}[A-Z]\\.?)|(?:(?:[A-Z]\\.\\s){1,3}[A-Z]\\.?)|(?:[A-Z]{1,4})|(?:(?:[A-Z]\\.-?){1,4})|(?:(?:[A-Z]\\.-?){1,3}[A-Z]\\.?)|(?:(?:[A-Z]-){1,3}[A-Z])|(?:(?:[A-Z]\\s){1,3}[A-Z]\\.?)|(?:(?:[A-Z]-){1,3}[A-Z]\\.?)', 'prefix' => 'Dell(?:[a|e])?(?:\\s|$)|Dalle(?:\\s|$)|D[a|e]ll\'(?:\\s|$)|Dela(?:\\s|$)|Del(?:\\s|$)|[Dd]e(?:\\s|$)(?:La(?:\\s|$)|Los(?:\\s|$))?|[Dd]e(?:\\s|$)|[Dd][a|i|u](?:\\s|$)|L[a|e|o](?:\\s|$)|[D|L|O]\'|St\\.?(?:\\s|$)|San(?:\\s|$)|[Dd]en(?:\\s|$)|[Vv]on(?:\\s|$)(?:[Dd]er(?:\\s|$))?|(?:[Ll][ea](?:\\s|$))?[Vv]an(?:\\s|$)(?:[Dd]e(?:n|r)?(?:\\s|$))?', 'givenName' => '(?:[^ \\t\\n\\r\\f\\v,.;()]{2,}|[^ \\t\\n\\r\\f\\v,.;()]{2,}\\-[^ \\t\\n\\r\\f\\v,.;()]{2,})'); // The expressions for given name, suffix and surname are the same $personRegex['surname'] = $personRegex['suffix'] = $personRegex['givenName']; $personRegex['double-surname'] = "(?:" . $personRegex['surname'] . "\\s)*" . $personRegex['surname']; // Shortcut for prefixed surname $personRegexPrefixedSurname = "(?P<prefix>(?:" . $personRegex['prefix'] . ")?)(?P<surname>" . $personRegex['surname'] . ")"; $personRegexPrefixedDoubleSurname = "(?P<prefix>(?:" . $personRegex['prefix'] . ")?)(?P<surname>" . $personRegex['double-surname'] . ")"; // Instantiate the target person description $personDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', $this->_assocType); // Clean the person string $personString = trim($personString); // 1. Extract title and degree from the person string and use this as suffix $suffixString = ''; $results = array(); if ($title && PKPString::regexp_match_get('/^(' . $personRegex['title'] . ')/i', $personString, $results)) { $suffixString = trim($results[1], ',:; '); $personString = PKPString::regexp_replace('/^(' . $personRegex['title'] . ')/i', '', $personString); } if ($degrees && PKPString::regexp_match_get('/(' . $personRegex['degrees'] . ')$/i', $personString, $results)) { $degreesArray = explode(',', trim($results[1], ',')); foreach ($degreesArray as $key => $degree) { $degreesArray[$key] = PKPString::trimPunctuation($degree); } $suffixString .= ' - ' . implode('; ', $degreesArray); $personString = PKPString::regexp_replace('/(' . $personRegex['degrees'] . ')$/i', '', $personString); } if (!empty($suffixString)) { $personDescription->addStatement('suffix', $suffixString); } // Space initials when followed by a given name or last name. $personString = PKPString::regexp_replace('/([A-Z])\\.([A-Z][a-z])/', '\\1. \\2', $personString); // 2. Extract names and initials from the person string // The parser expressions are ordered by specificity. The most specific expressions // come first. Only if these specific expressions don't work will we turn to less // specific ones. This avoids parsing errors. It also explains why we don't use the // ?-quantifier for optional elements like initials or middle name where they could // be misinterpreted. $personExpressions = array('/^' . $personRegexPrefixedSurname . '$/i', '/^(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedSurname . ',?\\s(?P<initials>' . $personRegex['initials'] . ')$/', '/^' . $personRegexPrefixedDoubleSurname . ',\\s(?P<givenName>' . $personRegex['givenName'] . ')\\s(?P<initials>' . $personRegex['initials'] . ')$/', '/^(?P<givenName>' . $personRegex['givenName'] . ')\\s(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedDoubleSurname . ',\\s(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)(?P<initials>' . $personRegex['initials'] . ')$/', '/^(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedDoubleSurname . ',(?P<givenName>(?:\\s' . $personRegex['givenName'] . ')+)$/', '/^(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)' . $personRegexPrefixedSurname . '$/', '/^\\s*(?P<surname>' . $personRegex['surname'] . ')(?P<suffix>(?:\\s+' . $personRegex['suffix'] . ')?)\\s*,\\s*(?P<initials>(?:' . $personRegex['initials'] . ')?)\\s*\\((?P<givenName>(?:\\s*' . $personRegex['givenName'] . ')+)\\s*\\)\\s*(?P<prefix>(?:' . $personRegex['prefix'] . ')?)$/', '/^(?P<givenName>' . $personRegex['givenName'] . ')\\.(?P<surname>' . $personRegex['double-surname'] . ')$/', '/^(?P<surname>.*)$/'); $results = array(); foreach ($personExpressions as $expressionId => $personExpression) { if ($nameFound = PKPString::regexp_match_get($personExpression, $personString, $results)) { // Given names if (!empty($results['givenName'])) { // Split given names $givenNames = explode(' ', trim($results['givenName'])); foreach ($givenNames as $givenName) { $personDescription->addStatement('given-names', $givenName); unset($givenName); } } // Initials (will also be saved as given names) if (!empty($results['initials'])) { $results['initials'] = str_replace(array('.', '-', ' '), array('', '', ''), $results['initials']); for ($initialNum = 0; $initialNum < PKPString::strlen($results['initials']); $initialNum++) { $initial = $results['initials'][$initialNum]; $personDescription->addStatement('given-names', $initial); unset($initial); } } // Surname if (!empty($results['surname'])) { // Correct all-upper surname if (strtoupper($results['surname']) == $results['surname']) { $results['surname'] = ucwords(strtolower($results['surname'])); } $personDescription->addStatement('surname', $results['surname']); } // Prefix/Suffix foreach (array('prefix', 'suffix') as $propertyName) { if (!empty($results[$propertyName])) { $results[$propertyName] = trim($results[$propertyName]); $personDescription->addStatement($propertyName, $results[$propertyName]); } } break; } } return $personDescription; }
/** * Processes form-submitted addresses for inclusion in * the recipient list * @param $currentList array Current recipient/cc/bcc list * @param $newAddresses array "Raw" form parameter for additional addresses */ function &processAddresses($currentList, &$newAddresses) { foreach ($newAddresses as $newAddress) { $regs = array(); // Match the form "My Name <*****@*****.**>" if (PKPString::regexp_match_get('/^([^<>' . "\n" . ']*[^<> ' . "\n" . '])[ ]*<(?P<email>' . PCRE_EMAIL_ADDRESS . ')>$/i', $newAddress, $regs)) { $currentList[] = array('name' => $regs[1], 'email' => $regs['email']); } elseif (PKPString::regexp_match_get('/^<?(?P<email>' . PCRE_EMAIL_ADDRESS . ')>?$/i', $newAddress, $regs)) { $currentList[] = array('name' => '', 'email' => $regs['email']); } elseif ($newAddress != '') { $this->errorMessages[] = array('type' => MAIL_ERROR_INVALID_EMAIL, 'address' => $newAddress); } } return $currentList; }
/** * @copydoc Filter::process() * @param $input string * @return MetadataDescription */ function &process(&$input) { $citationString =& $input; // Initialize the parser result array $matches = array(); $metadata = array(); // Parse out any embedded URLs $urlPattern = '(<?(https?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.,]*(\\?[^\\s>]+)?)?)?)>?)'; if (PKPString::regexp_match_get($urlPattern, $citationString, $matches)) { // Assume that the URL is a link to the resource. $metadata['uri'] = $matches[1]; // Remove the URL from the citation string $citationString = PKPString::regexp_replace($urlPattern, '', $citationString); // If the URL is a link to PubMed, save the PMID $pmIdExpressions = array('/list_uids=(?P<pmId>\\d+)/i', '/pubmed.*details_term=(?P<pmId>\\d+)/i', '/pubmedid=(?P<pmId>\\d+)/i'); foreach ($pmIdExpressions as $pmIdExpression) { if (PKPString::regexp_match_get($pmIdExpression, $matches[1], $pmIdMatches)) { $metadata['pub-id[@pub-id-type="pmid"]'] = $pmIdMatches['pmId']; break; } } } // Parse out an embedded PMID and remove from the citation string $pmidPattern = '/pmid:?\\s*(\\d+)/i'; if (PKPString::regexp_match_get($pmidPattern, $citationString, $matches)) { $metadata['pub-id[@pub-id-type="pmid"]'] = $matches[1]; $citationString = PKPString::regexp_replace($pmidPattern, '', $citationString); } // Parse out an embedded DOI and remove it from the citation string $doiPattern = '/doi:?\\s*(\\S+)/i'; if (PKPString::regexp_match_get($doiPattern, $citationString, $matches)) { $metadata['pub-id[@pub-id-type="doi"]'] = $matches[1]; $citationString = PKPString::regexp_replace($doiPattern, '', $citationString); } // Parse out the access date if we have one and remove it from the citation string $accessDatePattern = '/accessed:?\\s*([\\s\\w]+)/i'; if (PKPString::regexp_match_get($accessDatePattern, $citationString, $matches)) { $metadata['access-date'] = $matches[1]; $citationString = PKPString::regexp_replace($accessDatePattern, '', $citationString); } // Clean out square brackets $citationString = PKPString::regexp_replace('/\\[(\\s*(pubmed|medline|full text)\\s*)*]/i', '', $citationString); // Book citation $unparsedTail = ''; if (PKPString::regexp_match_get("/\\s*(?P<authors>[^\\.]+)\\.\\s*(?P<source>.*?)\\s*(?P<publisherLoc>[^\\.]*):\\s*(?P<publisherName>[^:]*?);\\s*(?P<date>\\d\\d\\d\\d.*?)(?P<tail>.*)/", $citationString, $matches)) { $metadata['[@publication-type]'] = NLM30_PUBLICATION_TYPE_BOOK; $metadata['author'] = $matches['authors']; $metadata['source'] = $matches['source']; $metadata['publisher-loc'] = $matches['publisherLoc']; $metadata['publisher-name'] = $matches['publisherName']; $metadata['date'] = $matches['date']; $unparsedTail = $matches['tail']; // Journal citation } elseif (PKPString::regexp_match_get("/\\s*(?P<authors>[^\\.]+)\\.\\s*(?P<titleSource>.*)\\s*(?P<date>\\d\\d\\d\\d.*?);(?P<volumeAndIssue>[^:]+):(?P<tail>.*)/", $citationString, $matches)) { $metadata['[@publication-type]'] = NLM30_PUBLICATION_TYPE_JOURNAL; $metadata['author'] = $matches['authors']; $titleSource = array(); if (PKPString::regexp_match_get("/(.*[\\.!\\?])(.*)/", trim($matches['titleSource'], " ."), $titleSource)) { $metadata['article-title'] = $titleSource[1]; $metadata['source'] = $titleSource[2]; } $metadata['date'] = $matches['date']; $volumeAndIssue = array(); if (PKPString::regexp_match_get("/([^\\(]+)(\\(([^\\)]+)\\))?/", $matches['volumeAndIssue'], $volumeAndIssue)) { $metadata['volume'] = $volumeAndIssue[1]; if (isset($volumeAndIssue[3])) { $metadata['issue'] = $volumeAndIssue[3]; } } $unparsedTail = $matches['tail']; // Web citation with or without authors } elseif (PKPString::regexp_match_get("/\\s*(?P<citationSource>.*?)\\s*URL:\\s*(?P<tail>.*)/", $citationString, $matches)) { $unparsedTail = $matches['tail']; $citationParts = explode(".", trim($matches['citationSource'], '. ')); switch (count($citationParts)) { case 0: // This case should never occur... assert(false); break; case 1: // Assume this to be a title for the web site. $metadata['article-title'] = $citationParts[0]; break; case 2: // Assume the format: Authors. Title. $metadata['author'] = $citationParts[0]; $metadata['article-title'] = $citationParts[1]; break; default: // Assume the format: Authors. Article Title. Journal Title. $metadata['author'] = array_shift($citationParts); // The last part is assumed to be the journal title $metadata['source'] = array_pop($citationParts); // Everything in between is assumed to belong to the article title $metadata['article-title'] = implode('.', $citationParts); } } // TODO: Handle in-ref titles, eg. with editor lists // Extract page numbers if possible $pagesPattern = "/^[:p\\.\\s]*(?P<fpage>[Ee]?\\d+)(-(?P<lpage>\\d+))?/"; if (!empty($unparsedTail) && PKPString::regexp_match_get($pagesPattern, $unparsedTail, $matches)) { $metadata['fpage'] = $matches['fpage']; if (isset($matches['lpage'])) { $metadata['lpage'] = $matches['lpage']; } // Add the unparsed part of the citation string as a comment so it doesn't get lost. $comment = PKPString::trimPunctuation(PKPString::regexp_replace($pagesPattern, '', $unparsedTail)); if (!empty($comment)) { $metadata['comment'] = $comment; } } // Make the meta-data fully NLM citation compliant $metadata =& $this->postProcessMetadataArray($metadata); // Create the NLM citation description return $this->getNlm30CitationDescriptionFromMetadataArray($metadata); }
/** * Handle fetch requests for this plugin. */ function fetch($args, $request) { if (!$this->getEnabled()) { return false; } $scheme = array_shift($args); switch ($scheme) { case 'doi': $doi = implode('/', $args); $journal = $request->getJournal(); $publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO'); /* @var $publishedArticleDao PublishedArticleDAO */ $article = $publishedArticleDao->getPublishedArticleByPubId('doi', $doi, $journal ? $journal->getId() : null); if (is_a($article, 'PublishedArticle')) { $request->redirect(null, 'article', 'view', $article->getBestArticleId()); } break; case 'vnp': // Volume, number, page // Volume, number, page case 'ynp': // Volume, number, year, page // This can only be used from within a journal context $journal = $request->getJournal(); if (!$journal) { break; } if ($scheme == 'vnp') { $volume = (int) array_shift($args); $year = null; } elseif ($scheme == 'ynp') { $year = (int) array_shift($args); $volume = null; } else { return; // Suppress scrutinizer warn } $number = array_shift($args); $page = (int) array_shift($args); $issueDao = DAORegistry::getDAO('IssueDAO'); $issues = $issueDao->getPublishedIssuesByNumber($journal->getId(), $volume, $number, $year); // Ensure only one issue matched, and fetch it. $issue = $issues->next(); if (!$issue || $issues->next()) { break; } unset($issues); $publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO'); $articles =& $publishedArticleDao->getPublishedArticles($issue->getId()); foreach ($articles as $article) { // Look for the correct page in the list of articles. $matches = null; if (PKPString::regexp_match_get('/^[Pp][Pp]?[.]?[ ]?(\\d+)$/', $article->getPages(), $matches)) { $matchedPage = $matches[1]; if ($page == $matchedPage) { $request->redirect(null, 'article', 'view', $article->getBestArticleId()); } } if (PKPString::regexp_match_get('/^[Pp][Pp]?[.]?[ ]?(\\d+)[ ]?-[ ]?([Pp][Pp]?[.]?[ ]?)?(\\d+)$/', $article->getPages(), $matches)) { $matchedPageFrom = $matches[1]; $matchedPageTo = $matches[3]; if ($page >= $matchedPageFrom && ($page < $matchedPageTo || $page == $matchedPageTo && ($matchedPageFrom = $matchedPageTo))) { $request->redirect(null, 'article', 'view', $article->getBestArticleId()); } } unset($article); } } // Failure. header("HTTP/1.0 500 Internal Server Error"); $templateMgr = TemplateManager::getManager($request); AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON); $templateMgr->assign('message', 'plugins.gateways.resolver.errors.errorMessage'); $templateMgr->display('frontend/pages/message.tpl'); exit; }
/** * Fills the given citation object with * meta-data retrieved from PubMed. * @param $pmid string * @return MetadataDescription */ function &_lookup($pmid) { $nullVar = null; // Use eFetch to get XML metadata for the given PMID $lookupParams = array('db' => 'pubmed', 'mode' => 'xml', 'tool' => 'pkp-wal', 'id' => $pmid); if (!is_null($this->getEmail())) { $lookupParams['email'] = $this->getEmail(); } // Call the eFetch URL and get an XML result if (is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_EFETCH, $lookupParams))) { return $nullVar; } $articleTitleNodes = $resultDOM->getElementsByTagName('ArticleTitle'); $articleTitleFirstNode = $articleTitleNodes->item(0); $medlineTaNodes = $resultDOM->getElementsByTagName('MedlineTA'); $medlineTaFirstNode = $medlineTaNodes->item(0); $metadata = array('pub-id[@pub-id-type="pmid"]' => $pmid, 'article-title' => $articleTitleFirstNode->textContent, 'source' => $medlineTaFirstNode->textContent); $volumeNodes = $resultDOM->getElementsByTagName('Volume'); $issueNodes = $resultDOM->getElementsByTagName('Issue'); if ($volumeNodes->length > 0) { $volumeFirstNode = $volumeNodes->item(0); } $metadata['volume'] = $volumeFirstNode->textContent; if ($issueNodes->length > 0) { $issueFirstNode = $issueNodes->item(0); } $metadata['issue'] = $issueFirstNode->textContent; // Get list of author full names foreach ($resultDOM->getElementsByTagName("Author") as $authorNode) { if (!isset($metadata['person-group[@person-group-type="author"]'])) { $metadata['person-group[@person-group-type="author"]'] = array(); } // Instantiate an NLM name description $authorDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', ASSOC_TYPE_AUTHOR); // Surname $lastNameNodes = $authorNode->getElementsByTagName('LastName'); $lastNameFirstNode = $lastNameNodes->item(0); $authorDescription->addStatement('surname', $lastNameFirstNode->textContent); // Given names $givenNamesString = ''; $firstNameNodes = $authorNode->getElementsByTagName('FirstName'); if ($firstNameNodes->length > 0) { $firstNameFirstNode = $firstNameNodes->item(0); $givenNamesString = $firstNameFirstNode->textContent; } else { $foreNameNodes = $authorNode->getElementsByTagName('ForeName'); if ($foreNameNodes->length > 0) { $foreNameFirstNode = $foreNameNodes->item(0); $givenNamesString = $foreNameFirstNode->textContent; } } if (!empty($givenNamesString)) { foreach (explode(' ', $givenNamesString) as $givenName) { $authorDescription->addStatement('given-names', PKPString::trimPunctuation($givenName)); } } // Suffix $suffixNodes = $authorNode->getElementsByTagName('Suffix'); if ($suffixNodes->length > 0) { $suffixFirstNode = $suffixNodes->item(0); $authorDescription->addStatement('suffix', $suffixFirstNode->textContent); } // Include collective names // FIXME: This corresponds to an NLM-citation <collab> tag and should be part of the Metadata implementation /*if ($resultDOM->getElementsByTagName("CollectiveName")->length > 0 && $authorNode->getElementsByTagName("CollectiveName")->item(0)->textContent != '') { }*/ $metadata['person-group[@person-group-type="author"]'][] =& $authorDescription; unset($authorDescription); } // Extract pagination $medlinePgnNodes = $resultDOM->getElementsByTagName('MedlinePgn'); $medlinePgnFirstNode = $medlinePgnNodes->item(0); if (PKPString::regexp_match_get("/^[:p\\.\\s]*(?P<fpage>[Ee]?\\d+)(-(?P<lpage>\\d+))?/", $medlinePgnFirstNode->textContent, $pages)) { $fPage = (int) $pages['fpage']; $metadata['fpage'] = $fPage; if (!empty($pages['lpage'])) { $lPage = (int) $pages['lpage']; // Deal with shortcuts like '382-7' if ($lPage < $fPage) { $lPage = (int) (PKPString::substr($pages['fpage'], 0, -PKPString::strlen($pages['lpage'])) . $pages['lpage']); } $metadata['lpage'] = $lPage; } } // Get publication date (can be in several places in PubMed). $dateNode = null; $articleDateNodes = $resultDOM->getElementsByTagName('ArticleDate'); if ($articleDateNodes->length > 0) { $dateNode = $articleDateNodes->item(0); } else { $pubDateNodes = $resultDOM->getElementsByTagName('PubDate'); if ($pubDateNodes->length > 0) { $dateNode = $pubDateNodes->item(0); } } // Retrieve the data parts and assemble date. if (!is_null($dateNode)) { $publicationDate = ''; $requiresNormalization = false; foreach (array('Year' => 4, 'Month' => 2, 'Day' => 2) as $dateElement => $padding) { $dateElementNodes = $dateNode->getElementsByTagName($dateElement); if ($dateElementNodes->length > 0) { if (!empty($publicationDate)) { $publicationDate .= '-'; } $dateElementFirstNode = $dateElementNodes->item(0); $datePart = str_pad($dateElementFirstNode->textContent, $padding, '0', STR_PAD_LEFT); if (!is_numeric($datePart)) { $requiresNormalization = true; } $publicationDate .= $datePart; } else { break; } } // Normalize the date to NLM standard if necessary. if ($requiresNormalization) { $dateFilter = new DateStringNormalizerFilter(); $publicationDate = $dateFilter->execute($publicationDate); } if (!empty($publicationDate)) { $metadata['date'] = $publicationDate; } } // Get publication type $publicationTypeNodes = $resultDOM->getElementsByTagName('PublicationType'); if ($publicationTypeNodes->length > 0) { foreach ($publicationTypeNodes as $publicationType) { // The vast majority of items on PubMed are articles so catch these... if (PKPString::strpos(PKPString::strtolower($publicationType->textContent), 'article') !== false) { $metadata['[@publication-type]'] = NLM30_PUBLICATION_TYPE_JOURNAL; break; } } } // Get DOI if it exists $articleIdNodes = $resultDOM->getElementsByTagName('ArticleId'); foreach ($articleIdNodes as $idNode) { if ($idNode->getAttribute('IdType') == 'doi') { $metadata['pub-id[@pub-id-type="doi"]'] = $idNode->textContent; } } // Use eLink utility to find fulltext links $lookupParams = array('dbfrom' => 'pubmed', 'cmd' => 'llinks', 'tool' => 'pkp-wal', 'id' => $pmid); if (!is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_ELINK, $lookupParams))) { // Get a list of possible links foreach ($resultDOM->getElementsByTagName("ObjUrl") as $linkOut) { $attributes = ''; foreach ($linkOut->getElementsByTagName("Attribute") as $attribute) { $attributes .= PKPString::strtolower($attribute->textContent) . ' / '; } // Only add links to open access resources if (PKPString::strpos($attributes, "subscription") === false && PKPString::strpos($attributes, "membership") === false && PKPString::strpos($attributes, "fee") === false && $attributes != "") { $urlNodes = $linkOut->getElementsByTagName('Url'); $urlFirstNode = $urlNodes->item(0); $links[] = $urlFirstNode->textContent; } } // Take the first link if we have any left (presumably pubmed returns them in preferential order) if (isset($links[0])) { $metadata['uri'] = $links[0]; } } return $this->getNlm30CitationDescriptionFromMetadataArray($metadata); }
/** * Convert a Windows path to a cygwin path. * @param string $path Windows path * @return string Cygwin path. */ function cygwinConversion($path) { $path = str_replace('\\', '/', $path); $matches = null; PKPString::regexp_match_get('/^([A-Z]):/i', $path, $matches); if (isset($matches[1]) && strlen($matches[1]) === 1) { $path = PKPString::regexp_replace('/^[A-Z]:/i', '/cygdrive/' . strtolower($matches[1]), $path); } return $path; }