static public regexp_replace ( $pattern, $replacement, $subject, $limit ) : mixed | ||
$pattern | string Regular expression | |
$replacement | string String to replace matches in $subject with | |
$subject | string String to apply regular expression to | |
$limit | int Number of replacements to perform, maximum, or -1 for no limit. | |
return | mixed |
/** * Display user login form. * Redirect to user index page if user is already validated. */ function index($args, $request) { $this->setupTemplate($request); if (Validation::isLoggedIn()) { $this->sendHome($request); } if (Config::getVar('security', 'force_login_ssl') && $request->getProtocol() != 'https') { // Force SSL connections for login $request->redirectSSL(); } $sessionManager = SessionManager::getManager(); $session = $sessionManager->getUserSession(); $templateMgr = TemplateManager::getManager($request); // If the user wasn't expecting a login page, i.e. if they're new to the // site and want to submit a paper, it helps to explain why they need to // register. if ($request->getUserVar('loginMessage')) { $templateMgr->assign('loginMessage', $request->getUserVar('loginMessage')); } $templateMgr->assign('username', $session->getSessionVar('username')); $templateMgr->assign('remember', $request->getUserVar('remember')); $templateMgr->assign('source', $request->getUserVar('source')); $templateMgr->assign('showRemember', Config::getVar('general', 'session_lifetime') > 0); // For force_login_ssl with base_url[...]: make sure SSL used for login form $loginUrl = $this->_getLoginUrl($request); if (Config::getVar('security', 'force_login_ssl')) { $loginUrl = PKPString::regexp_replace('/^http:/', 'https:', $loginUrl); } $templateMgr->assign('loginUrl', $loginUrl); $templateMgr->display('frontend/pages/userLogin.tpl'); }
/** * @copydoc Filter::process() * @param $citationString string * @return MetadataDescription */ function &process(&$input) { $nullVar = null; $queryParams = array('demo' => '3', 'textlines' => $input); // Parscit web form - the result is (mal-formed) HTML if (is_null($result = $this->callWebService(PARSCIT_WEBSERVICE, $queryParams, XSL_TRANSFORMER_DOCTYPE_STRING, 'POST'))) { return $nullVar; } $result = html_entity_decode($result); // Detect errors. if (!PKPString::regexp_match('/.*<algorithm[^>]+>.*<\\/algorithm>.*/s', $result)) { $translationParams = array('filterName' => $this->getDisplayName()); $this->addError(__('submission.citations.filter.webserviceResultTransformationError', $translationParams)); return $nullVar; } // Screen-scrape the tagged portion and turn it into XML. $xmlResult = PKPString::regexp_replace('/.*<algorithm[^>]+>(.*)<\\/algorithm>.*/s', '\\1', $result); $xmlResult = PKPString::regexp_replace('/&/', '&', $xmlResult); // Transform the result into an array of meta-data. if (is_null($metadata = $this->transformWebServiceResults($xmlResult, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'parscit.xsl'))) { return $nullVar; } // Extract a publisher from the place string if possible. $metadata =& $this->fixPublisherNameAndLocation($metadata); return $this->getNlm30CitationDescriptionFromMetadataArray($metadata); }
/** * @copydoc Filter::process() * @param $isbn string * @return MetadataDescription a looked up citation description * or null if the filter fails */ function &process($isbn) { $nullVar = null; // Instantiate the web service request $lookupParams = array('access_key' => $this->getApiKey(), 'index1' => 'isbn', 'results' => 'details,authors', 'value1' => $isbn); // Call the web service if (is_null($resultDOM =& $this->callWebService(ISBNDB_WEBSERVICE_URL, $lookupParams))) { return $nullVar; } // Transform and pre-process the web service result if (is_null($metadata =& $this->transformWebServiceResults($resultDOM, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'isbndb.xsl'))) { return $nullVar; } // Extract place and publisher from the combined entry. $metadata['publisher-loc'] = PKPString::trimPunctuation(PKPString::regexp_replace('/^(.+):.*/', '\\1', $metadata['place-publisher'])); $metadata['publisher-name'] = PKPString::trimPunctuation(PKPString::regexp_replace('/.*:([^,]+),?.*/', '\\1', $metadata['place-publisher'])); unset($metadata['place-publisher']); // Reformat the publication date $metadata['date'] = PKPString::regexp_replace('/^[^\\d{4}]+(\\d{4}).*/', '\\1', $metadata['date']); // Clean non-numerics from ISBN $metadata['isbn'] = PKPString::regexp_replace('/[^\\dX]*/', '', $isbn); // Set the publicationType $metadata['[@publication-type]'] = NLM30_PUBLICATION_TYPE_BOOK; return $this->getNlm30CitationDescriptionFromMetadataArray($metadata); }
/** * Split a string into a clean array of keywords * @param $text string * @param $allowWildcards boolean * @return array of keywords */ static function filterKeywords($text, $allowWildcards = false) { $minLength = Config::getVar('search', 'min_word_length'); $stopwords = self::_loadStopwords(); // Join multiple lines into a single string if (is_array($text)) { $text = join("\n", $text); } $cleanText = Core::cleanVar($text); // Remove punctuation $cleanText = PKPString::regexp_replace('/[!"\\#\\$%\'\\(\\)\\.\\?@\\[\\]\\^`\\{\\}~]/', '', $cleanText); $cleanText = PKPString::regexp_replace('/[\\+,:;&\\/<=>\\|\\\\]/', ' ', $cleanText); $cleanText = PKPString::regexp_replace('/[\\*]/', $allowWildcards ? '%' : ' ', $cleanText); $cleanText = PKPString::strtolower($cleanText); // Split into words $words = PKPString::regexp_split('/\\s+/', $cleanText); // FIXME Do not perform further filtering for some fields, e.g., author names? // Remove stopwords $keywords = array(); foreach ($words as $k) { if (!isset($stopwords[$k]) && PKPString::strlen($k) >= $minLength && !is_numeric($k)) { $keywords[] = PKPString::substr($k, 0, SEARCH_KEYWORD_MAX_LENGTH); } } return $keywords; }
/** * Format XML for single DC element. * @param $propertyName string * @param $value array * @param $multilingual boolean optional */ function formatElement($propertyName, $values, $multilingual = false) { if (!is_array($values)) { $values = array($values); } // Translate the property name to XML syntax. $openingElement = str_replace(array('[@', ']'), array(' ', ''), $propertyName); $closingElement = PKPString::regexp_replace('/\\[@.*/', '', $propertyName); // Create the actual XML entry. $response = ''; foreach ($values as $key => $value) { if ($multilingual) { $key = str_replace('_', '-', $key); assert(is_array($value)); foreach ($value as $subValue) { if ($key == METADATA_DESCRIPTION_UNKNOWN_LOCALE) { $response .= "\t<{$openingElement}>" . OAIUtils::prepOutput($subValue) . "</{$closingElement}>\n"; } else { $response .= "\t<{$openingElement} xml:lang=\"{$key}\">" . OAIUtils::prepOutput($subValue) . "</{$closingElement}>\n"; } } } else { assert(is_scalar($value)); $response .= "\t<{$openingElement}>" . OAIUtils::prepOutput($value) . "</{$closingElement}>\n"; } } return $response; }
/** * @see Filter::process() * @param $input string * @return mixed array */ function &process(&$input) { // The default implementation assumes that raw citations are // separated with line endings. // 1) Remove empty lines and normalize line endings. $input = PKPString::regexp_replace('/[\\r\\n]+/s', "\n", $input); // 2) Remove trailing/leading line breaks. $input = trim($input, "\n"); // 3) Break up at line endings. if (empty($input)) { $citations = array(); } else { $citations = explode("\n", $input); } // 4) Remove numbers from the beginning of each citation. foreach ($citations as $index => $citation) { $citations[$index] = PKPString::regexp_replace('/^\\s*[\\[#]?[0-9]+[.)\\]]?\\s*/', '', $citation); } return $citations; }
/** * Display user login form. * Redirect to user index page if user is already validated. */ function index($args, $request) { $this->setupTemplate($request); if (Validation::isLoggedIn()) { $this->sendHome($request); } if (Config::getVar('security', 'force_login_ssl') && $request->getProtocol() != 'https') { // Force SSL connections for login $request->redirectSSL(); } $sessionManager = SessionManager::getManager(); $session = $sessionManager->getUserSession(); $templateMgr = TemplateManager::getManager($request); $templateMgr->assign(array('loginMessage' => $request->getUserVar('loginMessage'), 'username' => $session->getSessionVar('username'), 'remember' => $request->getUserVar('remember'), 'source' => $request->getUserVar('source'), 'showRemember' => Config::getVar('general', 'session_lifetime') > 0)); // For force_login_ssl with base_url[...]: make sure SSL used for login form $loginUrl = $this->_getLoginUrl($request); if (Config::getVar('security', 'force_login_ssl')) { $loginUrl = PKPString::regexp_replace('/^http:/', 'https:', $loginUrl); } $templateMgr->assign('loginUrl', $loginUrl); $templateMgr->display('frontend/pages/userLogin.tpl'); }
/** * @see Form::fetch() */ function fetch($request) { $templateMgr = TemplateManager::getManager($request); // The form description depends on the current state // of the selection process: do we select a filter template // or configure the settings of a selected template? $filter =& $this->getFilter(); if (is_a($filter, 'Filter')) { $displayName = $filter->getDisplayName(); $templateMgr->assign('filterDisplayName', $displayName); if (count($filter->getSettings())) { // We need a filter specific translation key so that we // can explain the filter's configuration options. // We use the display name to generate such a key as this // is probably easiest for translators to understand. // This also has the advantage that we can explain // composite filters individually. // FIXME: When we start to translate display names then // please make sure that you use the en-US key for this // processing. Alternatively we might want to introduce // an alphanumeric "filter key" to the filters table. $filterKey = PKPString::regexp_replace('/[^a-zA-Z0-9]/', '', $displayName); $filterKey = strtolower(substr($filterKey, 0, 1)) . substr($filterKey, 1); $formDescriptionKey = $this->getDescription() . '.' . $filterKey; } else { $formDescriptionKey = $this->getDescription() . 'Confirm'; } } else { $templateMgr->assign('filterDisplayName', ''); $formDescriptionKey = $this->getDescription() . 'Template'; } $templateMgr->assign('formTitle', $this->getTitle()); $templateMgr->assign('formDescription', $formDescriptionKey); return parent::fetch($request); }
/** * 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; }
/** * Create and return an issue node, either as work or as manifestation. * @param $doc DOMDocument * @param $pubObject Issue * @return DOMElement */ function createIssueNode($doc, $pubObject) { $deployment = $this->getDeployment(); $context = $deployment->getContext(); $cache = $deployment->getCache(); $plugin = $deployment->getPlugin(); $request = Application::getRequest(); $router = $request->getRouter(); $issueNodeName = $this->isWork($context, $plugin) ? 'DOISerialIssueWork' : 'DOISerialIssueVersion'; $issueNode = $doc->createElementNS($deployment->getNamespace(), $issueNodeName); // Notification type (mandatory) $doi = $pubObject->getStoredPubId('doi'); $registeredDoi = $pubObject->getData('medra::registeredDoi'); assert(empty($registeredDoi) || $registeredDoi == $doi); $notificationType = empty($registeredDoi) ? O4DOI_NOTIFICATION_TYPE_NEW : O4DOI_NOTIFICATION_TYPE_UPDATE; $issueNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'NotificationType', $notificationType)); // DOI (mandatory) $issueNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'DOI', htmlspecialchars($doi, ENT_COMPAT, 'UTF-8'))); // DOI URL (mandatory) $url = $router->url($request, $context->getPath(), 'article', 'view', $pubObject->getBestIssueId(), null, null, true); if ($plugin->isTestMode($context)) { // Change server domain for testing. $url = PKPString::regexp_replace('#://[^\\s]+/index.php#', '://example.com/index.php', $url); } $issueNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'DOIWebsiteLink', $url)); // DOI strucural type $structuralType = $this->isWork($context, $plugin) ? 'Abstraction' : 'DigitalFixation'; $issueNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'DOIStructuralType', $structuralType)); // Registrant (mandatory) $issueNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'RegistrantName', htmlspecialchars($plugin->getSetting($context->getId(), 'registrantName'), ENT_COMPAT, 'UTF-8'))); // Registration authority (mandatory) $issueNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'RegistrationAuthority', 'mEDRA')); // Work/ProductIdentifier - proprietary ID $pubObjectProprietaryId = $context->getId() . '-' . $pubObject->getId(); $workOrProduct = $this->isWork($context, $plugin) ? 'Work' : 'Product'; $issueNode->appendChild($this->createIdentifierNode($doc, $workOrProduct, O4DOI_ID_TYPE_PROPRIETARY, $pubObjectProprietaryId)); // Issue/journal and object locale precedence. $journalLocalePrecedence = $objectLocalePrecedence = $this->getObjectLocalePrecedence($context, null, null); // Serial Publication (mandatory) $issueNode->appendChild($this->createSerialPublicationNode($doc, $journalLocalePrecedence, O4DOI_EPUB_FORMAT_HTML)); // Journal Issue (mandatory) $issueId = $pubObject->getId(); if (!$cache->isCached('issues', $issueId)) { $cache->add($pubObject, null); } $issueNode->appendChild($this->createJournalIssueNode($doc, $pubObject, $journalLocalePrecedence)); // Object Description 'OtherText' $descriptions = $this->getTranslationsByPrecedence($pubObject->getDescription(null), $objectLocalePrecedence); foreach ($descriptions as $locale => $description) { $issueNode->appendChild($this->createOtherTextNode($doc, $locale, $description)); } // 4) issue (as-work and as-manifestation): // related works: // - includes articles-as-work $articleDao = DAORegistry::getDAO('PublishedArticleDAO'); /* @var $articleDao PublishedArticleDAO */ $articlesByIssue = $articleDao->getPublishedArticles($issueId); $galleyDao = DAORegistry::getDAO('ArticleGalleyDAO'); /* @var $galleyDao ArticleGalleyDAO */ $galleysByIssue = array(); foreach ($articlesByIssue as $relatedArticle) { $articleProprietaryId = $context->getId() . '-' . $pubObject->getId() . '-' . $relatedArticle->getId(); $relatedArticleIds = array(O4DOI_ID_TYPE_PROPRIETARY => $articleProprietaryId); $doi = $relatedArticle->getStoredPubId('doi'); if (!empty($doi)) { $relatedArticleIds[O4DOI_ID_TYPE_DOI] = $doi; } $issueNode->appendChild($this->createRelatedNode($doc, 'Work', O4DOI_RELATION_INCLUDES, $relatedArticleIds)); // Collect galleys by issue $galleysByArticle = $galleyDao->getBySubmissionId($relatedArticle->getId())->toArray(); $galleysByIssue = array_merge($galleysByIssue, $galleysByArticle); unset($relatedArticle, $relatedArticleIds); } // related products: // - includes articles-as-manifestation foreach ($galleysByIssue as $relatedGalley) { $galleyProprietaryId = $context->getId() . '-' . $pubObject->getId() . '-' . $relatedGalley->getSubmissionId() . '-g' . $relatedGalley->getId(); $relatedGalleyIds = array(O4DOI_ID_TYPE_PROPRIETARY => $galleyProprietaryId); $doi = $relatedGalley->getStoredPubId('doi'); if (!empty($doi)) { $relatedGalleyIds[O4DOI_ID_TYPE_DOI] = $doi; } $issueNode->appendChild($this->createRelatedNode($doc, 'Product', O4DOI_RELATION_INCLUDES, $relatedGalleyIds)); unset($relatedGalley, $relatedGalleyIds); } return $issueNode; }
/** * Mark an object as "registered" * by saving it's DOI to the object's * "registeredDoi" setting. * We prefix the setting with the plug-in's * id so that we do not get name clashes * when several DOI registration plug-ins * are active at the same time. * @parem $request Request * @param $object Issue|PublishedArticle|ArticleGalley * @parem $testPrefix string */ function markRegistered($request, $object, $testPrefix) { $registeredDoi = $object->getPubId('doi'); assert(!empty($registeredDoi)); if ($this->isTestMode($request)) { $registeredDoi = PKPString::regexp_replace('#^[^/]+/#', $testPrefix . '/', $registeredDoi); } $this->saveRegisteredDoi($object, $registeredDoi); }
/** * Retrieve the DOI of an object. The DOI will be * patched if we are in test mode. * @param $object Issue|PublishedArticle|ArticleGalley * @return string */ function _getDoi(&$object) { $doi = $object->getPubId('doi'); if (!empty($doi) && $this->getTestMode()) { $doi = PKPString::regexp_replace('#^[^/]+/#', MEDRA_WS_TESTPREFIX . '/', $doi); } return $doi; }
/** * Strip SQL comments from SQL string. * @param $sql string */ function stripComments(&$sql) { $sql = trim(PKPString::regexp_replace(sprintf('/^\\s*%s(.*)$/m', $this->commentDelim), '', $sql)); }
/** * Translate query keywords. * @param $searchPhrase string * @return The translated search phrase. */ function _translateSearchPhrase($searchPhrase, $backwards = false) { static $queryKeywords; if (is_null($queryKeywords)) { // Query keywords. $queryKeywords = array(PKPString::strtoupper(__('search.operator.not')) => 'NOT', PKPString::strtoupper(__('search.operator.and')) => 'AND', PKPString::strtoupper(__('search.operator.or')) => 'OR'); } if ($backwards) { $translationTable = array_flip($queryKeywords); } else { $translationTable = $queryKeywords; } // Translate the search phrase. foreach ($translationTable as $translateFrom => $translateTo) { $searchPhrase = PKPString::regexp_replace("/(^|\\s){$translateFrom}(\\s|\$)/i", "\\1{$translateTo}\\2", $searchPhrase); } return $searchPhrase; }
/** * Suggest a username given the first and last names. * @return string */ static function suggestUsername($firstName, $lastName) { $initial = PKPString::substr($firstName, 0, 1); $suggestion = PKPString::regexp_replace('/[^a-zA-Z0-9_-]/', '', PKPString::strtolower($initial . $lastName)); $userDao = DAORegistry::getDAO('UserDAO'); for ($i = ''; $userDao->userExistsByUsername($suggestion . $i); $i++) { } return $suggestion . $i; }
/** * @see PubIdPlugin::getPubId() */ function getPubId($pubObject, $preview = false) { $urn = $pubObject->getStoredPubId($this->getPubIdType()); if (!$urn) { // Determine the type of the publishing object $pubObjectType = $this->getPubObjectType($pubObject); // Initialize variables for publication objects $issue = $pubObjectType == 'Issue' ? $pubObject : null; $article = $pubObjectType == 'Article' ? $pubObject : null; $galley = $pubObjectType == 'Galley' ? $pubObject : null; // Get the journal id of the object if (in_array($pubObjectType, array('Issue', 'Article'))) { $journalId = $pubObject->getJournalId(); } else { // Retrieve the published article assert(is_a($pubObject, 'SubmissionFile')); $articleDao = DAORegistry::getDAO('ArticleDAO'); $article = $articleDao->getById($pubObject->getArticleId(), null, true); if (!$article) { return null; } // Now we can identify the journal $journalId = $article->getJournalId(); } // get the journal $journal = $this->getJournal($journalId); if (!$journal) { return null; } $journalId = $journal->getId(); // Check whether URNs are enabled for the given object type $urnEnabled = $this->getSetting($journalId, "enable{$pubObjectType}URN") == '1'; if (!$urnEnabled) { return null; } // Retrieve the issue if (!is_a($pubObject, 'Issue')) { assert(!is_null($article)); $issueDao = DAORegistry::getDAO('IssueDAO'); $issue = $issueDao->getIssueByArticleId($article->getId(), $journal->getId()); } // Retrieve the URN prefix $urnPrefix = $this->getSetting($journal->getId(), 'urnPrefix'); if (empty($urnPrefix)) { return null; } // Generate the URN suffix $urnSuffixSetting = $this->getSetting($journal->getId(), 'urnSuffix'); switch ($urnSuffixSetting) { case 'publisherId': $urnSuffix = (string) call_user_func_array(array($pubObject, "getBest{$pubObjectType}Id"), array(&$journal)); // When the suffix equals the object's ID then // require an object-specific prefix to be sure that the suffix is unique if ($pubObjectType != 'Article' && $urnSuffix === (string) $pubObject->getId()) { $urnSuffix = strtolower_codesafe($pubObjectType[0]) . $urnSuffix; } if (!empty($urnSuffix)) { $urn = $urnPrefix . $urnSuffix; if ($this->getSetting($journal->getId(), 'checkNo')) { $urn .= $this->_calculateCheckNo($urn); } } break; case 'customIdentifier': $urnSuffix = $pubObject->getData('urnSuffix'); if (!empty($urnSuffix)) { $urn = $urnPrefix . $urnSuffix; } break; case 'pattern': $urnSuffix = $this->getSetting($journal->getId(), "urn{$pubObjectType}SuffixPattern"); // %j - journal initials $urnSuffix = PKPString::regexp_replace('/%j/', PKPString::strtolower($journal->getAcronym($journal->getPrimaryLocale())), $urnSuffix); // %x - custom identifier if ($pubObject->getStoredPubId('publisher-id')) { $urnSuffix = PKPString::regexp_replace('/%x/', $pubObject->getStoredPubId('publisher-id'), $urnSuffix); } if ($issue) { // %v - volume number $urnSuffix = PKPString::regexp_replace('/%v/', $issue->getVolume(), $urnSuffix); // %i - issue number $urnSuffix = PKPString::regexp_replace('/%i/', $issue->getNumber(), $urnSuffix); // %Y - year $urnSuffix = PKPString::regexp_replace('/%Y/', $issue->getYear(), $urnSuffix); } if ($article) { // %a - article id $urnSuffix = PKPString::regexp_replace('/%a/', $article->getId(), $urnSuffix); // %p - page number if ($article->getPages()) { $urnSuffix = PKPString::regexp_replace('/%p/', $article->getPages(), $urnSuffix); } } if ($galley) { // %g - galley id $urnSuffix = PKPString::regexp_replace('/%g/', $galley->getId(), $urnSuffix); } if (!empty($urnSuffix)) { $urn = $urnPrefix . $urnSuffix; if ($this->getSetting($journal->getId(), 'checkNo')) { $urn .= $this->_calculateCheckNo($urn); } } break; default: $urnSuffix = PKPString::strtolower($journal->getAcronym($journal->getPrimaryLocale())); if ($issue) { $urnSuffix .= '.v' . $issue->getVolume() . 'i' . $issue->getNumber(); } else { $urnSuffix .= '.v%vi%i'; } if ($article) { $urnSuffix .= '.' . $article->getId(); } if ($galley) { $urnSuffix .= '.g' . $galley->getId(); } $urn = $urnPrefix . $urnSuffix; if ($this->getSetting($journal->getId(), 'checkNo')) { $urn .= $this->_calculateCheckNo($urn); } } if ($urn && !$preview) { $this->setStoredPubId($pubObject, $pubObjectType, $urn); } } return $urn; }
/** * Take an NLM preliminary meta-data array and fix publisher-loc * and publisher-name entries: * - If there is a location but no name then try to extract a * publisher name from the location string. * - Make sure that location and name are not the same. * - Copy institution to publisher if no publisher is set, * otherwise leave the institution. * @param $metadata array * @return array */ function &fixPublisherNameAndLocation(&$metadata) { if (isset($metadata['publisher-loc'])) { // Extract publisher-name from publisher-loc if we don't have a // publisher-name in the parsing result. if (empty($metadata['publisher-name'])) { $metadata['publisher-name'] = PKPString::regexp_replace('/.*:([^,]+),?.*/', '\\1', $metadata['publisher-loc']); } // Remove publisher-name from publisher-loc $metadata['publisher-loc'] = PKPString::regexp_replace('/^(.+):.*/', '\\1', $metadata['publisher-loc']); // Check that publisher-name and location are not the same if (!empty($metadata['publisher-name']) && $metadata['publisher-name'] == $metadata['publisher-loc']) { unset($metadata['publisher-name']); } } // Copy the institution property (if any) as the publisher-name if (isset($metadata['institution']) && (!isset($metadata['publisher-name']) || empty($metadata['publisher-name']))) { $metadata['publisher-name'] = $metadata['institution']; } // Clean the result foreach (array('publisher-name', 'publisher-loc') as $publisherProperty) { if (isset($metadata[$publisherProperty])) { $metadata[$publisherProperty] = PKPString::trimPunctuation($metadata[$publisherProperty]); } } return $metadata; }
/** * Take a citation string and clean/normalize it * @param $citationString string * @return string */ function _cleanCitationString($citationString) { // 1) If the string contains non-UTF8 characters, convert it to UTF-8 if (Config::getVar('i18n', 'charset_normalization') && !PKPString::utf8_compliant($citationString)) { $citationString = PKPString::utf8_normalize($citationString); } // 2) Strip slashes and whitespace $citationString = trim(stripslashes($citationString)); // 3) Normalize whitespace $citationString = PKPString::regexp_replace('/[\\s]+/', ' ', $citationString); return $citationString; }
/** * Sanitize a value to be used in a file path. * Removes any characters except alphanumeric characters, underscores, and dashes. * @param $var string * @return string */ static function cleanFileVar($var) { return PKPString::regexp_replace('/[^\\w\\-]/', '', $var); }
/** * Create an identifier element with the object's DOI. * @param $object Issue|PublishedArticle|ArticleGalley * @param $relationType string One of the DATACITE_RELTYPE_* constants. * @return XMLNode|DOMImplementation|null Can be null if the given ID Type * has not been assigned to the given object. */ function &_relatedIdentifierElement(&$object, $relationType) { $id = $object->getStoredPubId('doi'); if (empty($id)) { return $nullVar; $nullVar = null; } if ($this->getTestMode()) { $id = PKPString::regexp_replace('#^[^/]+/#', DATACITE_API_TESTPREFIX . '/', $id); } return $this->createElementWithText('relatedIdentifier', $id, array('relatedIdentifierType' => DATACITE_IDTYPE_DOI, 'relationType' => $relationType)); }
/** * Create a serial version node. * @param $doc DOMDocument * @param $issn string * @param $productForm One of the O4DOI_PRODUCT_FORM_* constants * @param $epubFormat O4DOI_EPUB_FORMAT_* * @return DOMElement */ function createSerialVersionNode($doc, $issn, $productForm, $epubFormat = null) { $deployment = $this->getDeployment(); $context = $deployment->getContext(); $serialVersionNode = $doc->createElementNS($deployment->getNamespace(), 'SerialVersion'); // Proprietary Journal Identifier if ($productForm == O4DOI_PRODUCT_FORM_ELECTRONIC) { $serialVersionNode->appendChild($this->createIdentifierNode($doc, 'Product', O4DOI_ID_TYPE_PROPRIETARY, $context->getId())); } // ISSN if (!empty($issn)) { $issn = PKPString::regexp_replace('/[^0-9]/', '', $issn); $serialVersionNode->appendChild($this->createIdentifierNode($doc, 'Product', O4DOI_ID_TYPE_ISSN, $issn)); } // Product Form $serialVersionNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'ProductForm', $productForm)); if ($productForm == O4DOI_PRODUCT_FORM_ELECTRONIC) { // ePublication Format if ($epubFormat) { $serialVersionNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'EpubFormat', $epubFormat)); } // ePublication Format Description $serialVersionNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'EpubFormatDescription', 'Open Journal Systems (OJS)')); } return $serialVersionNode; }
/** * @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); }
/** * Build the test file UI as understood by Selenium. * @param string $fileFormat The test file format, e.g. "pdf". * @return string */ private function _getTestFileUri($fileFormat) { $testFile = 'tests/functional/pages/editor/test-files/test-article.' . $fileFormat; self::assertTrue(file_exists($testFile)); $testFile = realpath($testFile); if (Core::isWindows()) { $testFile = str_replace(DIRECTORY_SEPARATOR, '/', $testFile); $testFile = PKPString::regexp_replace('%^[A-Z]:/%', '/', $testFile); } $testFile = 'file://' . $testFile; return $testFile; }
/** * Create and return the article (as work or as manifestation) node. * @param $doc DOMDocument * @param $pubObject PublishedArticle|ArticleGalley * @return DOMElement */ function createArticleNode($doc, $pubObject) { $deployment = $this->getDeployment(); $context = $deployment->getContext(); $cache = $deployment->getCache(); $plugin = $deployment->getPlugin(); $request = Application::getRequest(); $router = $request->getRouter(); assert(is_a($pubObject, 'PublishedArticle') && $this->isWork($context, $plugin) || is_a($pubObject, 'ArticleGalley') && !$this->isWork($context, $plugin)); if (is_a($pubObject, 'PublishedArticle')) { $galley = null; $article = $pubObject; if (!$cache->isCached('articles', $article->getId())) { $cache->add($article, null); } $articleNodeName = 'DOISerialArticleWork'; $workOrProduct = 'Work'; $epubFormat = O4DOI_EPUB_FORMAT_HTML; } else { $galley = $pubObject; $galleyFile = $galley->getFile(); if ($cache->isCached('articles', $galley->getSubmissionId())) { $article = $cache->get('articles', $galley->getSubmissionId()); } else { $publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO'); /* @var $publishedArticleDao PublishedArticleDAO */ $article = $publishedArticleDao->getPublishedArticleByArticleId($galley->getSubmissionId()); if ($article) { $cache->add($article, null); } } $articleNodeName = 'DOISerialArticleVersion'; $workOrProduct = 'Product'; $epubFormat = null; if ($galley->isPdfGalley()) { $epubFormat = O4DOI_EPUB_FORMAT_PDF; } else { if ($galley->getRemoteURL() || $galleyFile->getFileType() == 'text/html') { $epubFormat = O4DOI_EPUB_FORMAT_HTML; } } } $articleNode = $doc->createElementNS($deployment->getNamespace(), $articleNodeName); // Notification type (mandatory) $doi = $pubObject->getStoredPubId('doi'); $registeredDoi = $pubObject->getData('medra::registeredDoi'); assert(empty($registeredDoi) || $registeredDoi == $doi); $notificationType = empty($registeredDoi) ? O4DOI_NOTIFICATION_TYPE_NEW : O4DOI_NOTIFICATION_TYPE_UPDATE; $articleNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'NotificationType', $notificationType)); // DOI (mandatory) $articleNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'DOI', $doi)); // DOI URL (mandatory) $urlPath = $article->getBestArticleId(); if ($galley) { $urlPath = array($article->getBestArticleId(), $galley->getBestGalleyId()); } $url = $router->url($request, $context->getPath(), 'article', 'view', $urlPath); if ($plugin->isTestMode($context)) { // Change server domain for testing. $url = PKPString::regexp_replace('#://[^\\s]+/index.php#', '://example.com/index.php', $url); } $articleNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'DOIWebsiteLink', $url)); // DOI strucural type $articleNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'DOIStructuralType', $this->getDOIStructuralType())); // Registrant (mandatory) $articleNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'RegistrantName', $plugin->getSetting($context->getId(), 'registrantName'))); // Registration authority (mandatory) $articleNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'RegistrationAuthority', 'mEDRA')); // WorkIdentifier - proprietary ID $pubObjectProprietaryId = $context->getId() . '-' . $article->getIssueId() . '-' . $article->getId(); if ($galley) { $pubObjectProprietaryId .= '-g' . $galley->getId(); } $articleNode->appendChild($this->createIdentifierNode($doc, $workOrProduct, O4DOI_ID_TYPE_PROPRIETARY, $pubObjectProprietaryId)); // Issue/journal locale precedence. $journalLocalePrecedence = $this->getObjectLocalePrecedence($context, null, null); // Serial Publication (mandatory) $articleNode->appendChild($this->createSerialPublicationNode($doc, $journalLocalePrecedence, $epubFormat)); // Journal Issue (mandatory) $issueId = $article->getIssueId(); if ($cache->isCached('issues', $issueId)) { $issue = $cache->get('issues', $issueId); } else { $issueDao = DAORegistry::getDAO('IssueDAO'); /* @var $issueDao IssueDAO */ $issue = $issueDao->getById($issueId, $context->getId()); if ($issue) { $cache->add($issue, null); } } $articleNode->appendChild($this->createJournalIssueNode($doc, $issue, $journalLocalePrecedence)); // Object locale precedence. $objectLocalePrecedence = $this->getObjectLocalePrecedence($context, $article, $galley); // Content Item (mandatory for articles) $articleNode->appendChild($this->createContentItemNode($doc, $issue, $article, $galley, $objectLocalePrecedence)); return $articleNode; }
/** * 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; }
/** * Saving object's DOI to the object's * "registeredDoi" setting. * We prefix the setting with the plugin's * id so that we do not get name clashes * when several DOI registration plug-ins * are active at the same time. * @param $context Context * @param $object Issue|PublishedArticle|ArticleGalley * @param $testPrefix string */ function saveRegisteredDoi($context, $object, $testPrefix = '10.1234') { $registeredDoi = $object->getStoredPubId('doi'); assert(!empty($registeredDoi)); if ($this->isTestMode($context)) { $registeredDoi = PKPString::regexp_replace('#^[^/]+/#', $testPrefix . '/', $registeredDoi); } $object->setData($this->getPluginSettingsPrefix() . '::' . DOI_EXPORT_REGISTERED_DOI, $registeredDoi); $this->updateObject($object); }
/** * Get the canonical URL of an object. * @param $request Request * @param $journal Journal * @param $object Issue|PublishedArticle|ArticleGalley */ function _getObjectUrl($request, $journal, $object) { $router = $request->getRouter(); // Retrieve the article of article files. if (is_a($object, 'SubmissionFile')) { $articleId = $object->getArticleId(); $cache = $this->getCache(); if ($cache->isCached('articles', $articleId)) { $article = $cache->get('articles', $articleId); } else { $articleDao = DAORegistry::getDAO('PublishedArticleDAO'); /* @var $articleDao PublishedArticleDAO */ $article = $articleDao->getPublishedArticleByArticleId($articleId, $journal->getId(), true); } assert(is_a($article, 'PublishedArticle')); } $url = null; switch (true) { case is_a($object, 'Issue'): $url = $router->url($request, null, 'issue', 'view', $object->getBestIssueId($journal)); break; case is_a($object, 'PublishedArticle'): $url = $router->url($request, null, 'article', 'view', $object->getBestArticleId($journal)); break; case is_a($object, 'ArticleGalley'): $url = $router->url($request, null, 'article', 'view', array($article->getBestArticleId($journal), $object->getBestGalleyId($journal))); break; } if ($this->isTestMode($request)) { // Change server domain for testing. $url = PKPString::regexp_replace('#://[^\\s]+/index.php#', '://example.com/index.php', $url); } return $url; }
/** * Fills the given citation description with * meta-data retrieved from Worldcat * @param $oclcId string * @return MetadataDescription */ function &_lookupWorldcat($oclcId) { $nullVar = null; $lookupParams = array('wskey' => $this->getApiKey()); if (is_null($resultDOM = $this->callWebService(WORLDCAT_WEBSERVICE_EXTRACT . urlencode($oclcId), $lookupParams))) { return $nullVar; } if (is_null($metadata = $this->transformWebServiceResults($resultDOM, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'worldcat.xsl'))) { return $nullVar; } // FIXME: Use MARC parsed author field in XSL rather than full name // Clean non-numerics from ISBN if (!empty($metadata['isbn'])) { $metadata['isbn'] = PKPString::regexp_replace('/[^\\dX]*/', '', $metadata['isbn']); } // Clean non-numerics from issued date (year) if (!empty($metadata['date'])) { $metadata['date'] = PKPString::regexp_replace('/,.*/', ', ', $metadata['date']); $metadata['date'] = PKPString::regexp_replace('/[^\\d{4}]/', '', $metadata['date']); } $citationDescription =& $this->getNlm30CitationDescriptionFromMetadataArray($metadata); return $citationDescription; }
/** * @copydoc PKPPubIdPlugin::getPubId() */ function getPubId($pubObject) { // Get the pub id type $pubIdType = $this->getPubIdType(); // If we already have an assigned pub id, use it. $storedPubId = $pubObject->getStoredPubId($pubIdType); if ($storedPubId) { return $storedPubId; } // Determine the type of the publishing object. $pubObjectType = $this->getPubObjectType($pubObject); // Initialize variables for publication objects. $submission = $pubObjectType == 'Submission' ? $pubObject : null; $representation = $pubObjectType == 'Representation' ? $pubObject : null; $submissionFile = $pubObjectType == 'SubmissionFile' ? $pubObject : null; // Get the context id. if ($pubObjectType == 'Submission') { $contextId = $pubObject->getContextId(); } else { // Retrieve the submission. assert(is_a($pubObject, 'Representation') || is_a($pubObject, 'SubmissionFile')); $submissionDao = Application::getSubmissionDAO(); $submission = $submissionDao->getById($pubObject->getSubmissionId(), null, true); if (!$submission) { return null; } // Now we can identify the context. $contextId = $submission->getContextId(); } // Check the context $context = $this->getContext($contextId); if (!$context) { return null; } $contextId = $context->getId(); // Check whether pub ids are enabled for the given object type. $objectTypeEnabled = $this->isObjectTypeEnabled($pubObjectType, $contextId); if (!$objectTypeEnabled) { return null; } // Retrieve the pub id prefix. $pubIdPrefix = $this->getSetting($contextId, $this->getPrefixFieldName()); if (empty($pubIdPrefix)) { return null; } // Generate the pub id suffix. $suffixFieldName = $this->getSuffixFieldName(); $suffixGenerationStrategy = $this->getSetting($contextId, $suffixFieldName); switch ($suffixGenerationStrategy) { case 'customId': $pubIdSuffix = $pubObject->getData($suffixFieldName); break; case 'pattern': $suffixPatternsFieldNames = $this->getSuffixPatternsFieldNames(); $pubIdSuffix = $this->getSetting($contextId, $suffixPatternsFieldNames[$pubObjectType]); // %p - press initials $pubIdSuffix = PKPString::regexp_replace('/%p/', PKPString::strtolower($context->getAcronym($context->getPrimaryLocale())), $pubIdSuffix); // %x - custom identifier if ($pubObject->getStoredPubId('publisher-id')) { $pubIdSuffix = PKPString::regexp_replace('/%x/', $pubObject->getStoredPubId('publisher-id'), $pubIdSuffix); } if ($submission) { // %m - monograph id $pubIdSuffix = PKPString::regexp_replace('/%m/', $submission->getId(), $pubIdSuffix); } if ($representation) { // %f - publication format id $pubIdSuffix = PKPString::regexp_replace('/%f/', $representation->getId(), $pubIdSuffix); } if ($submissionFile) { // %s - file id $pubIdSuffix = PKPString::regexp_replace('/%s/', $submissionFile->getFileId(), $pubIdSuffix); } break; default: $pubIdSuffix = PKPString::strtolower($context->getAcronym($context->getPrimaryLocale())); if ($submission) { $pubIdSuffix .= '.' . $submission->getId(); } if ($representation) { $pubIdSuffix .= '.' . $representation->getId(); } if ($submissionFile) { $pubIdSuffix .= '.' . $submissionFile->getFileId(); } } if (empty($pubIdSuffix)) { return null; } // Costruct the pub id from prefix and suffix. $pubId = $this->constructPubId($pubIdPrefix, $pubIdSuffix, $contextId); return $pubId; }
/** * @see Filter::process() * @param $pubObject Issue|PublishedArticle|ArticleGalley * @return DOMDocument */ function &process(&$pubObject) { // Create the XML document $doc = new DOMDocument('1.0', 'utf-8'); $doc->preserveWhiteSpace = false; $doc->formatOutput = true; $deployment = $this->getDeployment(); $context = $deployment->getContext(); $plugin = $deployment->getPlugin(); $cache = $plugin->getCache(); // Get all objects $issue = $article = $galley = $galleyFile = null; if (is_a($pubObject, 'Issue')) { $issue = $pubObject; if (!$cache->isCached('issues', $issue->getId())) { $cache->add($issue, null); } } elseif (is_a($pubObject, 'PublishedArticle')) { $article = $pubObject; if (!$cache->isCached('articles', $article->getId())) { $cache->add($article, null); } } elseif (is_a($pubObject, 'ArticleGalley')) { $galley = $pubObject; $galleyFile = $galley->getFile(); $articleId = $galley->getSubmissionId(); if ($cache->isCached('articles', $articleId)) { $article = $cache->get('articles', $articleId); } else { $articleDao = DAORegistry::getDAO('PublishedArticleDAO'); /* @var $articleDao PublishedArticleDAO */ $article = $articleDao->getPublishedArticleByArticleId($pubObject->getSubmissionId(), $context->getId()); if ($article) { $cache->add($article, null); } } } if (!$issue) { $issueId = $article->getIssueId(); if ($cache->isCached('issues', $issueId)) { $issue = $cache->get('issues', $issueId); } else { $issueDao = DAORegistry::getDAO('IssueDAO'); /* @var $issueDao IssueDAO */ $issue = $issueDao->getById($issueId, $context->getId()); if ($issue) { $cache->add($issue, null); } } } // The publisher is required. // Use the journal title as DataCite recommends for now. $publisher = $this->getPrimaryTranslation($context->getName(null), $objectLocalePrecedence); assert(!empty($publisher)); // The publication date is required. $publicationDate = isset($article) ? $article->getDatePublished() : null; if (empty($publicationDate)) { $publicationDate = $issue->getDatePublished(); } assert(!empty($publicationDate)); // Create the root node $rootNode = $this->createRootNode($doc); $doc->appendChild($rootNode); // Identify the object locale. $objectLocalePrecedence = $this->getObjectLocalePrecedence($context, $article, $galley); // DOI (mandatory) $doi = $pubObject->getStoredPubId('doi'); if ($plugin->isTestMode($context)) { $doi = PKPString::regexp_replace('#^[^/]+/#', DATACITE_API_TESTPREFIX . '/', $doi); } $rootNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'identifier', htmlspecialchars($doi, ENT_COMPAT, 'UTF-8'))); $node->setAttribute('identifierType', DATACITE_IDTYPE_DOI); // Creators (mandatory) $rootNode->appendChild($this->createCreatorsNode($doc, $issue, $article, $galley, $galleyFile, $publisher, $objectLocalePrecedence)); // Title (mandatory) $rootNode->appendChild($this->createTitlesNode($doc, $issue, $article, $galley, $galleyFile, $objectLocalePrecedence)); // Publisher (mandatory) $rootNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'publisher', htmlspecialchars($publisher, ENT_COMPAT, 'UTF-8'))); // Publication Year (mandatory) $rootNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'publicationYear', date('Y', strtotime($publicationDate)))); // Subjects $subject = null; if (!empty($galleyFile) && is_a($galleyFile, 'SupplementaryFile')) { $subject = $this->getPrimaryTranslation($galleyFile->getSubject(null), $objectLocalePrecedence); } elseif (!empty($article)) { $subject = $this->getPrimaryTranslation($article->getSubject(null), $objectLocalePrecedence); } if (!empty($subject)) { $subjectsNode = $doc->createElementNS($deployment->getNamespace(), 'subjects'); $subjectsNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'subject', htmlspecialchars($subject, ENT_COMPAT, 'UTF-8'))); $rootNode->appendChild($subjectsNode); } // Dates $rootNode->appendChild($this->createDatesNode($doc, $issue, $article, $galley, $galleyFile, $publicationDate)); // Language $rootNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'language', AppLocale::getIso1FromLocale($objectLocalePrecedence[0]))); // Resource Type $resourceTypeNode = $this->createResourceTypeNode($doc, $issue, $article, $galley, $galleyFile); if ($resourceTypeNode) { $rootNode->appendChild($resourceTypeNode); } // Alternate Identifiers $rootNode->appendChild($this->createAlternateIdentifiersNode($doc, $issue, $article, $galley)); // Related Identifiers $relatedIdentifiersNode = $this->createRelatedIdentifiersNode($doc, $issue, $article, $galley); if ($relatedIdentifiersNode) { $rootNode->appendChild($relatedIdentifiersNode); } // Sizes $sizesNode = $this->createSizesNode($doc, $issue, $article, $galley, $galleyFile); if ($sizesNode) { $rootNode->appendChild($sizesNode); } // Formats if (!empty($galleyFile)) { $format = $galleyFile->getFileType(); if (!empty($format)) { $formatsNode = $doc->createElementNS($deployment->getNamespace(), 'formats'); $formatsNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'format', htmlspecialchars($format, ENT_COMPAT, 'UTF-8'))); $rootNode->appendChild($formatsNode); } } // Rights $rightsURL = $article ? $article->getLicenseURL() : $context->getSetting('licenseURL'); if (!empty($rightsURL)) { $rightsNode = $doc->createElementNS($deployment->getNamespace(), 'rightsList'); $rightsNode->appendChild($node = $doc->createElementNS($deployment->getNamespace(), 'rights', htmlspecialchars(strip_tags(Application::getCCLicenseBadge($rightsURL)), ENT_COMPAT, 'UTF-8'))); $node->setAttribute('rightsURI', $rightsURL); $rootNode->appendChild($rightsNode); } // Descriptions $descriptionsNode = $this->createDescriptionsNode($doc, $issue, $article, $galley, $galleyFile, $objectLocalePrecedence); if ($descriptionsNode) { $rootNode->appendChild($descriptionsNode); } return $doc; }