/**
  * @see templates/article/footer.tpl
  */
 function callbackTemplateArticlePageFooter($hookName, $params)
 {
     $smarty =& $params[1];
     $output =& $params[2];
     // Identify similarity terms for the given article.
     $displayedArticle = $smarty->get_template_vars('article');
     $articleId = $displayedArticle->getId();
     import('classes.search.ArticleSearch');
     $articleSearch = new ArticleSearch();
     $searchTerms = $articleSearch->getSimilarityTerms($articleId);
     if (empty($searchTerms)) {
         return false;
     }
     // If we got similarity terms then execute a search with...
     // ... request, journal and error messages, ...
     $request = PKPApplication::getRequest();
     $router = $request->getRouter();
     $journal = $router->getContext($request);
     $error = null;
     // ... search keywords ...
     $query = implode(' ', $searchTerms);
     $keywords = array(null => $query);
     // ... and pagination.
     $rangeInfo = Handler::getRangeInfo($request, 'articlesBySimilarity');
     $rangeInfo->setCount(RECOMMEND_BY_SIMILARITY_PLUGIN_COUNT);
     $results = $articleSearch->retrieveResults($request, $journal, $keywords, $error, null, null, $rangeInfo, array($articleId));
     $smarty->assign('articlesBySimilarity', $results);
     $smarty->assign('articlesBySimilarityQuery', $query);
     $output .= $smarty->fetch($this->getTemplatePath() . 'articleFooter.tpl');
     return false;
 }
Exemplo n.º 2
0
 function display(&$args, $request)
 {
     $templateMgr = TemplateManager::getManager($request);
     parent::display($args, $request);
     $issueDao = DAORegistry::getDAO('IssueDAO');
     $publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO');
     $articleGalleyDao = DAORegistry::getDAO('ArticleGalleyDAO');
     $journal = $request->getJournal();
     switch (array_shift($args)) {
         case 'exportGalley':
             $articleId = array_shift($args);
             $galleyId = array_shift($args);
             $article = $publishedArticleDao->getPublishedArticleByArticleId($articleId);
             $galley = $articleGalleyDao->getById($galleyId, $articleId);
             if ($article && $galley && ($issue = $issueDao->getById($article->getIssueId(), $journal->getId()))) {
                 $this->exportArticle($journal, $issue, $article, $galley);
                 break;
             }
         default:
             // Display a list of articles for export
             AppLocale::requireComponents(LOCALE_COMPONENT_PKP_SUBMISSION);
             $publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO');
             $rangeInfo = Handler::getRangeInfo($this->getRequest(), $this->getRequest(), $this->getRequest(), $this->getRequest(), 'articles');
             $articleIds = $publishedArticleDao->getPublishedArticleIdsAlphabetizedByJournal($journal->getId(), false);
             $totalArticles = count($articleIds);
             $articleIds = array_slice($articleIds, $rangeInfo->getCount() * ($rangeInfo->getPage() - 1), $rangeInfo->getCount());
             import('lib.pkp.classes.core.VirtualArrayIterator');
             $articleSearch = new ArticleSearch();
             $iterator = new VirtualArrayIterator($articleSearch->formatResults($articleIds), $totalArticles, $rangeInfo->getPage(), $rangeInfo->getCount());
             $templateMgr->assign('articles', $iterator);
             $templateMgr->display($this->getTemplatePath() . 'index.tpl');
             break;
     }
 }
Exemplo n.º 3
0
 function display(&$args)
 {
     $templateMgr =& TemplateManager::getManager();
     parent::display($args);
     $issueDao =& DAORegistry::getDAO('IssueDAO');
     $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
     $articleGalleyDao =& DAORegistry::getDAO('ArticleGalleyDAO');
     $journal =& Request::getJournal();
     switch (array_shift($args)) {
         case 'exportGalley':
             $articleId = array_shift($args);
             $galleyId = array_shift($args);
             $article =& $publishedArticleDao->getPublishedArticleByArticleId($articleId);
             $galley =& $articleGalleyDao->getGalley($galleyId, $articleId);
             if ($article && $galley && ($issue =& $issueDao->getIssueById($article->getIssueId(), $journal->getJournalId()))) {
                 $this->exportArticle($journal, $issue, $article, $galley);
                 break;
             }
         default:
             // Display a list of articles for export
             $this->setBreadcrumbs();
             $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
             $rangeInfo = Handler::getRangeInfo('articles');
             $articleIds = $publishedArticleDao->getPublishedArticleIdsAlphabetizedByJournal($journal->getJournalId(), false);
             $totalArticles = count($articleIds);
             $articleIds = array_slice($articleIds, $rangeInfo->getCount() * ($rangeInfo->getPage() - 1), $rangeInfo->getCount());
             import('core.VirtualArrayIterator');
             $iterator =& new VirtualArrayIterator(ArticleSearch::formatResults($articleIds), $totalArticles, $rangeInfo->getPage(), $rangeInfo->getCount());
             $templateMgr->assign_by_ref('articles', $iterator);
             $templateMgr->display($this->getTemplatePath() . 'index.tpl');
             break;
     }
 }
Exemplo n.º 4
0
function view()
{
    // parse the search params
    $kind = get_http_var('type', "");
    $q = get_http_var('q');
    if (!$kind) {
        $j = get_http_var('j', "");
        $a = get_http_var('a', "");
        if ($j) {
            $q = $j;
            $kind = 'journo';
        }
        if ($a) {
            $q = $a;
            $kind = 'article';
        }
    }
    $art_page = get_http_var('p', 0);
    $journo_page = get_http_var('jp', 0);
    // special 'by' param for article searches
    $by = get_http_var('by', "");
    if ($by && $kind != 'journo') {
        $q .= " author:" . $by;
    }
    $sort_order = get_http_var('o');
    $article_results = null;
    if ($q != "" && $kind != 'journo') {
        $as = new ArticleSearch($q, $sort_order, $art_page, 'p');
        $article_results = $as->perform();
    }
    $journo_results = null;
    if ($q != "" && $kind != 'article') {
        $js = new JournoSearch($q, $journo_page, 'jp');
        $journo_results = $js->perform();
    }
    // hackhackhack
    /*
          if( $s['fmt'] == 'csv' ) {
            search_articles_output_csv($article_results->data);
            return;
          }
    */
    tmpl($q, $kind, $sort_order, $journo_results, $article_results);
}
Exemplo n.º 5
0
 /**
  * AJAX request for search query auto-completion.
  * @param $args array
  * @param $request Request
  * @return JSON string
  */
 function queryAutocomplete($args, $request)
 {
     $this->validate(null, $request);
     // Check whether auto-suggest is enabled.
     $suggestionList = array();
     $lucenePlugin = $this->_getLucenePlugin();
     $enabled = (bool) $lucenePlugin->getSetting(0, 'autosuggest');
     if ($enabled) {
         // Retrieve search criteria from the user input.
         $articleSearch = new ArticleSearch();
         $searchFilters = $articleSearch->getSearchFilters($request);
         // Get the autosuggest input and remove it from
         // the filter array.
         $autosuggestField = $request->getUserVar('searchField');
         $userInput = $searchFilters[$autosuggestField];
         if (isset($searchFilters[$autosuggestField])) {
             unset($searchFilters[$autosuggestField]);
         }
         // Instantiate a search request.
         $searchRequest = new SolrSearchRequest();
         $searchRequest->setJournal($searchFilters['searchJournal']);
         $searchRequest->setFromDate($searchFilters['fromDate']);
         $searchRequest->setToDate($searchFilters['toDate']);
         $keywords = $articleSearch->getKeywordsFromSearchFilters($searchFilters);
         $searchRequest->addQueryFromKeywords($keywords);
         // Get the web service.
         $solrWebService = $lucenePlugin->getSolrWebService();
         /* @var $solrWebService SolrWebService */
         $suggestions = $solrWebService->getAutosuggestions($searchRequest, $autosuggestField, $userInput, (int) $lucenePlugin->getSetting(0, 'autosuggestType'));
         // Prepare a suggestion list as understood by the
         // autocomplete JS handler.
         foreach ($suggestions as $suggestion) {
             $suggestionList[] = array('label' => $suggestion, 'value' => $suggestion);
         }
     }
     // Return the suggestions as JSON message.
     $json = new JSONMessage(true, $suggestionList);
     return $json->getString();
 }
Exemplo n.º 6
0
 /**
  * Show advanced search results.
  * @param $args array
  * @param $request PKPRequest
  */
 function advancedResults($args, &$request)
 {
     $this->validate();
     $this->setupTemplate($request, true);
     $rangeInfo = $this->getRangeInfo('search');
     $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
     $searchJournalId = $request->getUserVar('searchJournal');
     if (!empty($searchJournalId)) {
         $journalDao =& DAORegistry::getDAO('JournalDAO');
         $journal =& $journalDao->getById($searchJournalId);
         $yearRange = $publishedArticleDao->getArticleYearRange($journal->getId());
     } else {
         $journal =& $request->getJournal();
         $yearRange = $publishedArticleDao->getArticleYearRange(null);
     }
     // Load the keywords array with submitted values
     $keywords = array(null => ArticleSearch::parseQuery($request->getUserVar('query')));
     $keywords[ARTICLE_SEARCH_AUTHOR] = ArticleSearch::parseQuery($request->getUserVar('author'));
     $keywords[ARTICLE_SEARCH_TITLE] = ArticleSearch::parseQuery($request->getUserVar('title'));
     $keywords[ARTICLE_SEARCH_DISCIPLINE] = ArticleSearch::parseQuery($request->getUserVar('discipline'));
     $keywords[ARTICLE_SEARCH_SUBJECT] = ArticleSearch::parseQuery($request->getUserVar('subject'));
     $keywords[ARTICLE_SEARCH_TYPE] = ArticleSearch::parseQuery($request->getUserVar('type'));
     $keywords[ARTICLE_SEARCH_COVERAGE] = ArticleSearch::parseQuery($request->getUserVar('coverage'));
     $keywords[ARTICLE_SEARCH_GALLEY_FILE] = ArticleSearch::parseQuery($request->getUserVar('fullText'));
     $keywords[ARTICLE_SEARCH_SUPPLEMENTARY_FILE] = ArticleSearch::parseQuery($request->getUserVar('supplementaryFiles'));
     $fromDate = $request->getUserDateVar('dateFrom', 1, 1);
     if ($fromDate !== null) {
         $fromDate = date('Y-m-d H:i:s', $fromDate);
     }
     $toDate = $request->getUserDateVar('dateTo', 32, 12, null, 23, 59, 59);
     if ($toDate !== null) {
         $toDate = date('Y-m-d H:i:s', $toDate);
     }
     $results =& ArticleSearch::retrieveResults($journal, $keywords, $fromDate, $toDate, $rangeInfo);
     $templateMgr =& TemplateManager::getManager();
     $templateMgr->assign_by_ref('results', $results);
     $this->_assignAdvancedSearchParameters($request, $templateMgr, $yearRange);
     $templateMgr->display('search/searchResults.tpl');
 }
Exemplo n.º 7
0
 /**
  * Execute import/export tasks using the command-line interface.
  * @param $args Parameters to the plugin
  */
 function executeCLI($scriptName, &$args)
 {
     //		$command = array_shift($args);
     $xmlFile = array_shift($args);
     $journalPath = array_shift($args);
     $journalDao = DAORegistry::getDAO('JournalDAO');
     $issueDao = DAORegistry::getDAO('IssueDAO');
     $sectionDao = DAORegistry::getDAO('SectionDAO');
     $userDao = DAORegistry::getDAO('UserDAO');
     $publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO');
     $journal = $journalDao->getByPath($journalPath);
     if (!$journal) {
         if ($journalPath != '') {
             echo __('plugins.importexport.pubmed.cliError') . "\n";
             echo __('plugins.importexport.pubmed.error.unknownJournal', array('journalPath' => $journalPath)) . "\n\n";
         }
         $this->usage($scriptName);
         return;
     }
     if ($xmlFile != '') {
         switch (array_shift($args)) {
             case 'articles':
                 $articleSearch = new ArticleSearch();
                 $results = $articleSearch->formatResults($args);
                 if (!$this->exportArticles($results, $xmlFile)) {
                     echo __('plugins.importexport.pubmed.cliError') . "\n";
                     echo __('plugins.importexport.pubmed.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
                 }
                 return;
             case 'issue':
                 $issueId = array_shift($args);
                 $issue = $issueDao->getByBestId($issueId, $journal->getId());
                 if ($issue == null) {
                     echo __('plugins.importexport.pubmed.cliError') . "\n";
                     echo __('plugins.importexport.pubmed.export.error.issueNotFound', array('issueId' => $issueId)) . "\n\n";
                     return;
                 }
                 $issues = array($issue);
                 if (!$this->exportIssues($journal, $issues, $xmlFile)) {
                     echo __('plugins.importexport.pubmed.cliError') . "\n";
                     echo __('plugins.importexport.pubmed.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
                 }
                 return;
         }
     }
     $this->usage($scriptName);
 }
Exemplo n.º 8
0
 /**
  * @see ArticleSearch::retrieveResults()
  */
 function callbackRetrieveResults($hookName, $params)
 {
     assert($hookName == 'ArticleSearch::retrieveResults');
     // Unpack the parameters.
     list($journal, $keywords, $fromDate, $toDate, $page, $itemsPerPage, $dummy) = $params;
     $totalResults =& $params[6];
     // need to use reference
     $error =& $params[7];
     // need to use reference
     // Instantiate a search request.
     $searchRequest = new SolrSearchRequest();
     $searchRequest->setJournal($journal);
     $searchRequest->setFromDate($fromDate);
     $searchRequest->setToDate($toDate);
     $searchRequest->setPage($page);
     $searchRequest->setItemsPerPage($itemsPerPage);
     $searchRequest->addQueryFromKeywords($keywords);
     // Get the ordering criteria.
     list($orderBy, $orderDir) = $this->_getResultSetOrdering($journal);
     $searchRequest->setOrderBy($orderBy);
     $searchRequest->setOrderDir($orderDir == 'asc' ? true : false);
     // Configure alternative spelling suggestions.
     $spellcheck = (bool) $this->getSetting(0, 'spellcheck');
     $searchRequest->setSpellcheck($spellcheck);
     // Configure highlighting.
     $highlighting = (bool) $this->getSetting(0, 'highlighting');
     $searchRequest->setHighlighting($highlighting);
     // Configure faceting.
     // 1) Faceting will be disabled for filtered search categories.
     $activeFilters = array_keys($searchRequest->getQuery());
     if (is_a($journal, 'Journal')) {
         $activeFilters[] = 'journalTitle';
     }
     if (!empty($fromDate) || !empty($toDate)) {
         $activeFilters[] = 'publicationDate';
     }
     // 2) Switch faceting on for enabled categories that have no
     // active filters.
     $facetCategories = array_values(array_diff($this->_getEnabledFacetCategories(), $activeFilters));
     $searchRequest->setFacetCategories($facetCategories);
     // Configure custom ranking.
     $customRanking = (bool) $this->getSetting(0, 'customRanking');
     if ($customRanking) {
         $sectionDao =& DAORegistry::getDAO('SectionDAO');
         /* @var $sectionDao SectionDAO */
         if (is_a($journal, 'Journal')) {
             $sections = $sectionDao->getJournalSections($journal->getId());
         } else {
             $sections = $sectionDao->getSections();
         }
         while (!$sections->eof()) {
             /* @var $sections DAOResultFactory */
             $section =& $sections->next();
             $rankingBoost = $section->getData('rankingBoost');
             if (isset($rankingBoost)) {
                 $sectionBoost = (double) $rankingBoost;
             } else {
                 $sectionBoost = LUCENE_PLUGIN_DEFAULT_RANKING_BOOST;
             }
             if ($sectionBoost != LUCENE_PLUGIN_DEFAULT_RANKING_BOOST) {
                 $searchRequest->addBoostFactor('section_id', $section->getId(), $sectionBoost);
             }
             unset($section);
         }
         unset($sections);
     }
     // Call the solr web service.
     $solrWebService =& $this->getSolrWebService();
     $result =& $solrWebService->retrieveResults($searchRequest, $totalResults);
     if (is_null($result)) {
         $error = $solrWebService->getServiceMessage();
         $this->_informTechAdmin($error, $journal, true);
         $error .= ' ' . __('plugins.generic.lucene.message.techAdminInformed');
         return array();
     } else {
         // Store spelling suggestion, highlighting and faceting info
         // internally. We cannot route these back through the request
         // as the default search implementation does not support
         // these features.
         if ($spellcheck && isset($result['spellingSuggestion'])) {
             $this->_spellingSuggestion = $result['spellingSuggestion'];
             // Identify the field for which we got the suggestion.
             foreach ($keywords as $bitmap => $searchPhrase) {
                 if (!empty($searchPhrase)) {
                     switch ($bitmap) {
                         case null:
                             $queryField = 'query';
                             break;
                         case ARTICLE_SEARCH_INDEX_TERMS:
                             $queryField = 'indexTerms';
                             break;
                         default:
                             $indexFieldMap = ArticleSearch::getIndexFieldMap();
                             assert(isset($indexFieldMap[$bitmap]));
                             $queryField = $indexFieldMap[$bitmap];
                     }
                 }
             }
             $this->_spellingSuggestionField = $queryField;
         }
         if ($highlighting && isset($result['highlightedArticles'])) {
             $this->_highlightedArticles = $result['highlightedArticles'];
         }
         if (!empty($facetCategories) && isset($result['facets'])) {
             $this->_facets = $result['facets'];
         }
         // Return the scored results.
         if (isset($result['scoredResults']) && !empty($result['scoredResults'])) {
             return $result['scoredResults'];
         } else {
             return array();
         }
     }
 }
Exemplo n.º 9
0
 /**
  * Redirect to a search query that shows documents
  * similar to the one identified by an article id in the
  * request.
  * @param $args array
  * @param $request Request
  */
 function similarDocuments($args, &$request)
 {
     $this->validate(null, $request);
     // Retrieve the (mandatory) ID of the article that
     // we want similar documents for.
     $articleId = $request->getUserVar('articleId');
     if (!is_numeric($articleId)) {
         $request->redirect(null, 'search');
     }
     // Check whether a search plugin provides terms for a similarity search.
     $articleSearch = new ArticleSearch();
     $searchTerms = $articleSearch->getSimilarityTerms($articleId);
     // Redirect to a search query with the identified search terms (if any).
     if (empty($searchTerms)) {
         $searchParams = null;
     } else {
         $searchParams = array('query' => implode(' ', $searchTerms));
     }
     $request->redirect(null, 'search', 'search', null, $searchParams);
 }
Exemplo n.º 10
0
 /**
  * Show index of published articles by title.
  * @param $args array
  * @param $request PKPRequest
  */
 function titles($args, &$request)
 {
     $this->validate();
     $this->setupTemplate($request, true);
     $journal =& $request->getJournal();
     $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
     $rangeInfo = $this->getRangeInfo('search');
     $articleIds =& $publishedArticleDao->getPublishedArticleIdsAlphabetizedByJournal(isset($journal) ? $journal->getId() : null);
     $totalResults = count($articleIds);
     $articleIds = array_slice($articleIds, $rangeInfo->getCount() * ($rangeInfo->getPage() - 1), $rangeInfo->getCount());
     import('lib.pkp.classes.core.VirtualArrayIterator');
     $results = new VirtualArrayIterator(ArticleSearch::formatResults($articleIds), $totalResults, $rangeInfo->getPage(), $rangeInfo->getCount());
     $templateMgr =& TemplateManager::getManager();
     $templateMgr->assign_by_ref('results', $results);
     $templateMgr->display('search/titleIndex.tpl');
 }
Exemplo n.º 11
0
 /**
  * Show list of journal sections identify types.
  */
 function identifyTypes($args = array(), $request)
 {
     $this->setupTemplate($request);
     $router = $request->getRouter();
     $journal = $router->getContext($request);
     $browsePlugin =& PluginRegistry::getPlugin('generic', BROWSE_PLUGIN_NAME);
     $enableBrowseByIdentifyTypes = $browsePlugin->getSetting($journal->getId(), 'enableBrowseByIdentifyTypes');
     if ($enableBrowseByIdentifyTypes) {
         if (isset($args[0]) && $args[0] == 'view') {
             $identifyType = $request->getUserVar('identifyType');
             $sectionDao = DAORegistry::getDAO('SectionDAO');
             $sectionsIterator = $sectionDao->getByJournalId($journal->getId());
             $sections = array();
             while ($section = $sectionsIterator->next()) {
                 if ($section->getLocalizedIdentifyType() == $identifyType) {
                     $sections[] = $section;
                 }
             }
             $publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO');
             $publishedArticleIds = array();
             foreach ($sections as $section) {
                 $publishedArticleIdsBySection = $publishedArticleDao->getPublishedArticleIdsBySection($section->getId());
                 $publishedArticleIds = array_merge($publishedArticleIds, $publishedArticleIdsBySection);
             }
             $rangeInfo = $this->getRangeInfo($request, 'search');
             $totalResults = count($publishedArticleIds);
             $publishedArticleIds = array_slice($publishedArticleIds, $rangeInfo->getCount() * ($rangeInfo->getPage() - 1), $rangeInfo->getCount());
             $articleSearch = new ArticleSearch();
             $results = new VirtualArrayIterator($articleSearch->formatResults($publishedArticleIds), $totalResults, $rangeInfo->getPage(), $rangeInfo->getCount());
             $templateMgr = TemplateManager::getManager($request);
             $templateMgr->assign('results', $results);
             $templateMgr->assign('title', $identifyType);
             $templateMgr->assign('enableBrowseByIdentifyTypes', $enableBrowseByIdentifyTypes);
             $templateMgr->display($browsePlugin->getTemplatePath() . 'searchDetails.tpl');
         } else {
             $excludedIdentifyTypes = $browsePlugin->getSetting($journal->getId(), 'excludedIdentifyTypes');
             $sectionDao = DAORegistry::getDAO('SectionDAO');
             $sectionsIterator = $sectionDao->getByJournalId($journal->getId());
             $sectionidentifyTypes = array();
             while ($section = $sectionsIterator->next()) {
                 if ($section->getLocalizedIdentifyType() && !in_array($section->getId(), $excludedIdentifyTypes) && !in_array($section->getLocalizedIdentifyType(), $sectionidentifyTypes)) {
                     $sectionidentifyTypes[] = $section->getLocalizedIdentifyType();
                 }
             }
             sort($sectionidentifyTypes);
             $rangeInfo = $this->getRangeInfo($request, 'search');
             $totalResults = count($sectionidentifyTypes);
             $sectionidentifyTypes = array_slice($sectionidentifyTypes, $rangeInfo->getCount() * ($rangeInfo->getPage() - 1), $rangeInfo->getCount());
             $results = new VirtualArrayIterator($sectionidentifyTypes, $totalResults, $rangeInfo->getPage(), $rangeInfo->getCount());
             $templateMgr = TemplateManager::getManager($request);
             $templateMgr->assign('results', $results);
             $templateMgr->assign('enableBrowseByIdentifyTypes', $enableBrowseByIdentifyTypes);
             $templateMgr->display($browsePlugin->getTemplatePath() . 'searchIndex.tpl');
         }
     } else {
         $request->redirect(null, 'index');
     }
 }
Exemplo n.º 12
0
 /**
  * @covers ArticleSearch
  */
 public function testRetrieveResultsViaPluginHook()
 {
     // Diverting a search to the search plugin hook.
     HookRegistry::register('SubmissionSearch::retrieveResults', array($this, 'callbackRetrieveResults'));
     $testCases = array(array(null => 'query'), array('1' => 'author'), array('2' => 'title'), array(null => 'query', 1 => 'author', 2 => 'title'));
     $testFromDate = date('Y-m-d H:i:s', strtotime('2011-03-15 00:00:00'));
     $testToDate = date('Y-m-d H:i:s', strtotime('2012-03-15 18:30:00'));
     $error = '';
     foreach ($testCases as $testCase) {
         // Test a simple search with the simulated callback.
         $journal = new Journal();
         $keywords = $testCase;
         $articleSearch = new ArticleSearch();
         $searchResult = $articleSearch->retrieveResults($journal, $keywords, $error, $testFromDate, $testToDate);
         // Check the parameters passed into the callback.
         $expectedPage = 1;
         $expectedItemsPerPage = 20;
         $expectedTotalResults = 3;
         $expectedError = '';
         $expectedParams = array($journal, $testCase, $testFromDate, $testToDate, $expectedPage, $expectedItemsPerPage, $expectedTotalResults, $expectedError);
         self::assertEquals($expectedParams, $this->_retrieveResultsParams);
         // Test and clear the call history of the hook registry.
         $calledHooks = HookRegistry::getCalledHooks();
         self::assertEquals('SubmissionSearch::retrieveResults', $calledHooks[0][0]);
         HookRegistry::resetCalledHooks(true);
         // Test whether the result from the hook is being returned.
         self::assertInstanceOf('VirtualArrayIterator', $searchResult);
         // Test the total count.
         self::assertEquals(3, $searchResult->getCount());
         // Test the search result.
         $firstResult = $searchResult->next();
         self::assertArrayHasKey('article', $firstResult);
         self::assertEquals(SUBMISSION_SEARCH_TEST_ARTICLE_FROM_PLUGIN, $firstResult['article']->getId());
         self::assertEquals('', $error);
     }
     // Remove the test hook.
     HookRegistry::clear('SubmissionSearch::retrieveResults');
 }
Exemplo n.º 13
0
 /**
  * @see templates/article/footer.tpl
  */
 function callbackTemplateArticlePageFooter($hookName, $params)
 {
     $smarty =& $params[1];
     $output =& $params[2];
     // Find articles of the same author(s).
     $displayedArticle = $smarty->get_template_vars('article');
     $authors = $displayedArticle->getAuthors();
     $authorDao = DAORegistry::getDAO('AuthorDAO');
     /* @var $authorDao AuthorDAO */
     $foundArticles = array();
     foreach ($authors as $author) {
         /* @var $author Author */
         // The following article search is by name only as authors are
         // not normalized in OJS. This is rather crude and may produce
         // false positives or miss some entries. But there's no other way
         // until OJS allows users to consistently normalize authors (via name,
         // email, ORCID, whatever).
         $articles = $authorDao->getPublishedArticlesForAuthor(null, $author->getFirstName(), $author->getMiddleName(), $author->getLastName(), $author->getLocalizedAffiliation(), $author->getCountry());
         foreach ($articles as $article) {
             /* @var $article PublishedArticle */
             if ($displayedArticle->getId() == $article->getId()) {
                 continue;
             }
             $foundArticles[] = $article->getId();
         }
     }
     $results = array_unique($foundArticles);
     // Order results by metric.
     $application = PKPApplication::getApplication();
     $metricType = $application->getDefaultMetricType();
     if (empty($metricType)) {
         $smarty->assign('noMetricSelected', true);
     }
     $column = STATISTICS_DIMENSION_ARTICLE_ID;
     $filter = array(STATISTICS_DIMENSION_ASSOC_TYPE => array(ASSOC_TYPE_GALLEY, ASSOC_TYPE_ARTICLE), STATISTICS_DIMENSION_ARTICLE_ID => array($results));
     $orderBy = array(STATISTICS_METRIC => STATISTICS_ORDER_DESC);
     $statsReport = $application->getMetrics($metricType, $column, $filter, $orderBy);
     $orderedResults = array();
     foreach ($statsReport as $reportRow) {
         $orderedResults[] = $reportRow['submission_id'];
     }
     // Make sure we even get results that have no statistics (yet) and that
     // we get them in some consistent order for paging.
     $remainingResults = array_diff($results, $orderedResults);
     sort($remainingResults);
     $orderedResults = array_merge($orderedResults, $remainingResults);
     // Pagination.
     $request = PKPApplication::getRequest();
     $rangeInfo = Handler::getRangeInfo($request, 'articlesBySameAuthor');
     if ($rangeInfo && $rangeInfo->isValid()) {
         $page = $rangeInfo->getPage();
     } else {
         $page = 1;
     }
     $totalResults = count($orderedResults);
     $itemsPerPage = RECOMMEND_BY_AUTHOR_PLUGIN_COUNT;
     $offset = $itemsPerPage * ($page - 1);
     $length = max($totalResults - $offset, 0);
     $length = min($itemsPerPage, $length);
     if ($length == 0) {
         $pagedResults = array();
     } else {
         $pagedResults = array_slice($orderedResults, $offset, $length);
     }
     // Visualization.
     import('classes.search.ArticleSearch');
     $articleSearch = new ArticleSearch();
     $pagedResults = $articleSearch->formatResults($pagedResults);
     import('lib.pkp.classes.core.VirtualArrayIterator');
     $returner = new VirtualArrayIterator($pagedResults, $totalResults, $page, $itemsPerPage);
     $smarty->assign('articlesBySameAuthor', $returner);
     $output .= $smarty->fetch($this->getTemplatePath() . 'articleFooter.tpl');
     return false;
 }
Exemplo n.º 14
0
 function display(&$args, $request)
 {
     $templateMgr =& TemplateManager::getManager();
     parent::display($args, $request);
     $this->setBreadcrumbs();
     $journal =& Request::getJournal();
     $plugin =& $this->getSwordPlugin();
     $swordUrl = Request::getUserVar('swordUrl');
     $depositPointKey = Request::getUserVar('depositPoint');
     $depositPoints = $plugin->getSetting($journal->getId(), 'depositPoints');
     $username = Request::getUserVar('swordUsername');
     $password = Request::getUserVar('swordPassword');
     if (isset($depositPoints[$depositPointKey])) {
         $selectedDepositPoint = $depositPoints[$depositPointKey];
         if ($selectedDepositPoint['username'] != '') {
             $username = $selectedDepositPoint['username'];
         }
         if ($selectedDepositPoint['password'] != '') {
             $password = $selectedDepositPoint['password'];
         }
     }
     $swordDepositPoint = Request::getUserVar('swordDepositPoint');
     $depositEditorial = Request::getUserVar('depositEditorial');
     $depositGalleys = Request::getUserVar('depositGalleys');
     switch (array_shift($args)) {
         case 'deposit':
             $depositIds = array();
             try {
                 foreach (Request::getUserVar('articleId') as $articleId) {
                     $depositIds[] = $this->deposit($swordDepositPoint, $username, $password, $articleId, $depositEditorial, $depositGalleys);
                 }
             } catch (Exception $e) {
                 // Deposit failed
                 $templateMgr->assign(array('pageTitle' => 'plugins.importexport.sword.depositFailed', 'messageTranslated' => $e->getMessage(), 'backLink' => Request::url(null, null, null, array('plugin', $this->getName()), array('swordUrl' => $swordUrl, 'swordUsername' => $username, 'swordDepositPoint' => $swordDepositPoint, 'depositEditorial' => $depositEditorial, 'depositGalleys' => $depositGalleys)), 'backLinkLabel' => 'common.back'));
                 return $templateMgr->display('common/message.tpl');
             }
             // Deposit was successful
             $templateMgr->assign(array('pageTitle' => 'plugins.importexport.sword.depositSuccessful', 'message' => 'plugins.importexport.sword.depositSuccessfulDescription', 'backLink' => Request::url(null, null, null, array('plugin', $this->getName()), array('swordUrl' => $swordUrl, 'swordUsername' => $username, 'swordDepositPoint' => $swordDepositPoint, 'depositEditorial' => $depositEditorial, 'depositGalleys' => $depositGalleys)), 'backLinkLabel' => 'common.continue'));
             return $templateMgr->display('common/message.tpl');
             break;
         default:
             $journal =& Request::getJournal();
             $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
             $rangeInfo = Handler::getRangeInfo('articles');
             $articleIds = $publishedArticleDao->getPublishedArticleIdsAlphabetizedByJournal($journal->getId(), false);
             $totalArticles = count($articleIds);
             if ($rangeInfo->isValid()) {
                 $articleIds = array_slice($articleIds, $rangeInfo->getCount() * ($rangeInfo->getPage() - 1), $rangeInfo->getCount());
             }
             import('lib.pkp.classes.core.VirtualArrayIterator');
             $iterator = new VirtualArrayIterator(ArticleSearch::formatResults($articleIds), $totalArticles, $rangeInfo->getPage(), $rangeInfo->getCount());
             foreach (array('swordUrl', 'swordUsername', 'swordPassword', 'depositEditorial', 'depositGalleys', 'swordDepositPoint') as $var) {
                 $templateMgr->assign($var, Request::getUserVar($var));
             }
             $templateMgr->assign('depositPoints', $depositPoints);
             if (!empty($swordUrl)) {
                 $client = new SWORDAPPClient();
                 $doc = $client->servicedocument($swordUrl, $username, $password, '');
                 $depositPoints = array();
                 if (is_array($doc->sac_workspaces)) {
                     foreach ($doc->sac_workspaces as $workspace) {
                         if (is_array($workspace->sac_collections)) {
                             foreach ($workspace->sac_collections as $collection) {
                                 $depositPoints["{$collection->sac_href}"] = "{$collection->sac_colltitle}";
                             }
                         }
                     }
                 }
                 $templateMgr->assign_by_ref('swordDepositPoints', $depositPoints);
             }
             $templateMgr->assign_by_ref('articles', $iterator);
             $templateMgr->display($this->getTemplatePath() . 'articles.tpl');
             break;
     }
 }
Exemplo n.º 15
0
 /**
  * Return an array of search results matching the supplied
  * keyword IDs in decreasing order of match quality.
  * Keywords are supplied in an array of the following format:
  * $keywords[ARTICLE_SEARCH_AUTHOR] = array('John', 'Doe');
  * $keywords[ARTICLE_SEARCH_...] = array(...);
  * $keywords[null] = array('Matches', 'All', 'Fields');
  * @param $journal object The journal to search
  * @param $keywords array List of keywords
  * @param $error string a reference to a variable that will
  *  contain an error message if the search service produces
  *  an error.
  * @param $publishedFrom object Search-from date
  * @param $publishedTo object Search-to date
  * @param $rangeInfo Information on the range of results to return
  * @return VirtualArrayIterator An iterator with one entry per retrieved
  *  article containing the article, published article, issue, journal, etc.
  */
 function &retrieveResults(&$journal, &$keywords, &$error, $publishedFrom = null, $publishedTo = null, $rangeInfo = null)
 {
     // Pagination
     if ($rangeInfo && $rangeInfo->isValid()) {
         $page = $rangeInfo->getPage();
         $itemsPerPage = $rangeInfo->getCount();
     } else {
         $page = 1;
         $itemsPerPage = ARTICLE_SEARCH_DEFAULT_RESULT_LIMIT;
     }
     // Check whether a search plug-in jumps in to provide ranked search results.
     $totalResults = null;
     $results =& HookRegistry::call('ArticleSearch::retrieveResults', array(&$journal, &$keywords, $publishedFrom, $publishedTo, $page, $itemsPerPage, &$totalResults, &$error));
     // If no search plug-in is activated then fall back to the
     // default database search implementation.
     if ($results === false) {
         // Parse the query.
         foreach ($keywords as $searchType => $query) {
             $keywords[$searchType] = ArticleSearch::_parseQuery($query);
         }
         // Fetch all the results from all the keywords into one array
         // (mergedResults), where mergedResults[article_id]
         // = sum of all the occurences for all keywords associated with
         // that article ID.
         $mergedResults =& ArticleSearch::_getMergedArray($journal, $keywords, $publishedFrom, $publishedTo);
         // Convert mergedResults into an array (frequencyIndicator =>
         // $articleId).
         // The frequencyIndicator is a synthetically-generated number,
         // where higher is better, indicating the quality of the match.
         // It is generated here in such a manner that matches with
         // identical frequency do not collide.
         $results =& ArticleSearch::_getSparseArray($mergedResults);
         $totalResults = count($results);
         // Use only the results for the specified page.
         $offset = $itemsPerPage * ($page - 1);
         $length = max($totalResults - $offset, 0);
         $length = min($itemsPerPage, $length);
         if ($length == 0) {
             $results = array();
         } else {
             $results = array_slice($results, $offset, $length);
         }
     }
     // Take the range of results and retrieve the Article, Journal,
     // and associated objects.
     $results =& ArticleSearch::formatResults($results);
     // Return the appropriate iterator.
     import('lib.pkp.classes.core.VirtualArrayIterator');
     $returner = new VirtualArrayIterator($results, $totalResults, $page, $itemsPerPage);
     return $returner;
 }
Exemplo n.º 16
0
 /**
  * Execute import/export tasks using the command-line interface.
  * @param $args Parameters to the plugin
  */
 function executeCLI($scriptName, &$args)
 {
     $command = array_shift($args);
     $xmlFile = array_shift($args);
     $journalPath = array_shift($args);
     AppLocale::requireComponents(LOCALE_COMPONENT_APPLICATION_COMMON);
     $journalDao =& DAORegistry::getDAO('JournalDAO');
     $issueDao =& DAORegistry::getDAO('IssueDAO');
     $sectionDao =& DAORegistry::getDAO('SectionDAO');
     $userDao =& DAORegistry::getDAO('UserDAO');
     $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
     $journal =& $journalDao->getJournalByPath($journalPath);
     if (!$journal) {
         if ($journalPath != '') {
             echo __('plugins.importexport.native.cliError') . "\n";
             echo __('plugins.importexport.native.error.unknownJournal', array('journalPath' => $journalPath)) . "\n\n";
         }
         $this->usage($scriptName);
         return;
     }
     $this->import('NativeImportDom');
     if ($xmlFile && NativeImportDom::isRelativePath($xmlFile)) {
         $xmlFile = PWD . '/' . $xmlFile;
     }
     switch ($command) {
         case 'import':
             $userName = array_shift($args);
             $user =& $userDao->getByUsername($userName);
             if (!$user) {
                 if ($userName != '') {
                     echo __('plugins.importexport.native.cliError') . "\n";
                     echo __('plugins.importexport.native.error.unknownUser', array('userName' => $userName)) . "\n\n";
                 }
                 $this->usage($scriptName);
                 return;
             }
             $doc =& $this->getDocument($xmlFile);
             $context = array('user' => $user, 'journal' => $journal);
             switch ($this->getRootNodeName($doc)) {
                 case 'article':
                 case 'articles':
                     // Determine the extra context information required
                     // for importing articles.
                     if (array_shift($args) !== 'issue_id') {
                         return $this->usage($scriptName);
                     }
                     $issue =& $issueDao->getIssueByBestIssueId($issueId = array_shift($args), $journal->getId());
                     if (!$issue) {
                         echo __('plugins.importexport.native.cliError') . "\n";
                         echo __('plugins.importexport.native.export.error.issueNotFound', array('issueId' => $issueId)) . "\n\n";
                         return;
                     }
                     $context['issue'] =& $issue;
                     switch (array_shift($args)) {
                         case 'section_id':
                             $section =& $sectionDao->getSection($sectionIdentifier = array_shift($args));
                             break;
                         case 'section_name':
                             $section =& $sectionDao->getSectionByTitle($sectionIdentifier = array_shift($args), $journal->getId());
                             break;
                         case 'section_abbrev':
                             $section =& $sectionDao->getSectionByAbbrev($sectionIdentifier = array_shift($args), $journal->getId());
                             break;
                         default:
                             return $this->usage($scriptName);
                     }
                     if (!$section) {
                         echo __('plugins.importexport.native.cliError') . "\n";
                         echo __('plugins.importexport.native.export.error.sectionNotFound', array('sectionIdentifier' => $sectionIdentifier)) . "\n\n";
                         return;
                     }
                     $context['section'] =& $section;
             }
             $result = $this->handleImport($context, $doc, $errors, $issues, $articles, true);
             if ($result) {
                 echo __('plugins.importexport.native.import.success.description') . "\n\n";
                 if (!empty($issues)) {
                     echo __('issue.issues') . ":\n";
                 }
                 foreach ($issues as $issue) {
                     echo "\t" . $issue->getIssueIdentification() . "\n";
                 }
                 if (!empty($articles)) {
                     echo __('article.articles') . ":\n";
                 }
                 foreach ($articles as $article) {
                     echo "\t" . $article->getLocalizedTitle() . "\n";
                 }
             } else {
                 $errorsTranslated = array();
                 foreach ($errors as $error) {
                     $errorsTranslated[] = __($error[0], $error[1]);
                 }
                 echo __('plugins.importexport.native.cliError') . "\n";
                 foreach ($errorsTranslated as $errorTranslated) {
                     echo "\t" . $errorTranslated . "\n";
                 }
             }
             return;
             break;
         case 'export':
             if ($xmlFile != '') {
                 switch (array_shift($args)) {
                     case 'article':
                         $articleId = array_shift($args);
                         $publishedArticle =& $publishedArticleDao->getPublishedArticleByBestArticleId($journal->getId(), $articleId);
                         if ($publishedArticle == null) {
                             echo __('plugins.importexport.native.cliError') . "\n";
                             echo __('plugins.importexport.native.export.error.articleNotFound', array('articleId' => $articleId)) . "\n\n";
                             return;
                         }
                         $issue =& $issueDao->getIssueById($publishedArticle->getIssueId(), $journal->getId());
                         $sectionDao =& DAORegistry::getDAO('SectionDAO');
                         $section =& $sectionDao->getSection($publishedArticle->getSectionId());
                         if (!$this->exportArticle($journal, $issue, $section, $publishedArticle, $xmlFile)) {
                             echo __('plugins.importexport.native.cliError') . "\n";
                             echo __('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
                         }
                         return;
                     case 'articles':
                         $results =& ArticleSearch::formatResults($args);
                         if (!$this->exportArticles($results, $xmlFile)) {
                             echo __('plugins.importexport.native.cliError') . "\n";
                             echo __('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
                         }
                         return;
                     case 'issue':
                         $issueId = array_shift($args);
                         $issue =& $issueDao->getIssueByBestIssueId($issueId, $journal->getId());
                         if ($issue == null) {
                             echo __('plugins.importexport.native.cliError') . "\n";
                             echo __('plugins.importexport.native.export.error.issueNotFound', array('issueId' => $issueId)) . "\n\n";
                             return;
                         }
                         if (!$this->exportIssue($journal, $issue, $xmlFile)) {
                             echo __('plugins.importexport.native.cliError') . "\n";
                             echo __('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
                         }
                         return;
                     case 'issues':
                         $issues = array();
                         while (($issueId = array_shift($args)) !== null) {
                             $issue =& $issueDao->getIssueByBestIssueId($issueId, $journal->getId());
                             if ($issue == null) {
                                 echo __('plugins.importexport.native.cliError') . "\n";
                                 echo __('plugins.importexport.native.export.error.issueNotFound', array('issueId' => $issueId)) . "\n\n";
                                 return;
                             }
                             $issues[] =& $issue;
                         }
                         if (!$this->exportIssues($journal, $issues, $xmlFile)) {
                             echo __('plugins.importexport.native.cliError') . "\n";
                             echo __('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
                         }
                         return;
                 }
             }
             break;
     }
     $this->usage($scriptName);
 }
Exemplo n.º 17
0
 /**
  * Configure the search request from a keywords
  * array as required by ArticleSearch::retrieveResults()
  *
  * @param $keywords array See ArticleSearch::retrieveResults()
  */
 function addQueryFromKeywords($keywords)
 {
     // Get a mapping of OJS search fields bitmaps to index fields.
     $indexFieldMap = ArticleSearch::getIndexFieldMap();
     // The keywords list is indexed with a search field bitmap.
     foreach ($keywords as $searchFieldBitmap => $searchPhrase) {
         // Translate the search field from OJS to solr nomenclature.
         if (empty($searchFieldBitmap)) {
             // An empty search field means "all fields".
             $solrFields = array_values($indexFieldMap);
         } else {
             $solrFields = array();
             foreach ($indexFieldMap as $ojsField => $solrField) {
                 // The search field bitmap may stand for
                 // several actual index fields (e.g. the index terms
                 // field).
                 if ($searchFieldBitmap & $ojsField) {
                     $solrFields[] = $solrField;
                 }
             }
         }
         $solrFieldString = implode('|', $solrFields);
         $this->addQueryFieldPhrase($solrFieldString, $searchPhrase);
     }
 }
Exemplo n.º 18
0
 /**
  * Return an array of search results matching the supplied
  * keyword IDs in decreasing order of match quality.
  * Keywords are supplied in an array of the following format:
  * $keywords[ARTICLE_SEARCH_AUTHOR] = array('John', 'Doe');
  * $keywords[ARTICLE_SEARCH_...] = array(...);
  * $keywords[null] = array('Matches', 'All', 'Fields');
  * @param $journal object The journal to search
  * @param $keywords array List of keywords
  * @param $publishedFrom object Search-from date
  * @param $publishedTo object Search-to date
  * @param $rangeInfo Information on the range of results to return
  */
 function &retrieveResults(&$journal, &$keywords, $publishedFrom = null, $publishedTo = null, $rangeInfo = null)
 {
     // Fetch all the results from all the keywords into one array
     // (mergedResults), where mergedResults[article_id]
     // = sum of all the occurences for all keywords associated with
     // that article ID.
     // resultCount contains the sum of result counts for all keywords.
     $mergedResults =& ArticleSearch::_getMergedArray($journal, $keywords, $publishedFrom, $publishedTo, $resultCount);
     // Convert mergedResults into an array (frequencyIndicator =>
     // $articleId).
     // The frequencyIndicator is a synthetically-generated number,
     // where higher is better, indicating the quality of the match.
     // It is generated here in such a manner that matches with
     // identical frequency do not collide.
     $results =& ArticleSearch::_getSparseArray($mergedResults, $resultCount);
     $totalResults = count($results);
     // Use only the results for the specified page, if specified.
     if ($rangeInfo && $rangeInfo->isValid()) {
         $results = array_slice($results, $rangeInfo->getCount() * ($rangeInfo->getPage() - 1), $rangeInfo->getCount());
         $page = $rangeInfo->getPage();
         $itemsPerPage = $rangeInfo->getCount();
     } else {
         $page = 1;
         $itemsPerPage = max($totalResults, 1);
     }
     // Take the range of results and retrieve the Article, Journal,
     // and associated objects.
     $results =& ArticleSearch::formatResults($results);
     // Return the appropriate iterator.
     $returner =& new VirtualArrayIterator($results, $totalResults, $page, $itemsPerPage);
     return $returner;
 }
Exemplo n.º 19
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;
 }