Projet

Général

Profil

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

root / drupal7 / sites / all / modules / ds / modules / ds_search / ds_search.module @ bf6fb0ee

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
  // fix for Drupal 7.33+
58
  if(isset($build['theme_hook_original'])) {
59
    unset($build['theme_hook_original']);
60
  }
61

    
62
  // Check on empty search results.
63
  if (empty($build['search_results'])) {
64

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

    
71
    $build['search_empty'] = array('#markup' => search_help('search#noresults', drupal_help_arg()));
72
  }
73

    
74
  $build['search_results']['#sorted'] = TRUE;
75

    
76
  return $build;
77
}
78

    
79
/**
80
 * Implements hook_ds_fields_info().
81
 */
82
function ds_search_ds_fields_info($entity_type) {
83
  $fields = array();
84

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

    
100
  if (isset($fields[$entity_type])) {
101
    return array($entity_type => $fields[$entity_type]);
102
  }
103

    
104
  return;
105
}
106

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

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

    
134
/**
135
 * Implements hook_search_info().
136
 */
137
function ds_search_search_info() {
138
  return array(
139
    'title' => 'Content',
140
    'path' => variable_get('ds_search_path', 'content'),
141
  );
142
}
143

    
144
/**
145
 * Implements hook_node_update_index().
146
 */
147
function ds_search_update_index() {
148
  ds_search_invoke_node_search('update_index');
149
}
150

    
151
/**
152
 * Implements hook_search_status().
153
 */
154
function ds_search_search_status() {
155
  return ds_search_invoke_node_search('search_status');
156
}
157

    
158
/**
159
 * Implements hook_search_execute().
160
 */
161
function ds_search_search_execute($keys = NULL, $conditions = NULL) {
162
  // Save the keys in case we need them later on.
163
  ds_search_get_keys($keys);
164

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

    
172
  // Make sure the function exists.
173
  if (function_exists($ds_search_type)) {
174
    return $ds_search_type($keys, $conditions);
175
  }
176
}
177

    
178
/**
179
 * Save or get the search keys.
180
 */
181
function ds_search_get_keys($keys = NULL) {
182
  static $run, $saved_keys = FALSE;
183

    
184
  if (!$run) {
185
    $run = TRUE;
186
    $saved_keys = $keys;
187
  }
188
  else {
189
    return $saved_keys;
190
  }
191
}
192

    
193
/**
194
 * Invoke a given search hook on the node module.
195
 *
196
 * @param $hook
197
 *   Hook to invoke.
198
 */
199
function ds_search_invoke_node_search($hook) {
200

    
201
  $enabled_search_modules = variable_get('search_active_modules', array());
202

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

    
214
  return module_invoke('node', $hook);
215
}
216

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

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

    
239
/**
240
 * Implements hook_search_page().
241
 */
242
function ds_search_search_page($results) {
243

    
244
  // Build shared variables.
245
  $build = array('#type' => 'node');
246
  ds_build_shared_page_variables($build);
247

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

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

    
297
           default:
298
             $key = '#' . $build['search_results'][$id]['#entity_type'];
299
             break;
300
        }
301

    
302
        $build['search_results'][$id][$key]->ds_search_zebra = $parity;
303
      }
304

    
305
      // Let parity change always.
306
      $parity = $parity == 'odd' ? 'even' : 'odd';
307
    }
308
  }
309

    
310
  // Apache Solr multisearch grouping.
311
  if (variable_get('ds_search_apachesolr_multisite') && variable_get('ds_search_apachesolr_multisite_group') && variable_get('ds_search_type', 'node') == 'apachesolr_search') {
312
    _ds_search_group_by_type_multisearch($build);
313
  }
314

    
315
  return theme('ds_search_page', $build);
316
}
317

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

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

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

    
347
      // Move result into the wrapper of its type and unset previous.
348
      $build['search_results'][$result['#bundle']][$id] = $result;
349
      unset($build['search_results'][$id]);
350

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

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

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

    
378
      // Move result into other wrapper and unset previous.
379
      $build['search_results']['ds-other'][$id] = $result;
380
      unset($build['search_results'][$id]);
381

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

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

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

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

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

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

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

    
462
  // Language.
463
  if (variable_get('ds_search_language', FALSE)) {
464
    global $language;
465
    $query->condition('n.language', $language->language);
466
  }
467

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

    
479
  // Add the ranking expressions.
480
  _node_rankings($query);
481

    
482
  $limit = variable_get('ds_search_node_limit', 10);
483
  $query->limit($limit);
484

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

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

    
520
    ds_build_shared_page_variables($build);
521

    
522
    $uids = array();
523
    foreach ($results as $key => $result) {
524
      $uid = FALSE;
525

    
526
      // Try to get the uid from the $result['link'];
527
      $path = explode('/', $result['link']);
528
      $uid = end($path);
529

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

    
538
      if (is_numeric($uid)) {
539
        $uids[] = $uid;
540
      }
541

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

    
551
    // Return output.
552
    return theme('ds_search_page', $build);
553
  }
554
}
555

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

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

    
573
  // Search results.
574
  $build['search_results'] = array();
575

    
576
  // Pager.
577
  $build['search_pager'] = array('#markup' => theme('pager', array('tags' => NULL)));
578

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

    
592
/**
593
 * Return the extra variables.
594
 */
595
function ds_search_extra_variables($arg_keys = NULL) {
596
  $type = variable_get('ds_search_variables', 'none');
597

    
598
  // Define the number of results being shown on a page.
599
  // We rely on the apache solr rows for now.
600
  $items_per_page = variable_get('apachesolr_rows', 10);
601

    
602
  // Get the current page.
603
  $current_page = isset($_REQUEST['page']) ? $_REQUEST['page']+1 : 1;
604

    
605
  // Get the total number of results from the $GLOBALS.
606
  $total = isset($GLOBALS['pager_total_items'][0]) ? $GLOBALS['pager_total_items'][0] : 0;
607

    
608
  // Perform calculation
609
  $start = $items_per_page * $current_page - ($items_per_page - 1);
610
  $end = $items_per_page * $current_page;
611
  if ($end > $total) $end = $total;
612

    
613
  // Get the search keys.
614
  $keys = empty($arg_keys) ? trim(ds_search_get_keys()) : $arg_keys;
615

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

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

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

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

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

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

    
673
/**
674
 * Implements hook_apachesolr_query_alter().
675
 */
676
function ds_search_apachesolr_query_alter($query) {
677

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

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

    
692
  // Search per language.
693
  if (variable_get('ds_search_language', FALSE)) {
694
    global $language;
695
    $query->addFilter('ss_language', $language->language);
696
  }
697
}
698

    
699
/**
700
 * Process results on behalf of Apache Solr.
701
 */
702
function ds_search_process_results($results) {
703

    
704
  $processed_results = array();
705

    
706
  if (is_array($results) && !empty($results)) {
707
    foreach ($results as $result) {
708

    
709
      $load = entity_load($result['fields']['entity_type'], array($result['fields']['entity_id']));
710
      $entity = reset($load);
711
      if (!$entity) {
712
        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);
713
        continue;
714
      }
715

    
716
      // Add the snippet, url and extra info on the object.
717
      $entity->search_snippet = $result['snippet'];
718
      $entity->search_extra = $result['extra'];
719
      $entity->search_as_url = $result['fields']['url'];
720
      $entity->entity_type = $result['fields']['entity_type'];
721
      $entity->entity_id = $result['fields']['entity_id'];
722

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

    
731
      // Apache Solr multisite support.
732
      if (variable_get('ds_search_apachesolr_multisite')) {
733

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

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

    
752
  return $processed_results;
753
}
754

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