/** * 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; }
/** * Query parsing helper routine. * Returned structure is based on that used by the Search::QueryParser Perl module. */ function _parseQueryInternal($signTokens, $tokens, &$pos, $total) { $return = array('+' => array(), '' => array(), '-' => array()); $postBool = $preBool = ''; $submissionSearchIndex = new SubmissionSearchIndex(); $notOperator = PKPString::strtolower(__('search.operator.not')); $andOperator = PKPString::strtolower(__('search.operator.and')); $orOperator = PKPString::strtolower(__('search.operator.or')); while ($pos < $total) { if (!empty($signTokens[$pos])) { $sign = $signTokens[$pos]; } else { if (empty($sign)) { $sign = '+'; } } $token = PKPString::strtolower($tokens[$pos++]); switch ($token) { case $notOperator: $sign = '-'; break; case ')': return $return; case '(': $token = $this->_parseQueryInternal($signTokens, $tokens, $pos, $total); default: $postBool = ''; if ($pos < $total) { $peek = PKPString::strtolower($tokens[$pos]); if ($peek == $orOperator) { $postBool = 'or'; $pos++; } else { if ($peek == $andOperator) { $postBool = 'and'; $pos++; } } } $bool = empty($postBool) ? $preBool : $postBool; $preBool = $postBool; if ($bool == 'or') { $sign = ''; } if (is_array($token)) { $k = $token; } else { $k = $submissionSearchIndex->filterKeywords($token, true); } if (!empty($k)) { $return[$sign][] = $k; } $sign = ''; break; } } return $return; }
/** * Get a set of GalleryPlugin objects describing the available * compatible plugins in their newest versions. * @param $application PKPApplication * @param $category string Optional category name to use as filter * @param $search string Optional text to use as filter * @return array GalleryPlugin objects */ function getNewestCompatible($application, $category = null, $search = null) { $doc = $this->_getDocument(); $plugins = array(); foreach ($doc->getElementsByTagName('plugin') as $element) { $plugin = $this->_compatibleFromElement($element, $application); // May be null if no compatible version exists; also // apply search filters if any supplied. if ($plugin && ($category == '' || $plugin->getCategory() == $category) && ($search == '' || PKPString::strpos(PKPString::strtolower(serialize($plugin)), PKPString::strtolower($search)) !== false)) { $plugins[] = $plugin; } } return $plugins; }
/** * Retrieve all published authors for a press in an associative array by * the first letter of the last name, for example: * $returnedArray['S'] gives array($misterSmithObject, $misterSmytheObject, ...) * Keys will appear in sorted order. Note that if pressId is null, * alphabetized authors for all presses are returned. * @param $pressId int * @param $initial An initial the last names must begin with * @return array Authors ordered by sequence */ function getAuthorsAlphabetizedByPress($pressId = null, $initial = null, $rangeInfo = null) { $params = array('affiliation', AppLocale::getPrimaryLocale(), 'affiliation', AppLocale::getLocale()); if (isset($pressId)) { $params[] = $pressId; } if (isset($initial)) { $params[] = PKPString::strtolower($initial) . '%'; $initialSql = ' AND LOWER(a.last_name) LIKE LOWER(?)'; } else { $initialSql = ''; } $result = $this->retrieveRange('SELECT DISTINCT CAST(\'\' AS CHAR) AS url, a.author_id AS author_id, a.submission_id AS submission_id, CAST(\'\' AS CHAR) AS email, 0 AS primary_contact, 0 AS seq, a.first_name AS first_name, a.middle_name AS middle_name, a.last_name AS last_name, asl.setting_value AS affiliation_l, asl.locale, aspl.setting_value AS affiliation_pl, aspl.locale AS primary_locale, a.suffix AS suffix, a.user_group_id AS user_group_id, a.include_in_browse AS include_in_browse, 0 AS show_title, a.country FROM authors a LEFT JOIN author_settings aspl ON (a.author_id = aspl.author_id AND aspl.setting_name = ? AND aspl.locale = ?) LEFT JOIN author_settings asl ON (a.author_id = asl.author_id AND asl.setting_name = ? AND asl.locale = ?) JOIN submissions s ON (a.submission_id = s.submission_id) WHERE s.status = ' . STATUS_PUBLISHED . ' ' . (isset($pressId) ? 'AND s.context_id = ? ' : '') . ' AND (a.last_name IS NOT NULL AND a.last_name <> \'\')' . $initialSql . ' ORDER BY a.last_name, a.first_name', $params, $rangeInfo); return new DAOResultFactory($result, $this, '_fromRow'); }
/** * Retrieve all published authors for a journal in an associative array by * the first letter of the last name, for example: * $returnedArray['S'] gives array($misterSmithObject, $misterSmytheObject, ...) * Keys will appear in sorted order. Note that if journalId is null, * alphabetized authors for all enabled journals are returned. * @param $journalId int Optional journal ID to restrict results to * @param $initial An initial the last names must begin with * @param $rangeInfo Range information * @param $includeEmail Whether or not to include the email in the select distinct * @return DAOResultFactory Authors ordered by sequence */ function getAuthorsAlphabetizedByJournal($journalId = null, $initial = null, $rangeInfo = null, $includeEmail = false) { $params = array('affiliation', AppLocale::getPrimaryLocale(), 'affiliation', AppLocale::getLocale()); if (isset($journalId)) { $params[] = $journalId; } if (isset($initial)) { $params[] = PKPString::strtolower($initial) . '%'; $initialSql = ' AND LOWER(aa.last_name) LIKE LOWER(?)'; } else { $initialSql = ''; } $result = $this->retrieveRange('SELECT DISTINCT CAST(\'\' AS CHAR) AS url, 0 AS author_id, 0 AS submission_id, ' . ($includeEmail ? 'aa.email AS email,' : 'CAST(\'\' AS CHAR) AS email,') . ' 0 AS primary_contact, 0 AS seq, aa.first_name, aa.middle_name, aa.last_name, SUBSTRING(asl.setting_value FROM 1 FOR 255) AS affiliation_l, asl.locale, SUBSTRING(aspl.setting_value FROM 1 FOR 255) AS affiliation_pl, aspl.locale AS primary_locale, aa.country FROM authors aa LEFT JOIN author_settings aspl ON (aa.author_id = aspl.author_id AND aspl.setting_name = ? AND aspl.locale = ?) LEFT JOIN author_settings asl ON (aa.author_id = asl.author_id AND asl.setting_name = ? AND asl.locale = ?) JOIN submissions a ON (a.submission_id = aa.submission_id AND a.status = ' . STATUS_PUBLISHED . ') JOIN journals j ON (a.context_id = j.journal_id) JOIN published_submissions pa ON (pa.submission_id = a.submission_id) JOIN issues i ON (pa.issue_id = i.issue_id AND i.published = 1) WHERE ' . (isset($journalId) ? 'j.journal_id = ?' : 'j.enabled = 1') . ' AND (aa.last_name IS NOT NULL AND aa.last_name <> \'\')' . $initialSql . ' ORDER BY aa.last_name, aa.first_name', $params, $rangeInfo); return new DAOResultFactory($result, $this, '_returnSimpleAuthorFromRow'); }
/** * @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; }
/** * Handle incoming requests/notifications * @param $args array * @param $request PKPRequest */ function handle($args, $request) { $templateMgr = TemplateManager::getManager($request); $journal = $request->getJournal(); if (!$journal) { return parent::handle($args, $request); } // Just in case we need to contact someone import('lib.pkp.classes.mail.MailTemplate'); // Prefer technical support contact $contactName = $journal->getSetting('supportName'); $contactEmail = $journal->getSetting('supportEmail'); if (!$contactEmail) { // Fall back on primary contact $contactName = $journal->getSetting('contactName'); $contactEmail = $journal->getSetting('contactEmail'); } $mail = new MailTemplate('PAYPAL_INVESTIGATE_PAYMENT'); $mail->setReplyTo(null); $mail->addRecipient($contactEmail, $contactName); $paymentStatus = $request->getUserVar('payment_status'); switch (array_shift($args)) { case 'ipn': // Build a confirmation transaction. $req = 'cmd=_notify-validate'; if (get_magic_quotes_gpc()) { foreach ($_POST as $key => $value) { $req .= '&' . urlencode(stripslashes($key)) . '=' . urlencode(stripslashes($value)); } } else { foreach ($_POST as $key => $value) { $req .= '&' . urlencode($key) . '=' . urlencode($value); } } // Create POST response $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->getSetting($journal->getId(), 'paypalurl')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: PKP PayPal Service', 'Content-Type: application/x-www-form-urlencoded', 'Content-Length: ' . strlen($req))); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); $ret = curl_exec($ch); $curlError = curl_error($ch); curl_close($ch); // Check the confirmation response and handle as necessary. if (strcmp($ret, 'VERIFIED') == 0) { switch ($paymentStatus) { case 'Completed': $payPalDao = DAORegistry::getDAO('PayPalDAO'); $transactionId = $request->getUserVar('txn_id'); if ($payPalDao->transactionExists($transactionId)) { // A duplicate transaction was received; notify someone. $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Duplicate transaction ID: {$transactionId}", 'serverVars' => print_r($_SERVER, true))); $mail->send(); exit; } else { // New transaction succeeded. Record it. $payPalDao->insertTransaction($transactionId, $request->getUserVar('txn_type'), PKPString::strtolower($request->getUserVar('payer_email')), PKPString::strtolower($request->getUserVar('receiver_email')), $request->getUserVar('item_number'), $request->getUserVar('payment_date'), $request->getUserVar('payer_id'), $request->getUserVar('receiver_id')); $queuedPaymentId = $request->getUserVar('custom'); import('classes.payment.ojs.OJSPaymentManager'); $ojsPaymentManager = new OJSPaymentManager($request); // Verify the cost and user details as per PayPal spec. $queuedPayment =& $ojsPaymentManager->getQueuedPayment($queuedPaymentId); if (!$queuedPayment) { // The queued payment entry is missing. Complain. $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Missing queued payment ID: {$queuedPaymentId}", 'serverVars' => print_r($_SERVER, true))); $mail->send(); exit; } //NB: if/when paypal subscriptions are enabled, these checks will have to be adjusted // because subscription prices may change over time $queuedAmount = $queuedPayment->getAmount(); $grantedAmount = $request->getUserVar('mc_gross'); $queuedCurrency = $queuedPayment->getCurrencyCode(); $grantedCurrency = $request->getUserVar('mc_currency'); $grantedEmail = PKPString::strtolower($request->getUserVar('receiver_email')); $queuedEmail = PKPString::strtolower($this->getSetting($journal->getId(), 'selleraccount')); if ($queuedAmount != $grantedAmount && $queuedAmount > 0 || $queuedCurrency != $grantedCurrency || $grantedEmail != $queuedEmail) { // The integrity checks for the transaction failed. Complain. $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Granted amount: {$grantedAmount}\n" . "Queued amount: {$queuedAmount}\n" . "Granted currency: {$grantedCurrency}\n" . "Queued currency: {$queuedCurrency}\n" . "Granted to PayPal account: {$grantedEmail}\n" . "Configured PayPal account: {$queuedEmail}", 'serverVars' => print_r($_SERVER, true))); $mail->send(); exit; } // Update queued amount if amount set by user (e.g. donation) if ($queuedAmount == 0 && $grantedAmount > 0) { $queuedPaymentDao = DAORegistry::getDAO('QueuedPaymentDAO'); $queuedPayment->setAmount($grantedAmount); $queuedPayment->setCurrencyCode($grantedCurrency); $queuedPaymentDao->updateQueuedPayment($queuedPaymentId, $queuedPayment); } // Fulfill the queued payment. if ($ojsPaymentManager->fulfillQueuedPayment($request, $queuedPayment, $this->getName())) { exit; } // If we're still here, it means the payment couldn't be fulfilled. $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Queued payment ID {$queuedPaymentId} could not be fulfilled.", 'serverVars' => print_r($_SERVER, true))); $mail->send(); } exit; case 'Pending': // Ignore. exit; default: // An unhandled payment status was received; notify someone. $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Payment status: {$paymentStatus}", 'serverVars' => print_r($_SERVER, true))); $mail->send(); exit; } } else { // An unknown confirmation response was received; notify someone. $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Confirmation return: {$ret}\nCURL error: {$curlError}", 'serverVars' => print_r($_SERVER, true))); $mail->send(); exit; } case 'cancel': Handler::setupTemplate(); $templateMgr->assign(array('currentUrl' => $request->url(null, 'index'), 'pageTitle' => 'plugins.paymethod.paypal.purchase.cancelled.title', 'message' => 'plugins.paymethod.paypal.purchase.cancelled', 'backLink' => $request->getUserVar('ojsReturnUrl'), 'backLinkLabel' => 'common.continue')); $templateMgr->display('frontend/pages/message.tpl'); exit; } parent::handle($args, $request); // Don't know what to do with it }
/** * @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; }
/** * @function abntDateFormatWithDay Format date taking in consideration ABNT month abbreviations * @param $string string * @return string */ function abntDateFormatWithDay($string) { if (is_numeric($string)) { // it is a numeric string, we handle it as timestamp $timestamp = (int) $string; } else { $timestamp = strtotime($string); } $format = "%d %B %Y"; if (PKPString::strlen(strftime("%B", $timestamp)) > 4) { $format = "%d %b. %Y"; } return PKPString::strtolower(strftime($format, $timestamp)); }
/** * 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); }
/** * Retrieve auto-suggestions from the faceting service. * @param $url string * @param $searchRequest SolrSearchRequest * @param $userInput string * @param $fieldName string * @return array The generated suggestions. */ function _getFacetingAutosuggestions($url, $searchRequest, $userInput, $fieldName) { // Remove special characters from the user input. $searchTerms = strtr($userInput, '"()+-|&!', ' '); // Cut off the last search term. $searchTerms = explode(' ', $searchTerms); $facetPrefix = array_pop($searchTerms); if (empty($facetPrefix)) { return array(); } // Use the remaining search query to pre-filter // facet results. This may be an invalid query // but edismax will deal gracefully with syntax // errors. $userInput = PKPString::substr($userInput, 0, -PKPString::strlen($facetPrefix)); switch ($fieldName) { case 'query': // The 'query' filter goes against all fields. $articleSearch = new ArticleSearch(); $solrFields = array_values($articleSearch->getIndexFieldMap()); break; case 'indexTerms': // The 'index terms' filter goes against keyword index fields. $solrFields = array('discipline', 'subject', 'type', 'coverage'); break; default: // All other filters can be used directly. $solrFields = array($fieldName); } $solrFieldString = implode('|', $solrFields); $searchRequest->addQueryFieldPhrase($solrFieldString, $userInput); // Construct the main query. $params = $this->_getSearchQueryParameters($searchRequest); if (!isset($params['q'])) { // Use a catch-all query in case we have no limiting // search. $params['q'] = '*:*'; } if ($fieldName == 'query') { $params['facet.field'] = 'default_spell'; } else { $params['facet.field'] = $fieldName . '_spell'; } $facetPrefixLc = PKPString::strtolower($facetPrefix); $params['facet.prefix'] = $facetPrefixLc; // Make the request. $response = $this->_makeRequest($url, $params); if (!is_a($response, 'DOMXPath')) { return array(); } // Extract term suggestions. $nodeList = $response->query('//lst[@name="facet_fields"]/lst/int/@name'); if ($nodeList->length == 0) { return array(); } $termSuggestions = array(); foreach ($nodeList as $childNode) { $termSuggestions[] = $childNode->value; } // Add the term suggestion to the remaining user input. $suggestions = array(); foreach ($termSuggestions as $termSuggestion) { // Restore case if possible. if (strpos($termSuggestion, $facetPrefixLc) === 0) { $termSuggestion = $facetPrefix . PKPString::substr($termSuggestion, PKPString::strlen($facetPrefix)); } $suggestions[] = $userInput . $termSuggestion; } return $suggestions; }
/** * 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; }
/** * Subclasses can override this method to configure the * handler. * * NB: This method will be called after validation and * authorization. * * @param $request PKPRequest * @param $args array */ function initialize($request, $args = null) { // Set the controller id to the requested // page (page routing) or component name // (component routing) by default. $router = $request->getRouter(); if (is_a($router, 'PKPComponentRouter')) { $componentId = $router->getRequestedComponent($request); // Create a somewhat compressed but still globally unique // and human readable component id. // Example: "grid.citation.CitationGridHandler" // becomes "grid-citation-citationgrid" $componentId = str_replace('.', '-', PKPString::strtolower(PKPString::substr($componentId, 0, -7))); $this->setId($componentId); } else { assert(is_a($router, 'PKPPageRouter')); $this->setId($router->getRequestedPage($request)); } }
/** * @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. $issue = $pubObjectType == 'Issue' ? $pubObject : null; $submission = $pubObjectType == 'Submission' ? $pubObject : null; $representation = $pubObjectType == 'Representation' ? $pubObject : null; $submissionFile = $pubObjectType == 'SubmissionFile' ? $pubObject : null; // Get the context id. if (in_array($pubObjectType, array('Issue', 'Submission'))) { $contextId = $pubObject->getJournalId(); } 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->getJournalId(); } // 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 issue. if (!is_a($pubObject, 'Issue')) { assert(!is_null($submission)); $issueDao = DAORegistry::getDAO('IssueDAO'); /* @var $issueDao IssueDAO */ $issue = $issueDao->getIssueByArticleId($submission->getId(), $contextId); } if ($issue && $contextId != $issue->getJournalId()) { 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]); // %j - journal initials $pubIdSuffix = PKPString::regexp_replace('/%j/', 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 ($issue) { // %v - volume number $pubIdSuffix = PKPString::regexp_replace('/%v/', $issue->getVolume(), $pubIdSuffix); // %i - issue number $pubIdSuffix = PKPString::regexp_replace('/%i/', $issue->getNumber(), $pubIdSuffix); // %Y - year $pubIdSuffix = PKPString::regexp_replace('/%Y/', $issue->getYear(), $pubIdSuffix); } if ($submission) { // %a - article id $pubIdSuffix = PKPString::regexp_replace('/%a/', $submission->getId(), $pubIdSuffix); // %p - page number if ($submission->getPages()) { $pubIdSuffix = PKPString::regexp_replace('/%p/', $submission->getPages(), $pubIdSuffix); } } if ($representation) { // %g - galley id $pubIdSuffix = PKPString::regexp_replace('/%g/', $representation->getId(), $pubIdSuffix); } if ($submissionFile) { // %f - file id $pubIdSuffix = PKPString::regexp_replace('/%f/', $submissionFile->getFileId(), $pubIdSuffix); } break; default: $pubIdSuffix = PKPString::strtolower($context->getAcronym($context->getPrimaryLocale())); if ($issue) { $pubIdSuffix .= '.v' . $issue->getVolume() . 'i' . $issue->getNumber(); } else { $pubIdSuffix .= '.v%vi%i'; } if ($submission) { $pubIdSuffix .= '.' . $submission->getId(); } if ($representation) { $pubIdSuffix .= '.g' . $representation->getId(); } if ($submissionFile) { $pubIdSuffix .= '.f' . $submissionFile->getFileId(); } } if (empty($pubIdSuffix)) { return null; } // Costruct the pub id from prefix and suffix. $pubId = $this->constructPubId($pubIdPrefix, $pubIdSuffix, $contextId); return $pubId; }
/** * @see PubIdPlugin::getPubId() */ function getPubId($pubObject, $preview = false) { // 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, 'ArticleGalley')); $articleDao = DAORegistry::getDAO('PublishedArticleDAO'); /* @var $articleDao PublishedArticleDAO */ $article =& $articleDao->getPublishedArticleByArticleId($pubObject->getSubmissionId(), null, true); if (!$article) { return null; } // Now we can identify the journal. $journalId = $article->getJournalId(); } $journal = $this->getJournal($journalId); if (!$journal) { return null; } $journalId = $journal->getId(); // Check whether DOIs are enabled for the given object type. $doiEnabled = $this->getSetting($journalId, "enable{$pubObjectType}Doi") == '1'; if (!$doiEnabled) { return null; } // If we already have an assigned DOI, use it. $storedDOI = $pubObject->getStoredPubId('doi'); if ($storedDOI) { return $storedDOI; } // Retrieve the issue. if (!is_a($pubObject, 'Issue')) { assert(!is_null($article)); $issueDao = DAORegistry::getDAO('IssueDAO'); /* @var $issueDao IssueDAO */ $issue = $issueDao->getIssueByArticleId($article->getId(), $journal->getId()); } if ($issue && $journalId != $issue->getJournalId()) { return null; } // Retrieve the DOI prefix. $doiPrefix = $this->getSetting($journalId, 'doiPrefix'); if (empty($doiPrefix)) { return null; } // Generate the DOI suffix. $doiSuffixGenerationStrategy = $this->getSetting($journalId, 'doiSuffix'); switch ($doiSuffixGenerationStrategy) { case 'publisherId': switch ($pubObjectType) { case 'Issue': $doiSuffix = (string) $pubObject->getBestIssueId($journal); break; case 'Article': $doiSuffix = (string) $pubObject->getBestArticleId($journal); break; case 'Galley': $doiSuffix = (string) $pubObject->getBestGalleyId($journal); break; default: assert(false); } // 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' && $doiSuffix === (string) $pubObject->getId()) { $doiSuffix = strtolower_codesafe($pubObjectType[0]) . $doiSuffix; } break; case 'customId': $doiSuffix = $pubObject->getData('doiSuffix'); break; case 'pattern': $doiSuffix = $this->getSetting($journalId, "doi{$pubObjectType}SuffixPattern"); // %j - journal initials $doiSuffix = PKPString::regexp_replace('/%j/', PKPString::strtolower($journal->getAcronym($journal->getPrimaryLocale())), $doiSuffix); // %x - custom identifier if ($pubObject->getStoredPubId('publisher-id')) { $doiSuffix = PKPString::regexp_replace('/%x/', $pubObject->getStoredPubId('publisher-id'), $doiSuffix); } if ($issue) { // %v - volume number $doiSuffix = PKPString::regexp_replace('/%v/', $issue->getVolume(), $doiSuffix); // %i - issue number $doiSuffix = PKPString::regexp_replace('/%i/', $issue->getNumber(), $doiSuffix); // %Y - year $doiSuffix = PKPString::regexp_replace('/%Y/', $issue->getYear(), $doiSuffix); } if ($article) { // %a - article id $doiSuffix = PKPString::regexp_replace('/%a/', $article->getId(), $doiSuffix); // %p - page number if ($article->getPages()) { $doiSuffix = PKPString::regexp_replace('/%p/', $article->getPages(), $doiSuffix); } } if ($galley) { // %g - galley id $doiSuffix = PKPString::regexp_replace('/%g/', $galley->getId(), $doiSuffix); } break; default: $doiSuffix = PKPString::strtolower($journal->getAcronym($journal->getPrimaryLocale())); if ($issue) { $doiSuffix .= '.v' . $issue->getVolume() . 'i' . $issue->getNumber(); } else { $doiSuffix .= '.v%vi%i'; } if ($article) { $doiSuffix .= '.' . $article->getId(); } if ($galley) { $doiSuffix .= '.g' . $galley->getId(); } } if (empty($doiSuffix)) { return null; } // Join prefix and suffix. $doi = $doiPrefix . '/' . $doiSuffix; if (!$preview) { // Save the generated DOI. $this->setStoredPubId($pubObject, $pubObjectType, $doi); } return $doi; }