[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
14082024
/
Data
/
htdocs
/
htdocs
/
jurnal-kesmas
/
baru
/
classes
/
search
/
[
Home
]
File: ArticleSearch.php
<?php /** * @file classes/search/ArticleSearch.php * * Copyright (c) 2014-2021 Simon Fraser University * Copyright (c) 2003-2021 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class ArticleSearch * * @ingroup search * * @see ArticleSearchDAO * * @brief Class for retrieving article search results. * */ namespace APP\search; use APP\core\Application; use APP\core\Request; use APP\core\Services; use APP\facades\Repo; use APP\issue\IssueAction; use PKP\db\DAORegistry; use PKP\facades\Locale; use PKP\plugins\Hook; use PKP\search\SubmissionSearch; use PKP\submission\PKPSubmission; class ArticleSearch extends SubmissionSearch { /** * See SubmissionSearch::getSparseArray() */ public function getSparseArray($unorderedResults, $orderBy, $orderDir, $exclude) { // Calculate a well-ordered (unique) score. $resultCount = count($unorderedResults); $i = 0; $contextIds = []; foreach ($unorderedResults as $submissionId => &$data) { // Reference is necessary to permit modification $data['score'] = ($resultCount * $data['count']) + $i++; $contextIds[] = $data['journal_id']; } // If we got a primary sort order then apply it and use score as secondary // order only. // NB: We apply order after merging and before paging/formatting. Applying // order before merging would require us to retrieve dependent objects for // results being purged later. Doing everything in a closed SQL is not // possible (e.g. for authors). Applying sort order after paging and // formatting is not possible as we have to order the whole list before // slicing it. So this seems to be the most appropriate place, although we // may have to retrieve some objects again when formatting results. $orderedResults = []; $contextDao = Application::getContextDAO(); $contextTitles = []; if ($orderBy == 'popularityAll' || $orderBy == 'popularityMonth') { // Retrieve a metrics report for all submissions. $filter = [ 'submissionIds' => array_keys($unorderedResults), 'contextIds' => $contextIds, 'assocTypes' => [Application::ASSOC_TYPE_SUBMISSION, Application::ASSOC_TYPE_SUBMISSION_FILE] ]; if ($orderBy == 'popularityMonth') { $oneMonthAgo = date('Ymd', strtotime('-1 month')); $today = date('Ymd'); $filter['dateStart'] = $oneMonthAgo; $filter['dateEnd'] = $today; } $rawReport = Services::get('publicationStats')->getTotals($filter); foreach ($rawReport as $row) { $unorderedResults[$row->submission_id]['metric'] = $row->metric; } } $i = 0; // Used to prevent ties from clobbering each other $authorUserGroups = Repo::userGroup()->getCollector()->filterByRoleIds([\PKP\security\Role::ROLE_ID_AUTHOR])->getMany(); foreach ($unorderedResults as $submissionId => $data) { // Exclude unwanted IDs. if (in_array($submissionId, $exclude)) { continue; } switch ($orderBy) { case 'authors': $submission = Repo::submission()->get($submissionId); $orderKey = $submission->getCurrentPublication()->getAuthorString($authorUserGroups); break; case 'title': $submission = Repo::submission()->get($submissionId); $orderKey = ''; if (!empty($submission->getCurrentPublication())) { $orderKey = $submission->getCurrentPublication()->getLocalizedData('title'); } break; case 'journalTitle': if (!isset($contextTitles[$data['journal_id']])) { $context = $contextDao->getById($data['journal_id']); $contextTitles[$data['journal_id']] = $context->getLocalizedName(); } $orderKey = $contextTitles[$data['journal_id']]; break; case 'issuePublicationDate': case 'publicationDate': $orderKey = $data[$orderBy]; break; case 'popularityAll': case 'popularityMonth': $orderKey = ($data['metric'] ?? 0); break; default: // order by score. $orderKey = $data['score']; } if (!isset($orderedResults[$orderKey])) { $orderedResults[$orderKey] = []; } $orderedResults[$orderKey][$data['score'] + $i++] = $submissionId; } // Order the results by primary order. if (strtolower($orderDir) == 'asc') { ksort($orderedResults); } else { krsort($orderedResults); } // Order the result by secondary order and flatten it. $finalOrder = []; foreach ($orderedResults as $orderKey => $submissionIds) { if (count($submissionIds) == 1) { $finalOrder[] = array_pop($submissionIds); } else { if (strtolower($orderDir) == 'asc') { ksort($submissionIds); } else { krsort($submissionIds); } $finalOrder = array_merge($finalOrder, array_values($submissionIds)); } } return $finalOrder; } /** * Retrieve the search filters from the request. * * @param Request $request * * @return array All search filters (empty and active) */ public function getSearchFilters($request) { $searchFilters = [ 'query' => $request->getUserVar('query'), 'searchJournal' => $request->getUserVar('searchJournal'), 'abstract' => $request->getUserVar('abstract'), 'authors' => $request->getUserVar('authors'), 'title' => $request->getUserVar('title'), 'galleyFullText' => $request->getUserVar('galleyFullText'), 'discipline' => $request->getUserVar('discipline'), 'subject' => $request->getUserVar('subject'), 'type' => $request->getUserVar('type'), 'coverage' => $request->getUserVar('coverage'), 'indexTerms' => $request->getUserVar('indexTerms') ]; // Is this a simplified query from the navigation // block plugin? $simpleQuery = $request->getUserVar('simpleQuery'); if (!empty($simpleQuery)) { // In the case of a simplified query we get the // filter type from a drop-down. $searchType = $request->getUserVar('searchField'); if (array_key_exists($searchType, $searchFilters)) { $searchFilters[$searchType] = $simpleQuery; } } // Publishing dates. $fromDate = $request->getUserDateVar('dateFrom', 1, 1); $searchFilters['fromDate'] = (is_null($fromDate) ? null : date('Y-m-d H:i:s', $fromDate)); $toDate = $request->getUserDateVar('dateTo', 32, 12, null, 23, 59, 59); $searchFilters['toDate'] = (is_null($toDate) ? null : date('Y-m-d H:i:s', $toDate)); // Instantiate the context. $context = $request->getContext(); $siteSearch = !((bool)$context); if ($siteSearch) { $contextDao = Application::getContextDAO(); if (!empty($searchFilters['searchJournal'])) { $context = $contextDao->getById($searchFilters['searchJournal']); } elseif (array_key_exists('journalTitle', $request->getUserVars())) { $contexts = $contextDao->getAll(true); while ($context = $contexts->next()) { if (in_array( $request->getUserVar('journalTitle'), (array) $context->getName(null) )) { break; } } } } $searchFilters['searchJournal'] = $context; $searchFilters['siteSearch'] = $siteSearch; return $searchFilters; } /** * Load the keywords array from a given search filter. * * @param array $searchFilters Search filters as returned from * ArticleSearch::getSearchFilters() * * @return array Keyword array as required by SubmissionSearch::retrieveResults() */ public function getKeywordsFromSearchFilters($searchFilters) { $indexFieldMap = $this->getIndexFieldMap(); $indexFieldMap[SubmissionSearch::SUBMISSION_SEARCH_INDEX_TERMS] = 'indexTerms'; $keywords = []; if (isset($searchFilters['query'])) { $keywords[''] = $searchFilters['query']; } foreach ($indexFieldMap as $bitmap => $searchField) { if (isset($searchFilters[$searchField]) && !empty($searchFilters[$searchField])) { $keywords[$bitmap] = $searchFilters[$searchField]; } } return $keywords; } /** * See SubmissionSearch::formatResults() * * @param array $results * @param \PKP\user\User $user optional (if availability information is desired) * * @return array An array with the articles, published submissions, * issue, journal, section and the issue availability. */ public function formatResults($results, $user = null) { $contextDao = Application::getContextDAO(); $publishedSubmissionCache = []; $articleCache = []; $issueCache = []; $issueAvailabilityCache = []; $contextCache = []; $sectionCache = []; $returner = []; foreach ($results as $articleId) { // Get the article, storing in cache if necessary. if (!isset($articleCache[$articleId])) { $submission = Repo::submission()->get($articleId); $publishedSubmissionCache[$articleId] = $submission; $articleCache[$articleId] = $submission; } $article = $articleCache[$articleId]; $publishedSubmission = $publishedSubmissionCache[$articleId]; if ($publishedSubmission && $article) { $sectionId = $article->getSectionId(); if (!isset($sectionCache[$sectionId])) { $sectionCache[$sectionId] = Repo::section()->get($sectionId, $article->getData('contextId')); } // Get the context, storing in cache if necessary. $contextId = $article->getData('contextId'); if (!isset($contextCache[$contextId])) { $contextCache[$contextId] = $contextDao->getById($contextId); } // Get the issue, storing in cache if necessary. $issueId = $publishedSubmission->getCurrentPublication()->getData('issueId'); if ($issueId && !isset($issueCache[$issueId])) { $issue = Repo::issue()->get($issueId); $issueCache[$issueId] = $issue; $issueAction = new IssueAction(); $issueAvailabilityCache[$issueId] = !$issueAction->subscriptionRequired($issue, $contextCache[$contextId]) || $issueAction->subscribedUser($user, $contextCache[$contextId], $issueId, $articleId) || $issueAction->subscribedDomain(Application::get()->getRequest(), $contextCache[$contextId], $issueId, $articleId); } // Only display articles from published issues. if (!isset($issueCache[$issueId]) || !$issueCache[$issueId]->getPublished()) { continue; } // Store the retrieved objects in the result array. $returner[] = [ 'article' => $article, 'publishedSubmission' => $publishedSubmissionCache[$articleId], 'issue' => $issueCache[$issueId], 'journal' => $contextCache[$contextId], 'issueAvailable' => $issueAvailabilityCache[$issueId], 'section' => $sectionCache[$sectionId] ]; } } return $returner; } /** * Identify similarity terms for a given submission. * * @param int $submissionId * * @return null|array An array of string keywords or null * if some kind of error occurred. */ public function getSimilarityTerms($submissionId) { // Check whether a search plugin provides terms for a similarity search. $searchTerms = []; $result = Hook::call('ArticleSearch::getSimilarityTerms', [$submissionId, &$searchTerms]); // If no plugin implements the hook then use the subject keywords // of the submission for a similarity search. if ($result === false) { // Retrieve the article. $article = Repo::submission()->get($submissionId); if ($article->getData('status') === PKPSubmission::STATUS_PUBLISHED) { // Retrieve keywords (if any). $submissionSubjectDao = DAORegistry::getDAO('SubmissionKeywordDAO'); /** @var \PKP\submission\SubmissionKeywordDAO $submissionSubjectDao */ $allSearchTerms = array_filter($submissionSubjectDao->getKeywords($article->getCurrentPublication()->getId(), [Locale::getLocale(), $article->getLocale(), Locale::getPrimaryLocale()])); foreach ($allSearchTerms as $locale => $localeSearchTerms) { $searchTerms += $localeSearchTerms; } } } return $searchTerms; } public function getIndexFieldMap() { return [ SubmissionSearch::SUBMISSION_SEARCH_AUTHOR => 'authors', SubmissionSearch::SUBMISSION_SEARCH_TITLE => 'title', SubmissionSearch::SUBMISSION_SEARCH_ABSTRACT => 'abstract', SubmissionSearch::SUBMISSION_SEARCH_GALLEY_FILE => 'galleyFullText', SubmissionSearch::SUBMISSION_SEARCH_DISCIPLINE => 'discipline', SubmissionSearch::SUBMISSION_SEARCH_SUBJECT => 'subject', SubmissionSearch::SUBMISSION_SEARCH_KEYWORD => 'keyword', SubmissionSearch::SUBMISSION_SEARCH_TYPE => 'type', SubmissionSearch::SUBMISSION_SEARCH_COVERAGE => 'coverage' ]; } /** * See SubmissionSearch::getResultSetOrderingOptions() */ public function getResultSetOrderingOptions($request) { $resultSetOrderingOptions = [ 'score' => __('search.results.orderBy.relevance'), 'authors' => __('search.results.orderBy.author'), 'issuePublicationDate' => __('search.results.orderBy.issue'), 'publicationDate' => __('search.results.orderBy.date'), 'title' => __('search.results.orderBy.article') ]; // Only show the "popularity" options if we have a default metric. $resultSetOrderingOptions['popularityAll'] = __('search.results.orderBy.popularityAll'); $resultSetOrderingOptions['popularityMonth'] = __('search.results.orderBy.popularityMonth'); // Only show the "journal title" option if we have several journals. $context = $request->getContext(); if (!$context) { $resultSetOrderingOptions['journalTitle'] = __('search.results.orderBy.journal'); } // Let plugins mangle the search ordering options. Hook::call( 'SubmissionSearch::getResultSetOrderingOptions', [$context, &$resultSetOrderingOptions] ); return $resultSetOrderingOptions; } /** * See SubmissionSearch::getDefaultOrderDir() */ public function getDefaultOrderDir($orderBy) { $orderDir = 'asc'; if (in_array($orderBy, ['score', 'publicationDate', 'issuePublicationDate', 'popularityAll', 'popularityMonth'])) { $orderDir = 'desc'; } return $orderDir; } /** * See SubmissionSearch::getSearchDao() */ protected function getSearchDao() { return DAORegistry::getDAO('ArticleSearchDAO'); } } if (!PKP_STRICT_MODE) { class_alias('\APP\search\ArticleSearch', '\ArticleSearch'); }