Open Monograph Press  3.3.0
MonographSearch.inc.php
1 <?php
2 
18 import('lib.pkp.classes.search.SubmissionSearch');
19 
24  function getSparseArray($unorderedResults, $orderBy, $orderDir, $exclude) {
25  // Calculate a well-ordered (unique) score.
26  $resultCount = count($unorderedResults);
27  $i = 0;
28  foreach ($unorderedResults as $submissionId => &$data) {
29  // Reference is necessary to permit modification
30  $data['score'] = ($resultCount * $data['count']) + $i++;
31  }
32 
33  // If we got a primary sort order then apply it and use score as secondary
34  // order only.
35  // NB: We apply order after merging and before paging/formatting. Applying
36  // order before merging would require us to retrieve dependent objects for
37  // results being purged later. Doing everything in a closed SQL is not
38  // possible (e.g. for authors). Applying sort order after paging and
39  // formatting is not possible as we have to order the whole list before
40  // slicing it. So this seems to be the most appropriate place, although we
41  // may have to retrieve some objects again when formatting results.
42  $orderedResults = array();
43  $authorDao = DAORegistry::getDAO('AuthorDAO'); /* @var $authorDao AuthorDAO */
44  $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */
45  $contextDao = Application::getContextDAO();
46  $contextTitles = array();
47  if ($orderBy == 'popularityAll' || $orderBy == 'popularityMonth') {
49  $metricType = $application->getDefaultMetricType();
50  if (is_null($metricType)) {
51  // If no default metric has been found then sort by score...
52  $orderBy = 'score';
53  } else {
54  // Retrieve a metrics report for all submissions.
55  $column = STATISTICS_DIMENSION_SUBMISSION_ID;
56  $filter = array(
57  STATISTICS_DIMENSION_ASSOC_TYPE => array(ASSOC_TYPE_GALLEY, ASSOC_TYPE_SUBMISSION),
58  STATISTICS_DIMENSION_SUBMISSION_ID => array(array_keys($unorderedResults))
59  );
60  if ($orderBy == 'popularityMonth') {
61  $oneMonthAgo = date('Ymd', strtotime('-1 month'));
62  $today = date('Ymd');
63  $filter[STATISTICS_DIMENSION_DAY] = array('from' => $oneMonthAgo, 'to' => $today);
64  }
65  $rawReport = $application->getMetrics($metricType, $column, $filter);
66  foreach ($rawReport as $row) {
67  $unorderedResults[$row['submission_id']]['metric'] = (int)$row['metric'];
68  }
69  }
70  }
71 
72  $i=0; // Used to prevent ties from clobbering each other
73  foreach ($unorderedResults as $submissionId => $data) {
74  // Exclude unwanted IDs.
75  if (in_array($submissionId, $exclude)) continue;
76 
77  switch ($orderBy) {
78  case 'authors':
79  $submission = $submissionDao->getById($submissionId);
80  $orderKey = $submission->getAuthorString();
81  break;
82 
83  case 'title':
84  $submission = $submissionDao->getById($submissionId);
85  $orderKey = '';
86  if (!empty($submission->getCurrentPublication())) {
87  $orderKey = $submission->getCurrentPublication()->getLocalizedData('title');
88  }
89  break;
90 
91  case 'pressTitle':
92  if (!isset($contextTitles[$data['press_id']])) {
93  $press = $contextDao->getById($data['press_id']);
94  $contextTitles[$data['press_id']] = $press->getLocalizedName();
95  }
96  $orderKey = $contextTitles[$data['press_id']];
97  break;
98 
99  case 'publicationDate':
100  $orderKey = $data[$orderBy];
101  break;
102 
103  case 'popularityAll':
104  case 'popularityMonth':
105  $orderKey = (isset($data['metric']) ? $data['metric'] : 0);
106  break;
107 
108  default: // order by score.
109  $orderKey = $data['score'];
110  }
111  if (!isset($orderedResults[$orderKey])) {
112  $orderedResults[$orderKey] = array();
113  }
114  $orderedResults[$orderKey][$data['score'] + $i++] = $submissionId;
115  }
116 
117  // Order the results by primary order.
118  if (strtolower($orderDir) == 'asc') {
119  ksort($orderedResults);
120  } else {
121  krsort($orderedResults);
122  }
123 
124  // Order the result by secondary order and flatten it.
125  $finalOrder = array();
126  foreach($orderedResults as $orderKey => $submissionIds) {
127  if (count($submissionIds) == 1) {
128  $finalOrder[] = array_pop($submissionIds);
129  } else {
130  if (strtolower($orderDir) == 'asc') {
131  ksort($submissionIds);
132  } else {
133  krsort($submissionIds);
134  }
135  $finalOrder = array_merge($finalOrder, array_values($submissionIds));
136  }
137  }
138  return $finalOrder;
139  }
140 
146  function getSearchFilters($request) {
147  $searchFilters = array(
148  'query' => $request->getUserVar('query'),
149  'searchPress' => $request->getUserVar('searchPress'),
150  'abstract' => $request->getUserVar('abstract'),
151  'authors' => $request->getUserVar('authors'),
152  'title' => $request->getUserVar('title'),
153  'galleyFullText' => $request->getUserVar('galleyFullText'),
154  'suppFiles' => $request->getUserVar('suppFiles'),
155  'discipline' => $request->getUserVar('discipline'),
156  'subject' => $request->getUserVar('subject'),
157  'type' => $request->getUserVar('type'),
158  'coverage' => $request->getUserVar('coverage'),
159  'indexTerms' => $request->getUserVar('indexTerms')
160  );
161 
162  // Is this a simplified query from the navigation
163  // block plugin?
164  $simpleQuery = $request->getUserVar('simpleQuery');
165  if (!empty($simpleQuery)) {
166  // In the case of a simplified query we get the
167  // filter type from a drop-down.
168  $searchType = $request->getUserVar('searchField');
169  if (array_key_exists($searchType, $searchFilters)) {
170  $searchFilters[$searchType] = $simpleQuery;
171  }
172  }
173 
174  // Publishing dates.
175  $fromDate = $request->getUserDateVar('dateFrom', 1, 1);
176  $searchFilters['fromDate'] = (is_null($fromDate) ? null : date('Y-m-d H:i:s', $fromDate));
177  $toDate = $request->getUserDateVar('dateTo', 32, 12, null, 23, 59, 59);
178  $searchFilters['toDate'] = (is_null($toDate) ? null : date('Y-m-d H:i:s', $toDate));
179 
180  // Instantiate the context.
181  $context = $request->getContext();
182  $siteSearch = !((boolean)$context);
183  if ($siteSearch) {
184  $contextDao = Application::getContextDAO();
185  if (!empty($searchFilters['searchPress'])) {
186  $context = $contextDao->getById($searchFilters['searchPress']);
187  } elseif (array_key_exists('pressTitle', $request->getUserVars())) {
188  $contexts = $contextDao->getAll(true);
189  while ($context = $contexts->next()) {
190  if (in_array(
191  $request->getUserVar('pressTitle'),
192  (array) $context->getTitle(null)
193  )) break;
194  }
195  }
196  }
197  $searchFilters['searchPress'] = $context;
198  $searchFilters['siteSearch'] = $siteSearch;
199 
200  return $searchFilters;
201  }
202 
209  function getKeywordsFromSearchFilters($searchFilters) {
210  $indexFieldMap = $this->getIndexFieldMap();
211  $indexFieldMap[SUBMISSION_SEARCH_INDEX_TERMS] = 'indexTerms';
212  $keywords = array();
213  if (isset($searchFilters['query'])) {
214  $keywords[null] = $searchFilters['query'];
215  }
216  foreach($indexFieldMap as $bitmap => $searchField) {
217  if (isset($searchFilters[$searchField]) && !empty($searchFilters[$searchField])) {
218  $keywords[$bitmap] = $searchFilters[$searchField];
219  }
220  }
221  return $keywords;
222  }
223 
227  function formatResults($results, $user = null) {
228  $contextDao = Application::getContextDAO();
229  $seriesDao = DAORegistry::getDAO('SeriesDAO'); /* @var $seriesDao SeriesDAO */
230 
231  $publishedSubmissionCache = array();
232  $monographCache = array();
233  $contextCache = array();
234  $seriesCache = array();
235 
236  $returner = array();
237  foreach ($results as $monographId) {
238  // Get the monograph, storing in cache if necessary.
239  if (!isset($monographCache[$monographId])) {
240  $submission = Services::get('submission')->get($monographId);
241  $monographCache[$monographId] = $submission;
242  $publishedSubmissionCache[$monographId] = $submission;
243  }
244  unset($monograph, $publishedSubmission);
245  $monograph = $monographCache[$monographId];
246  $publishedSubmission = $publishedSubmissionCache[$monographId];
247 
248  if ($monograph) {
249  $seriesId = $monograph->getSeriesId();
250  if (!isset($seriesCache[$seriesId])) {
251  $seriesCache[$seriesId] = $seriesDao->getById($seriesId);
252  }
253 
254  // Get the context, storing in cache if necessary.
255  $contextId = $monograph->getData('contextId');
256  if (!isset($contextCache[$contextId])) {
257  $contextCache[$contextId] = $contextDao->getById($contextId);
258  }
259 
260  // Store the retrieved objects in the result array.
261  $returner[] = array(
262  'press' => $contextCache[$contextId],
263  'monograph' => $monograph,
264  'publishedSubmission' => $publishedSubmission,
265  'seriesArrangment' => $seriesCache[$seriesId]
266  );
267  }
268  }
269  return $returner;
270  }
271 
272  function getIndexFieldMap() {
273  return array(
274  SUBMISSION_SEARCH_AUTHOR => 'authors',
275  SUBMISSION_SEARCH_TITLE => 'title',
276  SUBMISSION_SEARCH_ABSTRACT => 'abstract',
277  SUBMISSION_SEARCH_GALLEY_FILE => 'galleyFullText',
278  SUBMISSION_SEARCH_SUPPLEMENTARY_FILE => 'suppFiles',
279  SUBMISSION_SEARCH_DISCIPLINE => 'discipline',
280  SUBMISSION_SEARCH_SUBJECT => 'subject',
281  SUBMISSION_SEARCH_TYPE => 'type',
282  SUBMISSION_SEARCH_COVERAGE => 'coverage'
283  );
284  }
285 
289  function getResultSetOrderingOptions($request) {
290  $resultSetOrderingOptions = array(
291  'score' => __('search.results.orderBy.relevance'),
292  'authors' => __('search.results.orderBy.author'),
293  'publicationDate' => __('search.results.orderBy.date'),
294  'title' => __('search.results.orderBy.monograph')
295  );
296 
297  // Only show the "popularity" options if we have a default metric.
299  $metricType = $application->getDefaultMetricType();
300  if (!is_null($metricType)) {
301  $resultSetOrderingOptions['popularityAll'] = __('search.results.orderBy.popularityAll');
302  $resultSetOrderingOptions['popularityMonth'] = __('search.results.orderBy.popularityMonth');
303  }
304 
305  // Only show the "press title" option if we have several presses.
306  $context = $request->getContext();
307  if (!is_a($context, 'Context')) {
308  $resultSetOrderingOptions['pressTitle'] = __('search.results.orderBy.press');
309  }
310 
311  // Let plugins mangle the search ordering options.
313  'SubmissionSearch::getResultSetOrderingOptions',
314  array($context, &$resultSetOrderingOptions)
315  );
316 
317  return $resultSetOrderingOptions;
318  }
319 
323  function getDefaultOrderDir($orderBy) {
324  $orderDir = 'asc';
325  if (in_array($orderBy, array('score', 'publicationDate', 'popularityAll', 'popularityMonth'))) {
326  $orderDir = 'desc';
327  }
328  return $orderDir;
329  }
330 
335  protected function getSearchDao() {
336  return DAORegistry::getDAO('MonographSearchDAO');
337  }
338 }
339 
340 
Application\getContextDAO
static getContextDAO()
Definition: Application.inc.php:145
SubmissionSearch
Class for retrieving search results.
Definition: SubmissionSearch.inc.php:35
$application
$application
Definition: index.php:61
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
MonographSearch\getKeywordsFromSearchFilters
getKeywordsFromSearchFilters($searchFilters)
Definition: MonographSearch.inc.php:209
MonographSearch
Class for retrieving monograph search results.
Definition: MonographSearch.inc.php:20
MonographSearch\getDefaultOrderDir
getDefaultOrderDir($orderBy)
Definition: MonographSearch.inc.php:323
MonographSearch\getSearchDao
getSearchDao()
Definition: MonographSearch.inc.php:335
MonographSearch\formatResults
formatResults($results, $user=null)
Definition: MonographSearch.inc.php:227
MonographSearch\getIndexFieldMap
getIndexFieldMap()
Definition: MonographSearch.inc.php:272
MonographSearch\getSparseArray
getSparseArray($unorderedResults, $orderBy, $orderDir, $exclude)
Definition: MonographSearch.inc.php:24
MonographSearch\getSearchFilters
getSearchFilters($request)
Definition: MonographSearch.inc.php:146
MonographSearch\getResultSetOrderingOptions
getResultSetOrderingOptions($request)
Definition: MonographSearch.inc.php:289
PKPApplication\get
static get()
Definition: PKPApplication.inc.php:235
HookRegistry\call
static call($hookName, $args=null)
Definition: HookRegistry.inc.php:86
PKPServices\get
static get($service)
Definition: PKPServices.inc.php:49