Exemplo n.º 1
0
 /**
  * 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 = String::regexp_replace('/[!"\\#\\$%\'\\(\\)\\.\\?@\\[\\]\\^`\\{\\}~]/', '', $cleanText);
     $cleanText = String::regexp_replace('/[\\+,:;&\\/<=>\\|\\\\]/', ' ', $cleanText);
     $cleanText = String::regexp_replace('/[\\*]/', $allowWildcards ? '%' : ' ', $cleanText);
     $cleanText = String::strtolower($cleanText);
     // Split into words
     $words = String::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]) && String::strlen($k) >= $minLength && !is_numeric($k)) {
             $keywords[] = String::substr($k, 0, SEARCH_KEYWORD_MAX_LENGTH);
         }
     }
     return $keywords;
 }
Exemplo n.º 2
0
 /**
  * @see PKPPlugin::getName()
  */
 function getName()
 {
     // Lazy load enabled plug-ins always use the plugin's class name
     // as plug-in name. Legacy plug-ins will override this method so
     // this implementation is backwards compatible.
     // NB: strtolower is required for PHP4 compatibility.
     return String::strtolower(get_class($this));
 }
Exemplo n.º 3
0
 /**
  * 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 = String::strtolower(__('search.operator.not'));
     $andOperator = String::strtolower(__('search.operator.and'));
     $orOperator = String::strtolower(__('search.operator.or'));
     while ($pos < $total) {
         if (!empty($signTokens[$pos])) {
             $sign = $signTokens[$pos];
         } else {
             if (empty($sign)) {
                 $sign = '+';
             }
         }
         $token = String::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 = String::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;
 }
Exemplo n.º 4
0
 /**
  * Return an HTML-formatted citation. Default implementation displays
  * an HTML-based citation using the citation.tpl template in the plugin
  * path.
  * @param $paper object
  */
 function cite(&$paper)
 {
     $loweredTitle = String::strtolower($paper->getLocalizedTitle());
     $apaCapitalized = String::ucfirst($loweredTitle);
     HookRegistry::register('Template::RT::CaptureCite', array(&$this, 'displayCitation'));
     $templateMgr =& TemplateManager::getManager();
     $templateMgr->assign_by_ref('citationPlugin', $this);
     $templateMgr->assign('apaCapitalized', $apaCapitalized);
     $templateMgr->display('rt/captureCite.tpl');
 }
Exemplo n.º 5
0
 function _handleOcsUrl($matchArray)
 {
     $url = $matchArray[2];
     $anchor = null;
     if (($i = strpos($url, '#')) !== false) {
         $anchor = substr($url, $i + 1);
         $url = substr($url, 0, $i);
     }
     $urlParts = explode('/', $url);
     if (isset($urlParts[0])) {
         switch (String::strtolower($urlParts[0])) {
             case 'conference':
                 $url = Request::url(isset($urlParts[1]) ? $urlParts[1] : Request::getRequestedConferencePath(), null, null, null, null, null, $anchor);
                 break;
             case 'paper':
                 if (isset($urlParts[1])) {
                     $url = Request::url(null, null, 'paper', 'view', $urlParts[1], null, $anchor);
                 }
                 break;
             case 'schedConf':
                 if (isset($urlParts[1])) {
                     $schedConfDao =& DAORegistry::getDAO('SchedConfDAO');
                     $conferenceDao =& DAORegistry::getDAO('ConferenceDAO');
                     $thisSchedConf =& $schedConfDao->getSchedConfByPath($urlParts[1]);
                     if (!$thisSchedConf) {
                         break;
                     }
                     $thisConference =& $conferenceDao->getConference($thisSchedConf->getConferenceId());
                     $url = Request::url($thisConference->getPath(), $thisSchedConf->getPath(), null, null, null, null, $anchor);
                 } else {
                     $url = Request::url(null, null, 'schedConfs', 'current', null, null, $anchor);
                 }
                 break;
             case 'suppfile':
                 if (isset($urlParts[1]) && isset($urlParts[2])) {
                     $url = Request::url(null, null, 'paper', 'downloadSuppFile', array($urlParts[1], $urlParts[2]), null, $anchor);
                 }
                 break;
             case 'sitepublic':
                 array_shift($urlParts);
                 import('file.PublicFileManager');
                 $publicFileManager = new PublicFileManager();
                 $url = Request::getBaseUrl() . '/' . $publicFileManager->getSiteFilesPath() . '/' . implode('/', $urlParts) . ($anchor ? '#' . $anchor : '');
                 break;
             case 'public':
                 array_shift($urlParts);
                 $schedConf =& Request::getSchedConf();
                 import('file.PublicFileManager');
                 $publicFileManager = new PublicFileManager();
                 $url = Request::getBaseUrl() . '/' . $publicFileManager->getSchedConfFilesPath($schedConf->getId()) . '/' . implode('/', $urlParts) . ($anchor ? '#' . $anchor : '');
                 break;
         }
     }
     return $matchArray[1] . $url . $matchArray[3];
 }
Exemplo n.º 6
0
 /**
  * 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 == '' || String::strpos(String::strtolower(serialize($plugin)), String::strtolower($search)) !== false)) {
             $plugins[] = $plugin;
         }
     }
     return $plugins;
 }
Exemplo n.º 7
0
 function _handleOjsUrl($matchArray)
 {
     $url = $matchArray[2];
     $anchor = null;
     if (($i = strpos($url, '#')) !== false) {
         $anchor = substr($url, $i + 1);
         $url = substr($url, 0, $i);
     }
     $urlParts = explode('/', $url);
     if (isset($urlParts[0])) {
         switch (String::strtolower($urlParts[0])) {
             case 'journal':
                 $url = Request::url(isset($urlParts[1]) ? $urlParts[1] : Request::getRequestedJournalPath(), null, null, null, null, $anchor);
                 break;
             case 'article':
                 if (isset($urlParts[1])) {
                     $url = Request::url(null, 'article', 'view', $urlParts[1], null, $anchor);
                 }
                 break;
             case 'issue':
                 if (isset($urlParts[1])) {
                     $url = Request::url(null, 'issue', 'view', $urlParts[1], null, $anchor);
                 } else {
                     $url = Request::url(null, 'issue', 'current', null, null, $anchor);
                 }
                 break;
             case 'suppfile':
                 if (isset($urlParts[1]) && isset($urlParts[2])) {
                     $url = Request::url(null, 'article', 'downloadSuppFile', array($urlParts[1], $urlParts[2]), null, $anchor);
                 }
                 break;
             case 'sitepublic':
                 array_shift($urlParts);
                 import('file.PublicFileManager');
                 $publicFileManager =& new PublicFileManager();
                 $url = Request::getBaseUrl() . '/' . $publicFileManager->getSiteFilesPath() . '/' . implode('/', $urlParts) . ($anchor ? '#' . $anchor : '');
                 break;
             case 'public':
                 array_shift($urlParts);
                 $journal =& Request::getJournal();
                 import('file.PublicFileManager');
                 $publicFileManager =& new PublicFileManager();
                 $url = Request::getBaseUrl() . '/' . $publicFileManager->getJournalFilesPath($journal->getJournalId()) . '/' . implode('/', $urlParts) . ($anchor ? '#' . $anchor : '');
                 break;
         }
     }
     return $matchArray[1] . $url . $matchArray[3];
 }
Exemplo n.º 8
0
    /**
     * 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[] = String::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');
    }
Exemplo n.º 9
0
    /**
     * 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 journals are returned.
     * @param $journalId int
     * @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 array 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[] = String::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 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) ? 'a.context_id = ? 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');
    }
Exemplo n.º 10
0
    /**
     * 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)
    {
        $authors = array();
        $params = array('affiliation', Locale::getPrimaryLocale(), 'affiliation', Locale::getLocale());
        if (isset($pressId)) {
            $params[] = $pressId;
        }
        if (isset($initial)) {
            $params[] = String::strtolower($initial) . '%';
            $initialSql = ' AND LOWER(ma.last_name) LIKE LOWER(?)';
        } else {
            $initialSql = '';
        }
        $result =& $this->retrieveRange('SELECT DISTINCT
				CAST(\'\' AS CHAR) AS url,
				0 AS author_id,
				0 AS submission_id,
				CAST(\'\' AS CHAR) AS email,
				0 AS primary_contact,
				0 AS seq,
				ma.first_name AS first_name,
				ma.middle_name AS middle_name,
				ma.last_name AS last_name,
				asl.setting_value AS affiliation_l,
				asl.locale,
				aspl.setting_value AS affiliation_pl,
				aspl.locale AS primary_locale,
				ma.country
			FROM	authors ma
				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 = ?)
				LEFT JOIN monographs a ON (ma.submission_id = a.monograph_id)
			WHERE	a.status = ' . STATUS_PUBLISHED . ' ' . (isset($pressId) ? 'AND a.press_id = ? ' : '') . '
				AND (ma.last_name IS NOT NULL AND ma.last_name <> \'\')' . $initialSql . '
			ORDER BY ma.last_name, ma.first_name', $params, $rangeInfo);
        $returner = new DAOResultFactory($result, $this, '_returnAuthorFromRow');
        return $returner;
    }
 /**
  * @see PubIdPlugin::getPubId()
  */
 function getPubId($monograph, $preview = false)
 {
     // Determine the type of the publishing object.
     $pubObjectType = $this->getPubObjectType($monograph);
     // Get the press id of the object.
     if (in_array($pubObjectType, array('Monograph', 'PublishedMonograph'))) {
         $pressId = $monograph->getContextId();
     } else {
         return null;
     }
     $press = $this->_getPress($pressId);
     if (!$press) {
         return null;
     }
     $pressId = $press->getId();
     // If we already have an assigned URN, use it.
     $storedURNDNB = $monograph->getStoredPubId('urn');
     if ($storedURNDNB) {
         return $storedURNDNB;
     }
     // Retrieve the URN prefix.
     $urnPrefix = $this->getSetting($pressId, 'urnDNBPrefix');
     if (empty($urnPrefix)) {
         return null;
     }
     // Generate the URN suffix.
     $urnSuffixGenerationStrategy = $this->getSetting($pressId, 'urnDNBSuffix');
     switch ($urnSuffixGenerationStrategy) {
         case 'pattern':
             $urnSuffix = $this->getSetting($pressId, "urnDNBSuffixPattern");
             // %p - press initials
             $urnSuffix = String::regexp_replace('/%p/', String::strtolower($press->getPath()), $urnSuffix);
             if ($monograph) {
                 // %m - monograph id
                 $urnSuffix = String::regexp_replace('/%m/', $monograph->getId(), $urnSuffix);
             }
             break;
         default:
             $urnSuffix = '-' . String::strtolower($press->getPath());
             if ($monograph) {
                 $urnSuffix .= '.' . $monograph->getId();
             }
     }
     if (empty($urnSuffix)) {
         return null;
     }
     // Join prefix and suffix.
     $urn = $urnPrefix . $urnSuffix;
     if (!$preview) {
         // Save the generated URN.
         $this->setStoredPubId($monograph, $pubObjectType, $urn);
     }
     return $urn . $this->_calculateUrnCheckNo($urn);
 }
 /**
  * If $value is found in the mapping, return the mapped value; otherwise
  * return $value untouched. The comparison ignores case and white-
  * space.
  * @param $value string
  * @return string
  */
 function mapLanguage($value)
 {
     $cache =& $this->_getMapCache();
     if ($newValue = $cache->get(String::strtolower(trim($value)))) {
         return $newValue;
     }
     return $value;
 }
Exemplo n.º 13
0
 /**
  * Get a DOI for this article.
  */
 function getDOI()
 {
     // If we already have an assigned DOI, use it.
     $storedDOI = $this->getStoredDOI();
     if ($storedDOI) {
         return $storedDOI;
     }
     // Otherwise, create a new one.
     $journalId = $this->getJournalId();
     // Get the Journal object (optimized)
     $journal =& Request::getJournal();
     if (!$journal || $journal->getId() != $journalId) {
         unset($journal);
         $journalDao =& DAORegistry::getDAO('JournalDAO');
         $journal =& $journalDao->getJournal($journalId);
     }
     if (($doiPrefix = $journal->getSetting('doiPrefix')) == '') {
         return null;
     }
     $doiSuffixSetting = $journal->getSetting('doiSuffix');
     // Get the issue
     $issueDao =& DAORegistry::getDAO('IssueDAO');
     $issue =& $issueDao->getIssueById($this->getIssueId(), $this->getJournalId(), true);
     if (!$issue || !$journal || $journal->getId() != $issue->getJournalId()) {
         return null;
     }
     switch ($doiSuffixSetting) {
         case 'customIdentifier':
             $doi = $doiPrefix . '/' . $this->getBestArticleId();
             break;
         case 'pattern':
             $suffixPattern = $journal->getSetting('doiSuffixPattern');
             // %j - journal initials
             $suffixPattern = String::regexp_replace('/%j/', String::strtolower($journal->getLocalizedSetting('initials')), $suffixPattern);
             // %v - volume number
             $suffixPattern = String::regexp_replace('/%v/', $issue->getVolume(), $suffixPattern);
             // %i - issue number
             $suffixPattern = String::regexp_replace('/%i/', $issue->getNumber(), $suffixPattern);
             // %Y - year
             $suffixPattern = String::regexp_replace('/%Y/', $issue->getYear(), $suffixPattern);
             // %a - article id
             $suffixPattern = String::regexp_replace('/%a/', $this->getArticleId(), $suffixPattern);
             // %p - page number
             $suffixPattern = String::regexp_replace('/%p/', $this->getPages(), $suffixPattern);
             $doi = $doiPrefix . '/' . $suffixPattern;
             break;
         default:
             $doi = $doiPrefix . '/' . String::strtolower($journal->getLocalizedSetting('initials')) . '.v' . $issue->getVolume() . 'i' . $issue->getNumber() . '.' . $this->getArticleId();
     }
     // Save the generated DOI
     $this->setStoredDOI($doi);
     $articleDao =& DAORegistry::getDAO('ArticleDAO');
     $articleDao->changeDOI($this->getId(), $doi);
     return $doi;
 }
Exemplo n.º 14
0
 /**
  * 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 = String::substr($userInput, 0, -String::strlen($facetPrefix));
     switch ($fieldName) {
         case 'query':
             // The 'query' filter goes agains 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 = String::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 . String::substr($termSuggestion, String::strlen($facetPrefix));
         }
         $suggestions[] = $userInput . $termSuggestion;
     }
     return $suggestions;
 }
Exemplo n.º 15
0
    /**
     * 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 journals are returned.
     * @param $journalId int
     * @param $initial An initial the last names must begin with
     * @return array Authors ordered by sequence
     */
    function &getAuthorsAlphabetizedByJournal($journalId = null, $initial = null, $rangeInfo = null)
    {
        $authors = array();
        $params = array();
        $locale = Locale::getLocale();
        $params[] = 'firstName';
        $params[] = $locale;
        $params[] = 'lastName';
        $params[] = $locale;
        $params[] = 'middleName';
        $params[] = $locale;
        $params[] = 'affiliation';
        $params[] = $locale;
        if (isset($journalId)) {
            $params[] = $journalId;
        }
        if (isset($initial)) {
            $params[] = String::strtolower($initial) . '%';
            $initialSql = ' AND LOWER(aal.setting_value) LIKE LOWER(?)';
        } else {
            $initialSql = '';
        }
        // Opatan Inc. : joined with article_author_settings to provide setting_value of author firstName
        $result =& $this->retrieveRange('SELECT DISTINCT
				CAST(\'\' AS CHAR(1)) AS url,
				0 AS author_id,
				0 AS article_id,
				CAST(\'\' AS CHAR(1)) AS email,
				0 AS primary_contact,
				0 AS seq,
				aaf.setting_value AS first_name,
				aam.setting_value AS middle_name,
				aal.setting_value AS last_name,
				aaaf.setting_value AS affiliation,
				aa.country
			FROM	article_authors aa
				LEFT JOIN article_author_settings aaf ON (aa.author_id = aaf.author_id AND aaf.setting_name = ? AND aaf.locale = ?)
				LEFT JOIN article_author_settings aal ON (aa.author_id = aal.author_id AND aal.setting_name = ? AND aal.locale = ?)
				LEFT JOIN article_author_settings aam ON (aa.author_id = aam.author_id AND aam.setting_name = ? AND aam.locale = ?)
				LEFT JOIN article_author_settings aaaf ON (aa.author_id = aaaf.author_id AND aaaf.setting_name = ? AND aaaf.locale = ?),
				articles a,
				published_articles pa,
				issues i
			WHERE	i.issue_id = pa.issue_id
				AND i.published = 1
				AND aa.article_id = a.article_id ' . (isset($journalId) ? 'AND a.journal_id = ? ' : '') . '
				AND pa.article_id = a.article_id
				AND a.status = ' . STATUS_PUBLISHED . '
				AND (aal.setting_value IS NOT NULL AND aal.setting_value <> \'\')' . $initialSql . '
			ORDER BY last_name, first_name', empty($params) ? false : $params, $rangeInfo);
        $returner =& new DAOResultFactory($result, $this, '_returnAuthorFromRow');
        return $returner;
    }
Exemplo n.º 16
0
 /**
  * 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('.', '-', String::strtolower(String::substr($componentId, 0, -7)));
         $this->setId($componentId);
     } else {
         assert(is_a($router, 'PKPPageRouter'));
         $this->setId($router->getRequestedPage($request));
     }
 }
 /**
  * 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', String::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 (String::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) (String::substr($pages['fpage'], 0, -String::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 (String::strpos(String::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 .= String::strtolower($attribute->textContent) . ' / ';
             }
             // Only add links to open access resources
             if (String::strpos($attributes, "subscription") === false && String::strpos($attributes, "membership") === false && String::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);
 }
Exemplo n.º 18
0
    /**
     * 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
     * @param $disallowRepeatedEmail Whether or not to include duplicated emails in the array
     * @return array Authors ordered by sequence
     */
    function &getAuthorsAlphabetizedByJournal($journalId = null, $initial = null, $rangeInfo = null, $includeEmail = false, $disallowRepeatedEmail = false)
    {
        $authors = array();
        $params = array('affiliation', AppLocale::getPrimaryLocale(), 'affiliation', AppLocale::getLocale());
        if (isset($journalId)) {
            $params[] = $journalId;
        }
        $params[] = AUTHOR_TOC_DEFAULT;
        $params[] = AUTHOR_TOC_SHOW;
        if (isset($initial)) {
            $params[] = String::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,
				CASE WHEN asl.setting_value = \'\' THEN NULL ELSE SUBSTRING(asl.setting_value FROM 1 FOR 255) END AS affiliation_l,
				CASE WHEN asl.setting_value = \'\' THEN NULL ELSE asl.locale END AS locale,
				CASE WHEN aspl.setting_value = \'\' THEN NULL ELSE SUBSTRING(aspl.setting_value FROM 1 FOR 255) END AS affiliation_pl,
				CASE WHEN aspl.setting_value = \'\' THEN NULL ELSE aspl.locale END AS primary_locale,
				CASE WHEN aa.country = \'\' THEN NULL ELSE aa.country END AS 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 = ?)
				' . ($disallowRepeatedEmail ? " LEFT JOIN authors aa2 ON (aa.email=aa2.email AND aa.author_id < aa2.author_id) " : "") . '
				JOIN articles a ON (a.article_id = aa.submission_id AND a.status = ' . STATUS_PUBLISHED . ')
				JOIN published_articles pa ON (pa.article_id = a.article_id)
				JOIN issues i ON (pa.issue_id = i.issue_id AND i.published = 1)
				JOIN sections s ON (a.section_id = s.section_id)
				JOIN journals j ON (a.journal_id = j.journal_id)
			WHERE ' . (isset($journalId) ? 'a.journal_id = ?' : 'j.enabled = 1') . '
				AND (aa.last_name IS NOT NULL AND aa.last_name <> \'\')
				AND ((s.hide_author = 0 AND a.hide_author = ?) OR a.hide_author = ?)
				' . ($disallowRepeatedEmail ? ' AND aa2.email IS NULL ' : '') . $initialSql . '
			ORDER BY aa.last_name, aa.first_name', $params, $rangeInfo);
        $returner = new DAOResultFactory($result, $this, '_returnSimpleAuthorFromRow');
        return $returner;
    }
Exemplo n.º 19
0
 /**
  * @see PubIdPlugin::getPubId()
  */
 function getPubId($pubObject, $preview = false)
 {
     // Determine the type of the publishing object.
     $pubObjectType = $this->getPubObjectType($pubObject);
     // Initialize variables for publication objects.
     $publicationFormat = $pubObjectType == 'PublicationFormat' ? $pubObject : null;
     $monograph = $pubObjectType == 'Monograph' ? $pubObject : null;
     // Get the press id of the object.
     if (in_array($pubObjectType, array('PublicationFormat', 'Monograph'))) {
         $pressId = $pubObject->getContextId();
     } else {
         return null;
     }
     $press = $this->_getPress($pressId);
     if (!$press) {
         return null;
     }
     $pressId = $press->getId();
     // If we already have an assigned DOI, use it.
     $storedDOI = $pubObject->getStoredPubId('doi');
     if ($storedDOI) {
         return $storedDOI;
     }
     // Retrieve the DOI prefix.
     $doiPrefix = $this->getSetting($pressId, 'doiPrefix');
     if (empty($doiPrefix)) {
         return null;
     }
     // Generate the DOI suffix.
     $doiSuffixGenerationStrategy = $this->getSetting($pressId, 'doiSuffix');
     switch ($doiSuffixGenerationStrategy) {
         case 'customId':
             $doiSuffix = $pubObject->getData('doiSuffix');
             break;
         case 'pattern':
             $doiSuffix = $this->getSetting($pressId, "doi{$pubObjectType}SuffixPattern");
             // %p - press initials
             $doiSuffix = String::regexp_replace('/%p/', String::strtolower($press->getPath()), $doiSuffix);
             if ($publicationFormat) {
                 // %m - monograph id, %f - publication format id
                 $doiSuffix = String::regexp_replace('/%m/', $publicationFormat->getMonographId(), $doiSuffix);
                 $doiSuffix = String::regexp_replace('/%f/', $publicationFormat->getId(), $doiSuffix);
             }
             if ($monograph) {
                 // %m - monograph id
                 $doiSuffix = String::regexp_replace('/%m/', $monograph->getId(), $doiSuffix);
             }
             break;
         default:
             $doiSuffix = String::strtolower($press->getPath());
             if ($publicationFormat) {
                 $doiSuffix .= '.' . $publicationFormat->getMonographId();
                 $doiSuffix .= '.' . $publicationFormat->getId();
             }
             if ($monograph) {
                 $doiSuffix .= '.' . $monograph->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;
 }
Exemplo n.º 20
0
 /**
  * @see PubIdPlugin::getPubId()
  */
 function getPubId(&$pubObject, $preview = false)
 {
     $doi = null;
     if (!$this->isExcluded($pubObject)) {
         // 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;
         $suppFile = $pubObjectType == 'SuppFile' ? $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, 'ArticleFile'));
             $articleDao =& DAORegistry::getDAO('PublishedArticleDAO');
             /* @var $articleDao PublishedArticleDAO */
             $article =& $articleDao->getPublishedArticleByArticleId($pubObject->getArticleId(), 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(), true);
         }
         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;
                     case 'SuppFile':
                         $doiSuffix = (string) $pubObject->getBestSuppFileId($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 = String::regexp_replace('/%j/', String::strtolower($journal->getLocalizedSetting('initials', $journal->getPrimaryLocale())), $doiSuffix);
                 // %x - custom identifier
                 if ($pubObject->getStoredPubId('publisher-id')) {
                     $doiSuffix = String::regexp_replace('/%x/', $pubObject->getStoredPubId('publisher-id'), $doiSuffix);
                 }
                 if ($issue) {
                     // %v - volume number
                     $doiSuffix = String::regexp_replace('/%v/', $issue->getVolume(), $doiSuffix);
                     // %i - issue number
                     $doiSuffix = String::regexp_replace('/%i/', $issue->getNumber(), $doiSuffix);
                     // %Y - year
                     $doiSuffix = String::regexp_replace('/%Y/', $issue->getYear(), $doiSuffix);
                 }
                 if ($article) {
                     // %a - article id
                     $doiSuffix = String::regexp_replace('/%a/', $article->getId(), $doiSuffix);
                     // %p - page number
                     if ($article->getPages()) {
                         $doiSuffix = String::regexp_replace('/%p/', $article->getPages(), $doiSuffix);
                     }
                 }
                 if ($galley) {
                     // %g - galley id
                     $doiSuffix = String::regexp_replace('/%g/', $galley->getId(), $doiSuffix);
                 }
                 if ($suppFile) {
                     // %s - supp file id
                     $doiSuffix = String::regexp_replace('/%s/', $suppFile->getId(), $doiSuffix);
                 }
                 break;
             default:
                 $doiSuffix = String::strtolower($journal->getLocalizedSetting('initials', $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 ($suppFile) {
                     $doiSuffix .= '.s' . $suppFile->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;
 }
Exemplo n.º 21
0
 /**
  * Convert a string to proper title case
  * @param $title string
  * @return string
  */
 function titleCase($title)
 {
     $smallWords = array('of', 'a', 'the', 'and', 'an', 'or', 'nor', 'but', 'is', 'if', 'then', 'else', 'when', 'at', 'from', 'by', 'on', 'off', 'for', 'in', 'out', 'over', 'to', 'into', 'with');
     $words = explode(' ', $title);
     foreach ($words as $key => $word) {
         if ($key == 0 or !in_array(String::strtolower($word), $smallWords)) {
             $words[$key] = ucfirst(String::strtolower($word));
         } else {
             $words[$key] = String::strtolower($word);
         }
     }
     $newTitle = implode(' ', $words);
     return $newTitle;
 }
Exemplo n.º 22
0
 public function testStrtolowerWhenAllIsLowerCaseShouldReturnAllLower()
 {
     $expected = "dafiti";
     $actual = String::strtolower("dafiti");
     $this->assertEquals($expected, $actual);
 }
Exemplo n.º 23
0
 /**
  * Suggest a username given the first and last names.
  * @return string
  */
 function suggestUsername($firstName, $lastName)
 {
     $initial = String::substr($firstName, 0, 1);
     $suggestion = String::regexp_replace('/[^a-zA-Z0-9_-]/', '', String::strtolower($initial . $lastName));
     $userDao =& DAORegistry::getDAO('UserDAO');
     for ($i = ''; $userDao->userExistsByUsername($suggestion . $i); $i++) {
     }
     return $suggestion . $i;
 }
Exemplo n.º 24
0
 /**
  * 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'), String::strtolower($request->getUserVar('payer_email')), String::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 = String::strtolower($request->getUserVar('receiver_email'));
                             $queuedEmail = String::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
 }
Exemplo n.º 25
0
 /**
  * Convert a string to proper title case
  * @param $title string
  * @return string
  */
 static function titleCase($title)
 {
     AppLocale::requireComponents(LOCALE_COMPONENT_PKP_COMMON);
     $smallWords = explode(' ', __('common.titleSmallWords'));
     $words = explode(' ', $title);
     foreach ($words as $key => $word) {
         if ($key == 0 or !in_array(String::strtolower($word), $smallWords)) {
             $words[$key] = ucfirst(String::strtolower($word));
         } else {
             $words[$key] = String::strtolower($word);
         }
     }
     $newTitle = implode(' ', $words);
     return $newTitle;
 }
Exemplo n.º 26
0
    /**
     * 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 journals are returned.
     * @param $journalId int
     * @param $initial An initial the last names must begin with
     * @return array Authors ordered by sequence
     */
    function &getAuthorsAlphabetizedByJournal($journalId = null, $initial = null, $rangeInfo = null)
    {
        $authors = array();
        $params = array();
        if (isset($journalId)) {
            $params[] = $journalId;
        }
        if (isset($initial)) {
            $params[] = String::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 article_id,
				CAST(\'\' AS CHAR) AS email,
				0 AS primary_contact,
				0 AS seq,
				aa.first_name AS first_name,
				aa.middle_name AS middle_name,
				aa.last_name AS last_name,
				aa.affiliation AS affiliation,
				aa.country
			FROM	article_authors aa,
				articles a,
				published_articles pa,
				issues i
			WHERE	i.issue_id = pa.issue_id
				AND i.published = 1
				AND aa.article_id = a.article_id ' . (isset($journalId) ? 'AND a.journal_id = ? ' : '') . '
				AND pa.article_id = a.article_id
				AND a.status = ' . STATUS_PUBLISHED . '
				AND (aa.last_name IS NOT NULL AND aa.last_name <> \'\')' . $initialSql . '
			ORDER BY aa.last_name, aa.first_name', empty($params) ? false : $params, $rangeInfo);
        $returner =& new DAOResultFactory($result, $this, '_returnAuthorFromRow');
        return $returner;
    }
Exemplo n.º 27
0
 /**
  * @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(), true);
         }
         // 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 = String::regexp_replace('/%j/', String::strtolower($journal->getAcronym($journal->getPrimaryLocale())), $urnSuffix);
                 // %x - custom identifier
                 if ($pubObject->getStoredPubId('publisher-id')) {
                     $urnSuffix = String::regexp_replace('/%x/', $pubObject->getStoredPubId('publisher-id'), $urnSuffix);
                 }
                 if ($issue) {
                     // %v - volume number
                     $urnSuffix = String::regexp_replace('/%v/', $issue->getVolume(), $urnSuffix);
                     // %i - issue number
                     $urnSuffix = String::regexp_replace('/%i/', $issue->getNumber(), $urnSuffix);
                     // %Y - year
                     $urnSuffix = String::regexp_replace('/%Y/', $issue->getYear(), $urnSuffix);
                 }
                 if ($article) {
                     // %a - article id
                     $urnSuffix = String::regexp_replace('/%a/', $article->getId(), $urnSuffix);
                     // %p - page number
                     if ($article->getPages()) {
                         $urnSuffix = String::regexp_replace('/%p/', $article->getPages(), $urnSuffix);
                     }
                 }
                 if ($galley) {
                     // %g - galley id
                     $urnSuffix = String::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 = String::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;
 }
Exemplo n.º 28
0
    /**
     * Retrieve all 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 journals are returned.
     * duplicates of email are suppressed
     * @param $journalId int
     * @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 array Authors ordered by sequence
     */
    function &getAuthorsAlphabetized($initial = null, $rangeInfo = null, $includeEmail = false)
    {
        $params = array();
        if (isset($initial)) {
            $params[] = String::strtolower($initial) . '%';
            $initialSql = ' AND LOWER(aa.last_name) LIKE LOWER(?)';
        } else {
            $initialSql = '';
        }
        $result =& $this->retrieveRange('SELECT aa.*
                        FROM	authors aa
				LEFT JOIN section_decisions sdec ON (aa.submission_id = sdec.article_id)
			WHERE	sdec.review_type = 1 AND (sdec.decision = 1 
				OR sdec.decision = 6 
				OR sdec.decision = 9) AND 
				(aa.last_name IS NOT NULL AND aa.last_name <> \'\')' . $initialSql . '
                                GROUP BY aa.email
			ORDER BY aa.last_name, aa.first_name', $params, $rangeInfo);
        $returner = new DAOResultFactory($result, $this, '_returnSimpleAuthorFromRow');
        return $returner;
    }
Exemplo n.º 29
0
 /**
  * Scans topic xml files for keywords
  * @param $mappingFile object The responsible mapping file
  * @param $matchingTopics array stores topics that match the keyword
  * @param $keyword string
  * @param $dir string
  * @param $file string
  * @modifies $matchingTopics array by reference
  */
 function scanTopic(&$mappingFile, &$matchingTopics, $keyword, $dir, $file)
 {
     if (preg_match('/^\\d{6,6}\\.xml$/', $file)) {
         $topicId = $mappingFile->getTopicIdForFilename($dir . DIRECTORY_SEPARATOR . $file);
         $topic =& $this->getTopic($topicId);
         if ($topic) {
             $numMatches = String::substr_count(String::strtolower($topic->getTitle()), $keyword);
             foreach ($topic->getSections() as $section) {
                 $numMatches += String::substr_count(String::strtolower($section->getTitle()), $keyword);
                 $numMatches += String::substr_count(String::strtolower($section->getContent()), $keyword);
             }
             if ($numMatches > 0) {
                 $matchingTopics[($numMatches << 16) + count($matchingTopics)] = $topic;
             }
         }
     }
 }
 /**
  * Fills the given citation object with
  * meta-data retrieved from PubMed.
  * @param $pmid string
  * @param $citationDescription MetadataDescription
  * @return MetadataDescription
  */
 function &_lookup($pmid, &$citationDescription)
 {
     $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;
     }
     $metadata = array('pub-id[@pub-id-type="pmid"]' => $pmid, 'article-title' => $resultDOM->getElementsByTagName("ArticleTitle")->item(0)->textContent, 'source' => $resultDOM->getElementsByTagName("MedlineTA")->item(0)->textContent);
     if ($resultDOM->getElementsByTagName("Volume")->length > 0) {
         $metadata['volume'] = $resultDOM->getElementsByTagName("Volume")->item(0)->textContent;
     }
     if ($resultDOM->getElementsByTagName("Issue")->length > 0) {
         $metadata['issue'] = $resultDOM->getElementsByTagName("Issue")->item(0)->textContent;
     }
     // get list of author full names
     $nlmNameSchema = new NlmNameSchema();
     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($nlmNameSchema, ASSOC_TYPE_AUTHOR);
         // Surname
         $authorDescription->addStatement('surname', $authorNode->getElementsByTagName("LastName")->item(0)->textContent);
         // Given names
         $givenNamesString = '';
         if ($authorNode->getElementsByTagName("FirstName")->length > 0) {
             $givenNamesString = $authorNode->getElementsByTagName("FirstName")->item(0)->textContent;
         } elseif ($authorNode->getElementsByTagName("ForeName")->length > 0) {
             $givenNamesString = $authorNode->getElementsByTagName("ForeName")->item(0)->textContent;
         }
         if (!empty($givenNamesString)) {
             foreach (explode(' ', $givenNamesString) as $givenName) {
                 $authorDescription->addStatement('given-names', String::trimPunctuation($givenName));
             }
         }
         // Suffix
         if ($authorNode->getElementsByTagName("Suffix")->length > 0) {
             $authorDescription->addStatement('suffix', $authorNode->getElementsByTagName("Suffix")->item(0)->textContent);
         }
         // Include collective names
         /*if ($resultDOM->getElementsByTagName("CollectiveName")->length > 0 && $authorNode->getElementsByTagName("CollectiveName")->item(0)->textContent != '') {
         			// FIXME: This corresponds to an NLM-citation <collab> tag and should be part of the Metadata implementation
         		}*/
         $metadata['person-group[@person-group-type="author"]'][] =& $authorDescription;
         unset($authorDescription);
     }
     // Extract pagination
     if (String::regexp_match_get("/^[:p\\.\\s]*(?P<fpage>[Ee]?\\d+)(-(?P<lpage>\\d+))?/", $resultDOM->getElementsByTagName("MedlinePgn")->item(0)->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) (String::substr($pages['fpage'], 0, -String::strlen($pages['lpage'])) . $pages['lpage']);
             }
             $metadata['lpage'] = $lPage;
         }
     }
     // Get publication date
     // TODO: The publication date could be in multiple places
     if ($resultDOM->getElementsByTagName("ArticleDate")->length > 0) {
         $publicationDate = $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Year")->item(0)->textContent . '-' . $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Month")->item(0)->textContent . '-' . $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Day")->item(0)->textContent;
         $metadata['date'] = $publicationDate;
     }
     // Get publication type
     if ($resultDOM->getElementsByTagName("PublicationType")->length > 0) {
         foreach ($resultDOM->getElementsByTagName("PublicationType") as $publicationType) {
             // The vast majority of items on PubMed are articles so catch these...
             if (String::strpos(String::strtolower($publicationType->textContent), 'article') !== false) {
                 $metadata['[@publication-type]'] = NLM_PUBLICATION_TYPE_JOURNAL;
                 break;
             }
         }
     }
     // Get DOI if it exists
     foreach ($resultDOM->getElementsByTagName("ArticleId") 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 .= String::strtolower($attribute->textContent) . ' / ';
             }
             // Only add links to open access resources
             if (String::strpos($attributes, "subscription") === false && String::strpos($attributes, "membership") === false && String::strpos($attributes, "fee") === false && $attributes != "") {
                 $links[] = $linkOut->getElementsByTagName("Url")->item(0)->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->addMetadataArrayToNlmCitationDescription($metadata, $citationDescription);
 }