Projet

Général

Profil

Paste
Télécharger (24,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ds / modules / ds_search / ds_search.module @ 3dfa8105

1
<?php
2

    
3
/**
4
 * @file
5
 * Display Suite search.
6
 */
7

    
8
/**
9
 * Implements hook_help().
10
 */
11
function ds_search_help($path, $arg) {
12
  switch ($path) {
13
    case 'admin/structure/ds/list/search':
14
      $output = '<dl>';
15
      $output .= '<dt>' . t('Display Suite defines its own search type for search. You need to enable it at !url when you are going to use Drupal core search. You do not have to enable and use it when using the Apachesolr module. Search results will be themed on the default Apachesolr pages.', array('!url' => l('search settings', 'admin/config/search/settings'))) . '</dt>';
16
      $output .= '</dl>';
17
      return $output;
18
  }
19
}
20

    
21
/**
22
 * Implements hook_menu().
23
 */
24
function ds_search_menu() {
25
  $items = array();
26

    
27
  $items['admin/structure/ds/list/search'] = array(
28
    'title' => 'Search',
29
    'description' => 'Configure search settings.',
30
    'page callback' => 'drupal_get_form',
31
    'page arguments' => array('ds_search_settings'),
32
    'access arguments' => array('admin_display_suite'),
33
    'file' => 'includes/ds_search.admin.inc',
34
    'type' => MENU_LOCAL_TASK,
35
  );
36

    
37
  return $items;
38
}
39

    
40
/**
41
 * Implements hook_theme().
42
 */
43
function ds_search_theme() {
44
  return array(
45
    'ds_search_page' => array(),
46
    'ds_search_group_by_type_settings' => array(
47
      'render element' => 'element',
48
      'file' => 'includes/ds_search.admin.inc',
49
    ),
50
  );
51
}
52

    
53
/**
54
 * Search page theming.
55
 */
56
function theme_ds_search_page($build) {
57

    
58
  // Check on empty search results.
59
  if (empty($build['search_results'])) {
60

    
61
    // Alter the title and extra variables.
62
    if (!empty($build['search_title'])) {
63
      $build['search_title']['#markup'] = '<h2>' . t('Your search yielded no results') . '</h2>';
64
      unset($build['search_extra']);
65
    }
66

    
67
    $build['search_empty'] = array('#markup' => search_help('search#noresults', drupal_help_arg()));
68
  }
69

    
70
  $build['search_results']['#sorted'] = TRUE;
71

    
72
  return $build;
73
}
74

    
75
/**
76
 * Implements hook_ds_fields_info().
77
 */
78
function ds_search_ds_fields_info($entity_type) {
79
  $fields = array();
80

    
81
  if ($entity_type == 'node') {
82
    $fields['node']['search_snippet'] = array(
83
      'title' => t('Search snippet'),
84
      'field_type' => DS_FIELD_TYPE_FUNCTION,
85
      'function' => 'ds_search_snippet',
86
      'ui_limit' => array('*|' . variable_get('ds_search_view_mode', 'search_result')),
87
    );
88
    $fields['node']['search_info'] = array(
89
      'title' => t('Search info'),
90
      'field_type' => DS_FIELD_TYPE_FUNCTION,
91
      'function' => 'ds_search_extra_info',
92
      'ui_limit' => array('*|' . variable_get('ds_search_view_mode', 'search_result')),
93
    );
94
  }
95

    
96
  if (isset($fields[$entity_type])) {
97
    return array($entity_type => $fields[$entity_type]);
98
  }
99

    
100
  return;
101
}
102

    
103
/**
104
 * Returns the snippet field.
105
 */
106
function ds_search_snippet($field) {
107
  // Apache Solr
108
  if (isset($field['entity']->search_snippet)) {
109
    return $field['entity']->search_snippet;
110
  }
111
  // Original node snippet
112
  elseif (isset($field['entity']->snippet)) {
113
    return $field['entity']->snippet;
114
  }
115
}
116

    
117
/**
118
 * Returns the info field, just like default search.
119
 */
120
function ds_search_extra_info($field) {
121
  $info = array();
122
  $info['user'] = theme('username', array('account' => $field['entity']));
123
  $info['date'] = format_date($field['entity']->changed, 'short');
124
  if (isset($field['entity']->search_extra) && is_array($field['entity']->search_extra)) {
125
    $info = array_merge($info, $field['entity']->search_extra);
126
  }
127
  return implode(' - ', $info);
128
}
129

    
130
/**
131
 * Implements hook_search_info().
132
 */
133
function ds_search_search_info() {
134
  return array(
135
    'title' => 'Content',
136
    'path' => variable_get('ds_search_path', 'content'),
137
  );
138
}
139

    
140
/**
141
 * Implements hook_node_update_index().
142
 */
143
function ds_search_update_index() {
144
  ds_search_invoke_node_search('update_index');
145
}
146

    
147
/**
148
 * Implements hook_search_status().
149
 */
150
function ds_search_search_status() {
151
  return ds_search_invoke_node_search('search_status');
152
}
153

    
154
/**
155
 * Implements hook_search_execute().
156
 */
157
function ds_search_search_execute($keys = NULL, $conditions = NULL) {
158
  // Save the keys in case we need them later on.
159
  ds_search_get_keys($keys);
160

    
161
  // We will call an extra function which handles the actual search.
162
  // In some cases, we simply copied a lot from the original hook,
163
  // because some modules already called drupal_render and were unsetting
164
  // the #theme key. By using our own search info type, we can call
165
  // hook_search_page ourselves and be as flexible as we need to be.
166
  $ds_search_type = variable_get('ds_search_type', 'node') . '_ds_search_execute';
167

    
168
  // Make sure the function exists.
169
  if (function_exists($ds_search_type)) {
170
    return $ds_search_type($keys, $conditions);
171
  }
172
}
173

    
174
/**
175
 * Save or get the search keys.
176
 */
177
function ds_search_get_keys($keys = NULL) {
178
  static $run, $saved_keys = FALSE;
179

    
180
  if (!$run) {
181
    $run = TRUE;
182
    $saved_keys = $keys;
183
  }
184
  else {
185
    return $saved_keys;
186
  }
187
}
188

    
189
/**
190
 * Invoke a given search hook on the node module.
191
 *
192
 * @param $hook
193
 *   Hook to invoke.
194
 */
195
function ds_search_invoke_node_search($hook) {
196

    
197
  $enabled_search_modules = variable_get('search_active_modules', array());
198

    
199
  // If node search is enabled, core is invoking it.
200
  if (isset($enabled_search_modules['node']) && $enabled_search_modules['node'] === 'node') {
201
    return;
202
  }
203
  else {
204
    $ds_search_type = variable_get('ds_search_type', 'node');
205
    if ($ds_search_type != 'node') {
206
      return;
207
    }
208
  }
209

    
210
  return module_invoke('node', $hook);
211
}
212

    
213
/**
214
 * DS entity view callback.
215
 *
216
 * Straight copy from Entity API module with fallback to Drupal core
217
 * view callbacks for nodes, files and maybe others later.
218
 */
219
function ds_entity_view_fallback($entity_type, $entities, $view_mode = 'full', $langcode = NULL, $page = NULL) {
220

    
221
  // Use the entity module in case it's enabled.
222
  if (module_exists('entity')) {
223
    return entity_view($entity_type, $entities, $view_mode, $langcode, $page);
224
  }
225
  else {
226
    if ($entity_type == 'node') {
227
      return node_view_multiple($entities, $view_mode);
228
    }
229
    elseif ($entity_type == 'file' && function_exists('file_view_multiple')) {
230
      return file_view_multiple($entities, $view_mode);
231
    }
232
  }
233
}
234

    
235
/**
236
 * Implements hook_search_page().
237
 */
238
function ds_search_search_page($results) {
239

    
240
  // Build shared variables.
241
  $build = array('#type' => 'node');
242
  ds_build_shared_page_variables($build);
243

    
244
  $i = 0;
245
  // Multi site Apache Solr support.
246
  if (variable_get('ds_search_apachesolr_multisite') && variable_get('ds_search_type', 'node') == 'apachesolr_search') {
247
    $build['search_results'] = $results;
248
  }
249
  else {
250
    foreach ($results as $id => $result) {
251
      // Use default search result theming for file in case it's configured.
252
      if ($result->entity_type == 'file' && variable_get('ds_search_file_render', FALSE)) {
253
        // Get the file type from the file entity module. We'll overwrite
254
        // the bundle here then as that makes more sense as a suggestion.
255
        if (function_exists('file_get_type')) {
256
          $type = file_get_type($result);
257
          $result->original_result['bundle'] = $type;
258
        }
259
        $build['search_results'][] = array(
260
          '#weight' => $i++,
261
          '#markup' => theme('search_result', array('result' => $result->original_result, 'module' => 'apachesolr_search')),
262
        );
263
        continue;
264
      }
265
      $entity_type = isset($result->entity_type) ? $result->entity_type : 'node';
266
      $data = ds_entity_view_fallback($entity_type, array($result->entity_id => $result), variable_get('ds_search_view_mode', 'search_result'));
267
      // Check that we got an actual result back.
268
      if ($data) {
269
        $data = reset($data);
270
        $data[$result->entity_id]['#weight'] = $i++;
271
        $build['search_results'][] = $data[$result->entity_id];
272
      }
273
    }
274
  }
275

    
276
  // Group by type.
277
  if (variable_get('ds_search_group_by_type') && variable_get('ds_search_group_by_type_settings') && !empty($build['search_results'])) {
278
    _ds_search_group_by_type($build);
279
  }
280
  else {
281
    // Provide zebra striping for results that are not grouped.
282
    $parity = 'odd';
283
    foreach ($build['search_results'] as $id => $result) {
284
      // We need to check on the entity type, as the container
285
      // where the object is stored in doesn't necessarily reflect
286
      // the name of the entity type.
287
      if (!empty($build['search_results'][$id]['#entity_type'])) {
288
        switch ($build['search_results'][$id]['#entity_type']) {
289
          case 'taxonomy_term':
290
            $key = '#term';
291
            break;
292

    
293
           default:
294
             $key = '#' . $build['search_results'][$id]['#entity_type'];
295
             break;
296
        }
297

    
298
        $build['search_results'][$id][$key]->ds_search_zebra = $parity;
299
      }
300

    
301
      // Let parity change always.
302
      $parity = $parity == 'odd' ? 'even' : 'odd';
303
    }
304
  }
305

    
306
  // Apache Solr multisearch grouping.
307
  if (variable_get('ds_search_apachesolr_multisite') && variable_get('ds_search_apachesolr_multisite_group') && variable_get('ds_search_type', 'node') == 'apachesolr_search') {
308
    _ds_search_group_by_type_multisearch($build);
309
  }
310

    
311
  return theme('ds_search_page', $build);
312
}
313

    
314
/**
315
 * Helper function to group by type.
316
 */
317
function _ds_search_group_by_type(&$build) {
318
  $settings = variable_get('ds_search_group_by_type_settings');
319
  foreach ($build['search_results'] as $id => $result) {
320
    if ($settings[$result['#bundle']]['status']) {
321

    
322
      // Type group.
323
      if (!isset($build['search_results'][$result['#bundle']])) {
324
        $type = $settings[$result['#bundle']]['wrapper'];
325
        $title = check_plain(t($settings[$result['#bundle']]['label']));
326
        $class = 'group-result group-result-' . strtr($result['#bundle'], '_', '-');
327
        $parity[$result['#bundle']] = 'odd';
328
        $build['search_results'][$result['#bundle']] = array(
329
          '#type' => $type,
330
          '#title' => $title,
331
          '#weight' => $settings[$result['#bundle']]['weight'],
332
          '#attributes' => array(
333
            'class' => array($class),
334
          ),
335
        );
336

    
337
        if ($type == 'markup') {
338
          $build['search_results'][$result['#bundle']]['#prefix'] = '<div class="' . $class . '">' . ((!empty($title)) ? ' <h2>' . $title . '</h2>' : '');
339
          $build['search_results'][$result['#bundle']]['#suffix'] = '</div>';
340
        }
341
      }
342

    
343
      // Move result into the wrapper of its type and unset previous.
344
      $build['search_results'][$result['#bundle']][$id] = $result;
345
      unset($build['search_results'][$id]);
346

    
347
      // Add the parity to the result to enable correct zebra striping.
348
      $build['search_results'][$result['#bundle']][$id]['#node']->ds_search_zebra = $parity[$result['#bundle']];
349
      $parity[$result['#bundle']] = $parity[$result['#bundle']] == 'odd' ? 'even' : 'odd';
350
    }
351
    else {
352

    
353
      // Other group.
354
      if (!isset($build['search_results']['ds-other'])) {
355
        $title = check_plain(t(variable_get('ds_search_group_by_type_other', 'Other')));
356
        $type = variable_get('ds_search_group_by_type_other_wrapper', 'fieldset');
357
        $class = 'group-result group-result-other';
358
        $parity['ds-other'] = 'odd';
359
        $build['search_results']['ds-other'] = array(
360
          '#type' => $type,
361
          '#title' => $title,
362
          '#weight' => 100,
363
          '#attributes' => array(
364
            'class' => array($class),
365
          ),
366
        );
367

    
368
        if ($type == 'markup') {
369
          $build['search_results']['ds-other']['#prefix'] = '<div class="' . $class . '">' . ((!empty($title)) ? '<h2>' . $title . '</h2>' : '');
370
          $build['search_results']['ds-other']['#suffix'] = '</div>';
371
        }
372
      }
373

    
374
      // Move result into other wrapper and unset previous.
375
      $build['search_results']['ds-other'][$id] = $result;
376
      unset($build['search_results'][$id]);
377

    
378
      // Add the parity to the result to enable correct zebra striping.
379
      $build['search_results']['ds-other'][$id]['#node']->ds_search_parity = $parity['ds-other'];
380
      $parity['ds-other'] = $parity['ds-other'] == 'odd' ? 'even' : 'odd';
381
    }
382
  }
383
}
384

    
385
/**
386
 * Helper function to perform grouping on Apache Solr multisearch.
387
 */
388
function _ds_search_group_by_type_multisearch(&$build) {
389
  $site_counter = array();
390
  $conf_array = array();
391
  $config = explode("\n", variable_get('ds_search_apachesolr_multisite_group_config'));
392
  foreach ($config as $weight => $conf) {
393
    $conf = trim($conf);
394
    if (empty($conf)) {
395
      continue;
396
    }
397
    $site_conf = explode('|', $conf);
398
    $conf_array[$site_conf[0]] = array(
399
      'label' => $site_conf[1],
400
      'wrapper' => $site_conf[2],
401
      'weight' => $weight,
402
    );
403
  }
404

    
405
  // Iterate over results.
406
  foreach ($build['search_results'] as $id => $result) {
407
    if (!isset($build['search_results'][$result['#site_hash']])) {
408
      $class = 'group-result group-result-' . strtr($result['#site_hash'], '_', '-');
409
      $build['search_results'][$result['#site_hash']] = array(
410
        '#type' => 'fieldset',
411
        '#weight' => $conf_array[$result['#site_hash']]['weight'],
412
        '#attributes' => array(
413
          'class' => array($class),
414
        ),
415
      );
416

    
417
      // Create site counter.
418
      $site_counter[$result['#site_hash']] = array(
419
        'counter' => 0,
420
        'title' => $conf_array[$result['#site_hash']]['label'],
421
        'type' => $conf_array[$result['#site_hash']]['wrapper'],
422
        'class' => $class,
423
      );
424
    }
425

    
426
    // Move result into other wrapper and unset previous. Also count for
427
    // every site so we can populate @total_per_site later on.
428
    $site_counter[$result['#site_hash']]['counter']++;
429
    $build['search_results'][$result['#site_hash']][$id] = $result;
430
    unset($build['search_results'][$id]);
431
  }
432

    
433
  // Site counter.
434
  foreach ($site_counter as $hash => $values) {
435
    $title = check_plain(t($values['title'], array('!total_per_site' => format_plural($values['counter'], '1 result', '@count results'))));
436
    if ($values['type'] == 'div') {
437
      $build['search_results'][$hash]['#prefix'] = '<div class="' . $values['class'] . '">' . ((!empty($title)) ? '<h2>' . $title . '</h2>' : '');
438
      $build['search_results'][$hash]['#suffix'] = '</div>';
439
    }
440
    else {
441
      $build['search_results'][$hash]['#title'] = $title;
442
    }
443
  }
444
}
445

    
446
/**
447
 * Search on behalf of Drupal Core.
448
 */
449
function node_ds_search_execute($keys = NULL, $conditions = NULL) {
450
  // Build matching conditions
451
  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('SearchQuery')->extend('PagerDefault');
452
  $query->join('node', 'n', 'n.nid = i.sid');
453
  $query
454
    ->condition('n.status', 1)
455
    ->addTag('node_access')
456
    ->searchExpression($keys, 'node');
457

    
458
  // Language.
459
  if (variable_get('ds_search_language', FALSE)) {
460
    global $language;
461
    $query->condition('n.language', $language->language);
462
  }
463

    
464
  // Insert special keywords.
465
  $query->setOption('type', 'n.type');
466
  $query->setOption('language', 'n.language');
467
  if ($query->setOption('term', 'ti.tid')) {
468
    $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
469
  }
470
  // Only continue if the first pass query matches.
471
  if (!$query->executeFirstPass()) {
472
    return array();
473
  }
474

    
475
  // Add the ranking expressions.
476
  _node_rankings($query);
477

    
478
  $limit = variable_get('ds_search_node_limit', 10);
479
  $query->limit($limit);
480

    
481
  // Load results.
482
  $find = $query->execute();
483
  $results = array();
484
  foreach ($find as $item) {
485
    $node = node_load($item->sid);
486
    $node->entity_type = 'node';
487
    $node->entity_id = $item->sid;
488
    $node->search_extra = module_invoke_all('node_search_result', $node);
489
    // Only build a node search snippet if this field is actually being used.
490
    $fields = ds_get_field_settings($node->entity_type, $node->type, 'search_result');
491
    if (!empty($fields) && isset($fields['search_snippet'])) {
492
      // Because the 'search_result' display is being built right now (and because it is being overridden by Display Suite),
493
      // it is necessary to use the 'search_index' display for rendered field content.
494
      $build = node_view($node, 'search_index');
495
      unset($build['#theme']);
496
      // Render the node.
497
      $rendered = drupal_render($build);
498
      // Attach extra information to the rendered output.
499
      $rendered .= ' ' . implode('', $node->search_extra);
500
      // Generate the snippet based on rendered content.
501
      $node->snippet = search_excerpt($keys, $rendered);
502
    }
503
    $results[$item->sid] = $node;
504
  }
505
  return $results;
506
}
507

    
508
/**
509
 * Override search results page for users.
510
 */
511
if (variable_get('ds_user_override_search_page', FALSE)) {
512
  function user_search_page($results) {
513
    $build = array('#type' => 'user');
514
    global $base_url;
515

    
516
    ds_build_shared_page_variables($build);
517

    
518
    $uids = array();
519
    foreach ($results as $key => $result) {
520
      $uid = FALSE;
521

    
522
      // Try to get the uid from the $result['link'];
523
      $path = explode('/', $result['link']);
524
      $uid = end($path);
525

    
526
      // Lookup drupal path, we are most likely having an alias.
527
      if (!is_numeric($uid)) {
528
        $path = str_replace($base_url . '/', '', $result['link']);
529
        $alias = drupal_get_normal_path($path);
530
        $path = explode('/', $alias);
531
        $uid = end($path);
532
      }
533

    
534
      if (is_numeric($uid)) {
535
        $uids[] = $uid;
536
      }
537

    
538
      // Return all uids.
539
      if (!empty($uids)) {
540
        $accounts = user_load_multiple($uids);
541
        foreach ($accounts as $account) {
542
          $build['search_results'][$account->uid] = user_view($account, variable_get('ds_search_view_mode', 'search_result'));
543
        }
544
      }
545
    }
546

    
547
    // Return output.
548
    return theme('ds_search_page', $build);
549
  }
550
}
551

    
552
/**
553
 * Build shared page variables.
554
 *
555
 * @param $build
556
 *   The build array.
557
 */
558
function ds_build_shared_page_variables(&$build) {
559
  // Search results title.
560
  if (variable_get('ds_search_show_title', FALSE)) {
561
    $build['search_title'] = array('#markup' => '<h2>' . t('Search results') . '</h2>');
562
  }
563

    
564
  // Extra variables.
565
  if (variable_get('ds_search_variables', 'none') != 'none') {
566
    $build['search_extra'] = array('#markup' => '<div class="ds-search-extra">' . ds_search_extra_variables(arg(2)) . '</div>');
567
  }
568

    
569
  // Search results.
570
  $build['search_results'] = array();
571

    
572
  // Pager.
573
  $build['search_pager'] = array('#markup' => theme('pager', array('tags' => NULL)));
574

    
575
  // CSS and JS.
576
  if (variable_get('ds_search_highlight', FALSE)) {
577
    drupal_add_css(drupal_get_path('module', 'ds_search') . '/css/ds_search.theme.css');
578
    drupal_add_js(drupal_get_path('module', 'ds_search') . '/js/ds_search.js');
579
    drupal_add_js(array(
580
      'ds_search' => array(
581
        'selector' => check_plain(variable_get('ds_search_highlight_selector', '.view-mode-search_result')),
582
        'search' => check_plain(arg(2)),
583
      ),
584
    ), 'setting');
585
  }
586
}
587

    
588
/**
589
 * Return the extra variables.
590
 */
591
function ds_search_extra_variables($arg_keys = NULL) {
592
  $type = variable_get('ds_search_variables', 'none');
593

    
594
  // Define the number of results being shown on a page.
595
  // We rely on the apache solr rows for now.
596
  $items_per_page = variable_get('apachesolr_rows', 10);
597

    
598
  // Get the current page.
599
  $current_page = isset($_REQUEST['page']) ? $_REQUEST['page']+1 : 1;
600

    
601
  // Get the total number of results from the $GLOBALS.
602
  $total = isset($GLOBALS['pager_total_items'][0]) ? $GLOBALS['pager_total_items'][0] : 0;
603

    
604
  // Perform calculation
605
  $start = $items_per_page * $current_page - ($items_per_page - 1);
606
  $end = $items_per_page * $current_page;
607
  if ($end > $total) $end = $total;
608

    
609
  // Get the search keys.
610
  $keys = empty($arg_keys) ? trim(ds_search_get_keys()) : $arg_keys;
611

    
612
  // Send the right extra variable.
613
  switch ($type) {
614
    case 'search_totals':
615
      return format_plural($total, 'One result', 'Total results: @total.', array('@total' => $total));
616
      break;
617

    
618
    case 'search_totals_plus_keywords':
619
      return format_plural($total, 'Your search for "<strong>@search</strong>" gave back 1 result.',
620
                                   'Your search for "<strong>@search</strong>" gave back @count results.',
621
                                   array('@search' => $keys));
622
      break;
623

    
624
    case 'search_totals_from_to_end':
625
      return format_plural($total, 'Displaying @start - @end of 1 result.',
626
                                   'Displaying @start - @end of @count results.',
627
                                   array('@start' => $start, '@end' => $end));
628
      break;
629
  }
630
}
631

    
632
/**
633
 * Implements hook_form_FORM_ID_alter().
634
 */
635
function ds_search_form_search_form_alter(&$form, $form_state) {
636
  if (variable_get('ds_search_type', 'node') == 'node' && isset($form['module']) && $form['module']['#value'] == 'ds_search') {
637
    if (variable_get('ds_search_node_form_alter', FALSE)) {
638
      $form['module']['#value'] = 'node';
639
      node_form_search_form_alter($form, $form_state);
640
    }
641
  }
642
}
643

    
644
/**
645
 * Implements hook_form_FORM_ID_alter().
646
 */
647
function ds_search_form_apachesolr_search_custom_page_search_form_alter(&$form, $form_state) {
648
  if (variable_get('ds_search_apachesolr_hide_current_filters', FALSE)) {
649
    $form['basic']['retain-filters']['#type'] = 'value';
650
    $form['basic']['retain-filters']['#value'] = variable_get('ds_search_apachesolr_current_filters_default', FALSE);
651
  }
652
}
653

    
654
/**
655
 * Implements hook_apachesolr_index_document_build().
656
 */
657
function ds_search_apachesolr_index_document_build(ApacheSolrDocument $document, $entity) {
658
  // Apache Solr multisite support. Render the node already here.
659
  if (variable_get('ds_search_apachesolr_multisite')) {
660
    ob_start();
661
    $element = node_view($entity, variable_get('ds_search_view_mode', 'search_result'));
662
    print drupal_render($element);
663
    $output = ob_get_contents();
664
    ob_end_clean();
665
    $document->addField('tm_ds_search_result', $output);
666
  }
667
}
668

    
669
/**
670
 * Implements hook_apachesolr_query_alter().
671
 */
672
function ds_search_apachesolr_query_alter($query) {
673

    
674
  // Apache Solr multisite support.
675
  if (variable_get('ds_search_apachesolr_multisite') && variable_get('ds_search_type', 'node') == 'apachesolr_search') {
676
    // Site hash.
677
    $query->addParam('fl', 'hash');
678
    // Rendered search result.
679
    $query->addParam('fl', 'tm_ds_search_result');
680

    
681
    // Make sure this site's search results are first.
682
    if (variable_get('ds_search_apachesolr_multisite_boost')) {
683
      $hash = apachesolr_site_hash();
684
      $query->addParam('bq', 'hash:' . $hash . '^' . variable_get('ds_search_apachesolr_multisite_boost_nr', 100));
685
    }
686
  }
687

    
688
  // Search per language.
689
  if (variable_get('ds_search_language', FALSE)) {
690
    global $language;
691
    $query->addFilter('ss_language', $language->language);
692
  }
693
}
694

    
695
/**
696
 * Process results on behalf of Apache Solr.
697
 */
698
function ds_search_process_results($results) {
699

    
700
  $processed_results = array();
701

    
702
  if (is_array($results) && !empty($results)) {
703
    foreach ($results as $result) {
704

    
705
      $load = entity_load($result['fields']['entity_type'], array($result['fields']['entity_id']));
706
      $entity = reset($load);
707
      if (!$entity) {
708
        watchdog('ds_search', "Empty entity loaded from results, possibly corrupt solr index? (@entity_type, @id)", array('@entity_type' => $result['fields']['entity_type'], '@id' => $result['fields']['entity_id']), WATCHDOG_DEBUG);
709
        continue;
710
      }
711

    
712
      // Add the snippet, url and extra info on the object.
713
      $entity->search_snippet = $result['snippet'];
714
      $entity->search_extra = $result['extra'];
715
      $entity->search_as_url = $result['fields']['url'];
716
      $entity->entity_type = $result['fields']['entity_type'];
717
      $entity->entity_id = $result['fields']['entity_id'];
718

    
719
      // Add the original result on the entity too in case this is a file
720
      // entity. Attachments have brittle support as the file entity only
721
      // exists in media 1.x or file entity 2.x. Because of that, we're
722
      // most likely will render files through theme('search_result').
723
      if ($result['fields']['entity_type'] == 'file') {
724
        $entity->original_result = $result;
725
      }
726

    
727
      // Apache Solr multisite support.
728
      if (variable_get('ds_search_apachesolr_multisite')) {
729

    
730
        // Pass along the uri path in case some people want to
731
        // do cool stuff themselves.
732
        $entity->uri['path'] = $entity->search_as_url;
733
        $entity->uri['options'] = array();
734

    
735
        // Prefix with site hash so we don't override same id's.
736
        $markup = $result['fields']['tm_ds_search_result'][0];
737
        $processed_results[$result['fields']['id'] . '-' . $result['fields']['entity_id']] = array(
738
          '#markup' => $markup,
739
          '#site_hash' => $result['fields']['hash'],
740
        );
741
      }
742
      else {
743
        $processed_results[$result['fields']['id'] . '-' . $result['fields']['entity_id']] = $entity;
744
      }
745
    }
746
  }
747

    
748
  return $processed_results;
749
}
750

    
751
/**
752
 * Implements hook_apachesolr_search_page_alter(&$build, $search_page).
753
 */
754
function ds_search_apachesolr_search_page_alter(&$build, $search_page) {
755
  if (!empty($build['search_results']['#results'])) {
756
    $results = ds_search_process_results($build['search_results']['#results']);
757
    $build['search_results'] = ds_search_search_page($results);
758
  }
759
}